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"
43 static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
44 [SWAP_DEAD] = UNIT_INACTIVE,
45 [SWAP_ACTIVATING] = UNIT_ACTIVATING,
46 [SWAP_ACTIVE] = UNIT_ACTIVE,
47 [SWAP_DEACTIVATING] = UNIT_DEACTIVATING,
48 [SWAP_ACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
49 [SWAP_ACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
50 [SWAP_DEACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
51 [SWAP_DEACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
52 [SWAP_FAILED] = UNIT_FAILED
55 static void swap_unset_proc_swaps(Swap *s) {
60 if (!s->parameters_proc_swaps.what)
63 /* Remove this unit from the chain of swaps which share the
64 * same kernel swap device. */
66 first = hashmap_get(UNIT(s)->manager->swaps_by_proc_swaps, s->parameters_proc_swaps.what);
67 LIST_REMOVE(Swap, same_proc_swaps, first, s);
70 hashmap_remove_and_replace(UNIT(s)->manager->swaps_by_proc_swaps, s->parameters_proc_swaps.what, first->parameters_proc_swaps.what, first);
72 hashmap_remove(UNIT(s)->manager->swaps_by_proc_swaps, s->parameters_proc_swaps.what);
74 free(s->parameters_proc_swaps.what);
75 s->parameters_proc_swaps.what = NULL;
78 static void swap_init(Unit *u) {
82 assert(UNIT(s)->load_state == UNIT_STUB);
84 s->timeout_usec = DEFAULT_TIMEOUT_USEC;
86 exec_context_init(&s->exec_context);
87 s->exec_context.std_output = u->manager->default_std_output;
88 s->exec_context.std_error = u->manager->default_std_error;
90 s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
92 s->timer_watch.type = WATCH_INVALID;
94 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
96 UNIT(s)->ignore_on_isolate = true;
99 static void swap_unwatch_control_pid(Swap *s) {
102 if (s->control_pid <= 0)
105 unit_unwatch_pid(UNIT(s), s->control_pid);
109 static void swap_done(Unit *u) {
114 swap_unset_proc_swaps(s);
119 free(s->parameters_fragment.what);
120 s->parameters_fragment.what = NULL;
122 exec_context_done(&s->exec_context);
123 exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
124 s->control_command = NULL;
126 swap_unwatch_control_pid(s);
128 unit_unwatch_timer(u, &s->timer_watch);
131 int swap_add_one_mount_link(Swap *s, Mount *m) {
137 if (UNIT(s)->load_state != UNIT_LOADED ||
138 UNIT(m)->load_state != UNIT_LOADED)
141 if (is_device_path(s->what))
144 if (!path_startswith(s->what, m->where))
147 if ((r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0)
153 static int swap_add_mount_links(Swap *s) {
159 LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT])
160 if ((r = swap_add_one_mount_link(s, MOUNT(other))) < 0)
166 static int swap_add_target_links(Swap *s) {
172 if (!s->from_fragment)
175 if ((r = manager_load_unit(UNIT(s)->manager, SPECIAL_SWAP_TARGET, NULL, NULL, &tu)) < 0)
178 return unit_add_dependency(UNIT(s), UNIT_BEFORE, tu, true);
181 static int swap_add_device_links(Swap *s) {
189 if (s->from_fragment)
190 p = &s->parameters_fragment;
194 if (is_device_path(s->what))
195 return unit_add_node_link(UNIT(s), s->what,
196 !p->noauto && p->nofail &&
197 UNIT(s)->manager->running_as == MANAGER_SYSTEM);
199 /* File based swap devices need to be ordered after
200 * systemd-remount-fs.service, since they might need a
201 * writable file system. */
202 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
205 static int swap_add_default_dependencies(Swap *s) {
210 if (UNIT(s)->manager->running_as != MANAGER_SYSTEM)
213 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
220 static int swap_verify(Swap *s) {
224 if (UNIT(s)->load_state != UNIT_LOADED)
227 if (!(e = unit_name_from_path(s->what, ".swap")))
230 b = unit_has_name(UNIT(s), e);
234 log_error("%s: Value of \"What\" and unit name do not match, not loading.\n", UNIT(s)->id);
238 if (s->exec_context.pam_name && s->exec_context.kill_mode != KILL_CONTROL_GROUP) {
239 log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(s)->id);
246 static int swap_load(Unit *u) {
251 assert(u->load_state == UNIT_STUB);
253 /* Load a .swap file */
254 if ((r = unit_load_fragment_and_dropin_optional(u)) < 0)
257 if (u->load_state == UNIT_LOADED) {
258 if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
261 if (UNIT(s)->fragment_path)
262 s->from_fragment = true;
265 if (s->parameters_fragment.what)
266 s->what = strdup(s->parameters_fragment.what);
267 else if (s->parameters_proc_swaps.what)
268 s->what = strdup(s->parameters_proc_swaps.what);
270 s->what = unit_name_to_path(u->id);
276 path_kill_slashes(s->what);
278 if (!UNIT(s)->description)
279 if ((r = unit_set_description(u, s->what)) < 0)
282 if ((r = swap_add_device_links(s)) < 0)
285 if ((r = swap_add_mount_links(s)) < 0)
288 if ((r = swap_add_target_links(s)) < 0)
291 if ((r = unit_add_default_cgroups(u)) < 0)
294 if (UNIT(s)->default_dependencies)
295 if ((r = swap_add_default_dependencies(s)) < 0)
299 return swap_verify(s);
302 static int swap_add_one(
305 const char *what_proc_swaps,
312 char *e = NULL, *wp = NULL;
320 assert(what_proc_swaps);
322 e = unit_name_from_path(what, ".swap");
326 u = manager_get_unit(m, e);
329 SWAP(u)->from_proc_swaps &&
330 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
336 u = unit_new(m, sizeof(Swap));
342 r = unit_add_name(u, e);
346 SWAP(u)->what = strdup(what);
347 if (!SWAP(u)->what) {
352 unit_add_to_load_queue(u);
356 p = &SWAP(u)->parameters_proc_swaps;
359 if (!(wp = strdup(what_proc_swaps))) {
364 if (!m->swaps_by_proc_swaps)
365 if (!(m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func))) {
373 first = hashmap_get(m->swaps_by_proc_swaps, wp);
374 LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u));
376 if ((r = hashmap_replace(m->swaps_by_proc_swaps, wp, first)) < 0)
381 SWAP(u)->is_active = true;
382 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
385 SWAP(u)->from_proc_swaps = true;
387 p->priority = priority;
391 unit_add_to_dbus_queue(u);
398 log_warning("Failed to load swap unit: %s", strerror(-r));
409 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
415 if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) {
416 struct udev_device *d;
418 struct udev_list_entry *item = NULL, *first = NULL;
420 /* So this is a proper swap device. Create swap units
421 * for all names this swap device is known under */
423 if (!(d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev)))
426 dn = udev_device_get_devnode(d);
428 r = swap_add_one(m, dn, device, prio, false, false, set_flags);
430 /* Add additional units for all symlinks */
431 first = udev_device_get_devlinks_list_entry(d);
432 udev_list_entry_foreach(item, first) {
435 /* Don't bother with the /dev/block links */
436 p = udev_list_entry_get_name(item);
438 if (path_startswith(p, "/dev/block/"))
441 if (stat(p, &st) >= 0)
442 if ((!S_ISBLK(st.st_mode)) || st.st_rdev != udev_device_get_devnum(d))
445 k = swap_add_one(m, p, device, prio, false, false, set_flags);
450 udev_device_unref(d);
453 k = swap_add_one(m, device, device, prio, false, false, set_flags);
460 static void swap_set_state(Swap *s, SwapState state) {
465 old_state = s->state;
468 if (state != SWAP_ACTIVATING &&
469 state != SWAP_ACTIVATING_SIGTERM &&
470 state != SWAP_ACTIVATING_SIGKILL &&
471 state != SWAP_DEACTIVATING &&
472 state != SWAP_DEACTIVATING_SIGTERM &&
473 state != SWAP_DEACTIVATING_SIGKILL) {
474 unit_unwatch_timer(UNIT(s), &s->timer_watch);
475 swap_unwatch_control_pid(s);
476 s->control_command = NULL;
477 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
480 if (state != old_state)
481 log_debug("%s changed %s -> %s",
483 swap_state_to_string(old_state),
484 swap_state_to_string(state));
486 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
489 static int swap_coldplug(Unit *u) {
491 SwapState new_state = SWAP_DEAD;
495 assert(s->state == SWAP_DEAD);
497 if (s->deserialized_state != s->state)
498 new_state = s->deserialized_state;
499 else if (s->from_proc_swaps)
500 new_state = SWAP_ACTIVE;
502 if (new_state != s->state) {
504 if (new_state == SWAP_ACTIVATING ||
505 new_state == SWAP_ACTIVATING_SIGTERM ||
506 new_state == SWAP_ACTIVATING_SIGKILL ||
507 new_state == SWAP_DEACTIVATING ||
508 new_state == SWAP_DEACTIVATING_SIGTERM ||
509 new_state == SWAP_DEACTIVATING_SIGKILL) {
511 if (s->control_pid <= 0)
514 if ((r = unit_watch_pid(UNIT(s), s->control_pid)) < 0)
517 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
521 swap_set_state(s, new_state);
527 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
534 if (s->from_proc_swaps)
535 p = &s->parameters_proc_swaps;
536 else if (s->from_fragment)
537 p = &s->parameters_fragment;
546 "%sFrom /proc/swaps: %s\n"
547 "%sFrom fragment: %s\n",
548 prefix, swap_state_to_string(s->state),
549 prefix, swap_result_to_string(s->result),
552 prefix, yes_no(p->noauto),
553 prefix, yes_no(p->nofail),
554 prefix, yes_no(s->from_proc_swaps),
555 prefix, yes_no(s->from_fragment));
557 if (s->control_pid > 0)
559 "%sControl PID: %lu\n",
560 prefix, (unsigned long) s->control_pid);
562 exec_context_dump(&s->exec_context, f, prefix);
565 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
573 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
576 if ((r = exec_spawn(c,
580 UNIT(s)->manager->environment,
584 UNIT(s)->manager->confirm_spawn,
585 UNIT(s)->cgroup_bondings,
586 UNIT(s)->cgroup_attributes,
592 if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
593 /* FIXME: we need to do something here */
601 unit_unwatch_timer(UNIT(s), &s->timer_watch);
606 static void swap_enter_dead(Swap *s, SwapResult f) {
609 if (f != SWAP_SUCCESS)
612 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
615 static void swap_enter_active(Swap *s, SwapResult f) {
618 if (f != SWAP_SUCCESS)
621 swap_set_state(s, SWAP_ACTIVE);
624 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
627 bool wait_for_exit = false;
631 if (f != SWAP_SUCCESS)
634 if (s->exec_context.kill_mode != KILL_NONE) {
635 int sig = (state == SWAP_ACTIVATING_SIGTERM ||
636 state == SWAP_DEACTIVATING_SIGTERM) ? s->exec_context.kill_signal : SIGKILL;
638 if (s->control_pid > 0) {
639 if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH)
641 log_warning("Failed to kill control process %li: %m", (long) s->control_pid);
643 wait_for_exit = true;
646 if (s->exec_context.kill_mode == KILL_CONTROL_GROUP) {
648 if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) {
653 /* Exclude the control pid from being killed via the cgroup */
654 if (s->control_pid > 0)
655 if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0)
658 r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, false, pid_set, NULL);
660 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
661 log_warning("Failed to kill control group: %s", strerror(-r));
663 wait_for_exit = true;
671 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
674 swap_set_state(s, state);
676 swap_enter_dead(s, SWAP_SUCCESS);
681 log_warning("%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
683 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
689 static void swap_enter_activating(Swap *s) {
694 s->control_command_id = SWAP_EXEC_ACTIVATE;
695 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
697 if (s->from_fragment)
698 priority = s->parameters_fragment.priority;
705 snprintf(p, sizeof(p), "%i", priority);
708 r = exec_command_set(
716 r = exec_command_set(
725 swap_unwatch_control_pid(s);
727 if ((r = swap_spawn(s, s->control_command, &s->control_pid)) < 0)
730 swap_set_state(s, SWAP_ACTIVATING);
735 log_warning("%s failed to run 'swapon' task: %s", UNIT(s)->id, strerror(-r));
736 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
739 static void swap_enter_deactivating(Swap *s) {
744 s->control_command_id = SWAP_EXEC_DEACTIVATE;
745 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
747 if ((r = exec_command_set(
754 swap_unwatch_control_pid(s);
756 if ((r = swap_spawn(s, s->control_command, &s->control_pid)) < 0)
759 swap_set_state(s, SWAP_DEACTIVATING);
764 log_warning("%s failed to run 'swapoff' task: %s", UNIT(s)->id, strerror(-r));
765 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
768 static int swap_start(Unit *u) {
773 /* We cannot fulfill this request right now, try again later
776 if (s->state == SWAP_DEACTIVATING ||
777 s->state == SWAP_DEACTIVATING_SIGTERM ||
778 s->state == SWAP_DEACTIVATING_SIGKILL ||
779 s->state == SWAP_ACTIVATING_SIGTERM ||
780 s->state == SWAP_ACTIVATING_SIGKILL)
783 if (s->state == SWAP_ACTIVATING)
786 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
788 s->result = SWAP_SUCCESS;
789 swap_enter_activating(s);
793 static int swap_stop(Unit *u) {
798 if (s->state == SWAP_DEACTIVATING ||
799 s->state == SWAP_DEACTIVATING_SIGTERM ||
800 s->state == SWAP_DEACTIVATING_SIGKILL ||
801 s->state == SWAP_ACTIVATING_SIGTERM ||
802 s->state == SWAP_ACTIVATING_SIGKILL)
805 assert(s->state == SWAP_ACTIVATING ||
806 s->state == SWAP_ACTIVE);
808 swap_enter_deactivating(s);
812 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
819 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
820 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
822 if (s->control_pid > 0)
823 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
825 if (s->control_command_id >= 0)
826 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
831 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
837 if (streq(key, "state")) {
840 if ((state = swap_state_from_string(value)) < 0)
841 log_debug("Failed to parse state value %s", value);
843 s->deserialized_state = state;
844 } else if (streq(key, "result")) {
847 f = swap_result_from_string(value);
849 log_debug("Failed to parse result value %s", value);
850 else if (f != SWAP_SUCCESS)
852 } else if (streq(key, "control-pid")) {
855 if (parse_pid(value, &pid) < 0)
856 log_debug("Failed to parse control-pid value %s", value);
858 s->control_pid = pid;
860 } else if (streq(key, "control-command")) {
863 if ((id = swap_exec_command_from_string(value)) < 0)
864 log_debug("Failed to parse exec-command value %s", value);
866 s->control_command_id = id;
867 s->control_command = s->exec_command + id;
871 log_debug("Unknown serialization key '%s'", key);
876 static UnitActiveState swap_active_state(Unit *u) {
879 return state_translation_table[SWAP(u)->state];
882 static const char *swap_sub_state_to_string(Unit *u) {
885 return swap_state_to_string(SWAP(u)->state);
888 static bool swap_check_gc(Unit *u) {
893 return s->from_proc_swaps;
896 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
903 if (pid != s->control_pid)
908 if (is_clean_exit(code, status))
910 else if (code == CLD_EXITED)
911 f = SWAP_FAILURE_EXIT_CODE;
912 else if (code == CLD_KILLED)
913 f = SWAP_FAILURE_SIGNAL;
914 else if (code == CLD_DUMPED)
915 f = SWAP_FAILURE_CORE_DUMP;
917 assert_not_reached("Unknown code");
919 if (f != SWAP_SUCCESS)
922 if (s->control_command) {
923 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
925 s->control_command = NULL;
926 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
929 log_full(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
930 "%s swap process exited, code=%s status=%i", u->id, sigchld_code_to_string(code), status);
934 case SWAP_ACTIVATING:
935 case SWAP_ACTIVATING_SIGTERM:
936 case SWAP_ACTIVATING_SIGKILL:
938 if (f == SWAP_SUCCESS)
939 swap_enter_active(s, f);
941 swap_enter_dead(s, f);
944 case SWAP_DEACTIVATING:
945 case SWAP_DEACTIVATING_SIGKILL:
946 case SWAP_DEACTIVATING_SIGTERM:
948 if (f == SWAP_SUCCESS)
949 swap_enter_dead(s, f);
951 swap_enter_dead(s, f);
955 assert_not_reached("Uh, control process died at wrong time.");
958 /* Notify clients about changed exit status */
959 unit_add_to_dbus_queue(u);
961 /* Request a reload of /proc/swaps, so that following units
962 * can follow our state change */
963 u->manager->request_reload = true;
966 static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
970 assert(elapsed == 1);
971 assert(w == &s->timer_watch);
975 case SWAP_ACTIVATING:
976 log_warning("%s activation timed out. Stopping.", u->id);
977 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
980 case SWAP_DEACTIVATING:
981 log_warning("%s deactivation timed out. Stopping.", u->id);
982 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
985 case SWAP_ACTIVATING_SIGTERM:
986 if (s->exec_context.send_sigkill) {
987 log_warning("%s activation timed out. Killing.", u->id);
988 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
990 log_warning("%s activation timed out. Skipping SIGKILL. Ignoring.", u->id);
991 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
995 case SWAP_DEACTIVATING_SIGTERM:
996 if (s->exec_context.send_sigkill) {
997 log_warning("%s deactivation timed out. Killing.", u->id);
998 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1000 log_warning("%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id);
1001 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1005 case SWAP_ACTIVATING_SIGKILL:
1006 case SWAP_DEACTIVATING_SIGKILL:
1007 log_warning("%s swap process still around after SIGKILL. Ignoring.", u->id);
1008 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1012 assert_not_reached("Timeout at wrong time.");
1016 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1022 rewind(m->proc_swaps);
1024 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1027 char *dev = NULL, *d;
1030 if ((k = fscanf(m->proc_swaps,
1031 "%ms " /* device/file */
1032 "%*s " /* type of swap */
1033 "%*s " /* swap size */
1035 "%i\n", /* priority */
1036 &dev, &prio)) != 2) {
1041 log_warning("Failed to parse /proc/swaps:%u.", i);
1052 k = swap_process_new_swap(m, d, prio, set_flags);
1062 int swap_dispatch_reload(Manager *m) {
1063 /* This function should go as soon as the kernel properly notifies us */
1065 if (_likely_(!m->request_reload))
1068 m->request_reload = false;
1070 return swap_fd_event(m, EPOLLPRI);
1073 int swap_fd_event(Manager *m, int events) {
1078 assert(events & EPOLLPRI);
1080 if ((r = swap_load_proc_swaps(m, true)) < 0) {
1081 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1083 /* Reset flags, just in case, for late calls */
1084 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1085 Swap *swap = SWAP(u);
1087 swap->is_active = swap->just_activated = false;
1093 manager_dispatch_load_queue(m);
1095 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1096 Swap *swap = SWAP(u);
1098 if (!swap->is_active) {
1099 /* This has just been deactivated */
1101 swap->from_proc_swaps = false;
1102 swap_unset_proc_swaps(swap);
1104 switch (swap->state) {
1107 swap_enter_dead(swap, SWAP_SUCCESS);
1111 swap_set_state(swap, swap->state);
1115 } else if (swap->just_activated) {
1117 /* New swap entry */
1119 switch (swap->state) {
1123 swap_enter_active(swap, SWAP_SUCCESS);
1127 /* Nothing really changed, but let's
1128 * issue an notification call
1129 * nonetheless, in case somebody is
1130 * waiting for this. */
1131 swap_set_state(swap, swap->state);
1136 /* Reset the flags for later calls */
1137 swap->is_active = swap->just_activated = false;
1143 static Unit *swap_following(Unit *u) {
1145 Swap *other, *first = NULL;
1149 if (streq_ptr(s->what, s->parameters_proc_swaps.what))
1152 /* Make everybody follow the unit that's named after the swap
1153 * device in the kernel */
1155 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1156 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1159 LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
1160 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1169 static int swap_following_set(Unit *u, Set **_set) {
1178 if (LIST_JUST_US(same_proc_swaps, s)) {
1183 if (!(set = set_new(NULL, NULL)))
1186 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1187 if ((r = set_put(set, other)) < 0)
1190 LIST_FOREACH_BEFORE(same_proc_swaps, other, s)
1191 if ((r = set_put(set, other)) < 0)
1202 static void swap_shutdown(Manager *m) {
1205 if (m->proc_swaps) {
1206 fclose(m->proc_swaps);
1207 m->proc_swaps = NULL;
1210 hashmap_free(m->swaps_by_proc_swaps);
1211 m->swaps_by_proc_swaps = NULL;
1214 static int swap_enumerate(Manager *m) {
1216 struct epoll_event ev;
1219 if (!m->proc_swaps) {
1220 if (!(m->proc_swaps = fopen("/proc/swaps", "re")))
1221 return (errno == ENOENT) ? 0 : -errno;
1223 m->swap_watch.type = WATCH_SWAP;
1224 m->swap_watch.fd = fileno(m->proc_swaps);
1227 ev.events = EPOLLPRI;
1228 ev.data.ptr = &m->swap_watch;
1230 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
1234 if ((r = swap_load_proc_swaps(m, false)) < 0)
1240 static void swap_reset_failed(Unit *u) {
1245 if (s->state == SWAP_FAILED)
1246 swap_set_state(s, SWAP_DEAD);
1248 s->result = SWAP_SUCCESS;
1251 static int swap_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError *error) {
1254 Set *pid_set = NULL;
1258 if (who == KILL_MAIN) {
1259 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Swap units have no main processes");
1263 if (s->control_pid <= 0 && who == KILL_CONTROL) {
1264 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
1268 if (who == KILL_CONTROL || who == KILL_ALL)
1269 if (s->control_pid > 0)
1270 if (kill(s->control_pid, signo) < 0)
1273 if (who == KILL_ALL && mode == KILL_CONTROL_GROUP) {
1276 if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func)))
1279 /* Exclude the control pid from being killed via the cgroup */
1280 if (s->control_pid > 0)
1281 if ((q = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) {
1286 q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
1288 if (q != -EAGAIN && q != -ESRCH && q != -ENOENT)
1299 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1300 [SWAP_DEAD] = "dead",
1301 [SWAP_ACTIVATING] = "activating",
1302 [SWAP_ACTIVE] = "active",
1303 [SWAP_DEACTIVATING] = "deactivating",
1304 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1305 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1306 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1307 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1308 [SWAP_FAILED] = "failed"
1311 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1313 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1314 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1315 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1318 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1320 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1321 [SWAP_SUCCESS] = "success",
1322 [SWAP_FAILURE_RESOURCES] = "resources",
1323 [SWAP_FAILURE_TIMEOUT] = "timeout",
1324 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1325 [SWAP_FAILURE_SIGNAL] = "signal",
1326 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1329 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1331 const UnitVTable swap_vtable = {
1333 .object_size = sizeof(Swap),
1340 .no_instances = true,
1346 .coldplug = swap_coldplug,
1350 .start = swap_start,
1355 .serialize = swap_serialize,
1356 .deserialize_item = swap_deserialize_item,
1358 .active_state = swap_active_state,
1359 .sub_state_to_string = swap_sub_state_to_string,
1361 .check_gc = swap_check_gc,
1363 .sigchld_event = swap_sigchld_event,
1364 .timer_event = swap_timer_event,
1366 .reset_failed = swap_reset_failed,
1368 .bus_interface = "org.freedesktop.systemd1.Swap",
1369 .bus_message_handler = bus_swap_message_handler,
1370 .bus_invalidating_properties = bus_swap_invalidating_properties,
1372 .following = swap_following,
1373 .following_set = swap_following_set,
1375 .enumerate = swap_enumerate,
1376 .shutdown = swap_shutdown,
1378 .status_message_formats = {
1379 .starting_stopping = {
1380 [0] = "Activating swap %s...",
1381 [1] = "Deactivating swap %s...",
1383 .finished_start_job = {
1384 [JOB_DONE] = "Activated swap %s.",
1385 [JOB_FAILED] = "Failed to activate swap %s.",
1386 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1387 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1389 .finished_stop_job = {
1390 [JOB_DONE] = "Deactivated swap %s.",
1391 [JOB_FAILED] = "Failed deactivating swap %s.",
1392 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",