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