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);
95 cgroup_context_init(&s->cgroup_context);
97 s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
99 s->timer_watch.type = WATCH_INVALID;
101 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
103 UNIT(s)->ignore_on_isolate = true;
106 static void swap_unwatch_control_pid(Swap *s) {
109 if (s->control_pid <= 0)
112 unit_unwatch_pid(UNIT(s), s->control_pid);
116 static void swap_done(Unit *u) {
121 swap_unset_proc_swaps(s);
126 free(s->parameters_fragment.what);
127 s->parameters_fragment.what = NULL;
129 exec_context_done(&s->exec_context, manager_is_reloading_or_reexecuting(u->manager));
130 exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
131 s->control_command = NULL;
133 cgroup_context_done(&s->cgroup_context);
135 swap_unwatch_control_pid(s);
137 unit_unwatch_timer(u, &s->timer_watch);
140 int swap_add_one_mount_link(Swap *s, Mount *m) {
146 if (UNIT(s)->load_state != UNIT_LOADED ||
147 UNIT(m)->load_state != UNIT_LOADED)
150 if (is_device_path(s->what))
153 if (!path_startswith(s->what, m->where))
156 r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
163 static int swap_add_mount_links(Swap *s) {
169 LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT])
170 if ((r = swap_add_one_mount_link(s, MOUNT(other))) < 0)
176 static int swap_add_device_links(Swap *s) {
184 if (s->from_fragment)
185 p = &s->parameters_fragment;
189 if (is_device_path(s->what))
190 return unit_add_node_link(UNIT(s), s->what, !p->noauto &&
191 UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
193 /* File based swap devices need to be ordered after
194 * systemd-remount-fs.service, since they might need a
195 * writable file system. */
196 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
199 static int swap_add_default_dependencies(Swap *s) {
204 if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
207 if (detect_container(NULL) > 0)
210 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
217 static int swap_verify(Swap *s) {
219 _cleanup_free_ char *e = NULL;
221 if (UNIT(s)->load_state != UNIT_LOADED)
224 e = unit_name_from_path(s->what, ".swap");
228 b = unit_has_name(UNIT(s), e);
230 log_error_unit(UNIT(s)->id,
231 "%s: Value of \"What\" and unit name do not match, not loading.",
236 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
237 log_error_unit(UNIT(s)->id,
238 "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.",
246 static int swap_load(Unit *u) {
251 assert(u->load_state == UNIT_STUB);
253 /* Load a .swap file */
254 r = unit_load_fragment_and_dropin_optional(u);
258 if (u->load_state == UNIT_LOADED) {
259 r = unit_add_exec_dependencies(u, &s->exec_context);
263 if (UNIT(s)->fragment_path)
264 s->from_fragment = true;
267 if (s->parameters_fragment.what)
268 s->what = strdup(s->parameters_fragment.what);
269 else if (s->parameters_proc_swaps.what)
270 s->what = strdup(s->parameters_proc_swaps.what);
272 s->what = unit_name_to_path(u->id);
278 path_kill_slashes(s->what);
280 if (!UNIT(s)->description)
281 if ((r = unit_set_description(u, s->what)) < 0)
284 r = swap_add_device_links(s);
288 r = swap_add_mount_links(s);
292 r = unit_add_default_slice(u);
296 if (UNIT(s)->default_dependencies) {
297 r = swap_add_default_dependencies(s);
302 r = unit_exec_context_defaults(u, &s->exec_context);
307 return swap_verify(s);
310 static int swap_add_one(
313 const char *what_proc_swaps,
320 _cleanup_free_ char *e = NULL;
329 assert(what_proc_swaps);
331 e = unit_name_from_path(what, ".swap");
335 u = manager_get_unit(m, e);
338 SWAP(u)->from_proc_swaps &&
339 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
345 u = unit_new(m, sizeof(Swap));
349 r = unit_add_name(u, e);
353 SWAP(u)->what = strdup(what);
354 if (!SWAP(u)->what) {
359 unit_add_to_load_queue(u);
363 p = &SWAP(u)->parameters_proc_swaps;
366 wp = strdup(what_proc_swaps);
372 if (!m->swaps_by_proc_swaps) {
373 m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func);
374 if (!m->swaps_by_proc_swaps) {
383 first = hashmap_get(m->swaps_by_proc_swaps, wp);
384 LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u));
386 r = hashmap_replace(m->swaps_by_proc_swaps, wp, first);
392 SWAP(u)->is_active = true;
393 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
396 SWAP(u)->from_proc_swaps = true;
398 p->priority = priority;
402 unit_add_to_dbus_queue(u);
407 log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
417 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
423 if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) {
424 struct udev_device *d;
426 struct udev_list_entry *item = NULL, *first = NULL;
428 /* So this is a proper swap device. Create swap units
429 * for all names this swap device is known under */
431 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
435 dn = udev_device_get_devnode(d);
436 /* Skip dn==device, since that case will be handled below */
437 if (dn && !streq(dn, device))
438 r = swap_add_one(m, dn, device, prio, false, false, set_flags);
440 /* Add additional units for all symlinks */
441 first = udev_device_get_devlinks_list_entry(d);
442 udev_list_entry_foreach(item, first) {
445 /* Don't bother with the /dev/block links */
446 p = udev_list_entry_get_name(item);
448 if (path_startswith(p, "/dev/block/"))
451 if (stat(p, &st) >= 0)
452 if ((!S_ISBLK(st.st_mode)) ||
453 st.st_rdev != udev_device_get_devnum(d))
456 k = swap_add_one(m, p, device, prio, false, false, set_flags);
461 udev_device_unref(d);
464 k = swap_add_one(m, device, device, prio, false, false, set_flags);
471 static void swap_set_state(Swap *s, SwapState state) {
476 old_state = s->state;
479 if (state != SWAP_ACTIVATING &&
480 state != SWAP_ACTIVATING_SIGTERM &&
481 state != SWAP_ACTIVATING_SIGKILL &&
482 state != SWAP_DEACTIVATING &&
483 state != SWAP_DEACTIVATING_SIGTERM &&
484 state != SWAP_DEACTIVATING_SIGKILL) {
485 unit_unwatch_timer(UNIT(s), &s->timer_watch);
486 swap_unwatch_control_pid(s);
487 s->control_command = NULL;
488 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
491 if (state != old_state)
492 log_debug_unit(UNIT(s)->id,
493 "%s changed %s -> %s",
495 swap_state_to_string(old_state),
496 swap_state_to_string(state));
498 unit_notify(UNIT(s), state_translation_table[old_state],
499 state_translation_table[state], true);
502 static int swap_coldplug(Unit *u) {
504 SwapState new_state = SWAP_DEAD;
508 assert(s->state == SWAP_DEAD);
510 if (s->deserialized_state != s->state)
511 new_state = s->deserialized_state;
512 else if (s->from_proc_swaps)
513 new_state = SWAP_ACTIVE;
515 if (new_state != s->state) {
517 if (new_state == SWAP_ACTIVATING ||
518 new_state == SWAP_ACTIVATING_SIGTERM ||
519 new_state == SWAP_ACTIVATING_SIGKILL ||
520 new_state == SWAP_DEACTIVATING ||
521 new_state == SWAP_DEACTIVATING_SIGTERM ||
522 new_state == SWAP_DEACTIVATING_SIGKILL) {
524 if (s->control_pid <= 0)
527 r = unit_watch_pid(UNIT(s), s->control_pid);
531 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
536 swap_set_state(s, new_state);
542 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
549 if (s->from_proc_swaps)
550 p = &s->parameters_proc_swaps;
551 else if (s->from_fragment)
552 p = &s->parameters_fragment;
560 "%sFrom /proc/swaps: %s\n"
561 "%sFrom fragment: %s\n",
562 prefix, swap_state_to_string(s->state),
563 prefix, swap_result_to_string(s->result),
565 prefix, yes_no(s->from_proc_swaps),
566 prefix, yes_no(s->from_fragment));
574 prefix, yes_no(p->noauto),
575 prefix, yes_no(p->nofail));
577 if (s->control_pid > 0)
579 "%sControl PID: %lu\n",
580 prefix, (unsigned long) s->control_pid);
582 exec_context_dump(&s->exec_context, f, prefix);
583 kill_context_dump(&s->kill_context, f, prefix);
586 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
594 unit_realize_cgroup(UNIT(s));
596 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
604 UNIT(s)->manager->environment,
608 UNIT(s)->manager->confirm_spawn,
609 UNIT(s)->cgroup_mask,
610 UNIT(s)->cgroup_path,
617 r = unit_watch_pid(UNIT(s), pid);
619 /* FIXME: we need to do something here */
627 unit_unwatch_timer(UNIT(s), &s->timer_watch);
632 static void swap_enter_dead(Swap *s, SwapResult f) {
635 if (f != SWAP_SUCCESS)
638 exec_context_tmp_dirs_done(&s->exec_context);
639 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
642 static void swap_enter_active(Swap *s, SwapResult f) {
645 if (f != SWAP_SUCCESS)
648 swap_set_state(s, SWAP_ACTIVE);
651 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
656 if (f != SWAP_SUCCESS)
659 r = unit_kill_context(
662 state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
670 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
674 swap_set_state(s, state);
676 swap_enter_dead(s, SWAP_SUCCESS);
681 log_warning_unit(UNIT(s)->id,
682 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
684 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
687 static void swap_enter_activating(Swap *s) {
692 s->control_command_id = SWAP_EXEC_ACTIVATE;
693 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
695 if (s->from_fragment)
696 priority = s->parameters_fragment.priority;
703 snprintf(p, sizeof(p), "%i", priority);
706 r = exec_command_set(
714 r = exec_command_set(
723 swap_unwatch_control_pid(s);
725 r = swap_spawn(s, s->control_command, &s->control_pid);
729 swap_set_state(s, SWAP_ACTIVATING);
734 log_warning_unit(UNIT(s)->id,
735 "%s failed to run 'swapon' task: %s",
736 UNIT(s)->id, strerror(-r));
737 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
740 static void swap_enter_deactivating(Swap *s) {
745 s->control_command_id = SWAP_EXEC_DEACTIVATE;
746 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
748 r = exec_command_set(s->control_command,
755 swap_unwatch_control_pid(s);
757 r = swap_spawn(s, s->control_command, &s->control_pid);
761 swap_set_state(s, SWAP_DEACTIVATING);
766 log_warning_unit(UNIT(s)->id,
767 "%s failed to run 'swapoff' task: %s",
768 UNIT(s)->id, strerror(-r));
769 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
772 static int swap_start(Unit *u) {
777 /* We cannot fulfill this request right now, try again later
780 if (s->state == SWAP_DEACTIVATING ||
781 s->state == SWAP_DEACTIVATING_SIGTERM ||
782 s->state == SWAP_DEACTIVATING_SIGKILL ||
783 s->state == SWAP_ACTIVATING_SIGTERM ||
784 s->state == SWAP_ACTIVATING_SIGKILL)
787 if (s->state == SWAP_ACTIVATING)
790 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
792 if (detect_container(NULL) > 0)
795 s->result = SWAP_SUCCESS;
796 swap_enter_activating(s);
800 static int swap_stop(Unit *u) {
805 if (s->state == SWAP_DEACTIVATING ||
806 s->state == SWAP_DEACTIVATING_SIGTERM ||
807 s->state == SWAP_DEACTIVATING_SIGKILL ||
808 s->state == SWAP_ACTIVATING_SIGTERM ||
809 s->state == SWAP_ACTIVATING_SIGKILL)
812 assert(s->state == SWAP_ACTIVATING ||
813 s->state == SWAP_ACTIVE);
815 if (detect_container(NULL) > 0)
818 swap_enter_deactivating(s);
822 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
829 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
830 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
832 if (s->control_pid > 0)
833 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
835 if (s->control_command_id >= 0)
836 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
838 exec_context_serialize(&s->exec_context, UNIT(s), f);
843 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
849 if (streq(key, "state")) {
852 state = swap_state_from_string(value);
854 log_debug_unit(u->id, "Failed to parse state value %s", value);
856 s->deserialized_state = state;
857 } else if (streq(key, "result")) {
860 f = swap_result_from_string(value);
862 log_debug_unit(u->id, "Failed to parse result value %s", value);
863 else if (f != SWAP_SUCCESS)
865 } else if (streq(key, "control-pid")) {
868 if (parse_pid(value, &pid) < 0)
869 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
871 s->control_pid = pid;
873 } else if (streq(key, "control-command")) {
876 id = swap_exec_command_from_string(value);
878 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
880 s->control_command_id = id;
881 s->control_command = s->exec_command + id;
883 } else if (streq(key, "tmp-dir")) {
890 s->exec_context.tmp_dir = t;
891 } else if (streq(key, "var-tmp-dir")) {
898 s->exec_context.var_tmp_dir = t;
900 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
905 _pure_ static UnitActiveState swap_active_state(Unit *u) {
908 return state_translation_table[SWAP(u)->state];
911 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
914 return swap_state_to_string(SWAP(u)->state);
917 _pure_ static bool swap_check_gc(Unit *u) {
922 return s->from_proc_swaps;
925 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
932 if (pid != s->control_pid)
937 if (is_clean_exit(code, status, NULL))
939 else if (code == CLD_EXITED)
940 f = SWAP_FAILURE_EXIT_CODE;
941 else if (code == CLD_KILLED)
942 f = SWAP_FAILURE_SIGNAL;
943 else if (code == CLD_DUMPED)
944 f = SWAP_FAILURE_CORE_DUMP;
946 assert_not_reached("Unknown code");
948 if (f != SWAP_SUCCESS)
951 if (s->control_command) {
952 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
954 s->control_command = NULL;
955 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
958 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
960 "%s swap process exited, code=%s status=%i",
961 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_unit(u->id, "%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_unit(u->id, "%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_unit(u->id, "%s activation timed out. Killing.", u->id);
1019 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1021 log_warning_unit(u->id, "%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_unit(u->id, "%s deactivation timed out. Killing.", u->id);
1029 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1031 log_warning_unit(u->id, "%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_unit(u->id, "%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) {
1250 if (!m->proc_swaps) {
1251 struct epoll_event ev = {
1253 .data.ptr = &m->swap_watch,
1256 m->proc_swaps = fopen("/proc/swaps", "re");
1258 return (errno == ENOENT) ? 0 : -errno;
1260 m->swap_watch.type = WATCH_SWAP;
1261 m->swap_watch.fd = fileno(m->proc_swaps);
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) {
1286 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1289 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1290 [SWAP_DEAD] = "dead",
1291 [SWAP_ACTIVATING] = "activating",
1292 [SWAP_ACTIVE] = "active",
1293 [SWAP_DEACTIVATING] = "deactivating",
1294 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1295 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1296 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1297 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1298 [SWAP_FAILED] = "failed"
1301 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1303 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1304 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1305 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1308 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1310 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1311 [SWAP_SUCCESS] = "success",
1312 [SWAP_FAILURE_RESOURCES] = "resources",
1313 [SWAP_FAILURE_TIMEOUT] = "timeout",
1314 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1315 [SWAP_FAILURE_SIGNAL] = "signal",
1316 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1319 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1321 const UnitVTable swap_vtable = {
1322 .object_size = sizeof(Swap),
1329 .private_section = "Swap",
1330 .exec_context_offset = offsetof(Swap, exec_context),
1331 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1334 .no_instances = true,
1340 .coldplug = swap_coldplug,
1344 .start = swap_start,
1349 .serialize = swap_serialize,
1350 .deserialize_item = swap_deserialize_item,
1352 .active_state = swap_active_state,
1353 .sub_state_to_string = swap_sub_state_to_string,
1355 .check_gc = swap_check_gc,
1357 .sigchld_event = swap_sigchld_event,
1358 .timer_event = swap_timer_event,
1360 .reset_failed = swap_reset_failed,
1362 .bus_interface = "org.freedesktop.systemd1.Swap",
1363 .bus_message_handler = bus_swap_message_handler,
1364 .bus_invalidating_properties = bus_swap_invalidating_properties,
1365 .bus_set_property = bus_swap_set_property,
1366 .bus_commit_properties = bus_swap_commit_properties,
1368 .following = swap_following,
1369 .following_set = swap_following_set,
1371 .enumerate = swap_enumerate,
1372 .shutdown = swap_shutdown,
1374 .status_message_formats = {
1375 .starting_stopping = {
1376 [0] = "Activating swap %s...",
1377 [1] = "Deactivating swap %s...",
1379 .finished_start_job = {
1380 [JOB_DONE] = "Activated swap %s.",
1381 [JOB_FAILED] = "Failed to activate swap %s.",
1382 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1383 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1385 .finished_stop_job = {
1386 [JOB_DONE] = "Deactivated swap %s.",
1387 [JOB_FAILED] = "Failed deactivating swap %s.",
1388 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",