chiark / gitweb /
Merge branch 'python-systemd-reader'
[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
650         assert(s);
651
652         if (f != SWAP_SUCCESS)
653                 s->result = f;
654
655         r = unit_kill_context(
656                         UNIT(s),
657                         &s->kill_context,
658                         state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
659                         -1,
660                         s->control_pid,
661                         false);
662         if (r < 0)
663                 goto fail;
664
665         if (r > 0) {
666                 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
667                 if (r < 0)
668                         goto fail;
669
670                 swap_set_state(s, state);
671         } else
672                 swap_enter_dead(s, SWAP_SUCCESS);
673
674         return;
675
676 fail:
677         log_warning_unit(UNIT(s)->id,
678                          "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
679
680         swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
681 }
682
683 static void swap_enter_activating(Swap *s) {
684         int r, priority;
685
686         assert(s);
687
688         s->control_command_id = SWAP_EXEC_ACTIVATE;
689         s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
690
691         if (s->from_fragment)
692                 priority = s->parameters_fragment.priority;
693         else
694                 priority = -1;
695
696         if (priority >= 0) {
697                 char p[LINE_MAX];
698
699                 snprintf(p, sizeof(p), "%i", priority);
700                 char_array_0(p);
701
702                 r = exec_command_set(
703                                 s->control_command,
704                                 "/sbin/swapon",
705                                 "-p",
706                                 p,
707                                 s->what,
708                                 NULL);
709         } else
710                 r = exec_command_set(
711                                 s->control_command,
712                                 "/sbin/swapon",
713                                 s->what,
714                                 NULL);
715
716         if (r < 0)
717                 goto fail;
718
719         swap_unwatch_control_pid(s);
720
721         r = swap_spawn(s, s->control_command, &s->control_pid);
722         if (r < 0)
723                 goto fail;
724
725         swap_set_state(s, SWAP_ACTIVATING);
726
727         return;
728
729 fail:
730         log_warning_unit(UNIT(s)->id,
731                          "%s failed to run 'swapon' task: %s",
732                          UNIT(s)->id, strerror(-r));
733         swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
734 }
735
736 static void swap_enter_deactivating(Swap *s) {
737         int r;
738
739         assert(s);
740
741         s->control_command_id = SWAP_EXEC_DEACTIVATE;
742         s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
743
744         r = exec_command_set(s->control_command,
745                              "/sbin/swapoff",
746                              s->what,
747                              NULL);
748         if (r < 0)
749                 goto fail;
750
751         swap_unwatch_control_pid(s);
752
753         r = swap_spawn(s, s->control_command, &s->control_pid);
754         if (r < 0)
755                 goto fail;
756
757         swap_set_state(s, SWAP_DEACTIVATING);
758
759         return;
760
761 fail:
762         log_warning_unit(UNIT(s)->id,
763                          "%s failed to run 'swapoff' task: %s",
764                          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         if (detect_container(NULL) > 0)
789                 return -EPERM;
790
791         s->result = SWAP_SUCCESS;
792         swap_enter_activating(s);
793         return 0;
794 }
795
796 static int swap_stop(Unit *u) {
797         Swap *s = SWAP(u);
798
799         assert(s);
800
801         if (s->state == SWAP_DEACTIVATING ||
802             s->state == SWAP_DEACTIVATING_SIGTERM ||
803             s->state == SWAP_DEACTIVATING_SIGKILL ||
804             s->state == SWAP_ACTIVATING_SIGTERM ||
805             s->state == SWAP_ACTIVATING_SIGKILL)
806                 return 0;
807
808         assert(s->state == SWAP_ACTIVATING ||
809                s->state == SWAP_ACTIVE);
810
811         if (detect_container(NULL) > 0)
812                 return -EPERM;
813
814         swap_enter_deactivating(s);
815         return 0;
816 }
817
818 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
819         Swap *s = SWAP(u);
820
821         assert(s);
822         assert(f);
823         assert(fds);
824
825         unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
826         unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
827
828         if (s->control_pid > 0)
829                 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
830
831         if (s->control_command_id >= 0)
832                 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
833
834         return 0;
835 }
836
837 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
838         Swap *s = SWAP(u);
839
840         assert(s);
841         assert(fds);
842
843         if (streq(key, "state")) {
844                 SwapState state;
845
846                 state = swap_state_from_string(value);
847                 if (state < 0)
848                         log_debug_unit(u->id, "Failed to parse state value %s", value);
849                 else
850                         s->deserialized_state = state;
851         } else if (streq(key, "result")) {
852                 SwapResult f;
853
854                 f = swap_result_from_string(value);
855                 if (f < 0)
856                         log_debug_unit(u->id, "Failed to parse result value %s", value);
857                 else if (f != SWAP_SUCCESS)
858                         s->result = f;
859         } else if (streq(key, "control-pid")) {
860                 pid_t pid;
861
862                 if (parse_pid(value, &pid) < 0)
863                         log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
864                 else
865                         s->control_pid = pid;
866
867         } else if (streq(key, "control-command")) {
868                 SwapExecCommand id;
869
870                 id = swap_exec_command_from_string(value);
871                 if (id < 0)
872                         log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
873                 else {
874                         s->control_command_id = id;
875                         s->control_command = s->exec_command + id;
876                 }
877
878         } else
879                 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
880
881         return 0;
882 }
883
884 static UnitActiveState swap_active_state(Unit *u) {
885         assert(u);
886
887         return state_translation_table[SWAP(u)->state];
888 }
889
890 static const char *swap_sub_state_to_string(Unit *u) {
891         assert(u);
892
893         return swap_state_to_string(SWAP(u)->state);
894 }
895
896 static bool swap_check_gc(Unit *u) {
897         Swap *s = SWAP(u);
898
899         assert(s);
900
901         return s->from_proc_swaps;
902 }
903
904 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
905         Swap *s = SWAP(u);
906         SwapResult f;
907
908         assert(s);
909         assert(pid >= 0);
910
911         if (pid != s->control_pid)
912                 return;
913
914         s->control_pid = 0;
915
916         if (is_clean_exit(code, status, NULL))
917                 f = SWAP_SUCCESS;
918         else if (code == CLD_EXITED)
919                 f = SWAP_FAILURE_EXIT_CODE;
920         else if (code == CLD_KILLED)
921                 f = SWAP_FAILURE_SIGNAL;
922         else if (code == CLD_DUMPED)
923                 f = SWAP_FAILURE_CORE_DUMP;
924         else
925                 assert_not_reached("Unknown code");
926
927         if (f != SWAP_SUCCESS)
928                 s->result = f;
929
930         if (s->control_command) {
931                 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
932
933                 s->control_command = NULL;
934                 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
935         }
936
937         log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
938                       u->id,
939                       "%s swap process exited, code=%s status=%i",
940                       u->id, sigchld_code_to_string(code), status);
941
942         switch (s->state) {
943
944         case SWAP_ACTIVATING:
945         case SWAP_ACTIVATING_SIGTERM:
946         case SWAP_ACTIVATING_SIGKILL:
947
948                 if (f == SWAP_SUCCESS)
949                         swap_enter_active(s, f);
950                 else
951                         swap_enter_dead(s, f);
952                 break;
953
954         case SWAP_DEACTIVATING:
955         case SWAP_DEACTIVATING_SIGKILL:
956         case SWAP_DEACTIVATING_SIGTERM:
957
958                 if (f == SWAP_SUCCESS)
959                         swap_enter_dead(s, f);
960                 else
961                         swap_enter_dead(s, f);
962                 break;
963
964         default:
965                 assert_not_reached("Uh, control process died at wrong time.");
966         }
967
968         /* Notify clients about changed exit status */
969         unit_add_to_dbus_queue(u);
970
971         /* Request a reload of /proc/swaps, so that following units
972          * can follow our state change */
973         u->manager->request_reload = true;
974 }
975
976 static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
977         Swap *s = SWAP(u);
978
979         assert(s);
980         assert(elapsed == 1);
981         assert(w == &s->timer_watch);
982
983         switch (s->state) {
984
985         case SWAP_ACTIVATING:
986                 log_warning_unit(u->id, "%s activation timed out. Stopping.", u->id);
987                 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
988                 break;
989
990         case SWAP_DEACTIVATING:
991                 log_warning_unit(u->id, "%s deactivation timed out. Stopping.", u->id);
992                 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
993                 break;
994
995         case SWAP_ACTIVATING_SIGTERM:
996                 if (s->kill_context.send_sigkill) {
997                         log_warning_unit(u->id, "%s activation timed out. Killing.", u->id);
998                         swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
999                 } else {
1000                         log_warning_unit(u->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", u->id);
1001                         swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1002                 }
1003                 break;
1004
1005         case SWAP_DEACTIVATING_SIGTERM:
1006                 if (s->kill_context.send_sigkill) {
1007                         log_warning_unit(u->id, "%s deactivation timed out. Killing.", u->id);
1008                         swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1009                 } else {
1010                         log_warning_unit(u->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id);
1011                         swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1012                 }
1013                 break;
1014
1015         case SWAP_ACTIVATING_SIGKILL:
1016         case SWAP_DEACTIVATING_SIGKILL:
1017                 log_warning_unit(u->id, "%s swap process still around after SIGKILL. Ignoring.", u->id);
1018                 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1019                 break;
1020
1021         default:
1022                 assert_not_reached("Timeout at wrong time.");
1023         }
1024 }
1025
1026 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1027         unsigned i;
1028         int r = 0;
1029
1030         assert(m);
1031
1032         rewind(m->proc_swaps);
1033
1034         (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1035
1036         for (i = 1;; i++) {
1037                 char *dev = NULL, *d;
1038                 int prio = 0, k;
1039
1040                 k = fscanf(m->proc_swaps,
1041                            "%ms "  /* device/file */
1042                            "%*s "  /* type of swap */
1043                            "%*s "  /* swap size */
1044                            "%*s "  /* used */
1045                            "%i\n", /* priority */
1046                            &dev, &prio);
1047                 if (k != 2) {
1048                         if (k == EOF)
1049                                 break;
1050
1051                         log_warning("Failed to parse /proc/swaps:%u", i);
1052                         free(dev);
1053                         continue;
1054                 }
1055
1056                 d = cunescape(dev);
1057                 free(dev);
1058
1059                 if (!d)
1060                         return -ENOMEM;
1061
1062                 k = swap_process_new_swap(m, d, prio, set_flags);
1063                 free(d);
1064
1065                 if (k < 0)
1066                         r = k;
1067         }
1068
1069         return r;
1070 }
1071
1072 int swap_dispatch_reload(Manager *m) {
1073         /* This function should go as soon as the kernel properly notifies us */
1074
1075         if (_likely_(!m->request_reload))
1076                 return 0;
1077
1078         m->request_reload = false;
1079
1080         return swap_fd_event(m, EPOLLPRI);
1081 }
1082
1083 int swap_fd_event(Manager *m, int events) {
1084         Unit *u;
1085         int r;
1086
1087         assert(m);
1088         assert(events & EPOLLPRI);
1089
1090         r = swap_load_proc_swaps(m, true);
1091         if (r < 0) {
1092                 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1093
1094                 /* Reset flags, just in case, for late calls */
1095                 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1096                         Swap *swap = SWAP(u);
1097
1098                         swap->is_active = swap->just_activated = false;
1099                 }
1100
1101                 return 0;
1102         }
1103
1104         manager_dispatch_load_queue(m);
1105
1106         LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1107                 Swap *swap = SWAP(u);
1108
1109                 if (!swap->is_active) {
1110                         /* This has just been deactivated */
1111
1112                         swap->from_proc_swaps = false;
1113                         swap_unset_proc_swaps(swap);
1114
1115                         switch (swap->state) {
1116
1117                         case SWAP_ACTIVE:
1118                                 swap_enter_dead(swap, SWAP_SUCCESS);
1119                                 break;
1120
1121                         default:
1122                                 swap_set_state(swap, swap->state);
1123                                 break;
1124                         }
1125
1126                 } else if (swap->just_activated) {
1127
1128                         /* New swap entry */
1129
1130                         switch (swap->state) {
1131
1132                         case SWAP_DEAD:
1133                         case SWAP_FAILED:
1134                                 swap_enter_active(swap, SWAP_SUCCESS);
1135                                 break;
1136
1137                         default:
1138                                 /* Nothing really changed, but let's
1139                                  * issue an notification call
1140                                  * nonetheless, in case somebody is
1141                                  * waiting for this. */
1142                                 swap_set_state(swap, swap->state);
1143                                 break;
1144                         }
1145                 }
1146
1147                 /* Reset the flags for later calls */
1148                 swap->is_active = swap->just_activated = false;
1149         }
1150
1151         return 1;
1152 }
1153
1154 static Unit *swap_following(Unit *u) {
1155         Swap *s = SWAP(u);
1156         Swap *other, *first = NULL;
1157
1158         assert(s);
1159
1160         if (streq_ptr(s->what, s->parameters_proc_swaps.what))
1161                 return NULL;
1162
1163         /* Make everybody follow the unit that's named after the swap
1164          * device in the kernel */
1165
1166         LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1167                 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1168                         return UNIT(other);
1169
1170         LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
1171                 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1172                         return UNIT(other);
1173
1174                 first = other;
1175         }
1176
1177         return UNIT(first);
1178 }
1179
1180 static int swap_following_set(Unit *u, Set **_set) {
1181         Swap *s = SWAP(u);
1182         Swap *other;
1183         Set *set;
1184         int r;
1185
1186         assert(s);
1187         assert(_set);
1188
1189         if (LIST_JUST_US(same_proc_swaps, s)) {
1190                 *_set = NULL;
1191                 return 0;
1192         }
1193
1194         if (!(set = set_new(NULL, NULL)))
1195                 return -ENOMEM;
1196
1197         LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1198                 if ((r = set_put(set, other)) < 0)
1199                         goto fail;
1200
1201         LIST_FOREACH_BEFORE(same_proc_swaps, other, s)
1202                 if ((r = set_put(set, other)) < 0)
1203                         goto fail;
1204
1205         *_set = set;
1206         return 1;
1207
1208 fail:
1209         set_free(set);
1210         return r;
1211 }
1212
1213 static void swap_shutdown(Manager *m) {
1214         assert(m);
1215
1216         if (m->proc_swaps) {
1217                 fclose(m->proc_swaps);
1218                 m->proc_swaps = NULL;
1219         }
1220
1221         hashmap_free(m->swaps_by_proc_swaps);
1222         m->swaps_by_proc_swaps = NULL;
1223 }
1224
1225 static int swap_enumerate(Manager *m) {
1226         int r;
1227         struct epoll_event ev;
1228         assert(m);
1229
1230         if (!m->proc_swaps) {
1231                 m->proc_swaps = fopen("/proc/swaps", "re");
1232                 if (!m->proc_swaps)
1233                         return (errno == ENOENT) ? 0 : -errno;
1234
1235                 m->swap_watch.type = WATCH_SWAP;
1236                 m->swap_watch.fd = fileno(m->proc_swaps);
1237
1238                 zero(ev);
1239                 ev.events = EPOLLPRI;
1240                 ev.data.ptr = &m->swap_watch;
1241
1242                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
1243                         return -errno;
1244         }
1245
1246         r = swap_load_proc_swaps(m, false);
1247         if (r < 0)
1248                 swap_shutdown(m);
1249
1250         return r;
1251 }
1252
1253 static void swap_reset_failed(Unit *u) {
1254         Swap *s = SWAP(u);
1255
1256         assert(s);
1257
1258         if (s->state == SWAP_FAILED)
1259                 swap_set_state(s, SWAP_DEAD);
1260
1261         s->result = SWAP_SUCCESS;
1262 }
1263
1264 static int swap_kill(Unit *u, KillWho who, int signo, DBusError *error) {
1265         Swap *s = SWAP(u);
1266         int r = 0;
1267         Set *pid_set = NULL;
1268
1269         assert(s);
1270
1271         if (who == KILL_MAIN) {
1272                 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Swap units have no main processes");
1273                 return -ESRCH;
1274         }
1275
1276         if (s->control_pid <= 0 && who == KILL_CONTROL) {
1277                 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
1278                 return -ESRCH;
1279         }
1280
1281         if (who == KILL_CONTROL || who == KILL_ALL)
1282                 if (s->control_pid > 0)
1283                         if (kill(s->control_pid, signo) < 0)
1284                                 r = -errno;
1285
1286         if (who == KILL_ALL) {
1287                 int q;
1288
1289                 pid_set = set_new(trivial_hash_func, trivial_compare_func);
1290                 if (!pid_set)
1291                         return -ENOMEM;
1292
1293                 /* Exclude the control pid from being killed via the cgroup */
1294                 if (s->control_pid > 0) {
1295                         q = set_put(pid_set, LONG_TO_PTR(s->control_pid));
1296                         if (q < 0) {
1297                                 r = q;
1298                                 goto finish;
1299                         }
1300                 }
1301
1302                 q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
1303                 if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
1304                         r = q;
1305         }
1306
1307 finish:
1308         if (pid_set)
1309                 set_free(pid_set);
1310
1311         return r;
1312 }
1313
1314 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1315         [SWAP_DEAD] = "dead",
1316         [SWAP_ACTIVATING] = "activating",
1317         [SWAP_ACTIVE] = "active",
1318         [SWAP_DEACTIVATING] = "deactivating",
1319         [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1320         [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1321         [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1322         [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1323         [SWAP_FAILED] = "failed"
1324 };
1325
1326 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1327
1328 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1329         [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1330         [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1331 };
1332
1333 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1334
1335 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1336         [SWAP_SUCCESS] = "success",
1337         [SWAP_FAILURE_RESOURCES] = "resources",
1338         [SWAP_FAILURE_TIMEOUT] = "timeout",
1339         [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1340         [SWAP_FAILURE_SIGNAL] = "signal",
1341         [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1342 };
1343
1344 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1345
1346 const UnitVTable swap_vtable = {
1347         .object_size = sizeof(Swap),
1348
1349         .sections =
1350                 "Unit\0"
1351                 "Swap\0"
1352                 "Install\0",
1353
1354         .exec_context_offset = offsetof(Swap, exec_context),
1355         .exec_section = "Swap",
1356
1357         .no_alias = true,
1358         .no_instances = true,
1359
1360         .init = swap_init,
1361         .load = swap_load,
1362         .done = swap_done,
1363
1364         .coldplug = swap_coldplug,
1365
1366         .dump = swap_dump,
1367
1368         .start = swap_start,
1369         .stop = swap_stop,
1370
1371         .kill = swap_kill,
1372
1373         .serialize = swap_serialize,
1374         .deserialize_item = swap_deserialize_item,
1375
1376         .active_state = swap_active_state,
1377         .sub_state_to_string = swap_sub_state_to_string,
1378
1379         .check_gc = swap_check_gc,
1380
1381         .sigchld_event = swap_sigchld_event,
1382         .timer_event = swap_timer_event,
1383
1384         .reset_failed = swap_reset_failed,
1385
1386         .bus_interface = "org.freedesktop.systemd1.Swap",
1387         .bus_message_handler = bus_swap_message_handler,
1388         .bus_invalidating_properties =  bus_swap_invalidating_properties,
1389
1390         .following = swap_following,
1391         .following_set = swap_following_set,
1392
1393         .enumerate = swap_enumerate,
1394         .shutdown = swap_shutdown,
1395
1396         .status_message_formats = {
1397                 .starting_stopping = {
1398                         [0] = "Activating swap %s...",
1399                         [1] = "Deactivating swap %s...",
1400                 },
1401                 .finished_start_job = {
1402                         [JOB_DONE]       = "Activated swap %s.",
1403                         [JOB_FAILED]     = "Failed to activate swap %s.",
1404                         [JOB_DEPENDENCY] = "Dependency failed for %s.",
1405                         [JOB_TIMEOUT]    = "Timed out activating swap %s.",
1406                 },
1407                 .finished_stop_job = {
1408                         [JOB_DONE]       = "Deactivated swap %s.",
1409                         [JOB_FAILED]     = "Failed deactivating swap %s.",
1410                         [JOB_TIMEOUT]    = "Timed out deactivating swap %s.",
1411                 },
1412         },
1413 };