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 #include "udev-util.h"
45 static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
46 [SWAP_DEAD] = UNIT_INACTIVE,
47 [SWAP_ACTIVATING] = UNIT_ACTIVATING,
48 [SWAP_ACTIVATING_DONE] = UNIT_ACTIVE,
49 [SWAP_ACTIVE] = UNIT_ACTIVE,
50 [SWAP_DEACTIVATING] = UNIT_DEACTIVATING,
51 [SWAP_ACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
52 [SWAP_ACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
53 [SWAP_DEACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
54 [SWAP_DEACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
55 [SWAP_FAILED] = UNIT_FAILED
58 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
59 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
61 static void swap_unset_proc_swaps(Swap *s) {
64 if (!s->from_proc_swaps)
67 free(s->parameters_proc_swaps.what);
68 s->parameters_proc_swaps.what = NULL;
70 s->from_proc_swaps = false;
73 static int swap_set_devnode(Swap *s, const char *devnode) {
80 r = hashmap_ensure_allocated(&UNIT(s)->manager->swaps_by_devnode, &string_hash_ops);
84 swaps = UNIT(s)->manager->swaps_by_devnode;
87 first = hashmap_get(swaps, s->devnode);
89 LIST_REMOVE(same_devnode, first, s);
91 hashmap_replace(swaps, first->devnode, first);
93 hashmap_remove(swaps, s->devnode);
100 s->devnode = strdup(devnode);
104 first = hashmap_get(swaps, s->devnode);
105 LIST_PREPEND(same_devnode, first, s);
107 return hashmap_replace(swaps, first->devnode, first);
113 static void swap_init(Unit *u) {
117 assert(UNIT(s)->load_state == UNIT_STUB);
119 s->timeout_usec = u->manager->default_timeout_start_usec;
121 s->exec_context.std_output = u->manager->default_std_output;
122 s->exec_context.std_error = u->manager->default_std_error;
124 s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
126 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
128 u->ignore_on_isolate = true;
131 static void swap_unwatch_control_pid(Swap *s) {
134 if (s->control_pid <= 0)
137 unit_unwatch_pid(UNIT(s), s->control_pid);
141 static void swap_done(Unit *u) {
146 swap_unset_proc_swaps(s);
147 swap_set_devnode(s, NULL);
152 free(s->parameters_fragment.what);
153 s->parameters_fragment.what = NULL;
155 free(s->parameters_fragment.options);
156 s->parameters_fragment.options = NULL;
158 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
159 exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
160 s->control_command = NULL;
162 swap_unwatch_control_pid(s);
164 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
167 static int swap_arm_timer(Swap *s) {
172 if (s->timeout_usec <= 0) {
173 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
177 if (s->timer_event_source) {
178 r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec);
182 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
185 return sd_event_add_time(
186 UNIT(s)->manager->event,
187 &s->timer_event_source,
189 now(CLOCK_MONOTONIC) + s->timeout_usec, 0,
190 swap_dispatch_timer, s);
193 static int swap_add_device_links(Swap *s) {
199 if (!s->from_fragment)
202 if (is_device_path(s->what))
203 return unit_add_node_link(UNIT(s), s->what, UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
205 /* File based swap devices need to be ordered after
206 * systemd-remount-fs.service, since they might need a
207 * writable file system. */
208 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
211 static int swap_add_default_dependencies(Swap *s) {
216 if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
219 if (detect_container(NULL) > 0)
222 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
226 if (!s->from_fragment)
227 /* The swap unit can either be for an alternative device name, in which
228 * case we don't need to add the dependency on swap.target because this unit
229 * is following a different unit which will have this dependency added,
230 * or it can be derived from /proc/swaps, in which case it was started
231 * manually, and should not become a dependency of swap.target. */
234 return unit_add_two_dependencies_by_name_inverse(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SWAP_TARGET, NULL, true);
237 static int swap_verify(Swap *s) {
239 _cleanup_free_ char *e = NULL;
241 if (UNIT(s)->load_state != UNIT_LOADED)
244 e = unit_name_from_path(s->what, ".swap");
248 b = unit_has_name(UNIT(s), e);
250 log_error_unit(UNIT(s)->id, "%s: Value of \"What\" and unit name do not match, not loading.", UNIT(s)->id);
254 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
255 log_error_unit(UNIT(s)->id, "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.", UNIT(s)->id);
262 static int swap_load_devnode(Swap *s) {
263 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
269 if (stat(s->what, &st) < 0 || !S_ISBLK(st.st_mode))
272 d = udev_device_new_from_devnum(UNIT(s)->manager->udev, 'b', st.st_rdev);
276 p = udev_device_get_devnode(d);
280 return swap_set_devnode(s, p);
283 static int swap_load(Unit *u) {
288 assert(u->load_state == UNIT_STUB);
290 /* Load a .swap file */
291 r = unit_load_fragment_and_dropin_optional(u);
295 if (u->load_state == UNIT_LOADED) {
297 if (UNIT(s)->fragment_path)
298 s->from_fragment = true;
301 if (s->parameters_fragment.what)
302 s->what = strdup(s->parameters_fragment.what);
303 else if (s->parameters_proc_swaps.what)
304 s->what = strdup(s->parameters_proc_swaps.what);
306 s->what = unit_name_to_path(u->id);
312 path_kill_slashes(s->what);
314 if (!UNIT(s)->description) {
315 r = unit_set_description(u, s->what);
320 r = unit_require_mounts_for(UNIT(s), s->what);
324 r = swap_add_device_links(s);
328 r = swap_load_devnode(s);
332 r = unit_patch_contexts(u);
336 r = unit_add_exec_dependencies(u, &s->exec_context);
340 r = unit_add_default_slice(u, &s->cgroup_context);
344 if (UNIT(s)->default_dependencies) {
345 r = swap_add_default_dependencies(s);
351 return swap_verify(s);
354 static int swap_add_one(
357 const char *what_proc_swaps,
361 _cleanup_free_ char *e = NULL;
369 assert(what_proc_swaps);
371 e = unit_name_from_path(what, ".swap");
375 u = manager_get_unit(m, e);
378 SWAP(u)->from_proc_swaps &&
379 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
385 u = unit_new(m, sizeof(Swap));
389 r = unit_add_name(u, e);
393 SWAP(u)->what = strdup(what);
394 if (!SWAP(u)->what) {
399 unit_add_to_load_queue(u);
403 p = &SWAP(u)->parameters_proc_swaps;
406 p->what = strdup(what_proc_swaps);
414 SWAP(u)->is_active = true;
415 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
418 SWAP(u)->from_proc_swaps = true;
420 p->priority = priority;
422 unit_add_to_dbus_queue(u);
427 log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
435 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
436 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
437 struct udev_list_entry *item = NULL, *first = NULL;
444 r = swap_add_one(m, device, device, prio, set_flags);
448 /* If this is a block device, then let's add duplicates for
449 * all other names of this block device */
450 if (stat(device, &st) < 0 || !S_ISBLK(st.st_mode))
453 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
457 /* Add the main device node */
458 dn = udev_device_get_devnode(d);
459 if (dn && !streq(dn, device))
460 swap_add_one(m, dn, device, prio, set_flags);
462 /* Add additional units for all symlinks */
463 first = udev_device_get_devlinks_list_entry(d);
464 udev_list_entry_foreach(item, first) {
467 /* Don't bother with the /dev/block links */
468 p = udev_list_entry_get_name(item);
470 if (streq(p, device))
473 if (path_startswith(p, "/dev/block/"))
476 if (stat(p, &st) >= 0)
477 if (!S_ISBLK(st.st_mode) ||
478 st.st_rdev != udev_device_get_devnum(d))
481 swap_add_one(m, p, device, prio, set_flags);
487 static void swap_set_state(Swap *s, SwapState state) {
492 old_state = s->state;
495 if (state != SWAP_ACTIVATING &&
496 state != SWAP_ACTIVATING_SIGTERM &&
497 state != SWAP_ACTIVATING_SIGKILL &&
498 state != SWAP_ACTIVATING_DONE &&
499 state != SWAP_DEACTIVATING &&
500 state != SWAP_DEACTIVATING_SIGTERM &&
501 state != SWAP_DEACTIVATING_SIGKILL) {
502 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
503 swap_unwatch_control_pid(s);
504 s->control_command = NULL;
505 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
508 if (state != old_state)
509 log_debug_unit(UNIT(s)->id,
510 "%s changed %s -> %s",
512 swap_state_to_string(old_state),
513 swap_state_to_string(state));
515 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
518 static int swap_coldplug(Unit *u) {
520 SwapState new_state = SWAP_DEAD;
524 assert(s->state == SWAP_DEAD);
526 if (s->deserialized_state != s->state)
527 new_state = s->deserialized_state;
528 else if (s->from_proc_swaps)
529 new_state = SWAP_ACTIVE;
531 if (new_state == s->state)
534 if (new_state == SWAP_ACTIVATING ||
535 new_state == SWAP_ACTIVATING_SIGTERM ||
536 new_state == SWAP_ACTIVATING_SIGKILL ||
537 new_state == SWAP_ACTIVATING_DONE ||
538 new_state == SWAP_DEACTIVATING ||
539 new_state == SWAP_DEACTIVATING_SIGTERM ||
540 new_state == SWAP_DEACTIVATING_SIGKILL) {
542 if (s->control_pid <= 0)
545 r = unit_watch_pid(UNIT(s), s->control_pid);
549 r = swap_arm_timer(s);
554 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;
576 "%sFrom /proc/swaps: %s\n"
577 "%sFrom fragment: %s\n",
578 prefix, swap_state_to_string(s->state),
579 prefix, swap_result_to_string(s->result),
581 prefix, yes_no(s->from_proc_swaps),
582 prefix, yes_no(s->from_fragment));
585 fprintf(f, "%sDevice Node: %s\n", prefix, s->devnode);
592 prefix, strempty(p->options));
594 if (s->control_pid > 0)
596 "%sControl PID: "PID_FMT"\n",
597 prefix, s->control_pid);
599 exec_context_dump(&s->exec_context, f, prefix);
600 kill_context_dump(&s->kill_context, f, prefix);
603 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
606 ExecParameters exec_params = {
607 .apply_permissions = true,
608 .apply_chroot = true,
609 .apply_tty_stdin = true,
616 unit_realize_cgroup(UNIT(s));
618 r = unit_setup_exec_runtime(UNIT(s));
622 r = swap_arm_timer(s);
626 exec_params.environment = UNIT(s)->manager->environment;
627 exec_params.confirm_spawn = UNIT(s)->manager->confirm_spawn;
628 exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
629 exec_params.cgroup_path = UNIT(s)->cgroup_path;
630 exec_params.cgroup_delegate = s->cgroup_context.delegate;
631 exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
632 exec_params.unit_id = UNIT(s)->id;
642 r = unit_watch_pid(UNIT(s), pid);
644 /* FIXME: we need to do something here */
652 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
657 static void swap_enter_dead(Swap *s, SwapResult f) {
660 if (f != SWAP_SUCCESS)
663 exec_runtime_destroy(s->exec_runtime);
664 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
666 exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
668 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
671 static void swap_enter_active(Swap *s, SwapResult f) {
674 if (f != SWAP_SUCCESS)
677 swap_set_state(s, SWAP_ACTIVE);
680 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
685 if (f != SWAP_SUCCESS)
688 r = unit_kill_context(
691 (state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM) ?
692 KILL_KILL : KILL_TERMINATE,
700 r = swap_arm_timer(s);
704 swap_set_state(s, state);
705 } else if (state == SWAP_ACTIVATING_SIGTERM)
706 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_SUCCESS);
707 else if (state == SWAP_DEACTIVATING_SIGTERM)
708 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_SUCCESS);
710 swap_enter_dead(s, SWAP_SUCCESS);
715 log_warning_unit(UNIT(s)->id,
716 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
718 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
721 static int mount_find_pri(const char *options, int *ret) {
731 opt = mount_test_option(options, "pri");
735 opt += strlen("pri");
740 r = strtoul(opt + 1, &end, 10);
744 if (end == opt + 1 || (*end != ',' && *end != 0))
751 static int mount_find_discard(const char *options, char **ret) {
761 opt = mount_test_option(options, "discard");
765 opt += strlen("discard");
766 if (*opt == ',' || *opt == '\0')
772 len = strcspn(opt + 1, ",");
776 ans = strndup(opt + 1, len);
786 static void swap_enter_activating(Swap *s) {
787 _cleanup_free_ char *discard = NULL;
788 int r, priority = -1;
792 s->control_command_id = SWAP_EXEC_ACTIVATE;
793 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
795 if (s->from_fragment) {
796 mount_find_discard(s->parameters_fragment.options, &discard);
798 priority = s->parameters_fragment.priority;
800 mount_find_pri(s->parameters_fragment.options, &priority);
803 r = exec_command_set(s->control_command, "/sbin/swapon", NULL);
808 char p[DECIMAL_STR_MAX(int)];
810 sprintf(p, "%i", priority);
811 r = exec_command_append(s->control_command, "-p", p, NULL);
816 if (discard && !streq(discard, "none")) {
817 const char *discard_arg;
819 if (streq(discard, "all"))
820 discard_arg = "--discard";
822 discard_arg = strappenda("--discard=", discard);
824 r = exec_command_append(s->control_command, discard_arg, NULL);
829 r = exec_command_append(s->control_command, s->what, NULL);
833 swap_unwatch_control_pid(s);
835 r = swap_spawn(s, s->control_command, &s->control_pid);
839 swap_set_state(s, SWAP_ACTIVATING);
844 log_warning_unit(UNIT(s)->id,
845 "%s failed to run 'swapon' task: %s",
846 UNIT(s)->id, strerror(-r));
847 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
850 static void swap_enter_deactivating(Swap *s) {
855 s->control_command_id = SWAP_EXEC_DEACTIVATE;
856 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
858 r = exec_command_set(s->control_command,
865 swap_unwatch_control_pid(s);
867 r = swap_spawn(s, s->control_command, &s->control_pid);
871 swap_set_state(s, SWAP_DEACTIVATING);
876 log_warning_unit(UNIT(s)->id,
877 "%s failed to run 'swapoff' task: %s",
878 UNIT(s)->id, strerror(-r));
879 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
882 static int swap_start(Unit *u) {
887 /* We cannot fulfill this request right now, try again later
890 if (s->state == SWAP_DEACTIVATING ||
891 s->state == SWAP_DEACTIVATING_SIGTERM ||
892 s->state == SWAP_DEACTIVATING_SIGKILL ||
893 s->state == SWAP_ACTIVATING_SIGTERM ||
894 s->state == SWAP_ACTIVATING_SIGKILL)
897 if (s->state == SWAP_ACTIVATING)
900 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
902 if (detect_container(NULL) > 0)
905 s->result = SWAP_SUCCESS;
906 swap_enter_activating(s);
910 static int swap_stop(Unit *u) {
915 if (s->state == SWAP_DEACTIVATING ||
916 s->state == SWAP_DEACTIVATING_SIGTERM ||
917 s->state == SWAP_DEACTIVATING_SIGKILL ||
918 s->state == SWAP_ACTIVATING_SIGTERM ||
919 s->state == SWAP_ACTIVATING_SIGKILL)
922 assert(s->state == SWAP_ACTIVATING ||
923 s->state == SWAP_ACTIVATING_DONE ||
924 s->state == SWAP_ACTIVE);
926 if (detect_container(NULL) > 0)
929 swap_enter_deactivating(s);
933 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
940 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
941 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
943 if (s->control_pid > 0)
944 unit_serialize_item_format(u, f, "control-pid", PID_FMT, s->control_pid);
946 if (s->control_command_id >= 0)
947 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
952 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
958 if (streq(key, "state")) {
961 state = swap_state_from_string(value);
963 log_debug_unit(u->id, "Failed to parse state value %s", value);
965 s->deserialized_state = state;
966 } else if (streq(key, "result")) {
969 f = swap_result_from_string(value);
971 log_debug_unit(u->id, "Failed to parse result value %s", value);
972 else if (f != SWAP_SUCCESS)
974 } else if (streq(key, "control-pid")) {
977 if (parse_pid(value, &pid) < 0)
978 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
980 s->control_pid = pid;
982 } else if (streq(key, "control-command")) {
985 id = swap_exec_command_from_string(value);
987 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
989 s->control_command_id = id;
990 s->control_command = s->exec_command + id;
993 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
998 _pure_ static UnitActiveState swap_active_state(Unit *u) {
1001 return state_translation_table[SWAP(u)->state];
1004 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
1007 return swap_state_to_string(SWAP(u)->state);
1010 _pure_ static bool swap_check_gc(Unit *u) {
1015 return s->from_proc_swaps;
1018 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1025 if (pid != s->control_pid)
1030 if (is_clean_exit(code, status, NULL))
1032 else if (code == CLD_EXITED)
1033 f = SWAP_FAILURE_EXIT_CODE;
1034 else if (code == CLD_KILLED)
1035 f = SWAP_FAILURE_SIGNAL;
1036 else if (code == CLD_DUMPED)
1037 f = SWAP_FAILURE_CORE_DUMP;
1039 assert_not_reached("Unknown code");
1041 if (f != SWAP_SUCCESS)
1044 if (s->control_command) {
1045 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
1047 s->control_command = NULL;
1048 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
1051 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
1053 "%s swap process exited, code=%s status=%i",
1054 u->id, sigchld_code_to_string(code), status);
1058 case SWAP_ACTIVATING:
1059 case SWAP_ACTIVATING_DONE:
1060 case SWAP_ACTIVATING_SIGTERM:
1061 case SWAP_ACTIVATING_SIGKILL:
1063 if (f == SWAP_SUCCESS)
1064 swap_enter_active(s, f);
1066 swap_enter_dead(s, f);
1069 case SWAP_DEACTIVATING:
1070 case SWAP_DEACTIVATING_SIGKILL:
1071 case SWAP_DEACTIVATING_SIGTERM:
1073 swap_enter_dead(s, f);
1077 assert_not_reached("Uh, control process died at wrong time.");
1080 /* Notify clients about changed exit status */
1081 unit_add_to_dbus_queue(u);
1084 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1085 Swap *s = SWAP(userdata);
1088 assert(s->timer_event_source == source);
1092 case SWAP_ACTIVATING:
1093 case SWAP_ACTIVATING_DONE:
1094 log_warning_unit(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
1095 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1098 case SWAP_DEACTIVATING:
1099 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
1100 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1103 case SWAP_ACTIVATING_SIGTERM:
1104 if (s->kill_context.send_sigkill) {
1105 log_warning_unit(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
1106 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1108 log_warning_unit(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1109 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1113 case SWAP_DEACTIVATING_SIGTERM:
1114 if (s->kill_context.send_sigkill) {
1115 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
1116 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1118 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1119 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1123 case SWAP_ACTIVATING_SIGKILL:
1124 case SWAP_DEACTIVATING_SIGKILL:
1125 log_warning_unit(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
1126 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1130 assert_not_reached("Timeout at wrong time.");
1136 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1142 rewind(m->proc_swaps);
1144 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1147 _cleanup_free_ char *dev = NULL, *d = NULL;
1150 k = fscanf(m->proc_swaps,
1151 "%ms " /* device/file */
1152 "%*s " /* type of swap */
1153 "%*s " /* swap size */
1155 "%i\n", /* priority */
1161 log_warning("Failed to parse /proc/swaps:%u", i);
1169 k = swap_process_new_swap(m, d, prio, set_flags);
1177 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1178 Manager *m = userdata;
1183 assert(revents & EPOLLPRI);
1185 r = swap_load_proc_swaps(m, true);
1187 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1189 /* Reset flags, just in case, for late calls */
1190 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1191 Swap *swap = SWAP(u);
1193 swap->is_active = swap->just_activated = false;
1199 manager_dispatch_load_queue(m);
1201 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1202 Swap *swap = SWAP(u);
1204 if (!swap->is_active) {
1205 /* This has just been deactivated */
1207 swap_unset_proc_swaps(swap);
1209 switch (swap->state) {
1212 swap_enter_dead(swap, SWAP_SUCCESS);
1217 swap_set_state(swap, swap->state);
1221 } else if (swap->just_activated) {
1223 /* New swap entry */
1225 switch (swap->state) {
1229 swap_enter_active(swap, SWAP_SUCCESS);
1232 case SWAP_ACTIVATING:
1233 swap_set_state(swap, SWAP_ACTIVATING_DONE);
1237 /* Nothing really changed, but let's
1238 * issue an notification call
1239 * nonetheless, in case somebody is
1240 * waiting for this. */
1241 swap_set_state(swap, swap->state);
1246 /* Reset the flags for later calls */
1247 swap->is_active = swap->just_activated = false;
1253 static Unit *swap_following(Unit *u) {
1255 Swap *other, *first = NULL;
1259 /* If the user configured the swap through /etc/fstab or
1260 * a device unit, follow that. */
1262 if (s->from_fragment)
1265 LIST_FOREACH_AFTER(same_devnode, other, s)
1266 if (other->from_fragment)
1269 LIST_FOREACH_BEFORE(same_devnode, other, s)
1270 if (other->from_fragment)
1273 /* Otherwise make everybody follow the unit that's named after
1274 * the swap device in the kernel */
1276 if (streq_ptr(s->what, s->devnode))
1279 LIST_FOREACH_AFTER(same_devnode, other, s)
1280 if (streq_ptr(other->what, other->devnode))
1283 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1284 if (streq_ptr(other->what, other->devnode))
1290 /* Fall back to the first on the list */
1294 static int swap_following_set(Unit *u, Set **_set) {
1295 Swap *s = SWAP(u), *other;
1302 if (LIST_JUST_US(same_devnode, s)) {
1307 set = set_new(NULL);
1311 LIST_FOREACH_AFTER(same_devnode, other, s) {
1312 r = set_put(set, other);
1317 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1318 r = set_put(set, other);
1331 static void swap_shutdown(Manager *m) {
1334 m->swap_event_source = sd_event_source_unref(m->swap_event_source);
1336 if (m->proc_swaps) {
1337 fclose(m->proc_swaps);
1338 m->proc_swaps = NULL;
1341 hashmap_free(m->swaps_by_devnode);
1342 m->swaps_by_devnode = NULL;
1345 static int swap_enumerate(Manager *m) {
1350 if (!m->proc_swaps) {
1351 m->proc_swaps = fopen("/proc/swaps", "re");
1353 return errno == ENOENT ? 0 : -errno;
1355 r = sd_event_add_io(m->event, &m->swap_event_source, fileno(m->proc_swaps), EPOLLPRI, swap_dispatch_io, m);
1359 /* Dispatch this before we dispatch SIGCHLD, so that
1360 * we always get the events from /proc/swaps before
1361 * the SIGCHLD of /sbin/swapon. */
1362 r = sd_event_source_set_priority(m->swap_event_source, -10);
1367 r = swap_load_proc_swaps(m, false);
1378 int swap_process_new_device(Manager *m, struct udev_device *dev) {
1379 struct udev_list_entry *item = NULL, *first = NULL;
1380 _cleanup_free_ char *e = NULL;
1388 dn = udev_device_get_devnode(dev);
1392 e = unit_name_from_path(dn, ".swap");
1396 s = hashmap_get(m->units, e);
1398 r = swap_set_devnode(s, dn);
1400 first = udev_device_get_devlinks_list_entry(dev);
1401 udev_list_entry_foreach(item, first) {
1402 _cleanup_free_ char *n = NULL;
1404 n = unit_name_from_path(udev_list_entry_get_name(item), ".swap");
1408 s = hashmap_get(m->units, n);
1412 q = swap_set_devnode(s, dn);
1421 int swap_process_removed_device(Manager *m, struct udev_device *dev) {
1426 dn = udev_device_get_devnode(dev);
1430 while ((s = hashmap_get(m->swaps_by_devnode, dn))) {
1433 q = swap_set_devnode(s, NULL);
1441 static void swap_reset_failed(Unit *u) {
1446 if (s->state == SWAP_FAILED)
1447 swap_set_state(s, SWAP_DEAD);
1449 s->result = SWAP_SUCCESS;
1452 static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1453 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1456 static int swap_get_timeout(Unit *u, uint64_t *timeout) {
1460 if (!s->timer_event_source)
1463 r = sd_event_source_get_time(s->timer_event_source, timeout);
1470 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1471 [SWAP_DEAD] = "dead",
1472 [SWAP_ACTIVATING] = "activating",
1473 [SWAP_ACTIVATING_DONE] = "activating-done",
1474 [SWAP_ACTIVE] = "active",
1475 [SWAP_DEACTIVATING] = "deactivating",
1476 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1477 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1478 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1479 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1480 [SWAP_FAILED] = "failed"
1483 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1485 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1486 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1487 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1490 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1492 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1493 [SWAP_SUCCESS] = "success",
1494 [SWAP_FAILURE_RESOURCES] = "resources",
1495 [SWAP_FAILURE_TIMEOUT] = "timeout",
1496 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1497 [SWAP_FAILURE_SIGNAL] = "signal",
1498 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1501 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1503 const UnitVTable swap_vtable = {
1504 .object_size = sizeof(Swap),
1505 .exec_context_offset = offsetof(Swap, exec_context),
1506 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1507 .kill_context_offset = offsetof(Swap, kill_context),
1508 .exec_runtime_offset = offsetof(Swap, exec_runtime),
1514 .private_section = "Swap",
1517 .no_instances = true,
1523 .coldplug = swap_coldplug,
1527 .start = swap_start,
1532 .get_timeout = swap_get_timeout,
1534 .serialize = swap_serialize,
1535 .deserialize_item = swap_deserialize_item,
1537 .active_state = swap_active_state,
1538 .sub_state_to_string = swap_sub_state_to_string,
1540 .check_gc = swap_check_gc,
1542 .sigchld_event = swap_sigchld_event,
1544 .reset_failed = swap_reset_failed,
1546 .bus_interface = "org.freedesktop.systemd1.Swap",
1547 .bus_vtable = bus_swap_vtable,
1548 .bus_set_property = bus_swap_set_property,
1549 .bus_commit_properties = bus_swap_commit_properties,
1551 .following = swap_following,
1552 .following_set = swap_following_set,
1554 .enumerate = swap_enumerate,
1555 .shutdown = swap_shutdown,
1557 .status_message_formats = {
1558 .starting_stopping = {
1559 [0] = "Activating swap %s...",
1560 [1] = "Deactivating swap %s...",
1562 .finished_start_job = {
1563 [JOB_DONE] = "Activated swap %s.",
1564 [JOB_FAILED] = "Failed to activate swap %s.",
1565 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1566 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1568 .finished_stop_job = {
1569 [JOB_DONE] = "Deactivated swap %s.",
1570 [JOB_FAILED] = "Failed deactivating swap %s.",
1571 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",