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"
44 static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
45 [SWAP_DEAD] = UNIT_INACTIVE,
46 [SWAP_ACTIVATING] = UNIT_ACTIVATING,
47 [SWAP_ACTIVE] = UNIT_ACTIVE,
48 [SWAP_DEACTIVATING] = UNIT_DEACTIVATING,
49 [SWAP_ACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
50 [SWAP_ACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
51 [SWAP_DEACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
52 [SWAP_DEACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
53 [SWAP_FAILED] = UNIT_FAILED
56 static void swap_unset_proc_swaps(Swap *s) {
62 if (!s->parameters_proc_swaps.what)
65 /* Remove this unit from the chain of swaps which share the
66 * same kernel swap device. */
67 swaps = UNIT(s)->manager->swaps_by_proc_swaps;
68 first = hashmap_get(swaps, s->parameters_proc_swaps.what);
69 LIST_REMOVE(Swap, same_proc_swaps, first, s);
72 hashmap_remove_and_replace(swaps,
73 s->parameters_proc_swaps.what,
74 first->parameters_proc_swaps.what,
77 hashmap_remove(swaps, s->parameters_proc_swaps.what);
79 free(s->parameters_proc_swaps.what);
80 s->parameters_proc_swaps.what = NULL;
83 static void swap_init(Unit *u) {
87 assert(UNIT(s)->load_state == UNIT_STUB);
89 s->timeout_usec = DEFAULT_TIMEOUT_USEC;
91 exec_context_init(&s->exec_context);
92 s->exec_context.std_output = u->manager->default_std_output;
93 s->exec_context.std_error = u->manager->default_std_error;
94 kill_context_init(&s->kill_context);
96 s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
98 s->timer_watch.type = WATCH_INVALID;
100 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
102 UNIT(s)->ignore_on_isolate = true;
105 static void swap_unwatch_control_pid(Swap *s) {
108 if (s->control_pid <= 0)
111 unit_unwatch_pid(UNIT(s), s->control_pid);
115 static void swap_done(Unit *u) {
120 swap_unset_proc_swaps(s);
125 free(s->parameters_fragment.what);
126 s->parameters_fragment.what = NULL;
128 exec_context_done(&s->exec_context);
129 exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
130 s->control_command = NULL;
132 swap_unwatch_control_pid(s);
134 unit_unwatch_timer(u, &s->timer_watch);
137 int swap_add_one_mount_link(Swap *s, Mount *m) {
143 if (UNIT(s)->load_state != UNIT_LOADED ||
144 UNIT(m)->load_state != UNIT_LOADED)
147 if (is_device_path(s->what))
150 if (!path_startswith(s->what, m->where))
153 r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
160 static int swap_add_mount_links(Swap *s) {
166 LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT])
167 if ((r = swap_add_one_mount_link(s, MOUNT(other))) < 0)
173 static int swap_add_device_links(Swap *s) {
181 if (s->from_fragment)
182 p = &s->parameters_fragment;
186 if (is_device_path(s->what))
187 return unit_add_node_link(UNIT(s), s->what,
188 !p->noauto && p->nofail &&
189 UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
191 /* File based swap devices need to be ordered after
192 * systemd-remount-fs.service, since they might need a
193 * writable file system. */
194 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
197 static int swap_add_default_dependencies(Swap *s) {
202 if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
205 if (detect_container(NULL) > 0)
208 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
215 static int swap_verify(Swap *s) {
217 char _cleanup_free_ *e = NULL;
219 if (UNIT(s)->load_state != UNIT_LOADED)
222 e = unit_name_from_path(s->what, ".swap");
226 b = unit_has_name(UNIT(s), e);
228 log_error("%s: Value of \"What\" and unit name do not match, not loading.", UNIT(s)->id);
232 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
233 log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.", UNIT(s)->id);
240 static int swap_load(Unit *u) {
245 assert(u->load_state == UNIT_STUB);
247 /* Load a .swap file */
248 r = unit_load_fragment_and_dropin_optional(u);
252 if (u->load_state == UNIT_LOADED) {
253 r = unit_add_exec_dependencies(u, &s->exec_context);
257 if (UNIT(s)->fragment_path)
258 s->from_fragment = true;
261 if (s->parameters_fragment.what)
262 s->what = strdup(s->parameters_fragment.what);
263 else if (s->parameters_proc_swaps.what)
264 s->what = strdup(s->parameters_proc_swaps.what);
266 s->what = unit_name_to_path(u->id);
272 path_kill_slashes(s->what);
274 if (!UNIT(s)->description)
275 if ((r = unit_set_description(u, s->what)) < 0)
278 r = swap_add_device_links(s);
282 r = swap_add_mount_links(s);
286 r = unit_add_default_cgroups(u);
290 if (UNIT(s)->default_dependencies) {
291 r = swap_add_default_dependencies(s);
296 r = unit_exec_context_defaults(u, &s->exec_context);
301 return swap_verify(s);
304 static int swap_add_one(
307 const char *what_proc_swaps,
314 char _cleanup_free_ *e = NULL;
323 assert(what_proc_swaps);
325 e = unit_name_from_path(what, ".swap");
329 u = manager_get_unit(m, e);
332 SWAP(u)->from_proc_swaps &&
333 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
339 u = unit_new(m, sizeof(Swap));
343 r = unit_add_name(u, e);
347 SWAP(u)->what = strdup(what);
348 if (!SWAP(u)->what) {
353 unit_add_to_load_queue(u);
357 p = &SWAP(u)->parameters_proc_swaps;
360 wp = strdup(what_proc_swaps);
366 if (!m->swaps_by_proc_swaps) {
367 m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func);
368 if (!m->swaps_by_proc_swaps) {
377 first = hashmap_get(m->swaps_by_proc_swaps, wp);
378 LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u));
380 r = hashmap_replace(m->swaps_by_proc_swaps, wp, first);
386 SWAP(u)->is_active = true;
387 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
390 SWAP(u)->from_proc_swaps = true;
392 p->priority = priority;
396 unit_add_to_dbus_queue(u);
401 log_warning("Failed to load swap unit: %s", strerror(-r));
411 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
417 if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) {
418 struct udev_device *d;
420 struct udev_list_entry *item = NULL, *first = NULL;
422 /* So this is a proper swap device. Create swap units
423 * for all names this swap device is known under */
425 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
429 dn = udev_device_get_devnode(d);
430 /* Skip dn==device, since that case will be handled below */
431 if (dn && !streq(dn, device))
432 r = swap_add_one(m, dn, device, prio, false, false, set_flags);
434 /* Add additional units for all symlinks */
435 first = udev_device_get_devlinks_list_entry(d);
436 udev_list_entry_foreach(item, first) {
439 /* Don't bother with the /dev/block links */
440 p = udev_list_entry_get_name(item);
442 if (path_startswith(p, "/dev/block/"))
445 if (stat(p, &st) >= 0)
446 if ((!S_ISBLK(st.st_mode)) ||
447 st.st_rdev != udev_device_get_devnum(d))
450 k = swap_add_one(m, p, device, prio, false, false, set_flags);
455 udev_device_unref(d);
458 k = swap_add_one(m, device, device, prio, false, false, set_flags);
465 static void swap_set_state(Swap *s, SwapState state) {
470 old_state = s->state;
473 if (state != SWAP_ACTIVATING &&
474 state != SWAP_ACTIVATING_SIGTERM &&
475 state != SWAP_ACTIVATING_SIGKILL &&
476 state != SWAP_DEACTIVATING &&
477 state != SWAP_DEACTIVATING_SIGTERM &&
478 state != SWAP_DEACTIVATING_SIGKILL) {
479 unit_unwatch_timer(UNIT(s), &s->timer_watch);
480 swap_unwatch_control_pid(s);
481 s->control_command = NULL;
482 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
485 if (state != old_state)
486 log_debug("%s changed %s -> %s",
488 swap_state_to_string(old_state),
489 swap_state_to_string(state));
491 unit_notify(UNIT(s), state_translation_table[old_state],
492 state_translation_table[state], true);
495 static int swap_coldplug(Unit *u) {
497 SwapState new_state = SWAP_DEAD;
501 assert(s->state == SWAP_DEAD);
503 if (s->deserialized_state != s->state)
504 new_state = s->deserialized_state;
505 else if (s->from_proc_swaps)
506 new_state = SWAP_ACTIVE;
508 if (new_state != s->state) {
510 if (new_state == SWAP_ACTIVATING ||
511 new_state == SWAP_ACTIVATING_SIGTERM ||
512 new_state == SWAP_ACTIVATING_SIGKILL ||
513 new_state == SWAP_DEACTIVATING ||
514 new_state == SWAP_DEACTIVATING_SIGTERM ||
515 new_state == SWAP_DEACTIVATING_SIGKILL) {
517 if (s->control_pid <= 0)
520 r = unit_watch_pid(UNIT(s), s->control_pid);
524 r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch);
529 swap_set_state(s, new_state);
535 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
542 if (s->from_proc_swaps)
543 p = &s->parameters_proc_swaps;
544 else if (s->from_fragment)
545 p = &s->parameters_fragment;
553 "%sFrom /proc/swaps: %s\n"
554 "%sFrom fragment: %s\n",
555 prefix, swap_state_to_string(s->state),
556 prefix, swap_result_to_string(s->result),
558 prefix, yes_no(s->from_proc_swaps),
559 prefix, yes_no(s->from_fragment));
567 prefix, yes_no(p->noauto),
568 prefix, yes_no(p->nofail));
570 if (s->control_pid > 0)
572 "%sControl PID: %lu\n",
573 prefix, (unsigned long) s->control_pid);
575 exec_context_dump(&s->exec_context, f, prefix);
576 kill_context_dump(&s->kill_context, f, prefix);
579 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
587 r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch);
595 UNIT(s)->manager->environment,
599 UNIT(s)->manager->confirm_spawn,
600 UNIT(s)->cgroup_bondings,
601 UNIT(s)->cgroup_attributes,
609 r = unit_watch_pid(UNIT(s), pid);
611 /* FIXME: we need to do something here */
619 unit_unwatch_timer(UNIT(s), &s->timer_watch);
624 static void swap_enter_dead(Swap *s, SwapResult f) {
627 if (f != SWAP_SUCCESS)
630 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
633 static void swap_enter_active(Swap *s, SwapResult f) {
636 if (f != SWAP_SUCCESS)
639 swap_set_state(s, SWAP_ACTIVE);
642 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
645 bool wait_for_exit = false;
649 if (f != SWAP_SUCCESS)
652 if (s->kill_context.kill_mode != KILL_NONE) {
653 int sig = (state == SWAP_ACTIVATING_SIGTERM ||
654 state == SWAP_DEACTIVATING_SIGTERM) ? s->kill_context.kill_signal : SIGKILL;
656 if (s->control_pid > 0) {
657 if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH)
659 log_warning("Failed to kill control process %li: %m", (long) s->control_pid);
661 wait_for_exit = true;
664 if (s->kill_context.kill_mode == KILL_CONTROL_GROUP) {
666 pid_set = set_new(trivial_hash_func, trivial_compare_func);
672 /* Exclude the control pid from being killed via the cgroup */
673 if (s->control_pid > 0) {
674 r = set_put(pid_set, LONG_TO_PTR(s->control_pid));
679 r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, false, pid_set, NULL);
681 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
682 log_warning("Failed to kill control group: %s", strerror(-r));
684 wait_for_exit = true;
692 r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch);
696 swap_set_state(s, state);
698 swap_enter_dead(s, SWAP_SUCCESS);
703 log_warning("%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
705 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
711 static void swap_enter_activating(Swap *s) {
716 s->control_command_id = SWAP_EXEC_ACTIVATE;
717 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
719 if (s->from_fragment)
720 priority = s->parameters_fragment.priority;
727 snprintf(p, sizeof(p), "%i", priority);
730 r = exec_command_set(
738 r = exec_command_set(
747 swap_unwatch_control_pid(s);
749 r = swap_spawn(s, s->control_command, &s->control_pid);
753 swap_set_state(s, SWAP_ACTIVATING);
758 log_warning("%s failed to run 'swapon' task: %s", UNIT(s)->id, strerror(-r));
759 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
762 static void swap_enter_deactivating(Swap *s) {
767 s->control_command_id = SWAP_EXEC_DEACTIVATE;
768 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
770 r = exec_command_set(s->control_command,
777 swap_unwatch_control_pid(s);
779 r = swap_spawn(s, s->control_command, &s->control_pid);
783 swap_set_state(s, SWAP_DEACTIVATING);
788 log_warning("%s failed to run 'swapoff' task: %s", UNIT(s)->id, strerror(-r));
789 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
792 static int swap_start(Unit *u) {
797 /* We cannot fulfill this request right now, try again later
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)
807 if (s->state == SWAP_ACTIVATING)
810 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
812 if (detect_container(NULL) > 0)
815 s->result = SWAP_SUCCESS;
816 swap_enter_activating(s);
820 static int swap_stop(Unit *u) {
825 if (s->state == SWAP_DEACTIVATING ||
826 s->state == SWAP_DEACTIVATING_SIGTERM ||
827 s->state == SWAP_DEACTIVATING_SIGKILL ||
828 s->state == SWAP_ACTIVATING_SIGTERM ||
829 s->state == SWAP_ACTIVATING_SIGKILL)
832 assert(s->state == SWAP_ACTIVATING ||
833 s->state == SWAP_ACTIVE);
835 if (detect_container(NULL) > 0)
838 swap_enter_deactivating(s);
842 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
849 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
850 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
852 if (s->control_pid > 0)
853 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
855 if (s->control_command_id >= 0)
856 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
861 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
867 if (streq(key, "state")) {
870 state = swap_state_from_string(value);
872 log_debug("Failed to parse state value %s", value);
874 s->deserialized_state = state;
875 } else if (streq(key, "result")) {
878 f = swap_result_from_string(value);
880 log_debug("Failed to parse result value %s", value);
881 else if (f != SWAP_SUCCESS)
883 } else if (streq(key, "control-pid")) {
886 if (parse_pid(value, &pid) < 0)
887 log_debug("Failed to parse control-pid value %s", value);
889 s->control_pid = pid;
891 } else if (streq(key, "control-command")) {
894 id = swap_exec_command_from_string(value);
896 log_debug("Failed to parse exec-command value %s", value);
898 s->control_command_id = id;
899 s->control_command = s->exec_command + id;
903 log_debug("Unknown serialization key '%s'", key);
908 static UnitActiveState swap_active_state(Unit *u) {
911 return state_translation_table[SWAP(u)->state];
914 static const char *swap_sub_state_to_string(Unit *u) {
917 return swap_state_to_string(SWAP(u)->state);
920 static bool swap_check_gc(Unit *u) {
925 return s->from_proc_swaps;
928 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
935 if (pid != s->control_pid)
940 if (is_clean_exit(code, status, NULL))
942 else if (code == CLD_EXITED)
943 f = SWAP_FAILURE_EXIT_CODE;
944 else if (code == CLD_KILLED)
945 f = SWAP_FAILURE_SIGNAL;
946 else if (code == CLD_DUMPED)
947 f = SWAP_FAILURE_CORE_DUMP;
949 assert_not_reached("Unknown code");
951 if (f != SWAP_SUCCESS)
954 if (s->control_command) {
955 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
957 s->control_command = NULL;
958 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
961 log_full(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
962 "%s swap process exited, code=%s status=%i", u->id, sigchld_code_to_string(code), status);
966 case SWAP_ACTIVATING:
967 case SWAP_ACTIVATING_SIGTERM:
968 case SWAP_ACTIVATING_SIGKILL:
970 if (f == SWAP_SUCCESS)
971 swap_enter_active(s, f);
973 swap_enter_dead(s, f);
976 case SWAP_DEACTIVATING:
977 case SWAP_DEACTIVATING_SIGKILL:
978 case SWAP_DEACTIVATING_SIGTERM:
980 if (f == SWAP_SUCCESS)
981 swap_enter_dead(s, f);
983 swap_enter_dead(s, f);
987 assert_not_reached("Uh, control process died at wrong time.");
990 /* Notify clients about changed exit status */
991 unit_add_to_dbus_queue(u);
993 /* Request a reload of /proc/swaps, so that following units
994 * can follow our state change */
995 u->manager->request_reload = true;
998 static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
1002 assert(elapsed == 1);
1003 assert(w == &s->timer_watch);
1007 case SWAP_ACTIVATING:
1008 log_warning("%s activation timed out. Stopping.", u->id);
1009 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1012 case SWAP_DEACTIVATING:
1013 log_warning("%s deactivation timed out. Stopping.", u->id);
1014 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1017 case SWAP_ACTIVATING_SIGTERM:
1018 if (s->kill_context.send_sigkill) {
1019 log_warning("%s activation timed out. Killing.", u->id);
1020 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1022 log_warning("%s activation timed out. Skipping SIGKILL. Ignoring.", u->id);
1023 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1027 case SWAP_DEACTIVATING_SIGTERM:
1028 if (s->kill_context.send_sigkill) {
1029 log_warning("%s deactivation timed out. Killing.", u->id);
1030 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1032 log_warning("%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id);
1033 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1037 case SWAP_ACTIVATING_SIGKILL:
1038 case SWAP_DEACTIVATING_SIGKILL:
1039 log_warning("%s swap process still around after SIGKILL. Ignoring.", u->id);
1040 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1044 assert_not_reached("Timeout at wrong time.");
1048 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1054 rewind(m->proc_swaps);
1056 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1059 char *dev = NULL, *d;
1062 k = fscanf(m->proc_swaps,
1063 "%ms " /* device/file */
1064 "%*s " /* type of swap */
1065 "%*s " /* swap size */
1067 "%i\n", /* priority */
1073 log_warning("Failed to parse /proc/swaps:%u", i);
1084 k = swap_process_new_swap(m, d, prio, set_flags);
1094 int swap_dispatch_reload(Manager *m) {
1095 /* This function should go as soon as the kernel properly notifies us */
1097 if (_likely_(!m->request_reload))
1100 m->request_reload = false;
1102 return swap_fd_event(m, EPOLLPRI);
1105 int swap_fd_event(Manager *m, int events) {
1110 assert(events & EPOLLPRI);
1112 r = swap_load_proc_swaps(m, true);
1114 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1116 /* Reset flags, just in case, for late calls */
1117 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1118 Swap *swap = SWAP(u);
1120 swap->is_active = swap->just_activated = false;
1126 manager_dispatch_load_queue(m);
1128 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1129 Swap *swap = SWAP(u);
1131 if (!swap->is_active) {
1132 /* This has just been deactivated */
1134 swap->from_proc_swaps = false;
1135 swap_unset_proc_swaps(swap);
1137 switch (swap->state) {
1140 swap_enter_dead(swap, SWAP_SUCCESS);
1144 swap_set_state(swap, swap->state);
1148 } else if (swap->just_activated) {
1150 /* New swap entry */
1152 switch (swap->state) {
1156 swap_enter_active(swap, SWAP_SUCCESS);
1160 /* Nothing really changed, but let's
1161 * issue an notification call
1162 * nonetheless, in case somebody is
1163 * waiting for this. */
1164 swap_set_state(swap, swap->state);
1169 /* Reset the flags for later calls */
1170 swap->is_active = swap->just_activated = false;
1176 static Unit *swap_following(Unit *u) {
1178 Swap *other, *first = NULL;
1182 if (streq_ptr(s->what, s->parameters_proc_swaps.what))
1185 /* Make everybody follow the unit that's named after the swap
1186 * device in the kernel */
1188 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1189 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1192 LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
1193 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1202 static int swap_following_set(Unit *u, Set **_set) {
1211 if (LIST_JUST_US(same_proc_swaps, s)) {
1216 if (!(set = set_new(NULL, NULL)))
1219 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1220 if ((r = set_put(set, other)) < 0)
1223 LIST_FOREACH_BEFORE(same_proc_swaps, other, s)
1224 if ((r = set_put(set, other)) < 0)
1235 static void swap_shutdown(Manager *m) {
1238 if (m->proc_swaps) {
1239 fclose(m->proc_swaps);
1240 m->proc_swaps = NULL;
1243 hashmap_free(m->swaps_by_proc_swaps);
1244 m->swaps_by_proc_swaps = NULL;
1247 static int swap_enumerate(Manager *m) {
1249 struct epoll_event ev;
1252 if (!m->proc_swaps) {
1253 m->proc_swaps = fopen("/proc/swaps", "re");
1255 return (errno == ENOENT) ? 0 : -errno;
1257 m->swap_watch.type = WATCH_SWAP;
1258 m->swap_watch.fd = fileno(m->proc_swaps);
1261 ev.events = EPOLLPRI;
1262 ev.data.ptr = &m->swap_watch;
1264 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
1268 r = swap_load_proc_swaps(m, false);
1275 static void swap_reset_failed(Unit *u) {
1280 if (s->state == SWAP_FAILED)
1281 swap_set_state(s, SWAP_DEAD);
1283 s->result = SWAP_SUCCESS;
1286 static int swap_kill(Unit *u, KillWho who, int signo, DBusError *error) {
1289 Set *pid_set = NULL;
1293 if (who == KILL_MAIN) {
1294 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Swap units have no main processes");
1298 if (s->control_pid <= 0 && who == KILL_CONTROL) {
1299 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
1303 if (who == KILL_CONTROL || who == KILL_ALL)
1304 if (s->control_pid > 0)
1305 if (kill(s->control_pid, signo) < 0)
1308 if (who == KILL_ALL) {
1311 pid_set = set_new(trivial_hash_func, trivial_compare_func);
1315 /* Exclude the control pid from being killed via the cgroup */
1316 if (s->control_pid > 0) {
1317 q = set_put(pid_set, LONG_TO_PTR(s->control_pid));
1324 q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
1325 if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
1336 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1337 [SWAP_DEAD] = "dead",
1338 [SWAP_ACTIVATING] = "activating",
1339 [SWAP_ACTIVE] = "active",
1340 [SWAP_DEACTIVATING] = "deactivating",
1341 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1342 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1343 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1344 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1345 [SWAP_FAILED] = "failed"
1348 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1350 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1351 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1352 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1355 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1357 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1358 [SWAP_SUCCESS] = "success",
1359 [SWAP_FAILURE_RESOURCES] = "resources",
1360 [SWAP_FAILURE_TIMEOUT] = "timeout",
1361 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1362 [SWAP_FAILURE_SIGNAL] = "signal",
1363 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1366 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1368 const UnitVTable swap_vtable = {
1369 .object_size = sizeof(Swap),
1370 .exec_context_offset = offsetof(Swap, exec_context),
1378 .no_instances = true,
1384 .coldplug = swap_coldplug,
1388 .start = swap_start,
1393 .serialize = swap_serialize,
1394 .deserialize_item = swap_deserialize_item,
1396 .active_state = swap_active_state,
1397 .sub_state_to_string = swap_sub_state_to_string,
1399 .check_gc = swap_check_gc,
1401 .sigchld_event = swap_sigchld_event,
1402 .timer_event = swap_timer_event,
1404 .reset_failed = swap_reset_failed,
1406 .bus_interface = "org.freedesktop.systemd1.Swap",
1407 .bus_message_handler = bus_swap_message_handler,
1408 .bus_invalidating_properties = bus_swap_invalidating_properties,
1410 .following = swap_following,
1411 .following_set = swap_following_set,
1413 .enumerate = swap_enumerate,
1414 .shutdown = swap_shutdown,
1416 .status_message_formats = {
1417 .starting_stopping = {
1418 [0] = "Activating swap %s...",
1419 [1] = "Deactivating swap %s...",
1421 .finished_start_job = {
1422 [JOB_DONE] = "Activated swap %s.",
1423 [JOB_FAILED] = "Failed to activate swap %s.",
1424 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1425 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1427 .finished_stop_job = {
1428 [JOB_DONE] = "Deactivated swap %s.",
1429 [JOB_FAILED] = "Failed deactivating swap %s.",
1430 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",