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,
191 !p->noauto && p->nofail &&
192 UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
194 /* File based swap devices need to be ordered after
195 * systemd-remount-fs.service, since they might need a
196 * writable file system. */
197 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
200 static int swap_add_default_dependencies(Swap *s) {
205 if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
208 if (detect_container(NULL) > 0)
211 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
218 static int swap_verify(Swap *s) {
220 _cleanup_free_ char *e = NULL;
222 if (UNIT(s)->load_state != UNIT_LOADED)
225 e = unit_name_from_path(s->what, ".swap");
229 b = unit_has_name(UNIT(s), e);
231 log_error_unit(UNIT(s)->id,
232 "%s: Value of \"What\" and unit name do not match, not loading.",
237 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
238 log_error_unit(UNIT(s)->id,
239 "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.",
247 static int swap_load(Unit *u) {
252 assert(u->load_state == UNIT_STUB);
254 /* Load a .swap file */
255 r = unit_load_fragment_and_dropin_optional(u);
259 if (u->load_state == UNIT_LOADED) {
260 r = unit_add_exec_dependencies(u, &s->exec_context);
264 if (UNIT(s)->fragment_path)
265 s->from_fragment = true;
268 if (s->parameters_fragment.what)
269 s->what = strdup(s->parameters_fragment.what);
270 else if (s->parameters_proc_swaps.what)
271 s->what = strdup(s->parameters_proc_swaps.what);
273 s->what = unit_name_to_path(u->id);
279 path_kill_slashes(s->what);
281 if (!UNIT(s)->description)
282 if ((r = unit_set_description(u, s->what)) < 0)
285 r = swap_add_device_links(s);
289 r = swap_add_mount_links(s);
293 r = unit_add_default_slice(u);
297 if (UNIT(s)->default_dependencies) {
298 r = swap_add_default_dependencies(s);
303 r = unit_exec_context_defaults(u, &s->exec_context);
308 return swap_verify(s);
311 static int swap_add_one(
314 const char *what_proc_swaps,
321 _cleanup_free_ char *e = NULL;
330 assert(what_proc_swaps);
332 e = unit_name_from_path(what, ".swap");
336 u = manager_get_unit(m, e);
339 SWAP(u)->from_proc_swaps &&
340 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
346 u = unit_new(m, sizeof(Swap));
350 r = unit_add_name(u, e);
354 SWAP(u)->what = strdup(what);
355 if (!SWAP(u)->what) {
360 unit_add_to_load_queue(u);
364 p = &SWAP(u)->parameters_proc_swaps;
367 wp = strdup(what_proc_swaps);
373 if (!m->swaps_by_proc_swaps) {
374 m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func);
375 if (!m->swaps_by_proc_swaps) {
384 first = hashmap_get(m->swaps_by_proc_swaps, wp);
385 LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u));
387 r = hashmap_replace(m->swaps_by_proc_swaps, wp, first);
393 SWAP(u)->is_active = true;
394 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
397 SWAP(u)->from_proc_swaps = true;
399 p->priority = priority;
403 unit_add_to_dbus_queue(u);
408 log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
418 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
424 if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) {
425 struct udev_device *d;
427 struct udev_list_entry *item = NULL, *first = NULL;
429 /* So this is a proper swap device. Create swap units
430 * for all names this swap device is known under */
432 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
436 dn = udev_device_get_devnode(d);
437 /* Skip dn==device, since that case will be handled below */
438 if (dn && !streq(dn, device))
439 r = swap_add_one(m, dn, device, prio, false, false, set_flags);
441 /* Add additional units for all symlinks */
442 first = udev_device_get_devlinks_list_entry(d);
443 udev_list_entry_foreach(item, first) {
446 /* Don't bother with the /dev/block links */
447 p = udev_list_entry_get_name(item);
449 if (path_startswith(p, "/dev/block/"))
452 if (stat(p, &st) >= 0)
453 if ((!S_ISBLK(st.st_mode)) ||
454 st.st_rdev != udev_device_get_devnum(d))
457 k = swap_add_one(m, p, device, prio, false, false, set_flags);
462 udev_device_unref(d);
465 k = swap_add_one(m, device, device, prio, false, false, set_flags);
472 static void swap_set_state(Swap *s, SwapState state) {
477 old_state = s->state;
480 if (state != SWAP_ACTIVATING &&
481 state != SWAP_ACTIVATING_SIGTERM &&
482 state != SWAP_ACTIVATING_SIGKILL &&
483 state != SWAP_DEACTIVATING &&
484 state != SWAP_DEACTIVATING_SIGTERM &&
485 state != SWAP_DEACTIVATING_SIGKILL) {
486 unit_unwatch_timer(UNIT(s), &s->timer_watch);
487 swap_unwatch_control_pid(s);
488 s->control_command = NULL;
489 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
492 if (state != old_state)
493 log_debug_unit(UNIT(s)->id,
494 "%s changed %s -> %s",
496 swap_state_to_string(old_state),
497 swap_state_to_string(state));
499 unit_notify(UNIT(s), state_translation_table[old_state],
500 state_translation_table[state], true);
503 static int swap_coldplug(Unit *u) {
505 SwapState new_state = SWAP_DEAD;
509 assert(s->state == SWAP_DEAD);
511 if (s->deserialized_state != s->state)
512 new_state = s->deserialized_state;
513 else if (s->from_proc_swaps)
514 new_state = SWAP_ACTIVE;
516 if (new_state != s->state) {
518 if (new_state == SWAP_ACTIVATING ||
519 new_state == SWAP_ACTIVATING_SIGTERM ||
520 new_state == SWAP_ACTIVATING_SIGKILL ||
521 new_state == SWAP_DEACTIVATING ||
522 new_state == SWAP_DEACTIVATING_SIGTERM ||
523 new_state == SWAP_DEACTIVATING_SIGKILL) {
525 if (s->control_pid <= 0)
528 r = unit_watch_pid(UNIT(s), s->control_pid);
532 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
537 swap_set_state(s, new_state);
543 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
550 if (s->from_proc_swaps)
551 p = &s->parameters_proc_swaps;
552 else if (s->from_fragment)
553 p = &s->parameters_fragment;
561 "%sFrom /proc/swaps: %s\n"
562 "%sFrom fragment: %s\n",
563 prefix, swap_state_to_string(s->state),
564 prefix, swap_result_to_string(s->result),
566 prefix, yes_no(s->from_proc_swaps),
567 prefix, yes_no(s->from_fragment));
575 prefix, yes_no(p->noauto),
576 prefix, yes_no(p->nofail));
578 if (s->control_pid > 0)
580 "%sControl PID: %lu\n",
581 prefix, (unsigned long) s->control_pid);
583 exec_context_dump(&s->exec_context, f, prefix);
584 kill_context_dump(&s->kill_context, f, prefix);
587 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
595 unit_realize_cgroup(UNIT(s));
597 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
605 UNIT(s)->manager->environment,
609 UNIT(s)->manager->confirm_spawn,
610 UNIT(s)->cgroup_mask,
611 UNIT(s)->cgroup_path,
618 r = unit_watch_pid(UNIT(s), pid);
620 /* FIXME: we need to do something here */
628 unit_unwatch_timer(UNIT(s), &s->timer_watch);
633 static void swap_enter_dead(Swap *s, SwapResult f) {
636 if (f != SWAP_SUCCESS)
639 exec_context_tmp_dirs_done(&s->exec_context);
640 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
643 static void swap_enter_active(Swap *s, SwapResult f) {
646 if (f != SWAP_SUCCESS)
649 swap_set_state(s, SWAP_ACTIVE);
652 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
657 if (f != SWAP_SUCCESS)
660 r = unit_kill_context(
663 state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
671 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
675 swap_set_state(s, state);
677 swap_enter_dead(s, SWAP_SUCCESS);
682 log_warning_unit(UNIT(s)->id,
683 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
685 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
688 static void swap_enter_activating(Swap *s) {
693 s->control_command_id = SWAP_EXEC_ACTIVATE;
694 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
696 if (s->from_fragment)
697 priority = s->parameters_fragment.priority;
704 snprintf(p, sizeof(p), "%i", priority);
707 r = exec_command_set(
715 r = exec_command_set(
724 swap_unwatch_control_pid(s);
726 r = swap_spawn(s, s->control_command, &s->control_pid);
730 swap_set_state(s, SWAP_ACTIVATING);
735 log_warning_unit(UNIT(s)->id,
736 "%s failed to run 'swapon' task: %s",
737 UNIT(s)->id, strerror(-r));
738 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
741 static void swap_enter_deactivating(Swap *s) {
746 s->control_command_id = SWAP_EXEC_DEACTIVATE;
747 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
749 r = exec_command_set(s->control_command,
756 swap_unwatch_control_pid(s);
758 r = swap_spawn(s, s->control_command, &s->control_pid);
762 swap_set_state(s, SWAP_DEACTIVATING);
767 log_warning_unit(UNIT(s)->id,
768 "%s failed to run 'swapoff' task: %s",
769 UNIT(s)->id, strerror(-r));
770 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
773 static int swap_start(Unit *u) {
778 /* We cannot fulfill this request right now, try again later
781 if (s->state == SWAP_DEACTIVATING ||
782 s->state == SWAP_DEACTIVATING_SIGTERM ||
783 s->state == SWAP_DEACTIVATING_SIGKILL ||
784 s->state == SWAP_ACTIVATING_SIGTERM ||
785 s->state == SWAP_ACTIVATING_SIGKILL)
788 if (s->state == SWAP_ACTIVATING)
791 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
793 if (detect_container(NULL) > 0)
796 s->result = SWAP_SUCCESS;
797 swap_enter_activating(s);
801 static int swap_stop(Unit *u) {
806 if (s->state == SWAP_DEACTIVATING ||
807 s->state == SWAP_DEACTIVATING_SIGTERM ||
808 s->state == SWAP_DEACTIVATING_SIGKILL ||
809 s->state == SWAP_ACTIVATING_SIGTERM ||
810 s->state == SWAP_ACTIVATING_SIGKILL)
813 assert(s->state == SWAP_ACTIVATING ||
814 s->state == SWAP_ACTIVE);
816 if (detect_container(NULL) > 0)
819 swap_enter_deactivating(s);
823 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
830 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
831 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
833 if (s->control_pid > 0)
834 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
836 if (s->control_command_id >= 0)
837 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
839 exec_context_serialize(&s->exec_context, UNIT(s), f);
844 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
850 if (streq(key, "state")) {
853 state = swap_state_from_string(value);
855 log_debug_unit(u->id, "Failed to parse state value %s", value);
857 s->deserialized_state = state;
858 } else if (streq(key, "result")) {
861 f = swap_result_from_string(value);
863 log_debug_unit(u->id, "Failed to parse result value %s", value);
864 else if (f != SWAP_SUCCESS)
866 } else if (streq(key, "control-pid")) {
869 if (parse_pid(value, &pid) < 0)
870 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
872 s->control_pid = pid;
874 } else if (streq(key, "control-command")) {
877 id = swap_exec_command_from_string(value);
879 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
881 s->control_command_id = id;
882 s->control_command = s->exec_command + id;
884 } else if (streq(key, "tmp-dir")) {
891 s->exec_context.tmp_dir = t;
892 } else if (streq(key, "var-tmp-dir")) {
899 s->exec_context.var_tmp_dir = t;
901 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
906 _pure_ static UnitActiveState swap_active_state(Unit *u) {
909 return state_translation_table[SWAP(u)->state];
912 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
915 return swap_state_to_string(SWAP(u)->state);
918 _pure_ static bool swap_check_gc(Unit *u) {
923 return s->from_proc_swaps;
926 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
933 if (pid != s->control_pid)
938 if (is_clean_exit(code, status, NULL))
940 else if (code == CLD_EXITED)
941 f = SWAP_FAILURE_EXIT_CODE;
942 else if (code == CLD_KILLED)
943 f = SWAP_FAILURE_SIGNAL;
944 else if (code == CLD_DUMPED)
945 f = SWAP_FAILURE_CORE_DUMP;
947 assert_not_reached("Unknown code");
949 if (f != SWAP_SUCCESS)
952 if (s->control_command) {
953 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
955 s->control_command = NULL;
956 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
959 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
961 "%s swap process exited, code=%s status=%i",
962 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_unit(u->id, "%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_unit(u->id, "%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_unit(u->id, "%s activation timed out. Killing.", u->id);
1020 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1022 log_warning_unit(u->id, "%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_unit(u->id, "%s deactivation timed out. Killing.", u->id);
1030 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1032 log_warning_unit(u->id, "%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_unit(u->id, "%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) {
1251 if (!m->proc_swaps) {
1252 struct epoll_event ev = {
1254 .data.ptr = &m->swap_watch,
1257 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);
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) {
1287 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1290 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1291 [SWAP_DEAD] = "dead",
1292 [SWAP_ACTIVATING] = "activating",
1293 [SWAP_ACTIVE] = "active",
1294 [SWAP_DEACTIVATING] = "deactivating",
1295 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1296 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1297 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1298 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1299 [SWAP_FAILED] = "failed"
1302 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1304 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1305 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1306 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1309 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1311 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1312 [SWAP_SUCCESS] = "success",
1313 [SWAP_FAILURE_RESOURCES] = "resources",
1314 [SWAP_FAILURE_TIMEOUT] = "timeout",
1315 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1316 [SWAP_FAILURE_SIGNAL] = "signal",
1317 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1320 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1322 const UnitVTable swap_vtable = {
1323 .object_size = sizeof(Swap),
1330 .private_section = "Swap",
1331 .exec_context_offset = offsetof(Swap, exec_context),
1332 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1335 .no_instances = true,
1341 .coldplug = swap_coldplug,
1345 .start = swap_start,
1350 .serialize = swap_serialize,
1351 .deserialize_item = swap_deserialize_item,
1353 .active_state = swap_active_state,
1354 .sub_state_to_string = swap_sub_state_to_string,
1356 .check_gc = swap_check_gc,
1358 .sigchld_event = swap_sigchld_event,
1359 .timer_event = swap_timer_event,
1361 .reset_failed = swap_reset_failed,
1363 .bus_interface = "org.freedesktop.systemd1.Swap",
1364 .bus_message_handler = bus_swap_message_handler,
1365 .bus_invalidating_properties = bus_swap_invalidating_properties,
1366 .bus_set_property = bus_swap_set_property,
1367 .bus_commit_properties = bus_swap_commit_properties,
1369 .following = swap_following,
1370 .following_set = swap_following_set,
1372 .enumerate = swap_enumerate,
1373 .shutdown = swap_shutdown,
1375 .status_message_formats = {
1376 .starting_stopping = {
1377 [0] = "Activating swap %s...",
1378 [1] = "Deactivating swap %s...",
1380 .finished_start_job = {
1381 [JOB_DONE] = "Activated swap %s.",
1382 [JOB_FAILED] = "Failed to activate swap %s.",
1383 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1384 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1386 .finished_stop_job = {
1387 [JOB_DONE] = "Deactivated swap %s.",
1388 [JOB_FAILED] = "Failed deactivating swap %s.",
1389 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",