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"
42 static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
43 [SWAP_DEAD] = UNIT_INACTIVE,
44 [SWAP_ACTIVATING] = UNIT_ACTIVATING,
45 [SWAP_ACTIVE] = UNIT_ACTIVE,
46 [SWAP_DEACTIVATING] = UNIT_DEACTIVATING,
47 [SWAP_ACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
48 [SWAP_ACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
49 [SWAP_DEACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
50 [SWAP_DEACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
51 [SWAP_FAILED] = UNIT_FAILED
54 static void swap_unset_proc_swaps(Swap *s) {
59 if (!s->parameters_proc_swaps.what)
62 /* Remove this unit from the chain of swaps which share the
63 * same kernel swap device. */
65 first = hashmap_get(UNIT(s)->manager->swaps_by_proc_swaps, s->parameters_proc_swaps.what);
66 LIST_REMOVE(Swap, same_proc_swaps, first, s);
69 hashmap_remove_and_replace(UNIT(s)->manager->swaps_by_proc_swaps, s->parameters_proc_swaps.what, first->parameters_proc_swaps.what, first);
71 hashmap_remove(UNIT(s)->manager->swaps_by_proc_swaps, s->parameters_proc_swaps.what);
73 free(s->parameters_proc_swaps.what);
74 s->parameters_proc_swaps.what = NULL;
77 static void swap_init(Unit *u) {
81 assert(UNIT(s)->load_state == UNIT_STUB);
83 s->timeout_usec = DEFAULT_TIMEOUT_USEC;
85 exec_context_init(&s->exec_context);
86 s->exec_context.std_output = u->manager->default_std_output;
87 s->exec_context.std_error = u->manager->default_std_error;
89 s->parameters_etc_fstab.priority = s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
91 s->timer_watch.type = WATCH_INVALID;
93 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
95 UNIT(s)->ignore_on_isolate = true;
98 static void swap_unwatch_control_pid(Swap *s) {
101 if (s->control_pid <= 0)
104 unit_unwatch_pid(UNIT(s), s->control_pid);
108 static void swap_done(Unit *u) {
113 swap_unset_proc_swaps(s);
118 free(s->parameters_etc_fstab.what);
119 free(s->parameters_fragment.what);
120 s->parameters_etc_fstab.what = 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) {
173 if (s->from_fragment)
174 p = &s->parameters_fragment;
175 else if (s->from_etc_fstab)
176 p = &s->parameters_etc_fstab;
180 if ((r = manager_load_unit(UNIT(s)->manager, SPECIAL_SWAP_TARGET, NULL, NULL, &tu)) < 0)
185 (p->handle || UNIT(s)->manager->swap_auto) &&
187 UNIT(s)->manager->running_as == MANAGER_SYSTEM)
188 if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(s), true)) < 0)
191 return unit_add_dependency(UNIT(s), UNIT_BEFORE, tu, true);
194 static int swap_add_device_links(Swap *s) {
202 if (s->from_fragment)
203 p = &s->parameters_fragment;
204 else if (s->from_etc_fstab)
205 p = &s->parameters_etc_fstab;
209 if (is_device_path(s->what))
210 return unit_add_node_link(UNIT(s), s->what,
211 !p->noauto && p->nofail &&
212 UNIT(s)->manager->running_as == MANAGER_SYSTEM);
214 /* File based swap devices need to be ordered after
215 * remount-rootfs.service, since they might need a
216 * writable file system. */
217 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_ROOTFS_SERVICE, NULL, true);
220 static int swap_add_default_dependencies(Swap *s) {
225 if (UNIT(s)->manager->running_as == MANAGER_SYSTEM) {
227 if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0)
234 static int swap_verify(Swap *s) {
238 if (UNIT(s)->load_state != UNIT_LOADED)
241 if (!(e = unit_name_from_path(s->what, ".swap")))
244 b = unit_has_name(UNIT(s), e);
248 log_error("%s: Value of \"What\" and unit name do not match, not loading.\n", UNIT(s)->id);
252 if (s->exec_context.pam_name && s->exec_context.kill_mode != KILL_CONTROL_GROUP) {
253 log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(s)->id);
260 static int swap_load(Unit *u) {
265 assert(u->load_state == UNIT_STUB);
267 /* Load a .swap file */
268 if ((r = unit_load_fragment_and_dropin_optional(u)) < 0)
271 if (u->load_state == UNIT_LOADED) {
272 if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
275 if (UNIT(s)->fragment_path)
276 s->from_fragment = true;
279 if (s->parameters_fragment.what)
280 s->what = strdup(s->parameters_fragment.what);
281 else if (s->parameters_etc_fstab.what)
282 s->what = strdup(s->parameters_etc_fstab.what);
283 else if (s->parameters_proc_swaps.what)
284 s->what = strdup(s->parameters_proc_swaps.what);
286 s->what = unit_name_to_path(u->id);
292 path_kill_slashes(s->what);
294 if (!UNIT(s)->description)
295 if ((r = unit_set_description(u, s->what)) < 0)
298 if ((r = swap_add_device_links(s)) < 0)
301 if ((r = swap_add_mount_links(s)) < 0)
304 if ((r = swap_add_target_links(s)) < 0)
307 if ((r = unit_add_default_cgroups(u)) < 0)
310 if (UNIT(s)->default_dependencies)
311 if ((r = swap_add_default_dependencies(s)) < 0)
315 return swap_verify(s);
321 const char *what_proc_swaps,
329 char *e = NULL, *wp = NULL;
337 e = unit_name_from_path(what, ".swap");
341 u = manager_get_unit(m, e);
343 if (what_proc_swaps &&
345 SWAP(u)->from_proc_swaps &&
346 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
352 u = unit_new(m, sizeof(Swap));
358 r = unit_add_name(u, e);
362 SWAP(u)->what = strdup(what);
363 if (!SWAP(u)->what) {
368 unit_add_to_load_queue(u);
372 if (what_proc_swaps) {
375 p = &SWAP(u)->parameters_proc_swaps;
378 if (!(wp = strdup(what_proc_swaps))) {
383 if (!m->swaps_by_proc_swaps)
384 if (!(m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func))) {
392 first = hashmap_get(m->swaps_by_proc_swaps, wp);
393 LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u));
395 if ((r = hashmap_replace(m->swaps_by_proc_swaps, wp, first)) < 0)
400 SWAP(u)->is_active = true;
401 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
404 SWAP(u)->from_proc_swaps = true;
407 p = &SWAP(u)->parameters_etc_fstab;
409 if (!(wp = strdup(what))) {
417 SWAP(u)->from_etc_fstab = true;
420 p->priority = priority;
425 unit_add_to_dbus_queue(u);
432 log_warning("Failed to load swap unit: %s", strerror(-r));
443 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
449 if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) {
450 struct udev_device *d;
452 struct udev_list_entry *item = NULL, *first = NULL;
454 /* So this is a proper swap device. Create swap units
455 * for all names this swap device is known under */
457 if (!(d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev)))
460 if ((dn = udev_device_get_devnode(d)))
461 r = swap_add_one(m, dn, device, prio, false, false, false, set_flags);
463 /* Add additional units for all symlinks */
464 first = udev_device_get_devlinks_list_entry(d);
465 udev_list_entry_foreach(item, first) {
468 /* Don't bother with the /dev/block links */
469 p = udev_list_entry_get_name(item);
471 if (path_startswith(p, "/dev/block/"))
474 if (stat(p, &st) >= 0)
475 if ((!S_ISBLK(st.st_mode)) || st.st_rdev != udev_device_get_devnum(d))
478 if ((k = swap_add_one(m, p, device, prio, false, false, false, set_flags)) < 0)
482 udev_device_unref(d);
485 if ((k = swap_add_one(m, device, device, prio, false, false, false, set_flags)) < 0)
491 static void swap_set_state(Swap *s, SwapState state) {
496 old_state = s->state;
499 if (state != SWAP_ACTIVATING &&
500 state != SWAP_ACTIVATING_SIGTERM &&
501 state != SWAP_ACTIVATING_SIGKILL &&
502 state != SWAP_DEACTIVATING &&
503 state != SWAP_DEACTIVATING_SIGTERM &&
504 state != SWAP_DEACTIVATING_SIGKILL) {
505 unit_unwatch_timer(UNIT(s), &s->timer_watch);
506 swap_unwatch_control_pid(s);
507 s->control_command = NULL;
508 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
511 if (state != old_state)
512 log_debug("%s changed %s -> %s",
514 swap_state_to_string(old_state),
515 swap_state_to_string(state));
517 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
520 static int swap_coldplug(Unit *u) {
522 SwapState new_state = SWAP_DEAD;
526 assert(s->state == SWAP_DEAD);
528 if (s->deserialized_state != s->state)
529 new_state = s->deserialized_state;
530 else if (s->from_proc_swaps)
531 new_state = SWAP_ACTIVE;
533 if (new_state != s->state) {
535 if (new_state == SWAP_ACTIVATING ||
536 new_state == SWAP_ACTIVATING_SIGTERM ||
537 new_state == SWAP_ACTIVATING_SIGKILL ||
538 new_state == SWAP_DEACTIVATING ||
539 new_state == SWAP_DEACTIVATING_SIGTERM ||
540 new_state == SWAP_DEACTIVATING_SIGKILL) {
542 if (s->control_pid <= 0)
545 if ((r = unit_watch_pid(UNIT(s), s->control_pid)) < 0)
548 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
552 swap_set_state(s, new_state);
558 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
565 if (s->from_proc_swaps)
566 p = &s->parameters_proc_swaps;
567 else if (s->from_fragment)
568 p = &s->parameters_fragment;
570 p = &s->parameters_etc_fstab;
580 "%sFrom /etc/fstab: %s\n"
581 "%sFrom /proc/swaps: %s\n"
582 "%sFrom fragment: %s\n",
583 prefix, swap_state_to_string(s->state),
584 prefix, swap_result_to_string(s->result),
587 prefix, yes_no(p->noauto),
588 prefix, yes_no(p->nofail),
589 prefix, yes_no(p->handle),
590 prefix, yes_no(s->from_etc_fstab),
591 prefix, yes_no(s->from_proc_swaps),
592 prefix, yes_no(s->from_fragment));
594 if (s->control_pid > 0)
596 "%sControl PID: %lu\n",
597 prefix, (unsigned long) s->control_pid);
599 exec_context_dump(&s->exec_context, f, prefix);
602 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
610 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
613 if ((r = exec_spawn(c,
617 UNIT(s)->manager->environment,
621 UNIT(s)->manager->confirm_spawn,
622 UNIT(s)->cgroup_bondings,
623 UNIT(s)->cgroup_attributes,
627 if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
628 /* FIXME: we need to do something here */
636 unit_unwatch_timer(UNIT(s), &s->timer_watch);
641 static void swap_enter_dead(Swap *s, SwapResult f) {
644 if (f != SWAP_SUCCESS)
647 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
650 static void swap_enter_active(Swap *s, SwapResult f) {
653 if (f != SWAP_SUCCESS)
656 swap_set_state(s, SWAP_ACTIVE);
659 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
662 bool wait_for_exit = false;
666 if (f != SWAP_SUCCESS)
669 if (s->exec_context.kill_mode != KILL_NONE) {
670 int sig = (state == SWAP_ACTIVATING_SIGTERM ||
671 state == SWAP_DEACTIVATING_SIGTERM) ? s->exec_context.kill_signal : SIGKILL;
673 if (s->control_pid > 0) {
674 if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH)
676 log_warning("Failed to kill control process %li: %m", (long) s->control_pid);
678 wait_for_exit = true;
681 if (s->exec_context.kill_mode == KILL_CONTROL_GROUP) {
683 if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) {
688 /* Exclude the control pid from being killed via the cgroup */
689 if (s->control_pid > 0)
690 if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0)
693 if ((r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set)) < 0) {
694 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
695 log_warning("Failed to kill control group: %s", strerror(-r));
697 wait_for_exit = true;
705 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
708 swap_set_state(s, state);
710 swap_enter_dead(s, SWAP_SUCCESS);
715 log_warning("%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
717 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
723 static void swap_enter_activating(Swap *s) {
728 s->control_command_id = SWAP_EXEC_ACTIVATE;
729 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
731 if (s->from_fragment)
732 priority = s->parameters_fragment.priority;
733 else if (s->from_etc_fstab)
734 priority = s->parameters_etc_fstab.priority;
741 snprintf(p, sizeof(p), "%i", priority);
744 r = exec_command_set(
752 r = exec_command_set(
761 swap_unwatch_control_pid(s);
763 if ((r = swap_spawn(s, s->control_command, &s->control_pid)) < 0)
766 swap_set_state(s, SWAP_ACTIVATING);
771 log_warning("%s failed to run 'swapon' task: %s", UNIT(s)->id, strerror(-r));
772 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
775 static void swap_enter_deactivating(Swap *s) {
780 s->control_command_id = SWAP_EXEC_DEACTIVATE;
781 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
783 if ((r = exec_command_set(
790 swap_unwatch_control_pid(s);
792 if ((r = swap_spawn(s, s->control_command, &s->control_pid)) < 0)
795 swap_set_state(s, SWAP_DEACTIVATING);
800 log_warning("%s failed to run 'swapoff' task: %s", UNIT(s)->id, strerror(-r));
801 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
804 static int swap_start(Unit *u) {
809 /* We cannot fulfill this request right now, try again later
812 if (s->state == SWAP_DEACTIVATING ||
813 s->state == SWAP_DEACTIVATING_SIGTERM ||
814 s->state == SWAP_DEACTIVATING_SIGKILL ||
815 s->state == SWAP_ACTIVATING_SIGTERM ||
816 s->state == SWAP_ACTIVATING_SIGKILL)
819 if (s->state == SWAP_ACTIVATING)
822 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
824 s->result = SWAP_SUCCESS;
825 swap_enter_activating(s);
829 static int swap_stop(Unit *u) {
834 if (s->state == SWAP_DEACTIVATING ||
835 s->state == SWAP_DEACTIVATING_SIGTERM ||
836 s->state == SWAP_DEACTIVATING_SIGKILL ||
837 s->state == SWAP_ACTIVATING_SIGTERM ||
838 s->state == SWAP_ACTIVATING_SIGKILL)
841 assert(s->state == SWAP_ACTIVATING ||
842 s->state == SWAP_ACTIVE);
844 swap_enter_deactivating(s);
848 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
855 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
856 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
858 if (s->control_pid > 0)
859 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
861 if (s->control_command_id >= 0)
862 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
867 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
873 if (streq(key, "state")) {
876 if ((state = swap_state_from_string(value)) < 0)
877 log_debug("Failed to parse state value %s", value);
879 s->deserialized_state = state;
880 } else if (streq(key, "result")) {
883 f = swap_result_from_string(value);
885 log_debug("Failed to parse result value %s", value);
886 else if (f != SWAP_SUCCESS)
888 } else if (streq(key, "control-pid")) {
891 if (parse_pid(value, &pid) < 0)
892 log_debug("Failed to parse control-pid value %s", value);
894 s->control_pid = pid;
896 } else if (streq(key, "control-command")) {
899 if ((id = swap_exec_command_from_string(value)) < 0)
900 log_debug("Failed to parse exec-command value %s", value);
902 s->control_command_id = id;
903 s->control_command = s->exec_command + id;
907 log_debug("Unknown serialization key '%s'", key);
912 static UnitActiveState swap_active_state(Unit *u) {
915 return state_translation_table[SWAP(u)->state];
918 static const char *swap_sub_state_to_string(Unit *u) {
921 return swap_state_to_string(SWAP(u)->state);
924 static bool swap_check_gc(Unit *u) {
929 return s->from_etc_fstab || s->from_proc_swaps;
932 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
939 if (pid != s->control_pid)
944 if (is_clean_exit(code, status))
946 else if (code == CLD_EXITED)
947 f = SWAP_FAILURE_EXIT_CODE;
948 else if (code == CLD_KILLED)
949 f = SWAP_FAILURE_SIGNAL;
950 else if (code == CLD_DUMPED)
951 f = SWAP_FAILURE_CORE_DUMP;
953 assert_not_reached("Unknown code");
955 if (f != SWAP_SUCCESS)
958 if (s->control_command) {
959 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
961 s->control_command = NULL;
962 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
965 log_full(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
966 "%s swap process exited, code=%s status=%i", u->id, sigchld_code_to_string(code), status);
970 case SWAP_ACTIVATING:
971 case SWAP_ACTIVATING_SIGTERM:
972 case SWAP_ACTIVATING_SIGKILL:
974 if (f == SWAP_SUCCESS)
975 swap_enter_active(s, f);
977 swap_enter_dead(s, f);
980 case SWAP_DEACTIVATING:
981 case SWAP_DEACTIVATING_SIGKILL:
982 case SWAP_DEACTIVATING_SIGTERM:
984 if (f == SWAP_SUCCESS)
985 swap_enter_dead(s, f);
987 swap_enter_dead(s, f);
991 assert_not_reached("Uh, control process died at wrong time.");
994 /* Notify clients about changed exit status */
995 unit_add_to_dbus_queue(u);
997 /* Request a reload of /proc/swaps, so that following units
998 * can follow our state change */
999 u->manager->request_reload = true;
1002 static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
1006 assert(elapsed == 1);
1007 assert(w == &s->timer_watch);
1011 case SWAP_ACTIVATING:
1012 log_warning("%s activation timed out. Stopping.", u->id);
1013 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1016 case SWAP_DEACTIVATING:
1017 log_warning("%s deactivation timed out. Stopping.", u->id);
1018 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1021 case SWAP_ACTIVATING_SIGTERM:
1022 if (s->exec_context.send_sigkill) {
1023 log_warning("%s activation timed out. Killing.", u->id);
1024 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1026 log_warning("%s activation timed out. Skipping SIGKILL. Ignoring.", u->id);
1027 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1031 case SWAP_DEACTIVATING_SIGTERM:
1032 if (s->exec_context.send_sigkill) {
1033 log_warning("%s deactivation timed out. Killing.", u->id);
1034 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1036 log_warning("%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id);
1037 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1041 case SWAP_ACTIVATING_SIGKILL:
1042 case SWAP_DEACTIVATING_SIGKILL:
1043 log_warning("%s swap process still around after SIGKILL. Ignoring.", u->id);
1044 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1048 assert_not_reached("Timeout at wrong time.");
1052 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1058 rewind(m->proc_swaps);
1060 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1063 char *dev = NULL, *d;
1066 if ((k = fscanf(m->proc_swaps,
1067 "%ms " /* device/file */
1068 "%*s " /* type of swap */
1069 "%*s " /* swap size */
1071 "%i\n", /* priority */
1072 &dev, &prio)) != 2) {
1077 log_warning("Failed to parse /proc/swaps:%u.", i);
1088 k = swap_process_new_swap(m, d, prio, set_flags);
1098 int swap_dispatch_reload(Manager *m) {
1099 /* This function should go as soon as the kernel properly notifies us */
1101 if (_likely_(!m->request_reload))
1104 m->request_reload = false;
1106 return swap_fd_event(m, EPOLLPRI);
1109 int swap_fd_event(Manager *m, int events) {
1114 assert(events & EPOLLPRI);
1116 if ((r = swap_load_proc_swaps(m, true)) < 0) {
1117 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1119 /* Reset flags, just in case, for late calls */
1120 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1121 Swap *swap = SWAP(u);
1123 swap->is_active = swap->just_activated = false;
1129 manager_dispatch_load_queue(m);
1131 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1132 Swap *swap = SWAP(u);
1134 if (!swap->is_active) {
1135 /* This has just been deactivated */
1137 swap->from_proc_swaps = false;
1138 swap_unset_proc_swaps(swap);
1140 switch (swap->state) {
1143 swap_enter_dead(swap, SWAP_SUCCESS);
1147 swap_set_state(swap, swap->state);
1151 } else if (swap->just_activated) {
1153 /* New swap entry */
1155 switch (swap->state) {
1159 swap_enter_active(swap, SWAP_SUCCESS);
1163 /* Nothing really changed, but let's
1164 * issue an notification call
1165 * nonetheless, in case somebody is
1166 * waiting for this. */
1167 swap_set_state(swap, swap->state);
1172 /* Reset the flags for later calls */
1173 swap->is_active = swap->just_activated = false;
1179 static Unit *swap_following(Unit *u) {
1181 Swap *other, *first = NULL;
1185 if (streq_ptr(s->what, s->parameters_proc_swaps.what))
1188 /* Make everybody follow the unit that's named after the swap
1189 * device in the kernel */
1191 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1192 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1195 LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
1196 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1205 static int swap_following_set(Unit *u, Set **_set) {
1214 if (LIST_JUST_US(same_proc_swaps, s)) {
1219 if (!(set = set_new(NULL, NULL)))
1222 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1223 if ((r = set_put(set, other)) < 0)
1226 LIST_FOREACH_BEFORE(same_proc_swaps, other, s)
1227 if ((r = set_put(set, other)) < 0)
1238 static void swap_shutdown(Manager *m) {
1241 if (m->proc_swaps) {
1242 fclose(m->proc_swaps);
1243 m->proc_swaps = NULL;
1246 hashmap_free(m->swaps_by_proc_swaps);
1247 m->swaps_by_proc_swaps = NULL;
1250 static int swap_enumerate(Manager *m) {
1252 struct epoll_event ev;
1255 if (!m->proc_swaps) {
1256 if (!(m->proc_swaps = fopen("/proc/swaps", "re")))
1257 return (errno == ENOENT) ? 0 : -errno;
1259 m->swap_watch.type = WATCH_SWAP;
1260 m->swap_watch.fd = fileno(m->proc_swaps);
1263 ev.events = EPOLLPRI;
1264 ev.data.ptr = &m->swap_watch;
1266 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
1270 /* We rely on mount.c to load /etc/fstab for us */
1272 if ((r = swap_load_proc_swaps(m, false)) < 0)
1278 static void swap_reset_failed(Unit *u) {
1283 if (s->state == SWAP_FAILED)
1284 swap_set_state(s, SWAP_DEAD);
1286 s->result = SWAP_SUCCESS;
1289 static int swap_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError *error) {
1292 Set *pid_set = NULL;
1296 if (who == KILL_MAIN) {
1297 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Swap units have no main processes");
1301 if (s->control_pid <= 0 && who == KILL_CONTROL) {
1302 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
1306 if (who == KILL_CONTROL || who == KILL_ALL)
1307 if (s->control_pid > 0)
1308 if (kill(s->control_pid, signo) < 0)
1311 if (who == KILL_ALL && mode == KILL_CONTROL_GROUP) {
1314 if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func)))
1317 /* Exclude the control pid from being killed via the cgroup */
1318 if (s->control_pid > 0)
1319 if ((q = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) {
1324 if ((q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set)) < 0)
1325 if (q != -EAGAIN && q != -ESRCH && q != -ENOENT)
1336 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1337 [SWAP_DEAD] = "dead",
1338 [SWAP_ACTIVATING] = "activating",
1339 [SWAP_ACTIVE] = "active",
1340 [SWAP_DEACTIVATING] = "deactivating",
1341 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1342 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1343 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1344 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1345 [SWAP_FAILED] = "failed"
1348 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1350 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1351 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1352 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1355 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1357 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1358 [SWAP_SUCCESS] = "success",
1359 [SWAP_FAILURE_RESOURCES] = "resources",
1360 [SWAP_FAILURE_TIMEOUT] = "timeout",
1361 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1362 [SWAP_FAILURE_SIGNAL] = "signal",
1363 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1366 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1368 const UnitVTable swap_vtable = {
1370 .object_size = sizeof(Swap),
1377 .no_instances = true,
1378 .show_status = true,
1384 .coldplug = swap_coldplug,
1388 .start = swap_start,
1393 .serialize = swap_serialize,
1394 .deserialize_item = swap_deserialize_item,
1396 .active_state = swap_active_state,
1397 .sub_state_to_string = swap_sub_state_to_string,
1399 .check_gc = swap_check_gc,
1401 .sigchld_event = swap_sigchld_event,
1402 .timer_event = swap_timer_event,
1404 .reset_failed = swap_reset_failed,
1406 .bus_interface = "org.freedesktop.systemd1.Swap",
1407 .bus_message_handler = bus_swap_message_handler,
1408 .bus_invalidating_properties = bus_swap_invalidating_properties,
1410 .following = swap_following,
1411 .following_set = swap_following_set,
1413 .enumerate = swap_enumerate,
1414 .shutdown = swap_shutdown