chiark / gitweb /
core: rework context initialization/destruction logic
[elogind.git] / src / core / swap.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <limits.h>
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <sys/epoll.h>
27 #include <sys/stat.h>
28 #include <sys/swap.h>
29 #include <libudev.h>
30
31 #include "unit.h"
32 #include "swap.h"
33 #include "load-fragment.h"
34 #include "load-dropin.h"
35 #include "unit-name.h"
36 #include "dbus-swap.h"
37 #include "special.h"
38 #include "bus-errors.h"
39 #include "exit-status.h"
40 #include "def.h"
41 #include "path-util.h"
42 #include "virt.h"
43 #include "udev-util.h"
44
45 static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
46         [SWAP_DEAD] = UNIT_INACTIVE,
47         [SWAP_ACTIVATING] = UNIT_ACTIVATING,
48         [SWAP_ACTIVATING_DONE] = UNIT_ACTIVE,
49         [SWAP_ACTIVE] = UNIT_ACTIVE,
50         [SWAP_DEACTIVATING] = UNIT_DEACTIVATING,
51         [SWAP_ACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
52         [SWAP_ACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
53         [SWAP_DEACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
54         [SWAP_DEACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
55         [SWAP_FAILED] = UNIT_FAILED
56 };
57
58 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
59 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
60
61 static void swap_unset_proc_swaps(Swap *s) {
62         assert(s);
63
64         if (!s->from_proc_swaps)
65                 return;
66
67         free(s->parameters_proc_swaps.what);
68         s->parameters_proc_swaps.what = NULL;
69
70         s->from_proc_swaps = false;
71 }
72
73 static int swap_set_devnode(Swap *s, const char *devnode) {
74         Hashmap *swaps;
75         Swap *first;
76         int r;
77
78         assert(s);
79
80         r = hashmap_ensure_allocated(&UNIT(s)->manager->swaps_by_devnode, string_hash_func, string_compare_func);
81         if (r < 0)
82                 return r;
83
84         swaps = UNIT(s)->manager->swaps_by_devnode;
85
86         if (s->devnode) {
87                 first = hashmap_get(swaps, s->devnode);
88
89                 LIST_REMOVE(same_devnode, first, s);
90                 if (first)
91                         hashmap_replace(swaps, first->devnode, first);
92                 else
93                         hashmap_remove(swaps, s->devnode);
94
95                 free(s->devnode);
96                 s->devnode = NULL;
97         }
98
99         if (devnode) {
100                 s->devnode = strdup(devnode);
101                 if (!s->devnode)
102                         return -ENOMEM;
103
104                 first = hashmap_get(swaps, s->devnode);
105                 LIST_PREPEND(same_devnode, first, s);
106
107                 return hashmap_replace(swaps, first->devnode, first);
108         }
109
110         return 0;
111 }
112
113 static void swap_init(Unit *u) {
114         Swap *s = SWAP(u);
115
116         assert(s);
117         assert(UNIT(s)->load_state == UNIT_STUB);
118
119         s->timeout_usec = u->manager->default_timeout_start_usec;
120
121         s->exec_context.std_output = u->manager->default_std_output;
122         s->exec_context.std_error = u->manager->default_std_error;
123
124         s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
125
126         s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
127
128         u->ignore_on_isolate = true;
129 }
130
131 static void swap_unwatch_control_pid(Swap *s) {
132         assert(s);
133
134         if (s->control_pid <= 0)
135                 return;
136
137         unit_unwatch_pid(UNIT(s), s->control_pid);
138         s->control_pid = 0;
139 }
140
141 static void swap_done(Unit *u) {
142         Swap *s = SWAP(u);
143
144         assert(s);
145
146         swap_unset_proc_swaps(s);
147         swap_set_devnode(s, NULL);
148
149         free(s->what);
150         s->what = NULL;
151
152         free(s->parameters_fragment.what);
153         s->parameters_fragment.what = NULL;
154
155         s->exec_runtime = exec_runtime_unref(s->exec_runtime);
156         exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
157         s->control_command = NULL;
158
159         swap_unwatch_control_pid(s);
160
161         s->timer_event_source = sd_event_source_unref(s->timer_event_source);
162 }
163
164 static int swap_arm_timer(Swap *s) {
165         int r;
166
167         assert(s);
168
169         if (s->timeout_usec <= 0) {
170                 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
171                 return 0;
172         }
173
174         if (s->timer_event_source) {
175                 r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec);
176                 if (r < 0)
177                         return r;
178
179                 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
180         }
181
182         return sd_event_add_monotonic(UNIT(s)->manager->event, &s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec, 0, swap_dispatch_timer, s);
183 }
184
185 static int swap_add_device_links(Swap *s) {
186         SwapParameters *p;
187
188         assert(s);
189
190         if (!s->what)
191                 return 0;
192
193         if (s->from_fragment)
194                 p = &s->parameters_fragment;
195         else
196                 return 0;
197
198         if (is_device_path(s->what))
199                 return unit_add_node_link(UNIT(s), s->what, !p->noauto && UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
200         else
201                 /* File based swap devices need to be ordered after
202                  * systemd-remount-fs.service, since they might need a
203                  * writable file system. */
204                 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
205 }
206
207 static int swap_add_default_dependencies(Swap *s) {
208         bool nofail = false, noauto = false;
209         int r;
210
211         assert(s);
212
213         if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
214                 return 0;
215
216         if (detect_container(NULL) > 0)
217                 return 0;
218
219         r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
220         if (r < 0)
221                 return r;
222
223         if (s->from_fragment) {
224                 SwapParameters *p = &s->parameters_fragment;
225
226                 nofail = p->nofail;
227                 noauto = p->noauto;
228         }
229
230         if (!noauto) {
231                 if (nofail)
232                         r = unit_add_dependency_by_name_inverse(UNIT(s), UNIT_WANTS, SPECIAL_SWAP_TARGET, NULL, true);
233                 else
234                         r = unit_add_two_dependencies_by_name_inverse(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SWAP_TARGET, NULL, true);
235                 if (r < 0)
236                         return r;
237         }
238
239         return 0;
240 }
241
242 static int swap_verify(Swap *s) {
243         bool b;
244         _cleanup_free_ char *e = NULL;
245
246         if (UNIT(s)->load_state != UNIT_LOADED)
247                 return 0;
248
249         e = unit_name_from_path(s->what, ".swap");
250         if (!e)
251                 return log_oom();
252
253         b = unit_has_name(UNIT(s), e);
254         if (!b) {
255                 log_error_unit(UNIT(s)->id, "%s: Value of \"What\" and unit name do not match, not loading.", UNIT(s)->id);
256                 return -EINVAL;
257         }
258
259         if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
260                 log_error_unit(UNIT(s)->id, "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.", UNIT(s)->id);
261                 return -EINVAL;
262         }
263
264         return 0;
265 }
266
267 static int swap_load_devnode(Swap *s) {
268         _cleanup_udev_device_unref_ struct udev_device *d = NULL;
269         struct stat st;
270         const char *p;
271
272         assert(s);
273
274         if (stat(s->what, &st) < 0 || !S_ISBLK(st.st_mode))
275                 return 0;
276
277         d = udev_device_new_from_devnum(UNIT(s)->manager->udev, 'b', st.st_rdev);
278         if (!d)
279                 return 0;
280
281         p = udev_device_get_devnode(d);
282         if (!p)
283                 return 0;
284
285         return swap_set_devnode(s, p);
286 }
287
288 static int swap_load(Unit *u) {
289         int r;
290         Swap *s = SWAP(u);
291
292         assert(s);
293         assert(u->load_state == UNIT_STUB);
294
295         /* Load a .swap file */
296         r = unit_load_fragment_and_dropin_optional(u);
297         if (r < 0)
298                 return r;
299
300         if (u->load_state == UNIT_LOADED) {
301
302                 if (UNIT(s)->fragment_path)
303                         s->from_fragment = true;
304
305                 if (!s->what) {
306                         if (s->parameters_fragment.what)
307                                 s->what = strdup(s->parameters_fragment.what);
308                         else if (s->parameters_proc_swaps.what)
309                                 s->what = strdup(s->parameters_proc_swaps.what);
310                         else
311                                 s->what = unit_name_to_path(u->id);
312
313                         if (!s->what)
314                                 return -ENOMEM;
315                 }
316
317                 path_kill_slashes(s->what);
318
319                 if (!UNIT(s)->description) {
320                         r = unit_set_description(u, s->what);
321                         if (r < 0)
322                                 return r;
323                 }
324
325                 r = unit_require_mounts_for(UNIT(s), s->what);
326                 if (r < 0)
327                         return r;
328
329                 r = swap_add_device_links(s);
330                 if (r < 0)
331                         return r;
332
333                 r = swap_load_devnode(s);
334                 if (r < 0)
335                         return r;
336
337                 r = unit_patch_contexts(u);
338                 if (r < 0)
339                         return r;
340
341                 r = unit_add_exec_dependencies(u, &s->exec_context);
342                 if (r < 0)
343                         return r;
344
345                 r = unit_add_default_slice(u, &s->cgroup_context);
346                 if (r < 0)
347                         return r;
348
349                 if (UNIT(s)->default_dependencies) {
350                         r = swap_add_default_dependencies(s);
351                         if (r < 0)
352                                 return r;
353                 }
354         }
355
356         return swap_verify(s);
357 }
358
359 static int swap_add_one(
360                 Manager *m,
361                 const char *what,
362                 const char *what_proc_swaps,
363                 int priority,
364                 bool noauto,
365                 bool nofail,
366                 bool set_flags) {
367
368         _cleanup_free_ char *e = NULL;
369         bool delete = false;
370         Unit *u = NULL;
371         int r;
372         SwapParameters *p;
373
374         assert(m);
375         assert(what);
376         assert(what_proc_swaps);
377
378         e = unit_name_from_path(what, ".swap");
379         if (!e)
380                 return log_oom();
381
382         u = manager_get_unit(m, e);
383
384         if (u &&
385             SWAP(u)->from_proc_swaps &&
386             !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
387                 return -EEXIST;
388
389         if (!u) {
390                 delete = true;
391
392                 u = unit_new(m, sizeof(Swap));
393                 if (!u)
394                         return log_oom();
395
396                 r = unit_add_name(u, e);
397                 if (r < 0)
398                         goto fail;
399
400                 SWAP(u)->what = strdup(what);
401                 if (!SWAP(u)->what) {
402                         r = log_oom();
403                         goto fail;
404                 }
405
406                 unit_add_to_load_queue(u);
407         } else
408                 delete = false;
409
410         p = &SWAP(u)->parameters_proc_swaps;
411
412         if (!p->what) {
413                 p->what = strdup(what_proc_swaps);
414                 if (!p->what) {
415                         r = -ENOMEM;
416                         goto fail;
417                 }
418         }
419
420         if (set_flags) {
421                 SWAP(u)->is_active = true;
422                 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
423         }
424
425         SWAP(u)->from_proc_swaps = true;
426
427         p->priority = priority;
428         p->noauto = noauto;
429         p->nofail = nofail;
430
431         unit_add_to_dbus_queue(u);
432
433         return 0;
434
435 fail:
436         log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
437
438         if (delete && u)
439                 unit_free(u);
440
441         return r;
442 }
443
444 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
445         _cleanup_udev_device_unref_ struct udev_device *d = NULL;
446         struct udev_list_entry *item = NULL, *first = NULL;
447         const char *dn;
448         struct stat st;
449         int r;
450
451         assert(m);
452
453         r = swap_add_one(m, device, device, prio, false, false, set_flags);
454         if (r < 0)
455                 return r;
456
457         /* If this is a block device, then let's add duplicates for
458          * all other names of this block device */
459         if (stat(device, &st) < 0 || !S_ISBLK(st.st_mode))
460                 return 0;
461
462         d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
463         if (!d)
464                 return 0;
465
466         /* Add the main device node */
467         dn = udev_device_get_devnode(d);
468         if (dn && !streq(dn, device))
469                 swap_add_one(m, dn, device, prio, false, false, set_flags);
470
471         /* Add additional units for all symlinks */
472         first = udev_device_get_devlinks_list_entry(d);
473         udev_list_entry_foreach(item, first) {
474                 const char *p;
475
476                 /* Don't bother with the /dev/block links */
477                 p = udev_list_entry_get_name(item);
478
479                 if (streq(p, device))
480                         continue;
481
482                 if (path_startswith(p, "/dev/block/"))
483                         continue;
484
485                 if (stat(p, &st) >= 0)
486                         if (!S_ISBLK(st.st_mode) ||
487                             st.st_rdev != udev_device_get_devnum(d))
488                                 continue;
489
490                 swap_add_one(m, p, device, prio, false, false, set_flags);
491         }
492
493         return r;
494 }
495
496 static void swap_set_state(Swap *s, SwapState state) {
497         SwapState old_state;
498
499         assert(s);
500
501         old_state = s->state;
502         s->state = state;
503
504         if (state != SWAP_ACTIVATING &&
505             state != SWAP_ACTIVATING_SIGTERM &&
506             state != SWAP_ACTIVATING_SIGKILL &&
507             state != SWAP_ACTIVATING_DONE &&
508             state != SWAP_DEACTIVATING &&
509             state != SWAP_DEACTIVATING_SIGTERM &&
510             state != SWAP_DEACTIVATING_SIGKILL) {
511                 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
512                 swap_unwatch_control_pid(s);
513                 s->control_command = NULL;
514                 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
515         }
516
517         if (state != old_state)
518                 log_debug_unit(UNIT(s)->id,
519                                "%s changed %s -> %s",
520                                UNIT(s)->id,
521                                swap_state_to_string(old_state),
522                                swap_state_to_string(state));
523
524         unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
525 }
526
527 static int swap_coldplug(Unit *u) {
528         Swap *s = SWAP(u);
529         SwapState new_state = SWAP_DEAD;
530         int r;
531
532         assert(s);
533         assert(s->state == SWAP_DEAD);
534
535         if (s->deserialized_state != s->state)
536                 new_state = s->deserialized_state;
537         else if (s->from_proc_swaps)
538                 new_state = SWAP_ACTIVE;
539
540         if (new_state == s->state)
541                 return 0;
542
543         if (new_state == SWAP_ACTIVATING ||
544             new_state == SWAP_ACTIVATING_SIGTERM ||
545             new_state == SWAP_ACTIVATING_SIGKILL ||
546             new_state == SWAP_ACTIVATING_DONE ||
547             new_state == SWAP_DEACTIVATING ||
548             new_state == SWAP_DEACTIVATING_SIGTERM ||
549             new_state == SWAP_DEACTIVATING_SIGKILL) {
550
551                 if (s->control_pid <= 0)
552                         return -EBADMSG;
553
554                 r = unit_watch_pid(UNIT(s), s->control_pid);
555                 if (r < 0)
556                         return r;
557
558                 r = swap_arm_timer(s);
559                 if (r < 0)
560                         return r;
561         }
562
563         swap_set_state(s, new_state);
564         return 0;
565 }
566
567 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
568         Swap *s = SWAP(u);
569         SwapParameters *p;
570
571         assert(s);
572         assert(f);
573
574         if (s->from_proc_swaps)
575                 p = &s->parameters_proc_swaps;
576         else if (s->from_fragment)
577                 p = &s->parameters_fragment;
578         else
579                 p = NULL;
580
581         fprintf(f,
582                 "%sSwap State: %s\n"
583                 "%sResult: %s\n"
584                 "%sWhat: %s\n"
585                 "%sFrom /proc/swaps: %s\n"
586                 "%sFrom fragment: %s\n",
587                 prefix, swap_state_to_string(s->state),
588                 prefix, swap_result_to_string(s->result),
589                 prefix, s->what,
590                 prefix, yes_no(s->from_proc_swaps),
591                 prefix, yes_no(s->from_fragment));
592
593         if (s->devnode)
594                 fprintf(f, "%sDevice Node: %s\n", prefix, s->devnode);
595
596         if (p)
597                 fprintf(f,
598                         "%sPriority: %i\n"
599                         "%sNoAuto: %s\n"
600                         "%sNoFail: %s\n",
601                         prefix, p->priority,
602                         prefix, yes_no(p->noauto),
603                         prefix, yes_no(p->nofail));
604
605         if (s->control_pid > 0)
606                 fprintf(f,
607                         "%sControl PID: %lu\n",
608                         prefix, (unsigned long) s->control_pid);
609
610         exec_context_dump(&s->exec_context, f, prefix);
611         kill_context_dump(&s->kill_context, f, prefix);
612 }
613
614 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
615         pid_t pid;
616         int r;
617
618         assert(s);
619         assert(c);
620         assert(_pid);
621
622         unit_realize_cgroup(UNIT(s));
623
624         r = unit_setup_exec_runtime(UNIT(s));
625         if (r < 0)
626                 goto fail;
627
628         r = swap_arm_timer(s);
629         if (r < 0)
630                 goto fail;
631
632         r = exec_spawn(c,
633                        NULL,
634                        &s->exec_context,
635                        NULL, 0,
636                        UNIT(s)->manager->environment,
637                        true,
638                        true,
639                        true,
640                        UNIT(s)->manager->confirm_spawn,
641                        UNIT(s)->manager->cgroup_supported,
642                        UNIT(s)->cgroup_path,
643                        manager_get_runtime_prefix(UNIT(s)->manager),
644                        UNIT(s)->id,
645                        0,
646                        NULL,
647                        s->exec_runtime,
648                        &pid);
649         if (r < 0)
650                 goto fail;
651
652         r = unit_watch_pid(UNIT(s), pid);
653         if (r < 0)
654                 /* FIXME: we need to do something here */
655                 goto fail;
656
657         *_pid = pid;
658
659         return 0;
660
661 fail:
662         s->timer_event_source = sd_event_source_unref(s->timer_event_source);
663
664         return r;
665 }
666
667 static void swap_enter_dead(Swap *s, SwapResult f) {
668         assert(s);
669
670         if (f != SWAP_SUCCESS)
671                 s->result = f;
672
673         exec_runtime_destroy(s->exec_runtime);
674         s->exec_runtime = exec_runtime_unref(s->exec_runtime);
675
676         exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
677
678         swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
679 }
680
681 static void swap_enter_active(Swap *s, SwapResult f) {
682         assert(s);
683
684         if (f != SWAP_SUCCESS)
685                 s->result = f;
686
687         swap_set_state(s, SWAP_ACTIVE);
688 }
689
690 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
691         int r;
692
693         assert(s);
694
695         if (f != SWAP_SUCCESS)
696                 s->result = f;
697
698         r = unit_kill_context(
699                         UNIT(s),
700                         &s->kill_context,
701                         state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
702                         -1,
703                         s->control_pid,
704                         false);
705         if (r < 0)
706                 goto fail;
707
708         if (r > 0) {
709                 r = swap_arm_timer(s);
710                 if (r < 0)
711                         goto fail;
712
713                 swap_set_state(s, state);
714         } else if (state == SWAP_ACTIVATING_SIGTERM)
715                 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_SUCCESS);
716         else if (state == SWAP_DEACTIVATING_SIGTERM)
717                 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_SUCCESS);
718         else
719                 swap_enter_dead(s, SWAP_SUCCESS);
720
721         return;
722
723 fail:
724         log_warning_unit(UNIT(s)->id,
725                          "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
726
727         swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
728 }
729
730 static void swap_enter_activating(Swap *s) {
731         int r, priority;
732
733         assert(s);
734
735         s->control_command_id = SWAP_EXEC_ACTIVATE;
736         s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
737
738         if (s->from_fragment)
739                 priority = s->parameters_fragment.priority;
740         else
741                 priority = -1;
742
743         if (priority >= 0) {
744                 char p[DECIMAL_STR_MAX(int)];
745
746                 sprintf(p, "%i", priority);
747
748                 r = exec_command_set(
749                                 s->control_command,
750                                 "/sbin/swapon",
751                                 "-p",
752                                 p,
753                                 s->what,
754                                 NULL);
755         } else
756                 r = exec_command_set(
757                                 s->control_command,
758                                 "/sbin/swapon",
759                                 s->what,
760                                 NULL);
761
762         if (r < 0)
763                 goto fail;
764
765         swap_unwatch_control_pid(s);
766
767         r = swap_spawn(s, s->control_command, &s->control_pid);
768         if (r < 0)
769                 goto fail;
770
771         swap_set_state(s, SWAP_ACTIVATING);
772
773         return;
774
775 fail:
776         log_warning_unit(UNIT(s)->id,
777                          "%s failed to run 'swapon' task: %s",
778                          UNIT(s)->id, strerror(-r));
779         swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
780 }
781
782 static void swap_enter_deactivating(Swap *s) {
783         int r;
784
785         assert(s);
786
787         s->control_command_id = SWAP_EXEC_DEACTIVATE;
788         s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
789
790         r = exec_command_set(s->control_command,
791                              "/sbin/swapoff",
792                              s->what,
793                              NULL);
794         if (r < 0)
795                 goto fail;
796
797         swap_unwatch_control_pid(s);
798
799         r = swap_spawn(s, s->control_command, &s->control_pid);
800         if (r < 0)
801                 goto fail;
802
803         swap_set_state(s, SWAP_DEACTIVATING);
804
805         return;
806
807 fail:
808         log_warning_unit(UNIT(s)->id,
809                          "%s failed to run 'swapoff' task: %s",
810                          UNIT(s)->id, strerror(-r));
811         swap_enter_active(s, SWAP_FAILURE_RESOURCES);
812 }
813
814 static int swap_start(Unit *u) {
815         Swap *s = SWAP(u);
816
817         assert(s);
818
819         /* We cannot fulfill this request right now, try again later
820          * please! */
821
822         if (s->state == SWAP_DEACTIVATING ||
823             s->state == SWAP_DEACTIVATING_SIGTERM ||
824             s->state == SWAP_DEACTIVATING_SIGKILL ||
825             s->state == SWAP_ACTIVATING_SIGTERM ||
826             s->state == SWAP_ACTIVATING_SIGKILL)
827                 return -EAGAIN;
828
829         if (s->state == SWAP_ACTIVATING)
830                 return 0;
831
832         assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
833
834         if (detect_container(NULL) > 0)
835                 return -EPERM;
836
837         s->result = SWAP_SUCCESS;
838         swap_enter_activating(s);
839         return 0;
840 }
841
842 static int swap_stop(Unit *u) {
843         Swap *s = SWAP(u);
844
845         assert(s);
846
847         if (s->state == SWAP_DEACTIVATING ||
848             s->state == SWAP_DEACTIVATING_SIGTERM ||
849             s->state == SWAP_DEACTIVATING_SIGKILL ||
850             s->state == SWAP_ACTIVATING_SIGTERM ||
851             s->state == SWAP_ACTIVATING_SIGKILL)
852                 return 0;
853
854         assert(s->state == SWAP_ACTIVATING ||
855                s->state == SWAP_ACTIVATING_DONE ||
856                s->state == SWAP_ACTIVE);
857
858         if (detect_container(NULL) > 0)
859                 return -EPERM;
860
861         swap_enter_deactivating(s);
862         return 0;
863 }
864
865 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
866         Swap *s = SWAP(u);
867
868         assert(s);
869         assert(f);
870         assert(fds);
871
872         unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
873         unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
874
875         if (s->control_pid > 0)
876                 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
877
878         if (s->control_command_id >= 0)
879                 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
880
881         return 0;
882 }
883
884 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
885         Swap *s = SWAP(u);
886
887         assert(s);
888         assert(fds);
889
890         if (streq(key, "state")) {
891                 SwapState state;
892
893                 state = swap_state_from_string(value);
894                 if (state < 0)
895                         log_debug_unit(u->id, "Failed to parse state value %s", value);
896                 else
897                         s->deserialized_state = state;
898         } else if (streq(key, "result")) {
899                 SwapResult f;
900
901                 f = swap_result_from_string(value);
902                 if (f < 0)
903                         log_debug_unit(u->id, "Failed to parse result value %s", value);
904                 else if (f != SWAP_SUCCESS)
905                         s->result = f;
906         } else if (streq(key, "control-pid")) {
907                 pid_t pid;
908
909                 if (parse_pid(value, &pid) < 0)
910                         log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
911                 else
912                         s->control_pid = pid;
913
914         } else if (streq(key, "control-command")) {
915                 SwapExecCommand id;
916
917                 id = swap_exec_command_from_string(value);
918                 if (id < 0)
919                         log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
920                 else {
921                         s->control_command_id = id;
922                         s->control_command = s->exec_command + id;
923                 }
924         } else
925                 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
926
927         return 0;
928 }
929
930 _pure_ static UnitActiveState swap_active_state(Unit *u) {
931         assert(u);
932
933         return state_translation_table[SWAP(u)->state];
934 }
935
936 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
937         assert(u);
938
939         return swap_state_to_string(SWAP(u)->state);
940 }
941
942 _pure_ static bool swap_check_gc(Unit *u) {
943         Swap *s = SWAP(u);
944
945         assert(s);
946
947         return s->from_proc_swaps;
948 }
949
950 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
951         Swap *s = SWAP(u);
952         SwapResult f;
953
954         assert(s);
955         assert(pid >= 0);
956
957         if (pid != s->control_pid)
958                 return;
959
960         s->control_pid = 0;
961
962         if (is_clean_exit(code, status, NULL))
963                 f = SWAP_SUCCESS;
964         else if (code == CLD_EXITED)
965                 f = SWAP_FAILURE_EXIT_CODE;
966         else if (code == CLD_KILLED)
967                 f = SWAP_FAILURE_SIGNAL;
968         else if (code == CLD_DUMPED)
969                 f = SWAP_FAILURE_CORE_DUMP;
970         else
971                 assert_not_reached("Unknown code");
972
973         if (f != SWAP_SUCCESS)
974                 s->result = f;
975
976         if (s->control_command) {
977                 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
978
979                 s->control_command = NULL;
980                 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
981         }
982
983         log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
984                       u->id,
985                       "%s swap process exited, code=%s status=%i",
986                       u->id, sigchld_code_to_string(code), status);
987
988         switch (s->state) {
989
990         case SWAP_ACTIVATING:
991         case SWAP_ACTIVATING_DONE:
992         case SWAP_ACTIVATING_SIGTERM:
993         case SWAP_ACTIVATING_SIGKILL:
994
995                 if (f == SWAP_SUCCESS)
996                         swap_enter_active(s, f);
997                 else
998                         swap_enter_dead(s, f);
999                 break;
1000
1001         case SWAP_DEACTIVATING:
1002         case SWAP_DEACTIVATING_SIGKILL:
1003         case SWAP_DEACTIVATING_SIGTERM:
1004
1005                 swap_enter_dead(s, f);
1006                 break;
1007
1008         default:
1009                 assert_not_reached("Uh, control process died at wrong time.");
1010         }
1011
1012         /* Notify clients about changed exit status */
1013         unit_add_to_dbus_queue(u);
1014 }
1015
1016 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1017         Swap *s = SWAP(userdata);
1018
1019         assert(s);
1020         assert(s->timer_event_source == source);
1021
1022         switch (s->state) {
1023
1024         case SWAP_ACTIVATING:
1025         case SWAP_ACTIVATING_DONE:
1026                 log_warning_unit(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
1027                 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1028                 break;
1029
1030         case SWAP_DEACTIVATING:
1031                 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
1032                 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1033                 break;
1034
1035         case SWAP_ACTIVATING_SIGTERM:
1036                 if (s->kill_context.send_sigkill) {
1037                         log_warning_unit(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
1038                         swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1039                 } else {
1040                         log_warning_unit(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1041                         swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1042                 }
1043                 break;
1044
1045         case SWAP_DEACTIVATING_SIGTERM:
1046                 if (s->kill_context.send_sigkill) {
1047                         log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
1048                         swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1049                 } else {
1050                         log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1051                         swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1052                 }
1053                 break;
1054
1055         case SWAP_ACTIVATING_SIGKILL:
1056         case SWAP_DEACTIVATING_SIGKILL:
1057                 log_warning_unit(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
1058                 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1059                 break;
1060
1061         default:
1062                 assert_not_reached("Timeout at wrong time.");
1063         }
1064
1065         return 0;
1066 }
1067
1068 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1069         unsigned i;
1070         int r = 0;
1071
1072         assert(m);
1073
1074         rewind(m->proc_swaps);
1075
1076         (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1077
1078         for (i = 1;; i++) {
1079                 _cleanup_free_ char *dev = NULL, *d = NULL;
1080                 int prio = 0, k;
1081
1082                 k = fscanf(m->proc_swaps,
1083                            "%ms "  /* device/file */
1084                            "%*s "  /* type of swap */
1085                            "%*s "  /* swap size */
1086                            "%*s "  /* used */
1087                            "%i\n", /* priority */
1088                            &dev, &prio);
1089                 if (k != 2) {
1090                         if (k == EOF)
1091                                 break;
1092
1093                         log_warning("Failed to parse /proc/swaps:%u", i);
1094                         continue;
1095                 }
1096
1097                 d = cunescape(dev);
1098                 if (!d)
1099                         return -ENOMEM;
1100
1101                 k = swap_process_new_swap(m, d, prio, set_flags);
1102                 if (k < 0)
1103                         r = k;
1104         }
1105
1106         return r;
1107 }
1108
1109 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1110         Manager *m = userdata;
1111         Unit *u;
1112         int r;
1113
1114         assert(m);
1115         assert(revents & EPOLLPRI);
1116
1117         r = swap_load_proc_swaps(m, true);
1118         if (r < 0) {
1119                 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1120
1121                 /* Reset flags, just in case, for late calls */
1122                 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1123                         Swap *swap = SWAP(u);
1124
1125                         swap->is_active = swap->just_activated = false;
1126                 }
1127
1128                 return 0;
1129         }
1130
1131         manager_dispatch_load_queue(m);
1132
1133         LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1134                 Swap *swap = SWAP(u);
1135
1136                 if (!swap->is_active) {
1137                         /* This has just been deactivated */
1138
1139                         swap_unset_proc_swaps(swap);
1140
1141                         switch (swap->state) {
1142
1143                         case SWAP_ACTIVE:
1144                                 swap_enter_dead(swap, SWAP_SUCCESS);
1145                                 break;
1146
1147                         default:
1148                                 /* Fire again */
1149                                 swap_set_state(swap, swap->state);
1150                                 break;
1151                         }
1152
1153                 } else if (swap->just_activated) {
1154
1155                         /* New swap entry */
1156
1157                         switch (swap->state) {
1158
1159                         case SWAP_DEAD:
1160                         case SWAP_FAILED:
1161                                 swap_enter_active(swap, SWAP_SUCCESS);
1162                                 break;
1163
1164                         case SWAP_ACTIVATING:
1165                                 swap_set_state(swap, SWAP_ACTIVATING_DONE);
1166                                 break;
1167
1168                         default:
1169                                 /* Nothing really changed, but let's
1170                                  * issue an notification call
1171                                  * nonetheless, in case somebody is
1172                                  * waiting for this. */
1173                                 swap_set_state(swap, swap->state);
1174                                 break;
1175                         }
1176                 }
1177
1178                 /* Reset the flags for later calls */
1179                 swap->is_active = swap->just_activated = false;
1180         }
1181
1182         return 1;
1183 }
1184
1185 static Unit *swap_following(Unit *u) {
1186         Swap *s = SWAP(u);
1187         Swap *other, *first = NULL;
1188
1189         assert(s);
1190
1191         if (streq_ptr(s->what, s->devnode))
1192                 return NULL;
1193
1194         /* Make everybody follow the unit that's named after the swap
1195          * device in the kernel */
1196
1197         LIST_FOREACH_AFTER(same_devnode, other, s)
1198                 if (streq_ptr(other->what, other->devnode))
1199                         return UNIT(other);
1200
1201         LIST_FOREACH_BEFORE(same_devnode, other, s) {
1202                 if (streq_ptr(other->what, other->devnode))
1203                         return UNIT(other);
1204
1205                 first = other;
1206         }
1207
1208         return UNIT(first);
1209 }
1210
1211 static int swap_following_set(Unit *u, Set **_set) {
1212         Swap *s = SWAP(u), *other;
1213         Set *set;
1214         int r;
1215
1216         assert(s);
1217         assert(_set);
1218
1219         if (LIST_JUST_US(same_devnode, s)) {
1220                 *_set = NULL;
1221                 return 0;
1222         }
1223
1224         set = set_new(NULL, NULL);
1225         if (!set)
1226                 return -ENOMEM;
1227
1228         LIST_FOREACH_AFTER(same_devnode, other, s) {
1229                 r = set_put(set, other);
1230                 if (r < 0)
1231                         goto fail;
1232         }
1233
1234         LIST_FOREACH_BEFORE(same_devnode, other, s) {
1235                 r = set_put(set, other);
1236                 if (r < 0)
1237                         goto fail;
1238         }
1239
1240         *_set = set;
1241         return 1;
1242
1243 fail:
1244         set_free(set);
1245         return r;
1246 }
1247
1248 static void swap_shutdown(Manager *m) {
1249         assert(m);
1250
1251         m->swap_event_source = sd_event_source_unref(m->swap_event_source);
1252
1253         if (m->proc_swaps) {
1254                 fclose(m->proc_swaps);
1255                 m->proc_swaps = NULL;
1256         }
1257
1258         hashmap_free(m->swaps_by_devnode);
1259         m->swaps_by_devnode = NULL;
1260 }
1261
1262 static int swap_enumerate(Manager *m) {
1263         int r;
1264
1265         assert(m);
1266
1267         if (!m->proc_swaps) {
1268                 m->proc_swaps = fopen("/proc/swaps", "re");
1269                 if (!m->proc_swaps)
1270                         return errno == ENOENT ? 0 : -errno;
1271
1272                 r = sd_event_add_io(m->event, &m->swap_event_source, fileno(m->proc_swaps), EPOLLPRI, swap_dispatch_io, m);
1273                 if (r < 0)
1274                         goto fail;
1275
1276                 /* Dispatch this before we dispatch SIGCHLD, so that
1277                  * we always get the events from /proc/swaps before
1278                  * the SIGCHLD of /sbin/swapon. */
1279                 r = sd_event_source_set_priority(m->swap_event_source, -10);
1280                 if (r < 0)
1281                         goto fail;
1282         }
1283
1284         r = swap_load_proc_swaps(m, false);
1285         if (r < 0)
1286                 goto fail;
1287
1288         return 0;
1289
1290 fail:
1291         swap_shutdown(m);
1292         return r;
1293 }
1294
1295 int swap_process_new_device(Manager *m, struct udev_device *dev) {
1296         struct udev_list_entry *item = NULL, *first = NULL;
1297         _cleanup_free_ char *e = NULL;
1298         const char *dn;
1299         Swap *s;
1300         int r = 0;
1301
1302         assert(m);
1303         assert(dev);
1304
1305         dn = udev_device_get_devnode(dev);
1306         if (!dn)
1307                 return 0;
1308
1309         e = unit_name_from_path(dn, ".swap");
1310         if (!e)
1311                 return -ENOMEM;
1312
1313         s = hashmap_get(m->units, e);
1314         if (s)
1315                 r = swap_set_devnode(s, dn);
1316
1317         first = udev_device_get_devlinks_list_entry(dev);
1318         udev_list_entry_foreach(item, first) {
1319                 _cleanup_free_ char *n = NULL;
1320
1321                 n = unit_name_from_path(udev_list_entry_get_name(item), ".swap");
1322                 if (!n)
1323                         return -ENOMEM;
1324
1325                 s = hashmap_get(m->units, n);
1326                 if (s) {
1327                         int q;
1328
1329                         q = swap_set_devnode(s, dn);
1330                         if (q < 0)
1331                                 r = q;
1332                 }
1333         }
1334
1335         return r;
1336 }
1337
1338 int swap_process_removed_device(Manager *m, struct udev_device *dev) {
1339         const char *dn;
1340         int r = 0;
1341         Swap *s;
1342
1343         dn = udev_device_get_devnode(dev);
1344         if (!dn)
1345                 return 0;
1346
1347         while ((s = hashmap_get(m->swaps_by_devnode, dn))) {
1348                 int q;
1349
1350                 q = swap_set_devnode(s, NULL);
1351                 if (q < 0)
1352                         r = q;
1353         }
1354
1355         return r;
1356 }
1357
1358 static void swap_reset_failed(Unit *u) {
1359         Swap *s = SWAP(u);
1360
1361         assert(s);
1362
1363         if (s->state == SWAP_FAILED)
1364                 swap_set_state(s, SWAP_DEAD);
1365
1366         s->result = SWAP_SUCCESS;
1367 }
1368
1369 static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1370         return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1371 }
1372
1373 static int swap_get_timeout(Unit *u, uint64_t *timeout) {
1374         Swap *s = SWAP(u);
1375         int r;
1376
1377         if (!s->timer_event_source)
1378                 return 0;
1379
1380         r = sd_event_source_get_time(s->timer_event_source, timeout);
1381         if (r < 0)
1382                 return r;
1383
1384         return 1;
1385 }
1386
1387 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1388         [SWAP_DEAD] = "dead",
1389         [SWAP_ACTIVATING] = "activating",
1390         [SWAP_ACTIVATING_DONE] = "activating-done",
1391         [SWAP_ACTIVE] = "active",
1392         [SWAP_DEACTIVATING] = "deactivating",
1393         [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1394         [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1395         [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1396         [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1397         [SWAP_FAILED] = "failed"
1398 };
1399
1400 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1401
1402 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1403         [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1404         [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1405 };
1406
1407 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1408
1409 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1410         [SWAP_SUCCESS] = "success",
1411         [SWAP_FAILURE_RESOURCES] = "resources",
1412         [SWAP_FAILURE_TIMEOUT] = "timeout",
1413         [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1414         [SWAP_FAILURE_SIGNAL] = "signal",
1415         [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1416 };
1417
1418 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1419
1420 const UnitVTable swap_vtable = {
1421         .object_size = sizeof(Swap),
1422         .exec_context_offset = offsetof(Swap, exec_context),
1423         .cgroup_context_offset = offsetof(Swap, cgroup_context),
1424         .kill_context_offset = offsetof(Swap, kill_context),
1425         .exec_runtime_offset = offsetof(Swap, exec_runtime),
1426
1427         .sections =
1428                 "Unit\0"
1429                 "Swap\0"
1430                 "Install\0",
1431         .private_section = "Swap",
1432
1433         .no_alias = true,
1434         .no_instances = true,
1435
1436         .init = swap_init,
1437         .load = swap_load,
1438         .done = swap_done,
1439
1440         .coldplug = swap_coldplug,
1441
1442         .dump = swap_dump,
1443
1444         .start = swap_start,
1445         .stop = swap_stop,
1446
1447         .kill = swap_kill,
1448
1449         .get_timeout = swap_get_timeout,
1450
1451         .serialize = swap_serialize,
1452         .deserialize_item = swap_deserialize_item,
1453
1454         .active_state = swap_active_state,
1455         .sub_state_to_string = swap_sub_state_to_string,
1456
1457         .check_gc = swap_check_gc,
1458
1459         .sigchld_event = swap_sigchld_event,
1460
1461         .reset_failed = swap_reset_failed,
1462
1463         .bus_interface = "org.freedesktop.systemd1.Swap",
1464         .bus_vtable = bus_swap_vtable,
1465         .bus_set_property = bus_swap_set_property,
1466         .bus_commit_properties = bus_swap_commit_properties,
1467
1468         .following = swap_following,
1469         .following_set = swap_following_set,
1470
1471         .enumerate = swap_enumerate,
1472         .shutdown = swap_shutdown,
1473
1474         .status_message_formats = {
1475                 .starting_stopping = {
1476                         [0] = "Activating swap %s...",
1477                         [1] = "Deactivating swap %s...",
1478                 },
1479                 .finished_start_job = {
1480                         [JOB_DONE]       = "Activated swap %s.",
1481                         [JOB_FAILED]     = "Failed to activate swap %s.",
1482                         [JOB_DEPENDENCY] = "Dependency failed for %s.",
1483                         [JOB_TIMEOUT]    = "Timed out activating swap %s.",
1484                 },
1485                 .finished_stop_job = {
1486                         [JOB_DONE]       = "Deactivated swap %s.",
1487                         [JOB_FAILED]     = "Failed deactivating swap %s.",
1488                         [JOB_TIMEOUT]    = "Timed out deactivating swap %s.",
1489                 },
1490         },
1491 };