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