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