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