1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
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.
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.
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/>.
26 #include <sys/epoll.h>
33 #include "load-fragment.h"
34 #include "load-dropin.h"
35 #include "unit-name.h"
36 #include "dbus-swap.h"
38 #include "bus-errors.h"
39 #include "exit-status.h"
41 #include "path-util.h"
43 static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
44 [SWAP_DEAD] = UNIT_INACTIVE,
45 [SWAP_ACTIVATING] = UNIT_ACTIVATING,
46 [SWAP_ACTIVE] = UNIT_ACTIVE,
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,
52 [SWAP_FAILED] = UNIT_FAILED
55 static void swap_unset_proc_swaps(Swap *s) {
60 if (!s->parameters_proc_swaps.what)
63 /* Remove this unit from the chain of swaps which share the
64 * same kernel swap device. */
66 first = hashmap_get(UNIT(s)->manager->swaps_by_proc_swaps, s->parameters_proc_swaps.what);
67 LIST_REMOVE(Swap, same_proc_swaps, first, s);
70 hashmap_remove_and_replace(UNIT(s)->manager->swaps_by_proc_swaps, s->parameters_proc_swaps.what, first->parameters_proc_swaps.what, first);
72 hashmap_remove(UNIT(s)->manager->swaps_by_proc_swaps, s->parameters_proc_swaps.what);
74 free(s->parameters_proc_swaps.what);
75 s->parameters_proc_swaps.what = NULL;
78 static void swap_init(Unit *u) {
82 assert(UNIT(s)->load_state == UNIT_STUB);
84 s->timeout_usec = DEFAULT_TIMEOUT_USEC;
86 exec_context_init(&s->exec_context);
87 s->exec_context.std_output = u->manager->default_std_output;
88 s->exec_context.std_error = u->manager->default_std_error;
90 s->parameters_etc_fstab.priority = s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
92 s->timer_watch.type = WATCH_INVALID;
94 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
96 UNIT(s)->ignore_on_isolate = true;
99 static void swap_unwatch_control_pid(Swap *s) {
102 if (s->control_pid <= 0)
105 unit_unwatch_pid(UNIT(s), s->control_pid);
109 static void swap_done(Unit *u) {
114 swap_unset_proc_swaps(s);
119 free(s->parameters_etc_fstab.what);
120 free(s->parameters_fragment.what);
121 s->parameters_etc_fstab.what = s->parameters_fragment.what = NULL;
123 exec_context_done(&s->exec_context);
124 exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
125 s->control_command = NULL;
127 swap_unwatch_control_pid(s);
129 unit_unwatch_timer(u, &s->timer_watch);
132 int swap_add_one_mount_link(Swap *s, Mount *m) {
138 if (UNIT(s)->load_state != UNIT_LOADED ||
139 UNIT(m)->load_state != UNIT_LOADED)
142 if (is_device_path(s->what))
145 if (!path_startswith(s->what, m->where))
148 if ((r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0)
154 static int swap_add_mount_links(Swap *s) {
160 LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT])
161 if ((r = swap_add_one_mount_link(s, MOUNT(other))) < 0)
167 static int swap_add_target_links(Swap *s) {
174 if (s->from_fragment)
175 p = &s->parameters_fragment;
176 else if (s->from_etc_fstab)
177 p = &s->parameters_etc_fstab;
181 if ((r = manager_load_unit(UNIT(s)->manager, SPECIAL_SWAP_TARGET, NULL, NULL, &tu)) < 0)
187 UNIT(s)->manager->running_as == MANAGER_SYSTEM)
188 if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(s), true)) < 0)
191 return unit_add_dependency(UNIT(s), UNIT_BEFORE, tu, true);
194 static int swap_add_device_links(Swap *s) {
202 if (s->from_fragment)
203 p = &s->parameters_fragment;
204 else if (s->from_etc_fstab)
205 p = &s->parameters_etc_fstab;
209 if (is_device_path(s->what))
210 return unit_add_node_link(UNIT(s), s->what,
211 !p->noauto && p->nofail &&
212 UNIT(s)->manager->running_as == MANAGER_SYSTEM);
214 /* File based swap devices need to be ordered after
215 * systemd-remount-fs.service, since they might need a
216 * writable file system. */
217 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
220 static int swap_add_default_dependencies(Swap *s) {
225 if (UNIT(s)->manager->running_as == MANAGER_SYSTEM) {
227 if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0)
234 static int swap_verify(Swap *s) {
238 if (UNIT(s)->load_state != UNIT_LOADED)
241 if (!(e = unit_name_from_path(s->what, ".swap")))
244 b = unit_has_name(UNIT(s), e);
248 log_error("%s: Value of \"What\" and unit name do not match, not loading.\n", UNIT(s)->id);
252 if (s->exec_context.pam_name && s->exec_context.kill_mode != KILL_CONTROL_GROUP) {
253 log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(s)->id);
260 static int swap_load(Unit *u) {
265 assert(u->load_state == UNIT_STUB);
267 /* Load a .swap file */
268 if ((r = unit_load_fragment_and_dropin_optional(u)) < 0)
271 if (u->load_state == UNIT_LOADED) {
272 if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
275 if (UNIT(s)->fragment_path)
276 s->from_fragment = true;
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);
286 s->what = unit_name_to_path(u->id);
292 path_kill_slashes(s->what);
294 if (!UNIT(s)->description)
295 if ((r = unit_set_description(u, s->what)) < 0)
298 if ((r = swap_add_device_links(s)) < 0)
301 if ((r = swap_add_mount_links(s)) < 0)
304 if ((r = swap_add_target_links(s)) < 0)
307 if ((r = unit_add_default_cgroups(u)) < 0)
310 if (UNIT(s)->default_dependencies)
311 if ((r = swap_add_default_dependencies(s)) < 0)
315 return swap_verify(s);
321 const char *what_proc_swaps,
328 char *e = NULL, *wp = NULL;
336 e = unit_name_from_path(what, ".swap");
340 u = manager_get_unit(m, e);
342 if (what_proc_swaps &&
344 SWAP(u)->from_proc_swaps &&
345 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
351 u = unit_new(m, sizeof(Swap));
357 r = unit_add_name(u, e);
361 SWAP(u)->what = strdup(what);
362 if (!SWAP(u)->what) {
367 unit_add_to_load_queue(u);
371 if (what_proc_swaps) {
374 p = &SWAP(u)->parameters_proc_swaps;
377 if (!(wp = strdup(what_proc_swaps))) {
382 if (!m->swaps_by_proc_swaps)
383 if (!(m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func))) {
391 first = hashmap_get(m->swaps_by_proc_swaps, wp);
392 LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u));
394 if ((r = hashmap_replace(m->swaps_by_proc_swaps, wp, first)) < 0)
399 SWAP(u)->is_active = true;
400 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
403 SWAP(u)->from_proc_swaps = true;
406 p = &SWAP(u)->parameters_etc_fstab;
408 if (!(wp = strdup(what))) {
416 SWAP(u)->from_etc_fstab = true;
419 p->priority = priority;
423 unit_add_to_dbus_queue(u);
430 log_warning("Failed to load swap unit: %s", strerror(-r));
441 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
447 if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) {
448 struct udev_device *d;
450 struct udev_list_entry *item = NULL, *first = NULL;
452 /* So this is a proper swap device. Create swap units
453 * for all names this swap device is known under */
455 if (!(d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev)))
458 dn = udev_device_get_devnode(d);
460 r = swap_add_one(m, dn, device, prio, false, false, set_flags);
462 /* Add additional units for all symlinks */
463 first = udev_device_get_devlinks_list_entry(d);
464 udev_list_entry_foreach(item, first) {
467 /* Don't bother with the /dev/block links */
468 p = udev_list_entry_get_name(item);
470 if (path_startswith(p, "/dev/block/"))
473 if (stat(p, &st) >= 0)
474 if ((!S_ISBLK(st.st_mode)) || st.st_rdev != udev_device_get_devnum(d))
477 k = swap_add_one(m, p, device, prio, false, false, set_flags);
482 udev_device_unref(d);
485 k = swap_add_one(m, device, device, prio, false, false, set_flags);
492 static void swap_set_state(Swap *s, SwapState state) {
497 old_state = s->state;
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;
512 if (state != old_state)
513 log_debug("%s changed %s -> %s",
515 swap_state_to_string(old_state),
516 swap_state_to_string(state));
518 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
521 static int swap_coldplug(Unit *u) {
523 SwapState new_state = SWAP_DEAD;
527 assert(s->state == SWAP_DEAD);
529 if (s->deserialized_state != s->state)
530 new_state = s->deserialized_state;
531 else if (s->from_proc_swaps)
532 new_state = SWAP_ACTIVE;
534 if (new_state != s->state) {
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) {
543 if (s->control_pid <= 0)
546 if ((r = unit_watch_pid(UNIT(s), s->control_pid)) < 0)
549 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
553 swap_set_state(s, new_state);
559 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
566 if (s->from_proc_swaps)
567 p = &s->parameters_proc_swaps;
568 else if (s->from_fragment)
569 p = &s->parameters_fragment;
571 p = &s->parameters_etc_fstab;
580 "%sFrom /etc/fstab: %s\n"
581 "%sFrom /proc/swaps: %s\n"
582 "%sFrom fragment: %s\n",
583 prefix, swap_state_to_string(s->state),
584 prefix, swap_result_to_string(s->result),
587 prefix, yes_no(p->noauto),
588 prefix, yes_no(p->nofail),
589 prefix, yes_no(s->from_etc_fstab),
590 prefix, yes_no(s->from_proc_swaps),
591 prefix, yes_no(s->from_fragment));
593 if (s->control_pid > 0)
595 "%sControl PID: %lu\n",
596 prefix, (unsigned long) s->control_pid);
598 exec_context_dump(&s->exec_context, f, prefix);
601 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
609 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
612 if ((r = exec_spawn(c,
616 UNIT(s)->manager->environment,
620 UNIT(s)->manager->confirm_spawn,
621 UNIT(s)->cgroup_bondings,
622 UNIT(s)->cgroup_attributes,
628 if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
629 /* FIXME: we need to do something here */
637 unit_unwatch_timer(UNIT(s), &s->timer_watch);
642 static void swap_enter_dead(Swap *s, SwapResult f) {
645 if (f != SWAP_SUCCESS)
648 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
651 static void swap_enter_active(Swap *s, SwapResult f) {
654 if (f != SWAP_SUCCESS)
657 swap_set_state(s, SWAP_ACTIVE);
660 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
663 bool wait_for_exit = false;
667 if (f != SWAP_SUCCESS)
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;
674 if (s->control_pid > 0) {
675 if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH)
677 log_warning("Failed to kill control process %li: %m", (long) s->control_pid);
679 wait_for_exit = true;
682 if (s->exec_context.kill_mode == KILL_CONTROL_GROUP) {
684 if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) {
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)
694 r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, false, pid_set, NULL);
696 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
697 log_warning("Failed to kill control group: %s", strerror(-r));
699 wait_for_exit = true;
707 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
710 swap_set_state(s, state);
712 swap_enter_dead(s, SWAP_SUCCESS);
717 log_warning("%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
719 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
725 static void swap_enter_activating(Swap *s) {
730 s->control_command_id = SWAP_EXEC_ACTIVATE;
731 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
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;
743 snprintf(p, sizeof(p), "%i", priority);
746 r = exec_command_set(
754 r = exec_command_set(
763 swap_unwatch_control_pid(s);
765 if ((r = swap_spawn(s, s->control_command, &s->control_pid)) < 0)
768 swap_set_state(s, SWAP_ACTIVATING);
773 log_warning("%s failed to run 'swapon' task: %s", UNIT(s)->id, strerror(-r));
774 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
777 static void swap_enter_deactivating(Swap *s) {
782 s->control_command_id = SWAP_EXEC_DEACTIVATE;
783 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
785 if ((r = exec_command_set(
792 swap_unwatch_control_pid(s);
794 if ((r = swap_spawn(s, s->control_command, &s->control_pid)) < 0)
797 swap_set_state(s, SWAP_DEACTIVATING);
802 log_warning("%s failed to run 'swapoff' task: %s", UNIT(s)->id, strerror(-r));
803 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
806 static int swap_start(Unit *u) {
811 /* We cannot fulfill this request right now, try again later
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)
821 if (s->state == SWAP_ACTIVATING)
824 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
826 s->result = SWAP_SUCCESS;
827 swap_enter_activating(s);
831 static int swap_stop(Unit *u) {
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)
843 assert(s->state == SWAP_ACTIVATING ||
844 s->state == SWAP_ACTIVE);
846 swap_enter_deactivating(s);
850 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
857 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
858 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
860 if (s->control_pid > 0)
861 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
863 if (s->control_command_id >= 0)
864 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
869 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
875 if (streq(key, "state")) {
878 if ((state = swap_state_from_string(value)) < 0)
879 log_debug("Failed to parse state value %s", value);
881 s->deserialized_state = state;
882 } else if (streq(key, "result")) {
885 f = swap_result_from_string(value);
887 log_debug("Failed to parse result value %s", value);
888 else if (f != SWAP_SUCCESS)
890 } else if (streq(key, "control-pid")) {
893 if (parse_pid(value, &pid) < 0)
894 log_debug("Failed to parse control-pid value %s", value);
896 s->control_pid = pid;
898 } else if (streq(key, "control-command")) {
901 if ((id = swap_exec_command_from_string(value)) < 0)
902 log_debug("Failed to parse exec-command value %s", value);
904 s->control_command_id = id;
905 s->control_command = s->exec_command + id;
909 log_debug("Unknown serialization key '%s'", key);
914 static UnitActiveState swap_active_state(Unit *u) {
917 return state_translation_table[SWAP(u)->state];
920 static const char *swap_sub_state_to_string(Unit *u) {
923 return swap_state_to_string(SWAP(u)->state);
926 static bool swap_check_gc(Unit *u) {
931 return s->from_etc_fstab || s->from_proc_swaps;
934 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
941 if (pid != s->control_pid)
946 if (is_clean_exit(code, status))
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;
955 assert_not_reached("Unknown code");
957 if (f != SWAP_SUCCESS)
960 if (s->control_command) {
961 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
963 s->control_command = NULL;
964 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
967 log_full(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
968 "%s swap process exited, code=%s status=%i", u->id, sigchld_code_to_string(code), status);
972 case SWAP_ACTIVATING:
973 case SWAP_ACTIVATING_SIGTERM:
974 case SWAP_ACTIVATING_SIGKILL:
976 if (f == SWAP_SUCCESS)
977 swap_enter_active(s, f);
979 swap_enter_dead(s, f);
982 case SWAP_DEACTIVATING:
983 case SWAP_DEACTIVATING_SIGKILL:
984 case SWAP_DEACTIVATING_SIGTERM:
986 if (f == SWAP_SUCCESS)
987 swap_enter_dead(s, f);
989 swap_enter_dead(s, f);
993 assert_not_reached("Uh, control process died at wrong time.");
996 /* Notify clients about changed exit status */
997 unit_add_to_dbus_queue(u);
999 /* Request a reload of /proc/swaps, so that following units
1000 * can follow our state change */
1001 u->manager->request_reload = true;
1004 static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
1008 assert(elapsed == 1);
1009 assert(w == &s->timer_watch);
1013 case SWAP_ACTIVATING:
1014 log_warning("%s activation timed out. Stopping.", u->id);
1015 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1018 case SWAP_DEACTIVATING:
1019 log_warning("%s deactivation timed out. Stopping.", u->id);
1020 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1023 case SWAP_ACTIVATING_SIGTERM:
1024 if (s->exec_context.send_sigkill) {
1025 log_warning("%s activation timed out. Killing.", u->id);
1026 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1028 log_warning("%s activation timed out. Skipping SIGKILL. Ignoring.", u->id);
1029 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1033 case SWAP_DEACTIVATING_SIGTERM:
1034 if (s->exec_context.send_sigkill) {
1035 log_warning("%s deactivation timed out. Killing.", u->id);
1036 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1038 log_warning("%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id);
1039 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1043 case SWAP_ACTIVATING_SIGKILL:
1044 case SWAP_DEACTIVATING_SIGKILL:
1045 log_warning("%s swap process still around after SIGKILL. Ignoring.", u->id);
1046 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1050 assert_not_reached("Timeout at wrong time.");
1054 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1060 rewind(m->proc_swaps);
1062 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1065 char *dev = NULL, *d;
1068 if ((k = fscanf(m->proc_swaps,
1069 "%ms " /* device/file */
1070 "%*s " /* type of swap */
1071 "%*s " /* swap size */
1073 "%i\n", /* priority */
1074 &dev, &prio)) != 2) {
1079 log_warning("Failed to parse /proc/swaps:%u.", i);
1090 k = swap_process_new_swap(m, d, prio, set_flags);
1100 int swap_dispatch_reload(Manager *m) {
1101 /* This function should go as soon as the kernel properly notifies us */
1103 if (_likely_(!m->request_reload))
1106 m->request_reload = false;
1108 return swap_fd_event(m, EPOLLPRI);
1111 int swap_fd_event(Manager *m, int events) {
1116 assert(events & EPOLLPRI);
1118 if ((r = swap_load_proc_swaps(m, true)) < 0) {
1119 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1121 /* Reset flags, just in case, for late calls */
1122 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1123 Swap *swap = SWAP(u);
1125 swap->is_active = swap->just_activated = false;
1131 manager_dispatch_load_queue(m);
1133 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1134 Swap *swap = SWAP(u);
1136 if (!swap->is_active) {
1137 /* This has just been deactivated */
1139 swap->from_proc_swaps = false;
1140 swap_unset_proc_swaps(swap);
1142 switch (swap->state) {
1145 swap_enter_dead(swap, SWAP_SUCCESS);
1149 swap_set_state(swap, swap->state);
1153 } else if (swap->just_activated) {
1155 /* New swap entry */
1157 switch (swap->state) {
1161 swap_enter_active(swap, SWAP_SUCCESS);
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);
1174 /* Reset the flags for later calls */
1175 swap->is_active = swap->just_activated = false;
1181 static Unit *swap_following(Unit *u) {
1183 Swap *other, *first = NULL;
1187 if (streq_ptr(s->what, s->parameters_proc_swaps.what))
1190 /* Make everybody follow the unit that's named after the swap
1191 * device in the kernel */
1193 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1194 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1197 LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
1198 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1207 static int swap_following_set(Unit *u, Set **_set) {
1216 if (LIST_JUST_US(same_proc_swaps, s)) {
1221 if (!(set = set_new(NULL, NULL)))
1224 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1225 if ((r = set_put(set, other)) < 0)
1228 LIST_FOREACH_BEFORE(same_proc_swaps, other, s)
1229 if ((r = set_put(set, other)) < 0)
1240 static void swap_shutdown(Manager *m) {
1243 if (m->proc_swaps) {
1244 fclose(m->proc_swaps);
1245 m->proc_swaps = NULL;
1248 hashmap_free(m->swaps_by_proc_swaps);
1249 m->swaps_by_proc_swaps = NULL;
1252 static int swap_enumerate(Manager *m) {
1254 struct epoll_event ev;
1257 if (!m->proc_swaps) {
1258 if (!(m->proc_swaps = fopen("/proc/swaps", "re")))
1259 return (errno == ENOENT) ? 0 : -errno;
1261 m->swap_watch.type = WATCH_SWAP;
1262 m->swap_watch.fd = fileno(m->proc_swaps);
1265 ev.events = EPOLLPRI;
1266 ev.data.ptr = &m->swap_watch;
1268 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
1272 /* We rely on mount.c to load /etc/fstab for us */
1274 if ((r = swap_load_proc_swaps(m, false)) < 0)
1280 static void swap_reset_failed(Unit *u) {
1285 if (s->state == SWAP_FAILED)
1286 swap_set_state(s, SWAP_DEAD);
1288 s->result = SWAP_SUCCESS;
1291 static int swap_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError *error) {
1294 Set *pid_set = NULL;
1298 if (who == KILL_MAIN) {
1299 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Swap units have no main processes");
1303 if (s->control_pid <= 0 && who == KILL_CONTROL) {
1304 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
1308 if (who == KILL_CONTROL || who == KILL_ALL)
1309 if (s->control_pid > 0)
1310 if (kill(s->control_pid, signo) < 0)
1313 if (who == KILL_ALL && mode == KILL_CONTROL_GROUP) {
1316 if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func)))
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) {
1326 q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
1328 if (q != -EAGAIN && q != -ESRCH && q != -ENOENT)
1339 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1340 [SWAP_DEAD] = "dead",
1341 [SWAP_ACTIVATING] = "activating",
1342 [SWAP_ACTIVE] = "active",
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",
1348 [SWAP_FAILED] = "failed"
1351 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1353 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1354 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1355 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1358 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1360 static 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"
1369 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1371 const UnitVTable swap_vtable = {
1373 .object_size = sizeof(Swap),
1380 .no_instances = true,
1386 .coldplug = swap_coldplug,
1390 .start = swap_start,
1395 .serialize = swap_serialize,
1396 .deserialize_item = swap_deserialize_item,
1398 .active_state = swap_active_state,
1399 .sub_state_to_string = swap_sub_state_to_string,
1401 .check_gc = swap_check_gc,
1403 .sigchld_event = swap_sigchld_event,
1404 .timer_event = swap_timer_event,
1406 .reset_failed = swap_reset_failed,
1408 .bus_interface = "org.freedesktop.systemd1.Swap",
1409 .bus_message_handler = bus_swap_message_handler,
1410 .bus_invalidating_properties = bus_swap_invalidating_properties,
1412 .following = swap_following,
1413 .following_set = swap_following_set,
1415 .enumerate = swap_enumerate,
1416 .shutdown = swap_shutdown,
1418 .status_message_formats = {
1419 .starting_stopping = {
1420 [0] = "Activating swap %s...",
1421 [1] = "Deactivating swap %s...",
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.",
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.",