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