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