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