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.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
631 exec_params.unit_id = UNIT(s)->id;
641 r = unit_watch_pid(UNIT(s), pid);
643 /* FIXME: we need to do something here */
651 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
656 static void swap_enter_dead(Swap *s, SwapResult f) {
659 if (f != SWAP_SUCCESS)
662 exec_runtime_destroy(s->exec_runtime);
663 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
665 exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
667 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
670 static void swap_enter_active(Swap *s, SwapResult f) {
673 if (f != SWAP_SUCCESS)
676 swap_set_state(s, SWAP_ACTIVE);
679 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
684 if (f != SWAP_SUCCESS)
687 r = unit_kill_context(
690 state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
698 r = swap_arm_timer(s);
702 swap_set_state(s, state);
703 } else if (state == SWAP_ACTIVATING_SIGTERM)
704 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_SUCCESS);
705 else if (state == SWAP_DEACTIVATING_SIGTERM)
706 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_SUCCESS);
708 swap_enter_dead(s, SWAP_SUCCESS);
713 log_warning_unit(UNIT(s)->id,
714 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
716 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
719 static int mount_find_pri(const char *options, int *ret) {
729 opt = mount_test_option(options, "pri");
733 opt += strlen("pri");
738 r = strtoul(opt + 1, &end, 10);
742 if (end == opt + 1 || (*end != ',' && *end != 0))
749 static int mount_find_discard(const char *options, char **ret) {
759 opt = mount_test_option(options, "discard");
763 opt += strlen("discard");
764 if (*opt == ',' || *opt == '\0')
770 len = strcspn(opt + 1, ",");
774 ans = strndup(opt + 1, len);
784 static void swap_enter_activating(Swap *s) {
785 _cleanup_free_ char *discard = NULL;
786 int r, priority = -1;
790 s->control_command_id = SWAP_EXEC_ACTIVATE;
791 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
793 if (s->from_fragment) {
794 mount_find_discard(s->parameters_fragment.options, &discard);
796 priority = s->parameters_fragment.priority;
798 mount_find_pri(s->parameters_fragment.options, &priority);
801 r = exec_command_set(s->control_command, "/sbin/swapon", NULL);
806 char p[DECIMAL_STR_MAX(int)];
808 sprintf(p, "%i", priority);
809 r = exec_command_append(s->control_command, "-p", p, NULL);
814 if (discard && !streq(discard, "none")) {
815 const char *discard_arg;
817 if (streq(discard, "all"))
818 discard_arg = "--discard";
820 discard_arg = strappenda("--discard=", discard);
822 r = exec_command_append(s->control_command, discard_arg, NULL);
827 r = exec_command_append(s->control_command, s->what, NULL);
831 swap_unwatch_control_pid(s);
833 r = swap_spawn(s, s->control_command, &s->control_pid);
837 swap_set_state(s, SWAP_ACTIVATING);
842 log_warning_unit(UNIT(s)->id,
843 "%s failed to run 'swapon' task: %s",
844 UNIT(s)->id, strerror(-r));
845 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
848 static void swap_enter_deactivating(Swap *s) {
853 s->control_command_id = SWAP_EXEC_DEACTIVATE;
854 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
856 r = exec_command_set(s->control_command,
863 swap_unwatch_control_pid(s);
865 r = swap_spawn(s, s->control_command, &s->control_pid);
869 swap_set_state(s, SWAP_DEACTIVATING);
874 log_warning_unit(UNIT(s)->id,
875 "%s failed to run 'swapoff' task: %s",
876 UNIT(s)->id, strerror(-r));
877 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
880 static int swap_start(Unit *u) {
885 /* We cannot fulfill this request right now, try again later
888 if (s->state == SWAP_DEACTIVATING ||
889 s->state == SWAP_DEACTIVATING_SIGTERM ||
890 s->state == SWAP_DEACTIVATING_SIGKILL ||
891 s->state == SWAP_ACTIVATING_SIGTERM ||
892 s->state == SWAP_ACTIVATING_SIGKILL)
895 if (s->state == SWAP_ACTIVATING)
898 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
900 if (detect_container(NULL) > 0)
903 s->result = SWAP_SUCCESS;
904 swap_enter_activating(s);
908 static int swap_stop(Unit *u) {
913 if (s->state == SWAP_DEACTIVATING ||
914 s->state == SWAP_DEACTIVATING_SIGTERM ||
915 s->state == SWAP_DEACTIVATING_SIGKILL ||
916 s->state == SWAP_ACTIVATING_SIGTERM ||
917 s->state == SWAP_ACTIVATING_SIGKILL)
920 assert(s->state == SWAP_ACTIVATING ||
921 s->state == SWAP_ACTIVATING_DONE ||
922 s->state == SWAP_ACTIVE);
924 if (detect_container(NULL) > 0)
927 swap_enter_deactivating(s);
931 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
938 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
939 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
941 if (s->control_pid > 0)
942 unit_serialize_item_format(u, f, "control-pid", PID_FMT, s->control_pid);
944 if (s->control_command_id >= 0)
945 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
950 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
956 if (streq(key, "state")) {
959 state = swap_state_from_string(value);
961 log_debug_unit(u->id, "Failed to parse state value %s", value);
963 s->deserialized_state = state;
964 } else if (streq(key, "result")) {
967 f = swap_result_from_string(value);
969 log_debug_unit(u->id, "Failed to parse result value %s", value);
970 else if (f != SWAP_SUCCESS)
972 } else if (streq(key, "control-pid")) {
975 if (parse_pid(value, &pid) < 0)
976 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
978 s->control_pid = pid;
980 } else if (streq(key, "control-command")) {
983 id = swap_exec_command_from_string(value);
985 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
987 s->control_command_id = id;
988 s->control_command = s->exec_command + id;
991 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
996 _pure_ static UnitActiveState swap_active_state(Unit *u) {
999 return state_translation_table[SWAP(u)->state];
1002 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
1005 return swap_state_to_string(SWAP(u)->state);
1008 _pure_ static bool swap_check_gc(Unit *u) {
1013 return s->from_proc_swaps;
1016 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1023 if (pid != s->control_pid)
1028 if (is_clean_exit(code, status, NULL))
1030 else if (code == CLD_EXITED)
1031 f = SWAP_FAILURE_EXIT_CODE;
1032 else if (code == CLD_KILLED)
1033 f = SWAP_FAILURE_SIGNAL;
1034 else if (code == CLD_DUMPED)
1035 f = SWAP_FAILURE_CORE_DUMP;
1037 assert_not_reached("Unknown code");
1039 if (f != SWAP_SUCCESS)
1042 if (s->control_command) {
1043 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
1045 s->control_command = NULL;
1046 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
1049 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
1051 "%s swap process exited, code=%s status=%i",
1052 u->id, sigchld_code_to_string(code), status);
1056 case SWAP_ACTIVATING:
1057 case SWAP_ACTIVATING_DONE:
1058 case SWAP_ACTIVATING_SIGTERM:
1059 case SWAP_ACTIVATING_SIGKILL:
1061 if (f == SWAP_SUCCESS)
1062 swap_enter_active(s, f);
1064 swap_enter_dead(s, f);
1067 case SWAP_DEACTIVATING:
1068 case SWAP_DEACTIVATING_SIGKILL:
1069 case SWAP_DEACTIVATING_SIGTERM:
1071 swap_enter_dead(s, f);
1075 assert_not_reached("Uh, control process died at wrong time.");
1078 /* Notify clients about changed exit status */
1079 unit_add_to_dbus_queue(u);
1082 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1083 Swap *s = SWAP(userdata);
1086 assert(s->timer_event_source == source);
1090 case SWAP_ACTIVATING:
1091 case SWAP_ACTIVATING_DONE:
1092 log_warning_unit(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
1093 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1096 case SWAP_DEACTIVATING:
1097 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
1098 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1101 case SWAP_ACTIVATING_SIGTERM:
1102 if (s->kill_context.send_sigkill) {
1103 log_warning_unit(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
1104 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1106 log_warning_unit(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1107 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1111 case SWAP_DEACTIVATING_SIGTERM:
1112 if (s->kill_context.send_sigkill) {
1113 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
1114 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1116 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1117 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1121 case SWAP_ACTIVATING_SIGKILL:
1122 case SWAP_DEACTIVATING_SIGKILL:
1123 log_warning_unit(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
1124 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1128 assert_not_reached("Timeout at wrong time.");
1134 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1140 rewind(m->proc_swaps);
1142 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1145 _cleanup_free_ char *dev = NULL, *d = NULL;
1148 k = fscanf(m->proc_swaps,
1149 "%ms " /* device/file */
1150 "%*s " /* type of swap */
1151 "%*s " /* swap size */
1153 "%i\n", /* priority */
1159 log_warning("Failed to parse /proc/swaps:%u", i);
1167 k = swap_process_new_swap(m, d, prio, set_flags);
1175 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1176 Manager *m = userdata;
1181 assert(revents & EPOLLPRI);
1183 r = swap_load_proc_swaps(m, true);
1185 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1187 /* Reset flags, just in case, for late calls */
1188 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1189 Swap *swap = SWAP(u);
1191 swap->is_active = swap->just_activated = false;
1197 manager_dispatch_load_queue(m);
1199 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1200 Swap *swap = SWAP(u);
1202 if (!swap->is_active) {
1203 /* This has just been deactivated */
1205 swap_unset_proc_swaps(swap);
1207 switch (swap->state) {
1210 swap_enter_dead(swap, SWAP_SUCCESS);
1215 swap_set_state(swap, swap->state);
1219 } else if (swap->just_activated) {
1221 /* New swap entry */
1223 switch (swap->state) {
1227 swap_enter_active(swap, SWAP_SUCCESS);
1230 case SWAP_ACTIVATING:
1231 swap_set_state(swap, SWAP_ACTIVATING_DONE);
1235 /* Nothing really changed, but let's
1236 * issue an notification call
1237 * nonetheless, in case somebody is
1238 * waiting for this. */
1239 swap_set_state(swap, swap->state);
1244 /* Reset the flags for later calls */
1245 swap->is_active = swap->just_activated = false;
1251 static Unit *swap_following(Unit *u) {
1253 Swap *other, *first = NULL;
1257 /* If the user configured the swap through /etc/fstab or
1258 * a device unit, follow that. */
1260 if (s->from_fragment)
1263 LIST_FOREACH_AFTER(same_devnode, other, s)
1264 if (other->from_fragment)
1267 LIST_FOREACH_BEFORE(same_devnode, other, s)
1268 if (other->from_fragment)
1271 /* Otherwise make everybody follow the unit that's named after
1272 * the swap device in the kernel */
1274 if (streq_ptr(s->what, s->devnode))
1277 LIST_FOREACH_AFTER(same_devnode, other, s)
1278 if (streq_ptr(other->what, other->devnode))
1281 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1282 if (streq_ptr(other->what, other->devnode))
1288 /* Fall back to the first on the list */
1292 static int swap_following_set(Unit *u, Set **_set) {
1293 Swap *s = SWAP(u), *other;
1300 if (LIST_JUST_US(same_devnode, s)) {
1305 set = set_new(NULL);
1309 LIST_FOREACH_AFTER(same_devnode, other, s) {
1310 r = set_put(set, other);
1315 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1316 r = set_put(set, other);
1329 static void swap_shutdown(Manager *m) {
1332 m->swap_event_source = sd_event_source_unref(m->swap_event_source);
1334 if (m->proc_swaps) {
1335 fclose(m->proc_swaps);
1336 m->proc_swaps = NULL;
1339 hashmap_free(m->swaps_by_devnode);
1340 m->swaps_by_devnode = NULL;
1343 static int swap_enumerate(Manager *m) {
1348 if (!m->proc_swaps) {
1349 m->proc_swaps = fopen("/proc/swaps", "re");
1351 return errno == ENOENT ? 0 : -errno;
1353 r = sd_event_add_io(m->event, &m->swap_event_source, fileno(m->proc_swaps), EPOLLPRI, swap_dispatch_io, m);
1357 /* Dispatch this before we dispatch SIGCHLD, so that
1358 * we always get the events from /proc/swaps before
1359 * the SIGCHLD of /sbin/swapon. */
1360 r = sd_event_source_set_priority(m->swap_event_source, -10);
1365 r = swap_load_proc_swaps(m, false);
1376 int swap_process_new_device(Manager *m, struct udev_device *dev) {
1377 struct udev_list_entry *item = NULL, *first = NULL;
1378 _cleanup_free_ char *e = NULL;
1386 dn = udev_device_get_devnode(dev);
1390 e = unit_name_from_path(dn, ".swap");
1394 s = hashmap_get(m->units, e);
1396 r = swap_set_devnode(s, dn);
1398 first = udev_device_get_devlinks_list_entry(dev);
1399 udev_list_entry_foreach(item, first) {
1400 _cleanup_free_ char *n = NULL;
1402 n = unit_name_from_path(udev_list_entry_get_name(item), ".swap");
1406 s = hashmap_get(m->units, n);
1410 q = swap_set_devnode(s, dn);
1419 int swap_process_removed_device(Manager *m, struct udev_device *dev) {
1424 dn = udev_device_get_devnode(dev);
1428 while ((s = hashmap_get(m->swaps_by_devnode, dn))) {
1431 q = swap_set_devnode(s, NULL);
1439 static void swap_reset_failed(Unit *u) {
1444 if (s->state == SWAP_FAILED)
1445 swap_set_state(s, SWAP_DEAD);
1447 s->result = SWAP_SUCCESS;
1450 static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1451 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1454 static int swap_get_timeout(Unit *u, uint64_t *timeout) {
1458 if (!s->timer_event_source)
1461 r = sd_event_source_get_time(s->timer_event_source, timeout);
1468 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1469 [SWAP_DEAD] = "dead",
1470 [SWAP_ACTIVATING] = "activating",
1471 [SWAP_ACTIVATING_DONE] = "activating-done",
1472 [SWAP_ACTIVE] = "active",
1473 [SWAP_DEACTIVATING] = "deactivating",
1474 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1475 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1476 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1477 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1478 [SWAP_FAILED] = "failed"
1481 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1483 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1484 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1485 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1488 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1490 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1491 [SWAP_SUCCESS] = "success",
1492 [SWAP_FAILURE_RESOURCES] = "resources",
1493 [SWAP_FAILURE_TIMEOUT] = "timeout",
1494 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1495 [SWAP_FAILURE_SIGNAL] = "signal",
1496 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1499 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1501 const UnitVTable swap_vtable = {
1502 .object_size = sizeof(Swap),
1503 .exec_context_offset = offsetof(Swap, exec_context),
1504 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1505 .kill_context_offset = offsetof(Swap, kill_context),
1506 .exec_runtime_offset = offsetof(Swap, exec_runtime),
1512 .private_section = "Swap",
1515 .no_instances = true,
1521 .coldplug = swap_coldplug,
1525 .start = swap_start,
1530 .get_timeout = swap_get_timeout,
1532 .serialize = swap_serialize,
1533 .deserialize_item = swap_deserialize_item,
1535 .active_state = swap_active_state,
1536 .sub_state_to_string = swap_sub_state_to_string,
1538 .check_gc = swap_check_gc,
1540 .sigchld_event = swap_sigchld_event,
1542 .reset_failed = swap_reset_failed,
1544 .bus_interface = "org.freedesktop.systemd1.Swap",
1545 .bus_vtable = bus_swap_vtable,
1546 .bus_set_property = bus_swap_set_property,
1547 .bus_commit_properties = bus_swap_commit_properties,
1549 .following = swap_following,
1550 .following_set = swap_following_set,
1552 .enumerate = swap_enumerate,
1553 .shutdown = swap_shutdown,
1555 .status_message_formats = {
1556 .starting_stopping = {
1557 [0] = "Activating swap %s...",
1558 [1] = "Deactivating swap %s...",
1560 .finished_start_job = {
1561 [JOB_DONE] = "Activated swap %s.",
1562 [JOB_FAILED] = "Failed to activate swap %s.",
1563 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1564 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1566 .finished_stop_job = {
1567 [JOB_DONE] = "Deactivated swap %s.",
1568 [JOB_FAILED] = "Failed deactivating swap %s.",
1569 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",