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