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)
186 UNIT(s)->manager->running_as == MANAGER_SYSTEM)
187 if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(s), true)) < 0)
190 return unit_add_dependency(UNIT(s), UNIT_BEFORE, tu, true);
193 static int swap_add_device_links(Swap *s) {
201 if (s->from_fragment)
202 p = &s->parameters_fragment;
203 else if (s->from_etc_fstab)
204 p = &s->parameters_etc_fstab;
208 if (is_device_path(s->what))
209 return unit_add_node_link(UNIT(s), s->what,
210 !p->noauto && p->nofail &&
211 UNIT(s)->manager->running_as == MANAGER_SYSTEM);
213 /* File based swap devices need to be ordered after
214 * systemd-remount-fs.service, since they might need a
215 * writable file system. */
216 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
219 static int swap_add_default_dependencies(Swap *s) {
224 if (UNIT(s)->manager->running_as == MANAGER_SYSTEM) {
226 if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0)
233 static int swap_verify(Swap *s) {
237 if (UNIT(s)->load_state != UNIT_LOADED)
240 if (!(e = unit_name_from_path(s->what, ".swap")))
243 b = unit_has_name(UNIT(s), e);
247 log_error("%s: Value of \"What\" and unit name do not match, not loading.\n", UNIT(s)->id);
251 if (s->exec_context.pam_name && s->exec_context.kill_mode != KILL_CONTROL_GROUP) {
252 log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(s)->id);
259 static int swap_load(Unit *u) {
264 assert(u->load_state == UNIT_STUB);
266 /* Load a .swap file */
267 if ((r = unit_load_fragment_and_dropin_optional(u)) < 0)
270 if (u->load_state == UNIT_LOADED) {
271 if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
274 if (UNIT(s)->fragment_path)
275 s->from_fragment = true;
278 if (s->parameters_fragment.what)
279 s->what = strdup(s->parameters_fragment.what);
280 else if (s->parameters_etc_fstab.what)
281 s->what = strdup(s->parameters_etc_fstab.what);
282 else if (s->parameters_proc_swaps.what)
283 s->what = strdup(s->parameters_proc_swaps.what);
285 s->what = unit_name_to_path(u->id);
291 path_kill_slashes(s->what);
293 if (!UNIT(s)->description)
294 if ((r = unit_set_description(u, s->what)) < 0)
297 if ((r = swap_add_device_links(s)) < 0)
300 if ((r = swap_add_mount_links(s)) < 0)
303 if ((r = swap_add_target_links(s)) < 0)
306 if ((r = unit_add_default_cgroups(u)) < 0)
309 if (UNIT(s)->default_dependencies)
310 if ((r = swap_add_default_dependencies(s)) < 0)
314 return swap_verify(s);
320 const char *what_proc_swaps,
327 char *e = NULL, *wp = NULL;
335 e = unit_name_from_path(what, ".swap");
339 u = manager_get_unit(m, e);
341 if (what_proc_swaps &&
343 SWAP(u)->from_proc_swaps &&
344 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
350 u = unit_new(m, sizeof(Swap));
356 r = unit_add_name(u, e);
360 SWAP(u)->what = strdup(what);
361 if (!SWAP(u)->what) {
366 unit_add_to_load_queue(u);
370 if (what_proc_swaps) {
373 p = &SWAP(u)->parameters_proc_swaps;
376 if (!(wp = strdup(what_proc_swaps))) {
381 if (!m->swaps_by_proc_swaps)
382 if (!(m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func))) {
390 first = hashmap_get(m->swaps_by_proc_swaps, wp);
391 LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u));
393 if ((r = hashmap_replace(m->swaps_by_proc_swaps, wp, first)) < 0)
398 SWAP(u)->is_active = true;
399 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
402 SWAP(u)->from_proc_swaps = true;
405 p = &SWAP(u)->parameters_etc_fstab;
407 if (!(wp = strdup(what))) {
415 SWAP(u)->from_etc_fstab = true;
418 p->priority = priority;
422 unit_add_to_dbus_queue(u);
429 log_warning("Failed to load swap unit: %s", strerror(-r));
440 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
446 if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) {
447 struct udev_device *d;
449 struct udev_list_entry *item = NULL, *first = NULL;
451 /* So this is a proper swap device. Create swap units
452 * for all names this swap device is known under */
454 if (!(d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev)))
457 dn = udev_device_get_devnode(d);
459 r = swap_add_one(m, dn, device, prio, false, false, set_flags);
461 /* Add additional units for all symlinks */
462 first = udev_device_get_devlinks_list_entry(d);
463 udev_list_entry_foreach(item, first) {
466 /* Don't bother with the /dev/block links */
467 p = udev_list_entry_get_name(item);
469 if (path_startswith(p, "/dev/block/"))
472 if (stat(p, &st) >= 0)
473 if ((!S_ISBLK(st.st_mode)) || st.st_rdev != udev_device_get_devnum(d))
476 k = swap_add_one(m, p, device, prio, false, false, set_flags);
481 udev_device_unref(d);
484 k = swap_add_one(m, device, device, prio, false, false, set_flags);
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;
579 "%sFrom /etc/fstab: %s\n"
580 "%sFrom /proc/swaps: %s\n"
581 "%sFrom fragment: %s\n",
582 prefix, swap_state_to_string(s->state),
583 prefix, swap_result_to_string(s->result),
586 prefix, yes_no(p->noauto),
587 prefix, yes_no(p->nofail),
588 prefix, yes_no(s->from_etc_fstab),
589 prefix, yes_no(s->from_proc_swaps),
590 prefix, yes_no(s->from_fragment));
592 if (s->control_pid > 0)
594 "%sControl PID: %lu\n",
595 prefix, (unsigned long) s->control_pid);
597 exec_context_dump(&s->exec_context, f, prefix);
600 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
608 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
611 if ((r = exec_spawn(c,
615 UNIT(s)->manager->environment,
619 UNIT(s)->manager->confirm_spawn,
620 UNIT(s)->cgroup_bondings,
621 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 r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set, NULL);
695 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
696 log_warning("Failed to kill control group: %s", strerror(-r));
698 wait_for_exit = true;
706 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
709 swap_set_state(s, state);
711 swap_enter_dead(s, SWAP_SUCCESS);
716 log_warning("%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
718 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
724 static void swap_enter_activating(Swap *s) {
729 s->control_command_id = SWAP_EXEC_ACTIVATE;
730 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
732 if (s->from_fragment)
733 priority = s->parameters_fragment.priority;
734 else if (s->from_etc_fstab)
735 priority = s->parameters_etc_fstab.priority;
742 snprintf(p, sizeof(p), "%i", priority);
745 r = exec_command_set(
753 r = exec_command_set(
762 swap_unwatch_control_pid(s);
764 if ((r = swap_spawn(s, s->control_command, &s->control_pid)) < 0)
767 swap_set_state(s, SWAP_ACTIVATING);
772 log_warning("%s failed to run 'swapon' task: %s", UNIT(s)->id, strerror(-r));
773 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
776 static void swap_enter_deactivating(Swap *s) {
781 s->control_command_id = SWAP_EXEC_DEACTIVATE;
782 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
784 if ((r = exec_command_set(
791 swap_unwatch_control_pid(s);
793 if ((r = swap_spawn(s, s->control_command, &s->control_pid)) < 0)
796 swap_set_state(s, SWAP_DEACTIVATING);
801 log_warning("%s failed to run 'swapoff' task: %s", UNIT(s)->id, strerror(-r));
802 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
805 static int swap_start(Unit *u) {
810 /* We cannot fulfill this request right now, try again later
813 if (s->state == SWAP_DEACTIVATING ||
814 s->state == SWAP_DEACTIVATING_SIGTERM ||
815 s->state == SWAP_DEACTIVATING_SIGKILL ||
816 s->state == SWAP_ACTIVATING_SIGTERM ||
817 s->state == SWAP_ACTIVATING_SIGKILL)
820 if (s->state == SWAP_ACTIVATING)
823 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
825 s->result = SWAP_SUCCESS;
826 swap_enter_activating(s);
830 static int swap_stop(Unit *u) {
835 if (s->state == SWAP_DEACTIVATING ||
836 s->state == SWAP_DEACTIVATING_SIGTERM ||
837 s->state == SWAP_DEACTIVATING_SIGKILL ||
838 s->state == SWAP_ACTIVATING_SIGTERM ||
839 s->state == SWAP_ACTIVATING_SIGKILL)
842 assert(s->state == SWAP_ACTIVATING ||
843 s->state == SWAP_ACTIVE);
845 swap_enter_deactivating(s);
849 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
856 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
857 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
859 if (s->control_pid > 0)
860 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
862 if (s->control_command_id >= 0)
863 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
868 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
874 if (streq(key, "state")) {
877 if ((state = swap_state_from_string(value)) < 0)
878 log_debug("Failed to parse state value %s", value);
880 s->deserialized_state = state;
881 } else if (streq(key, "result")) {
884 f = swap_result_from_string(value);
886 log_debug("Failed to parse result value %s", value);
887 else if (f != SWAP_SUCCESS)
889 } else if (streq(key, "control-pid")) {
892 if (parse_pid(value, &pid) < 0)
893 log_debug("Failed to parse control-pid value %s", value);
895 s->control_pid = pid;
897 } else if (streq(key, "control-command")) {
900 if ((id = swap_exec_command_from_string(value)) < 0)
901 log_debug("Failed to parse exec-command value %s", value);
903 s->control_command_id = id;
904 s->control_command = s->exec_command + id;
908 log_debug("Unknown serialization key '%s'", key);
913 static UnitActiveState swap_active_state(Unit *u) {
916 return state_translation_table[SWAP(u)->state];
919 static const char *swap_sub_state_to_string(Unit *u) {
922 return swap_state_to_string(SWAP(u)->state);
925 static bool swap_check_gc(Unit *u) {
930 return s->from_etc_fstab || s->from_proc_swaps;
933 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
940 if (pid != s->control_pid)
945 if (is_clean_exit(code, status))
947 else if (code == CLD_EXITED)
948 f = SWAP_FAILURE_EXIT_CODE;
949 else if (code == CLD_KILLED)
950 f = SWAP_FAILURE_SIGNAL;
951 else if (code == CLD_DUMPED)
952 f = SWAP_FAILURE_CORE_DUMP;
954 assert_not_reached("Unknown code");
956 if (f != SWAP_SUCCESS)
959 if (s->control_command) {
960 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
962 s->control_command = NULL;
963 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
966 log_full(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
967 "%s swap process exited, code=%s status=%i", u->id, sigchld_code_to_string(code), status);
971 case SWAP_ACTIVATING:
972 case SWAP_ACTIVATING_SIGTERM:
973 case SWAP_ACTIVATING_SIGKILL:
975 if (f == SWAP_SUCCESS)
976 swap_enter_active(s, f);
978 swap_enter_dead(s, f);
981 case SWAP_DEACTIVATING:
982 case SWAP_DEACTIVATING_SIGKILL:
983 case SWAP_DEACTIVATING_SIGTERM:
985 if (f == SWAP_SUCCESS)
986 swap_enter_dead(s, f);
988 swap_enter_dead(s, f);
992 assert_not_reached("Uh, control process died at wrong time.");
995 /* Notify clients about changed exit status */
996 unit_add_to_dbus_queue(u);
998 /* Request a reload of /proc/swaps, so that following units
999 * can follow our state change */
1000 u->manager->request_reload = true;
1003 static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
1007 assert(elapsed == 1);
1008 assert(w == &s->timer_watch);
1012 case SWAP_ACTIVATING:
1013 log_warning("%s activation timed out. Stopping.", u->id);
1014 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1017 case SWAP_DEACTIVATING:
1018 log_warning("%s deactivation timed out. Stopping.", u->id);
1019 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1022 case SWAP_ACTIVATING_SIGTERM:
1023 if (s->exec_context.send_sigkill) {
1024 log_warning("%s activation timed out. Killing.", u->id);
1025 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1027 log_warning("%s activation timed out. Skipping SIGKILL. Ignoring.", u->id);
1028 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1032 case SWAP_DEACTIVATING_SIGTERM:
1033 if (s->exec_context.send_sigkill) {
1034 log_warning("%s deactivation timed out. Killing.", u->id);
1035 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1037 log_warning("%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id);
1038 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1042 case SWAP_ACTIVATING_SIGKILL:
1043 case SWAP_DEACTIVATING_SIGKILL:
1044 log_warning("%s swap process still around after SIGKILL. Ignoring.", u->id);
1045 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1049 assert_not_reached("Timeout at wrong time.");
1053 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1059 rewind(m->proc_swaps);
1061 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1064 char *dev = NULL, *d;
1067 if ((k = fscanf(m->proc_swaps,
1068 "%ms " /* device/file */
1069 "%*s " /* type of swap */
1070 "%*s " /* swap size */
1072 "%i\n", /* priority */
1073 &dev, &prio)) != 2) {
1078 log_warning("Failed to parse /proc/swaps:%u.", i);
1089 k = swap_process_new_swap(m, d, prio, set_flags);
1099 int swap_dispatch_reload(Manager *m) {
1100 /* This function should go as soon as the kernel properly notifies us */
1102 if (_likely_(!m->request_reload))
1105 m->request_reload = false;
1107 return swap_fd_event(m, EPOLLPRI);
1110 int swap_fd_event(Manager *m, int events) {
1115 assert(events & EPOLLPRI);
1117 if ((r = swap_load_proc_swaps(m, true)) < 0) {
1118 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1120 /* Reset flags, just in case, for late calls */
1121 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1122 Swap *swap = SWAP(u);
1124 swap->is_active = swap->just_activated = false;
1130 manager_dispatch_load_queue(m);
1132 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1133 Swap *swap = SWAP(u);
1135 if (!swap->is_active) {
1136 /* This has just been deactivated */
1138 swap->from_proc_swaps = false;
1139 swap_unset_proc_swaps(swap);
1141 switch (swap->state) {
1144 swap_enter_dead(swap, SWAP_SUCCESS);
1148 swap_set_state(swap, swap->state);
1152 } else if (swap->just_activated) {
1154 /* New swap entry */
1156 switch (swap->state) {
1160 swap_enter_active(swap, SWAP_SUCCESS);
1164 /* Nothing really changed, but let's
1165 * issue an notification call
1166 * nonetheless, in case somebody is
1167 * waiting for this. */
1168 swap_set_state(swap, swap->state);
1173 /* Reset the flags for later calls */
1174 swap->is_active = swap->just_activated = false;
1180 static Unit *swap_following(Unit *u) {
1182 Swap *other, *first = NULL;
1186 if (streq_ptr(s->what, s->parameters_proc_swaps.what))
1189 /* Make everybody follow the unit that's named after the swap
1190 * device in the kernel */
1192 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1193 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1196 LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
1197 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1206 static int swap_following_set(Unit *u, Set **_set) {
1215 if (LIST_JUST_US(same_proc_swaps, s)) {
1220 if (!(set = set_new(NULL, NULL)))
1223 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1224 if ((r = set_put(set, other)) < 0)
1227 LIST_FOREACH_BEFORE(same_proc_swaps, other, s)
1228 if ((r = set_put(set, other)) < 0)
1239 static void swap_shutdown(Manager *m) {
1242 if (m->proc_swaps) {
1243 fclose(m->proc_swaps);
1244 m->proc_swaps = NULL;
1247 hashmap_free(m->swaps_by_proc_swaps);
1248 m->swaps_by_proc_swaps = NULL;
1251 static int swap_enumerate(Manager *m) {
1253 struct epoll_event ev;
1256 if (!m->proc_swaps) {
1257 if (!(m->proc_swaps = fopen("/proc/swaps", "re")))
1258 return (errno == ENOENT) ? 0 : -errno;
1260 m->swap_watch.type = WATCH_SWAP;
1261 m->swap_watch.fd = fileno(m->proc_swaps);
1264 ev.events = EPOLLPRI;
1265 ev.data.ptr = &m->swap_watch;
1267 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
1271 /* We rely on mount.c to load /etc/fstab for us */
1273 if ((r = swap_load_proc_swaps(m, false)) < 0)
1279 static void swap_reset_failed(Unit *u) {
1284 if (s->state == SWAP_FAILED)
1285 swap_set_state(s, SWAP_DEAD);
1287 s->result = SWAP_SUCCESS;
1290 static int swap_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError *error) {
1293 Set *pid_set = NULL;
1297 if (who == KILL_MAIN) {
1298 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Swap units have no main processes");
1302 if (s->control_pid <= 0 && who == KILL_CONTROL) {
1303 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
1307 if (who == KILL_CONTROL || who == KILL_ALL)
1308 if (s->control_pid > 0)
1309 if (kill(s->control_pid, signo) < 0)
1312 if (who == KILL_ALL && mode == KILL_CONTROL_GROUP) {
1315 if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func)))
1318 /* Exclude the control pid from being killed via the cgroup */
1319 if (s->control_pid > 0)
1320 if ((q = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) {
1325 q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set, NULL);
1327 if (q != -EAGAIN && q != -ESRCH && q != -ENOENT)
1338 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1339 [SWAP_DEAD] = "dead",
1340 [SWAP_ACTIVATING] = "activating",
1341 [SWAP_ACTIVE] = "active",
1342 [SWAP_DEACTIVATING] = "deactivating",
1343 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1344 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1345 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1346 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1347 [SWAP_FAILED] = "failed"
1350 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1352 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1353 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1354 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1357 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1359 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1360 [SWAP_SUCCESS] = "success",
1361 [SWAP_FAILURE_RESOURCES] = "resources",
1362 [SWAP_FAILURE_TIMEOUT] = "timeout",
1363 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1364 [SWAP_FAILURE_SIGNAL] = "signal",
1365 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1368 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1370 const UnitVTable swap_vtable = {
1372 .object_size = sizeof(Swap),
1379 .no_instances = true,
1380 .show_status = true,
1386 .coldplug = swap_coldplug,
1390 .start = swap_start,
1395 .serialize = swap_serialize,
1396 .deserialize_item = swap_deserialize_item,
1398 .active_state = swap_active_state,
1399 .sub_state_to_string = swap_sub_state_to_string,
1401 .check_gc = swap_check_gc,
1403 .sigchld_event = swap_sigchld_event,
1404 .timer_event = swap_timer_event,
1406 .reset_failed = swap_reset_failed,
1408 .bus_interface = "org.freedesktop.systemd1.Swap",
1409 .bus_message_handler = bus_swap_message_handler,
1410 .bus_invalidating_properties = bus_swap_invalidating_properties,
1412 .following = swap_following,
1413 .following_set = swap_following_set,
1415 .enumerate = swap_enumerate,
1416 .shutdown = swap_shutdown