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) {
61 if (!s->parameters_proc_swaps.what)
64 /* Remove this unit from the chain of swaps which share the
65 * same kernel swap device. */
67 first = hashmap_get(UNIT(s)->manager->swaps_by_proc_swaps, s->parameters_proc_swaps.what);
68 LIST_REMOVE(Swap, same_proc_swaps, first, s);
71 hashmap_remove_and_replace(UNIT(s)->manager->swaps_by_proc_swaps, s->parameters_proc_swaps.what, first->parameters_proc_swaps.what, first);
73 hashmap_remove(UNIT(s)->manager->swaps_by_proc_swaps, s->parameters_proc_swaps.what);
75 free(s->parameters_proc_swaps.what);
76 s->parameters_proc_swaps.what = NULL;
79 static void swap_init(Unit *u) {
83 assert(UNIT(s)->load_state == UNIT_STUB);
85 s->timeout_usec = DEFAULT_TIMEOUT_USEC;
87 exec_context_init(&s->exec_context);
88 s->exec_context.std_output = u->manager->default_std_output;
89 s->exec_context.std_error = u->manager->default_std_error;
90 kill_context_init(&s->kill_context);
92 s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
94 s->timer_watch.type = WATCH_INVALID;
96 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
98 UNIT(s)->ignore_on_isolate = true;
101 static void swap_unwatch_control_pid(Swap *s) {
104 if (s->control_pid <= 0)
107 unit_unwatch_pid(UNIT(s), s->control_pid);
111 static void swap_done(Unit *u) {
116 swap_unset_proc_swaps(s);
121 free(s->parameters_fragment.what);
122 s->parameters_fragment.what = NULL;
124 exec_context_done(&s->exec_context);
125 exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
126 s->control_command = NULL;
128 swap_unwatch_control_pid(s);
130 unit_unwatch_timer(u, &s->timer_watch);
133 int swap_add_one_mount_link(Swap *s, Mount *m) {
139 if (UNIT(s)->load_state != UNIT_LOADED ||
140 UNIT(m)->load_state != UNIT_LOADED)
143 if (is_device_path(s->what))
146 if (!path_startswith(s->what, m->where))
149 if ((r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0)
155 static int swap_add_mount_links(Swap *s) {
161 LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT])
162 if ((r = swap_add_one_mount_link(s, MOUNT(other))) < 0)
168 static int swap_add_device_links(Swap *s) {
176 if (s->from_fragment)
177 p = &s->parameters_fragment;
181 if (is_device_path(s->what))
182 return unit_add_node_link(UNIT(s), s->what,
183 !p->noauto && p->nofail &&
184 UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
186 /* File based swap devices need to be ordered after
187 * systemd-remount-fs.service, since they might need a
188 * writable file system. */
189 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
192 static int swap_add_default_dependencies(Swap *s) {
197 if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
200 if (detect_container(NULL) > 0)
203 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
210 static int swap_verify(Swap *s) {
214 if (UNIT(s)->load_state != UNIT_LOADED)
217 if (!(e = unit_name_from_path(s->what, ".swap")))
220 b = unit_has_name(UNIT(s), e);
224 log_error("%s: Value of \"What\" and unit name do not match, not loading.\n", UNIT(s)->id);
228 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
229 log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(s)->id);
236 static int swap_load(Unit *u) {
241 assert(u->load_state == UNIT_STUB);
243 /* Load a .swap file */
244 if ((r = unit_load_fragment_and_dropin_optional(u)) < 0)
247 if (u->load_state == UNIT_LOADED) {
248 if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
251 if (UNIT(s)->fragment_path)
252 s->from_fragment = true;
255 if (s->parameters_fragment.what)
256 s->what = strdup(s->parameters_fragment.what);
257 else if (s->parameters_proc_swaps.what)
258 s->what = strdup(s->parameters_proc_swaps.what);
260 s->what = unit_name_to_path(u->id);
266 path_kill_slashes(s->what);
268 if (!UNIT(s)->description)
269 if ((r = unit_set_description(u, s->what)) < 0)
272 if ((r = swap_add_device_links(s)) < 0)
275 if ((r = swap_add_mount_links(s)) < 0)
278 if ((r = unit_add_default_cgroups(u)) < 0)
281 if (UNIT(s)->default_dependencies)
282 if ((r = swap_add_default_dependencies(s)) < 0)
285 r = unit_exec_context_defaults(u, &s->exec_context);
290 return swap_verify(s);
293 static int swap_add_one(
296 const char *what_proc_swaps,
303 char *e = NULL, *wp = NULL;
311 assert(what_proc_swaps);
313 e = unit_name_from_path(what, ".swap");
317 u = manager_get_unit(m, e);
320 SWAP(u)->from_proc_swaps &&
321 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
327 u = unit_new(m, sizeof(Swap));
333 r = unit_add_name(u, e);
337 SWAP(u)->what = strdup(what);
338 if (!SWAP(u)->what) {
343 unit_add_to_load_queue(u);
347 p = &SWAP(u)->parameters_proc_swaps;
350 if (!(wp = strdup(what_proc_swaps))) {
355 if (!m->swaps_by_proc_swaps)
356 if (!(m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func))) {
364 first = hashmap_get(m->swaps_by_proc_swaps, wp);
365 LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u));
367 if ((r = hashmap_replace(m->swaps_by_proc_swaps, wp, first)) < 0)
372 SWAP(u)->is_active = true;
373 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
376 SWAP(u)->from_proc_swaps = true;
378 p->priority = priority;
382 unit_add_to_dbus_queue(u);
389 log_warning("Failed to load swap unit: %s", strerror(-r));
400 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
406 if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) {
407 struct udev_device *d;
409 struct udev_list_entry *item = NULL, *first = NULL;
411 /* So this is a proper swap device. Create swap units
412 * for all names this swap device is known under */
414 if (!(d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev)))
417 dn = udev_device_get_devnode(d);
419 r = swap_add_one(m, dn, device, prio, false, false, set_flags);
421 /* Add additional units for all symlinks */
422 first = udev_device_get_devlinks_list_entry(d);
423 udev_list_entry_foreach(item, first) {
426 /* Don't bother with the /dev/block links */
427 p = udev_list_entry_get_name(item);
429 if (path_startswith(p, "/dev/block/"))
432 if (stat(p, &st) >= 0)
433 if ((!S_ISBLK(st.st_mode)) || st.st_rdev != udev_device_get_devnum(d))
436 k = swap_add_one(m, p, device, prio, false, false, set_flags);
441 udev_device_unref(d);
444 k = swap_add_one(m, device, device, prio, false, false, set_flags);
451 static void swap_set_state(Swap *s, SwapState state) {
456 old_state = s->state;
459 if (state != SWAP_ACTIVATING &&
460 state != SWAP_ACTIVATING_SIGTERM &&
461 state != SWAP_ACTIVATING_SIGKILL &&
462 state != SWAP_DEACTIVATING &&
463 state != SWAP_DEACTIVATING_SIGTERM &&
464 state != SWAP_DEACTIVATING_SIGKILL) {
465 unit_unwatch_timer(UNIT(s), &s->timer_watch);
466 swap_unwatch_control_pid(s);
467 s->control_command = NULL;
468 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
471 if (state != old_state)
472 log_debug("%s changed %s -> %s",
474 swap_state_to_string(old_state),
475 swap_state_to_string(state));
477 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
480 static int swap_coldplug(Unit *u) {
482 SwapState new_state = SWAP_DEAD;
486 assert(s->state == SWAP_DEAD);
488 if (s->deserialized_state != s->state)
489 new_state = s->deserialized_state;
490 else if (s->from_proc_swaps)
491 new_state = SWAP_ACTIVE;
493 if (new_state != s->state) {
495 if (new_state == SWAP_ACTIVATING ||
496 new_state == SWAP_ACTIVATING_SIGTERM ||
497 new_state == SWAP_ACTIVATING_SIGKILL ||
498 new_state == SWAP_DEACTIVATING ||
499 new_state == SWAP_DEACTIVATING_SIGTERM ||
500 new_state == SWAP_DEACTIVATING_SIGKILL) {
502 if (s->control_pid <= 0)
505 if ((r = unit_watch_pid(UNIT(s), s->control_pid)) < 0)
508 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
512 swap_set_state(s, new_state);
518 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
525 if (s->from_proc_swaps)
526 p = &s->parameters_proc_swaps;
527 else if (s->from_fragment)
528 p = &s->parameters_fragment;
536 "%sFrom /proc/swaps: %s\n"
537 "%sFrom fragment: %s\n",
538 prefix, swap_state_to_string(s->state),
539 prefix, swap_result_to_string(s->result),
541 prefix, yes_no(s->from_proc_swaps),
542 prefix, yes_no(s->from_fragment));
550 prefix, yes_no(p->noauto),
551 prefix, yes_no(p->nofail));
553 if (s->control_pid > 0)
555 "%sControl PID: %lu\n",
556 prefix, (unsigned long) s->control_pid);
558 exec_context_dump(&s->exec_context, f, prefix);
559 kill_context_dump(&s->kill_context, f, prefix);
562 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
570 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
573 if ((r = exec_spawn(c,
577 UNIT(s)->manager->environment,
581 UNIT(s)->manager->confirm_spawn,
582 UNIT(s)->cgroup_bondings,
583 UNIT(s)->cgroup_attributes,
590 if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
591 /* FIXME: we need to do something here */
599 unit_unwatch_timer(UNIT(s), &s->timer_watch);
604 static void swap_enter_dead(Swap *s, SwapResult f) {
607 if (f != SWAP_SUCCESS)
610 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
613 static void swap_enter_active(Swap *s, SwapResult f) {
616 if (f != SWAP_SUCCESS)
619 swap_set_state(s, SWAP_ACTIVE);
622 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
625 bool wait_for_exit = false;
629 if (f != SWAP_SUCCESS)
632 if (s->kill_context.kill_mode != KILL_NONE) {
633 int sig = (state == SWAP_ACTIVATING_SIGTERM ||
634 state == SWAP_DEACTIVATING_SIGTERM) ? s->kill_context.kill_signal : SIGKILL;
636 if (s->control_pid > 0) {
637 if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH)
639 log_warning("Failed to kill control process %li: %m", (long) s->control_pid);
641 wait_for_exit = true;
644 if (s->kill_context.kill_mode == KILL_CONTROL_GROUP) {
646 if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) {
651 /* Exclude the control pid from being killed via the cgroup */
652 if (s->control_pid > 0)
653 if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0)
656 r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, false, pid_set, NULL);
658 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
659 log_warning("Failed to kill control group: %s", strerror(-r));
661 wait_for_exit = true;
669 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
672 swap_set_state(s, state);
674 swap_enter_dead(s, SWAP_SUCCESS);
679 log_warning("%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
681 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 if ((r = swap_spawn(s, s->control_command, &s->control_pid)) < 0)
728 swap_set_state(s, SWAP_ACTIVATING);
733 log_warning("%s failed to run 'swapon' task: %s", UNIT(s)->id, strerror(-r));
734 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
737 static void swap_enter_deactivating(Swap *s) {
742 s->control_command_id = SWAP_EXEC_DEACTIVATE;
743 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
745 if ((r = exec_command_set(
752 swap_unwatch_control_pid(s);
754 if ((r = swap_spawn(s, s->control_command, &s->control_pid)) < 0)
757 swap_set_state(s, SWAP_DEACTIVATING);
762 log_warning("%s failed to run 'swapoff' task: %s", UNIT(s)->id, strerror(-r));
763 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
766 static int swap_start(Unit *u) {
771 /* We cannot fulfill this request right now, try again later
774 if (s->state == SWAP_DEACTIVATING ||
775 s->state == SWAP_DEACTIVATING_SIGTERM ||
776 s->state == SWAP_DEACTIVATING_SIGKILL ||
777 s->state == SWAP_ACTIVATING_SIGTERM ||
778 s->state == SWAP_ACTIVATING_SIGKILL)
781 if (s->state == SWAP_ACTIVATING)
784 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
786 if (detect_container(NULL) > 0)
789 s->result = SWAP_SUCCESS;
790 swap_enter_activating(s);
794 static int swap_stop(Unit *u) {
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 assert(s->state == SWAP_ACTIVATING ||
807 s->state == SWAP_ACTIVE);
809 if (detect_container(NULL) > 0)
812 swap_enter_deactivating(s);
816 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
823 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
824 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
826 if (s->control_pid > 0)
827 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
829 if (s->control_command_id >= 0)
830 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
835 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
841 if (streq(key, "state")) {
844 if ((state = swap_state_from_string(value)) < 0)
845 log_debug("Failed to parse state value %s", value);
847 s->deserialized_state = state;
848 } else if (streq(key, "result")) {
851 f = swap_result_from_string(value);
853 log_debug("Failed to parse result value %s", value);
854 else if (f != SWAP_SUCCESS)
856 } else if (streq(key, "control-pid")) {
859 if (parse_pid(value, &pid) < 0)
860 log_debug("Failed to parse control-pid value %s", value);
862 s->control_pid = pid;
864 } else if (streq(key, "control-command")) {
867 if ((id = swap_exec_command_from_string(value)) < 0)
868 log_debug("Failed to parse exec-command value %s", value);
870 s->control_command_id = id;
871 s->control_command = s->exec_command + id;
875 log_debug("Unknown serialization key '%s'", key);
880 static UnitActiveState swap_active_state(Unit *u) {
883 return state_translation_table[SWAP(u)->state];
886 static const char *swap_sub_state_to_string(Unit *u) {
889 return swap_state_to_string(SWAP(u)->state);
892 static bool swap_check_gc(Unit *u) {
897 return s->from_proc_swaps;
900 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
907 if (pid != s->control_pid)
912 if (is_clean_exit(code, status, NULL))
914 else if (code == CLD_EXITED)
915 f = SWAP_FAILURE_EXIT_CODE;
916 else if (code == CLD_KILLED)
917 f = SWAP_FAILURE_SIGNAL;
918 else if (code == CLD_DUMPED)
919 f = SWAP_FAILURE_CORE_DUMP;
921 assert_not_reached("Unknown code");
923 if (f != SWAP_SUCCESS)
926 if (s->control_command) {
927 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
929 s->control_command = NULL;
930 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
933 log_full(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
934 "%s swap process exited, code=%s status=%i", u->id, sigchld_code_to_string(code), status);
938 case SWAP_ACTIVATING:
939 case SWAP_ACTIVATING_SIGTERM:
940 case SWAP_ACTIVATING_SIGKILL:
942 if (f == SWAP_SUCCESS)
943 swap_enter_active(s, f);
945 swap_enter_dead(s, f);
948 case SWAP_DEACTIVATING:
949 case SWAP_DEACTIVATING_SIGKILL:
950 case SWAP_DEACTIVATING_SIGTERM:
952 if (f == SWAP_SUCCESS)
953 swap_enter_dead(s, f);
955 swap_enter_dead(s, f);
959 assert_not_reached("Uh, control process died at wrong time.");
962 /* Notify clients about changed exit status */
963 unit_add_to_dbus_queue(u);
965 /* Request a reload of /proc/swaps, so that following units
966 * can follow our state change */
967 u->manager->request_reload = true;
970 static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
974 assert(elapsed == 1);
975 assert(w == &s->timer_watch);
979 case SWAP_ACTIVATING:
980 log_warning("%s activation timed out. Stopping.", u->id);
981 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
984 case SWAP_DEACTIVATING:
985 log_warning("%s deactivation timed out. Stopping.", u->id);
986 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
989 case SWAP_ACTIVATING_SIGTERM:
990 if (s->kill_context.send_sigkill) {
991 log_warning("%s activation timed out. Killing.", u->id);
992 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
994 log_warning("%s activation timed out. Skipping SIGKILL. Ignoring.", u->id);
995 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
999 case SWAP_DEACTIVATING_SIGTERM:
1000 if (s->kill_context.send_sigkill) {
1001 log_warning("%s deactivation timed out. Killing.", u->id);
1002 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1004 log_warning("%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id);
1005 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1009 case SWAP_ACTIVATING_SIGKILL:
1010 case SWAP_DEACTIVATING_SIGKILL:
1011 log_warning("%s swap process still around after SIGKILL. Ignoring.", u->id);
1012 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1016 assert_not_reached("Timeout at wrong time.");
1020 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1026 rewind(m->proc_swaps);
1028 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1031 char *dev = NULL, *d;
1034 if ((k = fscanf(m->proc_swaps,
1035 "%ms " /* device/file */
1036 "%*s " /* type of swap */
1037 "%*s " /* swap size */
1039 "%i\n", /* priority */
1040 &dev, &prio)) != 2) {
1045 log_warning("Failed to parse /proc/swaps:%u.", i);
1056 k = swap_process_new_swap(m, d, prio, set_flags);
1066 int swap_dispatch_reload(Manager *m) {
1067 /* This function should go as soon as the kernel properly notifies us */
1069 if (_likely_(!m->request_reload))
1072 m->request_reload = false;
1074 return swap_fd_event(m, EPOLLPRI);
1077 int swap_fd_event(Manager *m, int events) {
1082 assert(events & EPOLLPRI);
1084 if ((r = swap_load_proc_swaps(m, true)) < 0) {
1085 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1087 /* Reset flags, just in case, for late calls */
1088 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1089 Swap *swap = SWAP(u);
1091 swap->is_active = swap->just_activated = false;
1097 manager_dispatch_load_queue(m);
1099 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1100 Swap *swap = SWAP(u);
1102 if (!swap->is_active) {
1103 /* This has just been deactivated */
1105 swap->from_proc_swaps = false;
1106 swap_unset_proc_swaps(swap);
1108 switch (swap->state) {
1111 swap_enter_dead(swap, SWAP_SUCCESS);
1115 swap_set_state(swap, swap->state);
1119 } else if (swap->just_activated) {
1121 /* New swap entry */
1123 switch (swap->state) {
1127 swap_enter_active(swap, SWAP_SUCCESS);
1131 /* Nothing really changed, but let's
1132 * issue an notification call
1133 * nonetheless, in case somebody is
1134 * waiting for this. */
1135 swap_set_state(swap, swap->state);
1140 /* Reset the flags for later calls */
1141 swap->is_active = swap->just_activated = false;
1147 static Unit *swap_following(Unit *u) {
1149 Swap *other, *first = NULL;
1153 if (streq_ptr(s->what, s->parameters_proc_swaps.what))
1156 /* Make everybody follow the unit that's named after the swap
1157 * device in the kernel */
1159 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1160 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1163 LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
1164 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1173 static int swap_following_set(Unit *u, Set **_set) {
1182 if (LIST_JUST_US(same_proc_swaps, s)) {
1187 if (!(set = set_new(NULL, NULL)))
1190 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1191 if ((r = set_put(set, other)) < 0)
1194 LIST_FOREACH_BEFORE(same_proc_swaps, other, s)
1195 if ((r = set_put(set, other)) < 0)
1206 static void swap_shutdown(Manager *m) {
1209 if (m->proc_swaps) {
1210 fclose(m->proc_swaps);
1211 m->proc_swaps = NULL;
1214 hashmap_free(m->swaps_by_proc_swaps);
1215 m->swaps_by_proc_swaps = NULL;
1218 static int swap_enumerate(Manager *m) {
1220 struct epoll_event ev;
1223 if (!m->proc_swaps) {
1224 if (!(m->proc_swaps = fopen("/proc/swaps", "re")))
1225 return (errno == ENOENT) ? 0 : -errno;
1227 m->swap_watch.type = WATCH_SWAP;
1228 m->swap_watch.fd = fileno(m->proc_swaps);
1231 ev.events = EPOLLPRI;
1232 ev.data.ptr = &m->swap_watch;
1234 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
1238 if ((r = swap_load_proc_swaps(m, false)) < 0)
1244 static void swap_reset_failed(Unit *u) {
1249 if (s->state == SWAP_FAILED)
1250 swap_set_state(s, SWAP_DEAD);
1252 s->result = SWAP_SUCCESS;
1255 static int swap_kill(Unit *u, KillWho who, int signo, DBusError *error) {
1258 Set *pid_set = NULL;
1262 if (who == KILL_MAIN) {
1263 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Swap units have no main processes");
1267 if (s->control_pid <= 0 && who == KILL_CONTROL) {
1268 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
1272 if (who == KILL_CONTROL || who == KILL_ALL)
1273 if (s->control_pid > 0)
1274 if (kill(s->control_pid, signo) < 0)
1277 if (who == KILL_ALL) {
1280 pid_set = set_new(trivial_hash_func, trivial_compare_func);
1284 /* Exclude the control pid from being killed via the cgroup */
1285 if (s->control_pid > 0) {
1286 q = set_put(pid_set, LONG_TO_PTR(s->control_pid));
1293 q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
1294 if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
1305 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1306 [SWAP_DEAD] = "dead",
1307 [SWAP_ACTIVATING] = "activating",
1308 [SWAP_ACTIVE] = "active",
1309 [SWAP_DEACTIVATING] = "deactivating",
1310 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1311 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1312 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1313 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1314 [SWAP_FAILED] = "failed"
1317 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1319 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1320 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1321 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1324 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1326 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1327 [SWAP_SUCCESS] = "success",
1328 [SWAP_FAILURE_RESOURCES] = "resources",
1329 [SWAP_FAILURE_TIMEOUT] = "timeout",
1330 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1331 [SWAP_FAILURE_SIGNAL] = "signal",
1332 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1335 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1337 const UnitVTable swap_vtable = {
1338 .object_size = sizeof(Swap),
1339 .exec_context_offset = offsetof(Swap, exec_context),
1347 .no_instances = true,
1353 .coldplug = swap_coldplug,
1357 .start = swap_start,
1362 .serialize = swap_serialize,
1363 .deserialize_item = swap_deserialize_item,
1365 .active_state = swap_active_state,
1366 .sub_state_to_string = swap_sub_state_to_string,
1368 .check_gc = swap_check_gc,
1370 .sigchld_event = swap_sigchld_event,
1371 .timer_event = swap_timer_event,
1373 .reset_failed = swap_reset_failed,
1375 .bus_interface = "org.freedesktop.systemd1.Swap",
1376 .bus_message_handler = bus_swap_message_handler,
1377 .bus_invalidating_properties = bus_swap_invalidating_properties,
1379 .following = swap_following,
1380 .following_set = swap_following_set,
1382 .enumerate = swap_enumerate,
1383 .shutdown = swap_shutdown,
1385 .status_message_formats = {
1386 .starting_stopping = {
1387 [0] = "Activating swap %s...",
1388 [1] = "Deactivating swap %s...",
1390 .finished_start_job = {
1391 [JOB_DONE] = "Activated swap %s.",
1392 [JOB_FAILED] = "Failed to activate swap %s.",
1393 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1394 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1396 .finished_stop_job = {
1397 [JOB_DONE] = "Deactivated swap %s.",
1398 [JOB_FAILED] = "Failed deactivating swap %s.",
1399 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",