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);
431 r = swap_add_one(m, dn, device, prio, false, false, set_flags);
433 /* Add additional units for all symlinks */
434 first = udev_device_get_devlinks_list_entry(d);
435 udev_list_entry_foreach(item, first) {
438 /* Don't bother with the /dev/block links */
439 p = udev_list_entry_get_name(item);
441 if (path_startswith(p, "/dev/block/"))
444 if (stat(p, &st) >= 0)
445 if ((!S_ISBLK(st.st_mode)) ||
446 st.st_rdev != udev_device_get_devnum(d))
449 k = swap_add_one(m, p, device, prio, false, false, set_flags);
454 udev_device_unref(d);
457 k = swap_add_one(m, device, device, prio, false, false, set_flags);
464 static void swap_set_state(Swap *s, SwapState state) {
469 old_state = s->state;
472 if (state != SWAP_ACTIVATING &&
473 state != SWAP_ACTIVATING_SIGTERM &&
474 state != SWAP_ACTIVATING_SIGKILL &&
475 state != SWAP_DEACTIVATING &&
476 state != SWAP_DEACTIVATING_SIGTERM &&
477 state != SWAP_DEACTIVATING_SIGKILL) {
478 unit_unwatch_timer(UNIT(s), &s->timer_watch);
479 swap_unwatch_control_pid(s);
480 s->control_command = NULL;
481 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
484 if (state != old_state)
485 log_debug("%s changed %s -> %s",
487 swap_state_to_string(old_state),
488 swap_state_to_string(state));
490 unit_notify(UNIT(s), state_translation_table[old_state],
491 state_translation_table[state], true);
494 static int swap_coldplug(Unit *u) {
496 SwapState new_state = SWAP_DEAD;
500 assert(s->state == SWAP_DEAD);
502 if (s->deserialized_state != s->state)
503 new_state = s->deserialized_state;
504 else if (s->from_proc_swaps)
505 new_state = SWAP_ACTIVE;
507 if (new_state != s->state) {
509 if (new_state == SWAP_ACTIVATING ||
510 new_state == SWAP_ACTIVATING_SIGTERM ||
511 new_state == SWAP_ACTIVATING_SIGKILL ||
512 new_state == SWAP_DEACTIVATING ||
513 new_state == SWAP_DEACTIVATING_SIGTERM ||
514 new_state == SWAP_DEACTIVATING_SIGKILL) {
516 if (s->control_pid <= 0)
519 r = unit_watch_pid(UNIT(s), s->control_pid);
523 r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch);
528 swap_set_state(s, new_state);
534 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
541 if (s->from_proc_swaps)
542 p = &s->parameters_proc_swaps;
543 else if (s->from_fragment)
544 p = &s->parameters_fragment;
552 "%sFrom /proc/swaps: %s\n"
553 "%sFrom fragment: %s\n",
554 prefix, swap_state_to_string(s->state),
555 prefix, swap_result_to_string(s->result),
557 prefix, yes_no(s->from_proc_swaps),
558 prefix, yes_no(s->from_fragment));
566 prefix, yes_no(p->noauto),
567 prefix, yes_no(p->nofail));
569 if (s->control_pid > 0)
571 "%sControl PID: %lu\n",
572 prefix, (unsigned long) s->control_pid);
574 exec_context_dump(&s->exec_context, f, prefix);
575 kill_context_dump(&s->kill_context, f, prefix);
578 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
586 r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch);
594 UNIT(s)->manager->environment,
598 UNIT(s)->manager->confirm_spawn,
599 UNIT(s)->cgroup_bondings,
600 UNIT(s)->cgroup_attributes,
608 r = unit_watch_pid(UNIT(s), pid);
610 /* FIXME: we need to do something here */
618 unit_unwatch_timer(UNIT(s), &s->timer_watch);
623 static void swap_enter_dead(Swap *s, SwapResult f) {
626 if (f != SWAP_SUCCESS)
629 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
632 static void swap_enter_active(Swap *s, SwapResult f) {
635 if (f != SWAP_SUCCESS)
638 swap_set_state(s, SWAP_ACTIVE);
641 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
644 bool wait_for_exit = false;
648 if (f != SWAP_SUCCESS)
651 if (s->kill_context.kill_mode != KILL_NONE) {
652 int sig = (state == SWAP_ACTIVATING_SIGTERM ||
653 state == SWAP_DEACTIVATING_SIGTERM) ? s->kill_context.kill_signal : SIGKILL;
655 if (s->control_pid > 0) {
656 if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH)
658 log_warning("Failed to kill control process %li: %m", (long) s->control_pid);
660 wait_for_exit = true;
663 if (s->kill_context.kill_mode == KILL_CONTROL_GROUP) {
665 pid_set = set_new(trivial_hash_func, trivial_compare_func);
671 /* Exclude the control pid from being killed via the cgroup */
672 if (s->control_pid > 0) {
673 r = set_put(pid_set, LONG_TO_PTR(s->control_pid));
678 r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, false, pid_set, NULL);
680 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
681 log_warning("Failed to kill control group: %s", strerror(-r));
683 wait_for_exit = true;
691 r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch);
695 swap_set_state(s, state);
697 swap_enter_dead(s, SWAP_SUCCESS);
702 log_warning("%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
704 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
710 static void swap_enter_activating(Swap *s) {
715 s->control_command_id = SWAP_EXEC_ACTIVATE;
716 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
718 if (s->from_fragment)
719 priority = s->parameters_fragment.priority;
726 snprintf(p, sizeof(p), "%i", priority);
729 r = exec_command_set(
737 r = exec_command_set(
746 swap_unwatch_control_pid(s);
748 r = swap_spawn(s, s->control_command, &s->control_pid);
752 swap_set_state(s, SWAP_ACTIVATING);
757 log_warning("%s failed to run 'swapon' task: %s", UNIT(s)->id, strerror(-r));
758 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
761 static void swap_enter_deactivating(Swap *s) {
766 s->control_command_id = SWAP_EXEC_DEACTIVATE;
767 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
769 r = exec_command_set(s->control_command,
776 swap_unwatch_control_pid(s);
778 r = swap_spawn(s, s->control_command, &s->control_pid);
782 swap_set_state(s, SWAP_DEACTIVATING);
787 log_warning("%s failed to run 'swapoff' task: %s", UNIT(s)->id, strerror(-r));
788 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
791 static int swap_start(Unit *u) {
796 /* We cannot fulfill this request right now, try again later
799 if (s->state == SWAP_DEACTIVATING ||
800 s->state == SWAP_DEACTIVATING_SIGTERM ||
801 s->state == SWAP_DEACTIVATING_SIGKILL ||
802 s->state == SWAP_ACTIVATING_SIGTERM ||
803 s->state == SWAP_ACTIVATING_SIGKILL)
806 if (s->state == SWAP_ACTIVATING)
809 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
811 if (detect_container(NULL) > 0)
814 s->result = SWAP_SUCCESS;
815 swap_enter_activating(s);
819 static int swap_stop(Unit *u) {
824 if (s->state == SWAP_DEACTIVATING ||
825 s->state == SWAP_DEACTIVATING_SIGTERM ||
826 s->state == SWAP_DEACTIVATING_SIGKILL ||
827 s->state == SWAP_ACTIVATING_SIGTERM ||
828 s->state == SWAP_ACTIVATING_SIGKILL)
831 assert(s->state == SWAP_ACTIVATING ||
832 s->state == SWAP_ACTIVE);
834 if (detect_container(NULL) > 0)
837 swap_enter_deactivating(s);
841 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
848 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
849 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
851 if (s->control_pid > 0)
852 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
854 if (s->control_command_id >= 0)
855 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
860 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
866 if (streq(key, "state")) {
869 state = swap_state_from_string(value);
871 log_debug("Failed to parse state value %s", value);
873 s->deserialized_state = state;
874 } else if (streq(key, "result")) {
877 f = swap_result_from_string(value);
879 log_debug("Failed to parse result value %s", value);
880 else if (f != SWAP_SUCCESS)
882 } else if (streq(key, "control-pid")) {
885 if (parse_pid(value, &pid) < 0)
886 log_debug("Failed to parse control-pid value %s", value);
888 s->control_pid = pid;
890 } else if (streq(key, "control-command")) {
893 id = swap_exec_command_from_string(value);
895 log_debug("Failed to parse exec-command value %s", value);
897 s->control_command_id = id;
898 s->control_command = s->exec_command + id;
902 log_debug("Unknown serialization key '%s'", key);
907 static UnitActiveState swap_active_state(Unit *u) {
910 return state_translation_table[SWAP(u)->state];
913 static const char *swap_sub_state_to_string(Unit *u) {
916 return swap_state_to_string(SWAP(u)->state);
919 static bool swap_check_gc(Unit *u) {
924 return s->from_proc_swaps;
927 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
934 if (pid != s->control_pid)
939 if (is_clean_exit(code, status, NULL))
941 else if (code == CLD_EXITED)
942 f = SWAP_FAILURE_EXIT_CODE;
943 else if (code == CLD_KILLED)
944 f = SWAP_FAILURE_SIGNAL;
945 else if (code == CLD_DUMPED)
946 f = SWAP_FAILURE_CORE_DUMP;
948 assert_not_reached("Unknown code");
950 if (f != SWAP_SUCCESS)
953 if (s->control_command) {
954 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
956 s->control_command = NULL;
957 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
960 log_full(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
961 "%s swap process exited, code=%s status=%i", u->id, sigchld_code_to_string(code), status);
965 case SWAP_ACTIVATING:
966 case SWAP_ACTIVATING_SIGTERM:
967 case SWAP_ACTIVATING_SIGKILL:
969 if (f == SWAP_SUCCESS)
970 swap_enter_active(s, f);
972 swap_enter_dead(s, f);
975 case SWAP_DEACTIVATING:
976 case SWAP_DEACTIVATING_SIGKILL:
977 case SWAP_DEACTIVATING_SIGTERM:
979 if (f == SWAP_SUCCESS)
980 swap_enter_dead(s, f);
982 swap_enter_dead(s, f);
986 assert_not_reached("Uh, control process died at wrong time.");
989 /* Notify clients about changed exit status */
990 unit_add_to_dbus_queue(u);
992 /* Request a reload of /proc/swaps, so that following units
993 * can follow our state change */
994 u->manager->request_reload = true;
997 static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
1001 assert(elapsed == 1);
1002 assert(w == &s->timer_watch);
1006 case SWAP_ACTIVATING:
1007 log_warning("%s activation timed out. Stopping.", u->id);
1008 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1011 case SWAP_DEACTIVATING:
1012 log_warning("%s deactivation timed out. Stopping.", u->id);
1013 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1016 case SWAP_ACTIVATING_SIGTERM:
1017 if (s->kill_context.send_sigkill) {
1018 log_warning("%s activation timed out. Killing.", u->id);
1019 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1021 log_warning("%s activation timed out. Skipping SIGKILL. Ignoring.", u->id);
1022 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1026 case SWAP_DEACTIVATING_SIGTERM:
1027 if (s->kill_context.send_sigkill) {
1028 log_warning("%s deactivation timed out. Killing.", u->id);
1029 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1031 log_warning("%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id);
1032 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1036 case SWAP_ACTIVATING_SIGKILL:
1037 case SWAP_DEACTIVATING_SIGKILL:
1038 log_warning("%s swap process still around after SIGKILL. Ignoring.", u->id);
1039 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1043 assert_not_reached("Timeout at wrong time.");
1047 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1053 rewind(m->proc_swaps);
1055 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1058 char *dev = NULL, *d;
1061 k = fscanf(m->proc_swaps,
1062 "%ms " /* device/file */
1063 "%*s " /* type of swap */
1064 "%*s " /* swap size */
1066 "%i\n", /* priority */
1072 log_warning("Failed to parse /proc/swaps:%u", i);
1083 k = swap_process_new_swap(m, d, prio, set_flags);
1093 int swap_dispatch_reload(Manager *m) {
1094 /* This function should go as soon as the kernel properly notifies us */
1096 if (_likely_(!m->request_reload))
1099 m->request_reload = false;
1101 return swap_fd_event(m, EPOLLPRI);
1104 int swap_fd_event(Manager *m, int events) {
1109 assert(events & EPOLLPRI);
1111 r = swap_load_proc_swaps(m, true);
1113 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1115 /* Reset flags, just in case, for late calls */
1116 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1117 Swap *swap = SWAP(u);
1119 swap->is_active = swap->just_activated = false;
1125 manager_dispatch_load_queue(m);
1127 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1128 Swap *swap = SWAP(u);
1130 if (!swap->is_active) {
1131 /* This has just been deactivated */
1133 swap->from_proc_swaps = false;
1134 swap_unset_proc_swaps(swap);
1136 switch (swap->state) {
1139 swap_enter_dead(swap, SWAP_SUCCESS);
1143 swap_set_state(swap, swap->state);
1147 } else if (swap->just_activated) {
1149 /* New swap entry */
1151 switch (swap->state) {
1155 swap_enter_active(swap, SWAP_SUCCESS);
1159 /* Nothing really changed, but let's
1160 * issue an notification call
1161 * nonetheless, in case somebody is
1162 * waiting for this. */
1163 swap_set_state(swap, swap->state);
1168 /* Reset the flags for later calls */
1169 swap->is_active = swap->just_activated = false;
1175 static Unit *swap_following(Unit *u) {
1177 Swap *other, *first = NULL;
1181 if (streq_ptr(s->what, s->parameters_proc_swaps.what))
1184 /* Make everybody follow the unit that's named after the swap
1185 * device in the kernel */
1187 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1188 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1191 LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
1192 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1201 static int swap_following_set(Unit *u, Set **_set) {
1210 if (LIST_JUST_US(same_proc_swaps, s)) {
1215 if (!(set = set_new(NULL, NULL)))
1218 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1219 if ((r = set_put(set, other)) < 0)
1222 LIST_FOREACH_BEFORE(same_proc_swaps, other, s)
1223 if ((r = set_put(set, other)) < 0)
1234 static void swap_shutdown(Manager *m) {
1237 if (m->proc_swaps) {
1238 fclose(m->proc_swaps);
1239 m->proc_swaps = NULL;
1242 hashmap_free(m->swaps_by_proc_swaps);
1243 m->swaps_by_proc_swaps = NULL;
1246 static int swap_enumerate(Manager *m) {
1248 struct epoll_event ev;
1251 if (!m->proc_swaps) {
1252 m->proc_swaps = fopen("/proc/swaps", "re");
1254 return (errno == ENOENT) ? 0 : -errno;
1256 m->swap_watch.type = WATCH_SWAP;
1257 m->swap_watch.fd = fileno(m->proc_swaps);
1260 ev.events = EPOLLPRI;
1261 ev.data.ptr = &m->swap_watch;
1263 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
1267 r = swap_load_proc_swaps(m, false);
1274 static void swap_reset_failed(Unit *u) {
1279 if (s->state == SWAP_FAILED)
1280 swap_set_state(s, SWAP_DEAD);
1282 s->result = SWAP_SUCCESS;
1285 static int swap_kill(Unit *u, KillWho who, int signo, DBusError *error) {
1288 Set *pid_set = NULL;
1292 if (who == KILL_MAIN) {
1293 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Swap units have no main processes");
1297 if (s->control_pid <= 0 && who == KILL_CONTROL) {
1298 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
1302 if (who == KILL_CONTROL || who == KILL_ALL)
1303 if (s->control_pid > 0)
1304 if (kill(s->control_pid, signo) < 0)
1307 if (who == KILL_ALL) {
1310 pid_set = set_new(trivial_hash_func, trivial_compare_func);
1314 /* Exclude the control pid from being killed via the cgroup */
1315 if (s->control_pid > 0) {
1316 q = set_put(pid_set, LONG_TO_PTR(s->control_pid));
1323 q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
1324 if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
1335 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1336 [SWAP_DEAD] = "dead",
1337 [SWAP_ACTIVATING] = "activating",
1338 [SWAP_ACTIVE] = "active",
1339 [SWAP_DEACTIVATING] = "deactivating",
1340 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1341 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1342 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1343 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1344 [SWAP_FAILED] = "failed"
1347 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1349 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1350 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1351 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1354 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1356 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1357 [SWAP_SUCCESS] = "success",
1358 [SWAP_FAILURE_RESOURCES] = "resources",
1359 [SWAP_FAILURE_TIMEOUT] = "timeout",
1360 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1361 [SWAP_FAILURE_SIGNAL] = "signal",
1362 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1365 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1367 const UnitVTable swap_vtable = {
1368 .object_size = sizeof(Swap),
1369 .exec_context_offset = offsetof(Swap, exec_context),
1377 .no_instances = true,
1383 .coldplug = swap_coldplug,
1387 .start = swap_start,
1392 .serialize = swap_serialize,
1393 .deserialize_item = swap_deserialize_item,
1395 .active_state = swap_active_state,
1396 .sub_state_to_string = swap_sub_state_to_string,
1398 .check_gc = swap_check_gc,
1400 .sigchld_event = swap_sigchld_event,
1401 .timer_event = swap_timer_event,
1403 .reset_failed = swap_reset_failed,
1405 .bus_interface = "org.freedesktop.systemd1.Swap",
1406 .bus_message_handler = bus_swap_message_handler,
1407 .bus_invalidating_properties = bus_swap_invalidating_properties,
1409 .following = swap_following,
1410 .following_set = swap_following_set,
1412 .enumerate = swap_enumerate,
1413 .shutdown = swap_shutdown,
1415 .status_message_formats = {
1416 .starting_stopping = {
1417 [0] = "Activating swap %s...",
1418 [1] = "Deactivating swap %s...",
1420 .finished_start_job = {
1421 [JOB_DONE] = "Activated swap %s.",
1422 [JOB_FAILED] = "Failed to activate swap %s.",
1423 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1424 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1426 .finished_stop_job = {
1427 [JOB_DONE] = "Deactivated swap %s.",
1428 [JOB_FAILED] = "Failed deactivating swap %s.",
1429 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",