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) ?
691 KILL_KILL : KILL_TERMINATE,
699 r = swap_arm_timer(s);
703 swap_set_state(s, state);
704 } else if (state == SWAP_ACTIVATING_SIGTERM)
705 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_SUCCESS);
706 else if (state == SWAP_DEACTIVATING_SIGTERM)
707 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_SUCCESS);
709 swap_enter_dead(s, SWAP_SUCCESS);
714 log_warning_unit(UNIT(s)->id,
715 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
717 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
720 static int mount_find_pri(const char *options, int *ret) {
730 opt = mount_test_option(options, "pri");
734 opt += strlen("pri");
739 r = strtoul(opt + 1, &end, 10);
743 if (end == opt + 1 || (*end != ',' && *end != 0))
750 static int mount_find_discard(const char *options, char **ret) {
760 opt = mount_test_option(options, "discard");
764 opt += strlen("discard");
765 if (*opt == ',' || *opt == '\0')
771 len = strcspn(opt + 1, ",");
775 ans = strndup(opt + 1, len);
785 static void swap_enter_activating(Swap *s) {
786 _cleanup_free_ char *discard = NULL;
787 int r, priority = -1;
791 s->control_command_id = SWAP_EXEC_ACTIVATE;
792 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
794 if (s->from_fragment) {
795 mount_find_discard(s->parameters_fragment.options, &discard);
797 priority = s->parameters_fragment.priority;
799 mount_find_pri(s->parameters_fragment.options, &priority);
802 r = exec_command_set(s->control_command, "/sbin/swapon", NULL);
807 char p[DECIMAL_STR_MAX(int)];
809 sprintf(p, "%i", priority);
810 r = exec_command_append(s->control_command, "-p", p, NULL);
815 if (discard && !streq(discard, "none")) {
816 const char *discard_arg;
818 if (streq(discard, "all"))
819 discard_arg = "--discard";
821 discard_arg = strappenda("--discard=", discard);
823 r = exec_command_append(s->control_command, discard_arg, NULL);
828 r = exec_command_append(s->control_command, s->what, NULL);
832 swap_unwatch_control_pid(s);
834 r = swap_spawn(s, s->control_command, &s->control_pid);
838 swap_set_state(s, SWAP_ACTIVATING);
843 log_warning_unit(UNIT(s)->id,
844 "%s failed to run 'swapon' task: %s",
845 UNIT(s)->id, strerror(-r));
846 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
849 static void swap_enter_deactivating(Swap *s) {
854 s->control_command_id = SWAP_EXEC_DEACTIVATE;
855 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
857 r = exec_command_set(s->control_command,
864 swap_unwatch_control_pid(s);
866 r = swap_spawn(s, s->control_command, &s->control_pid);
870 swap_set_state(s, SWAP_DEACTIVATING);
875 log_warning_unit(UNIT(s)->id,
876 "%s failed to run 'swapoff' task: %s",
877 UNIT(s)->id, strerror(-r));
878 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
881 static int swap_start(Unit *u) {
886 /* We cannot fulfill this request right now, try again later
889 if (s->state == SWAP_DEACTIVATING ||
890 s->state == SWAP_DEACTIVATING_SIGTERM ||
891 s->state == SWAP_DEACTIVATING_SIGKILL ||
892 s->state == SWAP_ACTIVATING_SIGTERM ||
893 s->state == SWAP_ACTIVATING_SIGKILL)
896 if (s->state == SWAP_ACTIVATING)
899 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
901 if (detect_container(NULL) > 0)
904 s->result = SWAP_SUCCESS;
905 swap_enter_activating(s);
909 static int swap_stop(Unit *u) {
914 if (s->state == SWAP_DEACTIVATING ||
915 s->state == SWAP_DEACTIVATING_SIGTERM ||
916 s->state == SWAP_DEACTIVATING_SIGKILL ||
917 s->state == SWAP_ACTIVATING_SIGTERM ||
918 s->state == SWAP_ACTIVATING_SIGKILL)
921 assert(s->state == SWAP_ACTIVATING ||
922 s->state == SWAP_ACTIVATING_DONE ||
923 s->state == SWAP_ACTIVE);
925 if (detect_container(NULL) > 0)
928 swap_enter_deactivating(s);
932 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
939 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
940 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
942 if (s->control_pid > 0)
943 unit_serialize_item_format(u, f, "control-pid", PID_FMT, s->control_pid);
945 if (s->control_command_id >= 0)
946 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
951 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
957 if (streq(key, "state")) {
960 state = swap_state_from_string(value);
962 log_debug_unit(u->id, "Failed to parse state value %s", value);
964 s->deserialized_state = state;
965 } else if (streq(key, "result")) {
968 f = swap_result_from_string(value);
970 log_debug_unit(u->id, "Failed to parse result value %s", value);
971 else if (f != SWAP_SUCCESS)
973 } else if (streq(key, "control-pid")) {
976 if (parse_pid(value, &pid) < 0)
977 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
979 s->control_pid = pid;
981 } else if (streq(key, "control-command")) {
984 id = swap_exec_command_from_string(value);
986 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
988 s->control_command_id = id;
989 s->control_command = s->exec_command + id;
992 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
997 _pure_ static UnitActiveState swap_active_state(Unit *u) {
1000 return state_translation_table[SWAP(u)->state];
1003 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
1006 return swap_state_to_string(SWAP(u)->state);
1009 _pure_ static bool swap_check_gc(Unit *u) {
1014 return s->from_proc_swaps;
1017 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1024 if (pid != s->control_pid)
1029 if (is_clean_exit(code, status, NULL))
1031 else if (code == CLD_EXITED)
1032 f = SWAP_FAILURE_EXIT_CODE;
1033 else if (code == CLD_KILLED)
1034 f = SWAP_FAILURE_SIGNAL;
1035 else if (code == CLD_DUMPED)
1036 f = SWAP_FAILURE_CORE_DUMP;
1038 assert_not_reached("Unknown code");
1040 if (f != SWAP_SUCCESS)
1043 if (s->control_command) {
1044 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
1046 s->control_command = NULL;
1047 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
1050 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
1052 "%s swap process exited, code=%s status=%i",
1053 u->id, sigchld_code_to_string(code), status);
1057 case SWAP_ACTIVATING:
1058 case SWAP_ACTIVATING_DONE:
1059 case SWAP_ACTIVATING_SIGTERM:
1060 case SWAP_ACTIVATING_SIGKILL:
1062 if (f == SWAP_SUCCESS)
1063 swap_enter_active(s, f);
1065 swap_enter_dead(s, f);
1068 case SWAP_DEACTIVATING:
1069 case SWAP_DEACTIVATING_SIGKILL:
1070 case SWAP_DEACTIVATING_SIGTERM:
1072 swap_enter_dead(s, f);
1076 assert_not_reached("Uh, control process died at wrong time.");
1079 /* Notify clients about changed exit status */
1080 unit_add_to_dbus_queue(u);
1083 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1084 Swap *s = SWAP(userdata);
1087 assert(s->timer_event_source == source);
1091 case SWAP_ACTIVATING:
1092 case SWAP_ACTIVATING_DONE:
1093 log_warning_unit(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
1094 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1097 case SWAP_DEACTIVATING:
1098 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
1099 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1102 case SWAP_ACTIVATING_SIGTERM:
1103 if (s->kill_context.send_sigkill) {
1104 log_warning_unit(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
1105 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1107 log_warning_unit(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1108 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1112 case SWAP_DEACTIVATING_SIGTERM:
1113 if (s->kill_context.send_sigkill) {
1114 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
1115 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1117 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1118 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1122 case SWAP_ACTIVATING_SIGKILL:
1123 case SWAP_DEACTIVATING_SIGKILL:
1124 log_warning_unit(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
1125 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1129 assert_not_reached("Timeout at wrong time.");
1135 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1141 rewind(m->proc_swaps);
1143 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1146 _cleanup_free_ char *dev = NULL, *d = NULL;
1149 k = fscanf(m->proc_swaps,
1150 "%ms " /* device/file */
1151 "%*s " /* type of swap */
1152 "%*s " /* swap size */
1154 "%i\n", /* priority */
1160 log_warning("Failed to parse /proc/swaps:%u", i);
1168 k = swap_process_new_swap(m, d, prio, set_flags);
1176 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1177 Manager *m = userdata;
1182 assert(revents & EPOLLPRI);
1184 r = swap_load_proc_swaps(m, true);
1186 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1188 /* Reset flags, just in case, for late calls */
1189 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1190 Swap *swap = SWAP(u);
1192 swap->is_active = swap->just_activated = false;
1198 manager_dispatch_load_queue(m);
1200 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1201 Swap *swap = SWAP(u);
1203 if (!swap->is_active) {
1204 /* This has just been deactivated */
1206 swap_unset_proc_swaps(swap);
1208 switch (swap->state) {
1211 swap_enter_dead(swap, SWAP_SUCCESS);
1216 swap_set_state(swap, swap->state);
1220 } else if (swap->just_activated) {
1222 /* New swap entry */
1224 switch (swap->state) {
1228 swap_enter_active(swap, SWAP_SUCCESS);
1231 case SWAP_ACTIVATING:
1232 swap_set_state(swap, SWAP_ACTIVATING_DONE);
1236 /* Nothing really changed, but let's
1237 * issue an notification call
1238 * nonetheless, in case somebody is
1239 * waiting for this. */
1240 swap_set_state(swap, swap->state);
1245 /* Reset the flags for later calls */
1246 swap->is_active = swap->just_activated = false;
1252 static Unit *swap_following(Unit *u) {
1254 Swap *other, *first = NULL;
1258 /* If the user configured the swap through /etc/fstab or
1259 * a device unit, follow that. */
1261 if (s->from_fragment)
1264 LIST_FOREACH_AFTER(same_devnode, other, s)
1265 if (other->from_fragment)
1268 LIST_FOREACH_BEFORE(same_devnode, other, s)
1269 if (other->from_fragment)
1272 /* Otherwise make everybody follow the unit that's named after
1273 * the swap device in the kernel */
1275 if (streq_ptr(s->what, s->devnode))
1278 LIST_FOREACH_AFTER(same_devnode, other, s)
1279 if (streq_ptr(other->what, other->devnode))
1282 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1283 if (streq_ptr(other->what, other->devnode))
1289 /* Fall back to the first on the list */
1293 static int swap_following_set(Unit *u, Set **_set) {
1294 Swap *s = SWAP(u), *other;
1301 if (LIST_JUST_US(same_devnode, s)) {
1306 set = set_new(NULL);
1310 LIST_FOREACH_AFTER(same_devnode, other, s) {
1311 r = set_put(set, other);
1316 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1317 r = set_put(set, other);
1330 static void swap_shutdown(Manager *m) {
1333 m->swap_event_source = sd_event_source_unref(m->swap_event_source);
1335 if (m->proc_swaps) {
1336 fclose(m->proc_swaps);
1337 m->proc_swaps = NULL;
1340 hashmap_free(m->swaps_by_devnode);
1341 m->swaps_by_devnode = NULL;
1344 static int swap_enumerate(Manager *m) {
1349 if (!m->proc_swaps) {
1350 m->proc_swaps = fopen("/proc/swaps", "re");
1352 return errno == ENOENT ? 0 : -errno;
1354 r = sd_event_add_io(m->event, &m->swap_event_source, fileno(m->proc_swaps), EPOLLPRI, swap_dispatch_io, m);
1358 /* Dispatch this before we dispatch SIGCHLD, so that
1359 * we always get the events from /proc/swaps before
1360 * the SIGCHLD of /sbin/swapon. */
1361 r = sd_event_source_set_priority(m->swap_event_source, -10);
1366 r = swap_load_proc_swaps(m, false);
1377 int swap_process_new_device(Manager *m, struct udev_device *dev) {
1378 struct udev_list_entry *item = NULL, *first = NULL;
1379 _cleanup_free_ char *e = NULL;
1387 dn = udev_device_get_devnode(dev);
1391 e = unit_name_from_path(dn, ".swap");
1395 s = hashmap_get(m->units, e);
1397 r = swap_set_devnode(s, dn);
1399 first = udev_device_get_devlinks_list_entry(dev);
1400 udev_list_entry_foreach(item, first) {
1401 _cleanup_free_ char *n = NULL;
1403 n = unit_name_from_path(udev_list_entry_get_name(item), ".swap");
1407 s = hashmap_get(m->units, n);
1411 q = swap_set_devnode(s, dn);
1420 int swap_process_removed_device(Manager *m, struct udev_device *dev) {
1425 dn = udev_device_get_devnode(dev);
1429 while ((s = hashmap_get(m->swaps_by_devnode, dn))) {
1432 q = swap_set_devnode(s, NULL);
1440 static void swap_reset_failed(Unit *u) {
1445 if (s->state == SWAP_FAILED)
1446 swap_set_state(s, SWAP_DEAD);
1448 s->result = SWAP_SUCCESS;
1451 static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1452 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1455 static int swap_get_timeout(Unit *u, uint64_t *timeout) {
1459 if (!s->timer_event_source)
1462 r = sd_event_source_get_time(s->timer_event_source, timeout);
1469 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1470 [SWAP_DEAD] = "dead",
1471 [SWAP_ACTIVATING] = "activating",
1472 [SWAP_ACTIVATING_DONE] = "activating-done",
1473 [SWAP_ACTIVE] = "active",
1474 [SWAP_DEACTIVATING] = "deactivating",
1475 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1476 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1477 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1478 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1479 [SWAP_FAILED] = "failed"
1482 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1484 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1485 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1486 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1489 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1491 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1492 [SWAP_SUCCESS] = "success",
1493 [SWAP_FAILURE_RESOURCES] = "resources",
1494 [SWAP_FAILURE_TIMEOUT] = "timeout",
1495 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1496 [SWAP_FAILURE_SIGNAL] = "signal",
1497 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1500 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1502 const UnitVTable swap_vtable = {
1503 .object_size = sizeof(Swap),
1504 .exec_context_offset = offsetof(Swap, exec_context),
1505 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1506 .kill_context_offset = offsetof(Swap, kill_context),
1507 .exec_runtime_offset = offsetof(Swap, exec_runtime),
1513 .private_section = "Swap",
1516 .no_instances = true,
1522 .coldplug = swap_coldplug,
1526 .start = swap_start,
1531 .get_timeout = swap_get_timeout,
1533 .serialize = swap_serialize,
1534 .deserialize_item = swap_deserialize_item,
1536 .active_state = swap_active_state,
1537 .sub_state_to_string = swap_sub_state_to_string,
1539 .check_gc = swap_check_gc,
1541 .sigchld_event = swap_sigchld_event,
1543 .reset_failed = swap_reset_failed,
1545 .bus_interface = "org.freedesktop.systemd1.Swap",
1546 .bus_vtable = bus_swap_vtable,
1547 .bus_set_property = bus_swap_set_property,
1548 .bus_commit_properties = bus_swap_commit_properties,
1550 .following = swap_following,
1551 .following_set = swap_following_set,
1553 .enumerate = swap_enumerate,
1554 .shutdown = swap_shutdown,
1556 .status_message_formats = {
1557 .starting_stopping = {
1558 [0] = "Activating swap %s...",
1559 [1] = "Deactivating swap %s...",
1561 .finished_start_job = {
1562 [JOB_DONE] = "Activated swap %s.",
1563 [JOB_FAILED] = "Failed to activate swap %s.",
1564 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1565 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1567 .finished_stop_job = {
1568 [JOB_DONE] = "Deactivated swap %s.",
1569 [JOB_FAILED] = "Failed deactivating swap %s.",
1570 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",