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