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) {
201 if (s->from_fragment)
202 p = &s->parameters_fragment;
206 if (is_device_path(s->what))
207 return unit_add_node_link(UNIT(s), s->what, !p->noauto && UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
209 /* File based swap devices need to be ordered after
210 * systemd-remount-fs.service, since they might need a
211 * writable file system. */
212 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
215 static int swap_add_default_dependencies(Swap *s) {
221 if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
224 if (detect_container(NULL) > 0)
227 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
231 if (!s->from_fragment)
232 /* The swap unit can either be for an alternative device name, in which
233 * case we don't need to add the dependency on swap.target because this unit
234 * is following a different unit which will have this dependency added,
235 * or it can be derived from /proc/swaps, in which case it was started
236 * manually, and should not become a dependency of swap.target. */
239 nofail = s->parameters_fragment.nofail;
240 noauto = s->parameters_fragment.noauto;
244 r = unit_add_dependency_by_name_inverse(UNIT(s), UNIT_WANTS, SPECIAL_SWAP_TARGET, NULL, true);
246 r = unit_add_two_dependencies_by_name_inverse(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SWAP_TARGET, NULL, true);
249 return r < 0 ? r : 0;
252 static int swap_verify(Swap *s) {
254 _cleanup_free_ char *e = NULL;
256 if (UNIT(s)->load_state != UNIT_LOADED)
259 e = unit_name_from_path(s->what, ".swap");
263 b = unit_has_name(UNIT(s), e);
265 log_error_unit(UNIT(s)->id, "%s: Value of \"What\" and unit name do not match, not loading.", UNIT(s)->id);
269 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
270 log_error_unit(UNIT(s)->id, "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.", UNIT(s)->id);
277 static int swap_load_devnode(Swap *s) {
278 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
284 if (stat(s->what, &st) < 0 || !S_ISBLK(st.st_mode))
287 d = udev_device_new_from_devnum(UNIT(s)->manager->udev, 'b', st.st_rdev);
291 p = udev_device_get_devnode(d);
295 return swap_set_devnode(s, p);
298 static int swap_load(Unit *u) {
303 assert(u->load_state == UNIT_STUB);
305 /* Load a .swap file */
306 r = unit_load_fragment_and_dropin_optional(u);
310 if (u->load_state == UNIT_LOADED) {
312 if (UNIT(s)->fragment_path)
313 s->from_fragment = true;
316 if (s->parameters_fragment.what)
317 s->what = strdup(s->parameters_fragment.what);
318 else if (s->parameters_proc_swaps.what)
319 s->what = strdup(s->parameters_proc_swaps.what);
321 s->what = unit_name_to_path(u->id);
327 path_kill_slashes(s->what);
329 if (!UNIT(s)->description) {
330 r = unit_set_description(u, s->what);
335 r = unit_require_mounts_for(UNIT(s), s->what);
339 r = swap_add_device_links(s);
343 r = swap_load_devnode(s);
347 r = unit_patch_contexts(u);
351 r = unit_add_exec_dependencies(u, &s->exec_context);
355 r = unit_add_default_slice(u, &s->cgroup_context);
359 if (UNIT(s)->default_dependencies) {
360 r = swap_add_default_dependencies(s);
366 return swap_verify(s);
369 static int swap_add_one(
372 const char *what_proc_swaps,
378 _cleanup_free_ char *e = NULL;
386 assert(what_proc_swaps);
388 e = unit_name_from_path(what, ".swap");
392 u = manager_get_unit(m, e);
395 SWAP(u)->from_proc_swaps &&
396 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
402 u = unit_new(m, sizeof(Swap));
406 r = unit_add_name(u, e);
410 SWAP(u)->what = strdup(what);
411 if (!SWAP(u)->what) {
416 unit_add_to_load_queue(u);
420 p = &SWAP(u)->parameters_proc_swaps;
423 p->what = strdup(what_proc_swaps);
431 SWAP(u)->is_active = true;
432 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
435 SWAP(u)->from_proc_swaps = true;
437 p->priority = priority;
441 unit_add_to_dbus_queue(u);
446 log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
454 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
455 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
456 struct udev_list_entry *item = NULL, *first = NULL;
463 r = swap_add_one(m, device, device, prio, false, false, set_flags);
467 /* If this is a block device, then let's add duplicates for
468 * all other names of this block device */
469 if (stat(device, &st) < 0 || !S_ISBLK(st.st_mode))
472 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
476 /* Add the main device node */
477 dn = udev_device_get_devnode(d);
478 if (dn && !streq(dn, device))
479 swap_add_one(m, dn, device, prio, false, false, set_flags);
481 /* Add additional units for all symlinks */
482 first = udev_device_get_devlinks_list_entry(d);
483 udev_list_entry_foreach(item, first) {
486 /* Don't bother with the /dev/block links */
487 p = udev_list_entry_get_name(item);
489 if (streq(p, device))
492 if (path_startswith(p, "/dev/block/"))
495 if (stat(p, &st) >= 0)
496 if (!S_ISBLK(st.st_mode) ||
497 st.st_rdev != udev_device_get_devnum(d))
500 swap_add_one(m, p, device, prio, false, false, set_flags);
506 static void swap_set_state(Swap *s, SwapState state) {
511 old_state = s->state;
514 if (state != SWAP_ACTIVATING &&
515 state != SWAP_ACTIVATING_SIGTERM &&
516 state != SWAP_ACTIVATING_SIGKILL &&
517 state != SWAP_ACTIVATING_DONE &&
518 state != SWAP_DEACTIVATING &&
519 state != SWAP_DEACTIVATING_SIGTERM &&
520 state != SWAP_DEACTIVATING_SIGKILL) {
521 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
522 swap_unwatch_control_pid(s);
523 s->control_command = NULL;
524 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
527 if (state != old_state)
528 log_debug_unit(UNIT(s)->id,
529 "%s changed %s -> %s",
531 swap_state_to_string(old_state),
532 swap_state_to_string(state));
534 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
537 static int swap_coldplug(Unit *u) {
539 SwapState new_state = SWAP_DEAD;
543 assert(s->state == SWAP_DEAD);
545 if (s->deserialized_state != s->state)
546 new_state = s->deserialized_state;
547 else if (s->from_proc_swaps)
548 new_state = SWAP_ACTIVE;
550 if (new_state == s->state)
553 if (new_state == SWAP_ACTIVATING ||
554 new_state == SWAP_ACTIVATING_SIGTERM ||
555 new_state == SWAP_ACTIVATING_SIGKILL ||
556 new_state == SWAP_ACTIVATING_DONE ||
557 new_state == SWAP_DEACTIVATING ||
558 new_state == SWAP_DEACTIVATING_SIGTERM ||
559 new_state == SWAP_DEACTIVATING_SIGKILL) {
561 if (s->control_pid <= 0)
564 r = unit_watch_pid(UNIT(s), s->control_pid);
568 r = swap_arm_timer(s);
573 swap_set_state(s, new_state);
577 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
584 if (s->from_proc_swaps)
585 p = &s->parameters_proc_swaps;
586 else if (s->from_fragment)
587 p = &s->parameters_fragment;
595 "%sFrom /proc/swaps: %s\n"
596 "%sFrom fragment: %s\n",
597 prefix, swap_state_to_string(s->state),
598 prefix, swap_result_to_string(s->result),
600 prefix, yes_no(s->from_proc_swaps),
601 prefix, yes_no(s->from_fragment));
604 fprintf(f, "%sDevice Node: %s\n", prefix, s->devnode);
613 prefix, yes_no(p->noauto),
614 prefix, yes_no(p->nofail),
615 prefix, strempty(p->options));
617 if (s->control_pid > 0)
619 "%sControl PID: "PID_FMT"\n",
620 prefix, s->control_pid);
622 exec_context_dump(&s->exec_context, f, prefix);
623 kill_context_dump(&s->kill_context, f, prefix);
626 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
629 ExecParameters exec_params = {
630 .apply_permissions = true,
631 .apply_chroot = true,
632 .apply_tty_stdin = true,
639 unit_realize_cgroup(UNIT(s));
641 r = unit_setup_exec_runtime(UNIT(s));
645 r = swap_arm_timer(s);
649 exec_params.environment = UNIT(s)->manager->environment;
650 exec_params.confirm_spawn = UNIT(s)->manager->confirm_spawn;
651 exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
652 exec_params.cgroup_path = UNIT(s)->cgroup_path;
653 exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
654 exec_params.unit_id = UNIT(s)->id;
664 r = unit_watch_pid(UNIT(s), pid);
666 /* FIXME: we need to do something here */
674 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
679 static void swap_enter_dead(Swap *s, SwapResult f) {
682 if (f != SWAP_SUCCESS)
685 exec_runtime_destroy(s->exec_runtime);
686 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
688 exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
690 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
693 static void swap_enter_active(Swap *s, SwapResult f) {
696 if (f != SWAP_SUCCESS)
699 swap_set_state(s, SWAP_ACTIVE);
702 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
707 if (f != SWAP_SUCCESS)
710 r = unit_kill_context(
713 state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
721 r = swap_arm_timer(s);
725 swap_set_state(s, state);
726 } else if (state == SWAP_ACTIVATING_SIGTERM)
727 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_SUCCESS);
728 else if (state == SWAP_DEACTIVATING_SIGTERM)
729 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_SUCCESS);
731 swap_enter_dead(s, SWAP_SUCCESS);
736 log_warning_unit(UNIT(s)->id,
737 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
739 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
742 static int mount_find_pri(const char *options, int *ret) {
752 opt = mount_test_option(options, "pri");
756 opt += strlen("pri");
761 r = strtoul(opt + 1, &end, 10);
765 if (end == opt + 1 || (*end != ',' && *end != 0))
772 static int mount_find_discard(const char *options, char **ret) {
782 opt = mount_test_option(options, "discard");
786 opt += strlen("discard");
787 if (*opt == ',' || *opt == '\0')
793 len = strcspn(opt + 1, ",");
797 ans = strndup(opt + 1, len);
807 static void swap_enter_activating(Swap *s) {
808 _cleanup_free_ char *discard = NULL;
809 int r, priority = -1;
813 s->control_command_id = SWAP_EXEC_ACTIVATE;
814 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
816 if (s->from_fragment) {
817 mount_find_discard(s->parameters_fragment.options, &discard);
819 priority = s->parameters_fragment.priority;
821 mount_find_pri(s->parameters_fragment.options, &priority);
824 r = exec_command_set(s->control_command, "/sbin/swapon", NULL);
829 char p[DECIMAL_STR_MAX(int)];
831 sprintf(p, "%i", priority);
832 r = exec_command_append(s->control_command, "-p", p, NULL);
837 if (discard && !streq(discard, "none")) {
838 const char *discard_arg;
840 if (streq(discard, "all"))
841 discard_arg = "--discard";
843 discard_arg = strappenda("--discard=", discard);
845 r = exec_command_append(s->control_command, discard_arg, NULL);
850 r = exec_command_append(s->control_command, s->what, NULL);
854 swap_unwatch_control_pid(s);
856 r = swap_spawn(s, s->control_command, &s->control_pid);
860 swap_set_state(s, SWAP_ACTIVATING);
865 log_warning_unit(UNIT(s)->id,
866 "%s failed to run 'swapon' task: %s",
867 UNIT(s)->id, strerror(-r));
868 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
871 static void swap_enter_deactivating(Swap *s) {
876 s->control_command_id = SWAP_EXEC_DEACTIVATE;
877 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
879 r = exec_command_set(s->control_command,
886 swap_unwatch_control_pid(s);
888 r = swap_spawn(s, s->control_command, &s->control_pid);
892 swap_set_state(s, SWAP_DEACTIVATING);
897 log_warning_unit(UNIT(s)->id,
898 "%s failed to run 'swapoff' task: %s",
899 UNIT(s)->id, strerror(-r));
900 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
903 static int swap_start(Unit *u) {
908 /* We cannot fulfill this request right now, try again later
911 if (s->state == SWAP_DEACTIVATING ||
912 s->state == SWAP_DEACTIVATING_SIGTERM ||
913 s->state == SWAP_DEACTIVATING_SIGKILL ||
914 s->state == SWAP_ACTIVATING_SIGTERM ||
915 s->state == SWAP_ACTIVATING_SIGKILL)
918 if (s->state == SWAP_ACTIVATING)
921 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
923 if (detect_container(NULL) > 0)
926 s->result = SWAP_SUCCESS;
927 swap_enter_activating(s);
931 static int swap_stop(Unit *u) {
936 if (s->state == SWAP_DEACTIVATING ||
937 s->state == SWAP_DEACTIVATING_SIGTERM ||
938 s->state == SWAP_DEACTIVATING_SIGKILL ||
939 s->state == SWAP_ACTIVATING_SIGTERM ||
940 s->state == SWAP_ACTIVATING_SIGKILL)
943 assert(s->state == SWAP_ACTIVATING ||
944 s->state == SWAP_ACTIVATING_DONE ||
945 s->state == SWAP_ACTIVE);
947 if (detect_container(NULL) > 0)
950 swap_enter_deactivating(s);
954 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
961 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
962 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
964 if (s->control_pid > 0)
965 unit_serialize_item_format(u, f, "control-pid", PID_FMT, s->control_pid);
967 if (s->control_command_id >= 0)
968 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
973 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
979 if (streq(key, "state")) {
982 state = swap_state_from_string(value);
984 log_debug_unit(u->id, "Failed to parse state value %s", value);
986 s->deserialized_state = state;
987 } else if (streq(key, "result")) {
990 f = swap_result_from_string(value);
992 log_debug_unit(u->id, "Failed to parse result value %s", value);
993 else if (f != SWAP_SUCCESS)
995 } else if (streq(key, "control-pid")) {
998 if (parse_pid(value, &pid) < 0)
999 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
1001 s->control_pid = pid;
1003 } else if (streq(key, "control-command")) {
1006 id = swap_exec_command_from_string(value);
1008 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
1010 s->control_command_id = id;
1011 s->control_command = s->exec_command + id;
1014 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
1019 _pure_ static UnitActiveState swap_active_state(Unit *u) {
1022 return state_translation_table[SWAP(u)->state];
1025 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
1028 return swap_state_to_string(SWAP(u)->state);
1031 _pure_ static bool swap_check_gc(Unit *u) {
1036 return s->from_proc_swaps;
1039 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1046 if (pid != s->control_pid)
1051 if (is_clean_exit(code, status, NULL))
1053 else if (code == CLD_EXITED)
1054 f = SWAP_FAILURE_EXIT_CODE;
1055 else if (code == CLD_KILLED)
1056 f = SWAP_FAILURE_SIGNAL;
1057 else if (code == CLD_DUMPED)
1058 f = SWAP_FAILURE_CORE_DUMP;
1060 assert_not_reached("Unknown code");
1062 if (f != SWAP_SUCCESS)
1065 if (s->control_command) {
1066 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
1068 s->control_command = NULL;
1069 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
1072 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
1074 "%s swap process exited, code=%s status=%i",
1075 u->id, sigchld_code_to_string(code), status);
1079 case SWAP_ACTIVATING:
1080 case SWAP_ACTIVATING_DONE:
1081 case SWAP_ACTIVATING_SIGTERM:
1082 case SWAP_ACTIVATING_SIGKILL:
1084 if (f == SWAP_SUCCESS)
1085 swap_enter_active(s, f);
1087 swap_enter_dead(s, f);
1090 case SWAP_DEACTIVATING:
1091 case SWAP_DEACTIVATING_SIGKILL:
1092 case SWAP_DEACTIVATING_SIGTERM:
1094 swap_enter_dead(s, f);
1098 assert_not_reached("Uh, control process died at wrong time.");
1101 /* Notify clients about changed exit status */
1102 unit_add_to_dbus_queue(u);
1105 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1106 Swap *s = SWAP(userdata);
1109 assert(s->timer_event_source == source);
1113 case SWAP_ACTIVATING:
1114 case SWAP_ACTIVATING_DONE:
1115 log_warning_unit(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
1116 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1119 case SWAP_DEACTIVATING:
1120 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
1121 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1124 case SWAP_ACTIVATING_SIGTERM:
1125 if (s->kill_context.send_sigkill) {
1126 log_warning_unit(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
1127 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1129 log_warning_unit(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1130 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1134 case SWAP_DEACTIVATING_SIGTERM:
1135 if (s->kill_context.send_sigkill) {
1136 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
1137 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1139 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1140 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1144 case SWAP_ACTIVATING_SIGKILL:
1145 case SWAP_DEACTIVATING_SIGKILL:
1146 log_warning_unit(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
1147 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1151 assert_not_reached("Timeout at wrong time.");
1157 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1163 rewind(m->proc_swaps);
1165 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1168 _cleanup_free_ char *dev = NULL, *d = NULL;
1171 k = fscanf(m->proc_swaps,
1172 "%ms " /* device/file */
1173 "%*s " /* type of swap */
1174 "%*s " /* swap size */
1176 "%i\n", /* priority */
1182 log_warning("Failed to parse /proc/swaps:%u", i);
1190 k = swap_process_new_swap(m, d, prio, set_flags);
1198 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1199 Manager *m = userdata;
1204 assert(revents & EPOLLPRI);
1206 r = swap_load_proc_swaps(m, true);
1208 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1210 /* Reset flags, just in case, for late calls */
1211 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1212 Swap *swap = SWAP(u);
1214 swap->is_active = swap->just_activated = false;
1220 manager_dispatch_load_queue(m);
1222 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1223 Swap *swap = SWAP(u);
1225 if (!swap->is_active) {
1226 /* This has just been deactivated */
1228 swap_unset_proc_swaps(swap);
1230 switch (swap->state) {
1233 swap_enter_dead(swap, SWAP_SUCCESS);
1238 swap_set_state(swap, swap->state);
1242 } else if (swap->just_activated) {
1244 /* New swap entry */
1246 switch (swap->state) {
1250 swap_enter_active(swap, SWAP_SUCCESS);
1253 case SWAP_ACTIVATING:
1254 swap_set_state(swap, SWAP_ACTIVATING_DONE);
1258 /* Nothing really changed, but let's
1259 * issue an notification call
1260 * nonetheless, in case somebody is
1261 * waiting for this. */
1262 swap_set_state(swap, swap->state);
1267 /* Reset the flags for later calls */
1268 swap->is_active = swap->just_activated = false;
1274 static Unit *swap_following(Unit *u) {
1276 Swap *other, *first = NULL;
1280 /* If the user configured the swap through /etc/fstab or
1281 * a device unit, follow that. */
1283 if (s->from_fragment)
1286 LIST_FOREACH_AFTER(same_devnode, other, s)
1287 if (other->from_fragment)
1290 LIST_FOREACH_BEFORE(same_devnode, other, s)
1291 if (other->from_fragment)
1294 /* Otherwise make everybody follow the unit that's named after
1295 * the swap device in the kernel */
1297 if (streq_ptr(s->what, s->devnode))
1300 LIST_FOREACH_AFTER(same_devnode, other, s)
1301 if (streq_ptr(other->what, other->devnode))
1304 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1305 if (streq_ptr(other->what, other->devnode))
1311 /* Fall back to the first on the list */
1315 static int swap_following_set(Unit *u, Set **_set) {
1316 Swap *s = SWAP(u), *other;
1323 if (LIST_JUST_US(same_devnode, s)) {
1328 set = set_new(NULL);
1332 LIST_FOREACH_AFTER(same_devnode, other, s) {
1333 r = set_put(set, other);
1338 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1339 r = set_put(set, other);
1352 static void swap_shutdown(Manager *m) {
1355 m->swap_event_source = sd_event_source_unref(m->swap_event_source);
1357 if (m->proc_swaps) {
1358 fclose(m->proc_swaps);
1359 m->proc_swaps = NULL;
1362 hashmap_free(m->swaps_by_devnode);
1363 m->swaps_by_devnode = NULL;
1366 static int swap_enumerate(Manager *m) {
1371 if (!m->proc_swaps) {
1372 m->proc_swaps = fopen("/proc/swaps", "re");
1374 return errno == ENOENT ? 0 : -errno;
1376 r = sd_event_add_io(m->event, &m->swap_event_source, fileno(m->proc_swaps), EPOLLPRI, swap_dispatch_io, m);
1380 /* Dispatch this before we dispatch SIGCHLD, so that
1381 * we always get the events from /proc/swaps before
1382 * the SIGCHLD of /sbin/swapon. */
1383 r = sd_event_source_set_priority(m->swap_event_source, -10);
1388 r = swap_load_proc_swaps(m, false);
1399 int swap_process_new_device(Manager *m, struct udev_device *dev) {
1400 struct udev_list_entry *item = NULL, *first = NULL;
1401 _cleanup_free_ char *e = NULL;
1409 dn = udev_device_get_devnode(dev);
1413 e = unit_name_from_path(dn, ".swap");
1417 s = hashmap_get(m->units, e);
1419 r = swap_set_devnode(s, dn);
1421 first = udev_device_get_devlinks_list_entry(dev);
1422 udev_list_entry_foreach(item, first) {
1423 _cleanup_free_ char *n = NULL;
1425 n = unit_name_from_path(udev_list_entry_get_name(item), ".swap");
1429 s = hashmap_get(m->units, n);
1433 q = swap_set_devnode(s, dn);
1442 int swap_process_removed_device(Manager *m, struct udev_device *dev) {
1447 dn = udev_device_get_devnode(dev);
1451 while ((s = hashmap_get(m->swaps_by_devnode, dn))) {
1454 q = swap_set_devnode(s, NULL);
1462 static void swap_reset_failed(Unit *u) {
1467 if (s->state == SWAP_FAILED)
1468 swap_set_state(s, SWAP_DEAD);
1470 s->result = SWAP_SUCCESS;
1473 static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1474 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1477 static int swap_get_timeout(Unit *u, uint64_t *timeout) {
1481 if (!s->timer_event_source)
1484 r = sd_event_source_get_time(s->timer_event_source, timeout);
1491 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1492 [SWAP_DEAD] = "dead",
1493 [SWAP_ACTIVATING] = "activating",
1494 [SWAP_ACTIVATING_DONE] = "activating-done",
1495 [SWAP_ACTIVE] = "active",
1496 [SWAP_DEACTIVATING] = "deactivating",
1497 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1498 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1499 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1500 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1501 [SWAP_FAILED] = "failed"
1504 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1506 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1507 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1508 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1511 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1513 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1514 [SWAP_SUCCESS] = "success",
1515 [SWAP_FAILURE_RESOURCES] = "resources",
1516 [SWAP_FAILURE_TIMEOUT] = "timeout",
1517 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1518 [SWAP_FAILURE_SIGNAL] = "signal",
1519 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1522 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1524 const UnitVTable swap_vtable = {
1525 .object_size = sizeof(Swap),
1526 .exec_context_offset = offsetof(Swap, exec_context),
1527 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1528 .kill_context_offset = offsetof(Swap, kill_context),
1529 .exec_runtime_offset = offsetof(Swap, exec_runtime),
1535 .private_section = "Swap",
1538 .no_instances = true,
1544 .coldplug = swap_coldplug,
1548 .start = swap_start,
1553 .get_timeout = swap_get_timeout,
1555 .serialize = swap_serialize,
1556 .deserialize_item = swap_deserialize_item,
1558 .active_state = swap_active_state,
1559 .sub_state_to_string = swap_sub_state_to_string,
1561 .check_gc = swap_check_gc,
1563 .sigchld_event = swap_sigchld_event,
1565 .reset_failed = swap_reset_failed,
1567 .bus_interface = "org.freedesktop.systemd1.Swap",
1568 .bus_vtable = bus_swap_vtable,
1569 .bus_set_property = bus_swap_set_property,
1570 .bus_commit_properties = bus_swap_commit_properties,
1572 .following = swap_following,
1573 .following_set = swap_following_set,
1575 .enumerate = swap_enumerate,
1576 .shutdown = swap_shutdown,
1578 .status_message_formats = {
1579 .starting_stopping = {
1580 [0] = "Activating swap %s...",
1581 [1] = "Deactivating swap %s...",
1583 .finished_start_job = {
1584 [JOB_DONE] = "Activated swap %s.",
1585 [JOB_FAILED] = "Failed to activate swap %s.",
1586 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1587 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1589 .finished_stop_job = {
1590 [JOB_DONE] = "Deactivated swap %s.",
1591 [JOB_FAILED] = "Failed deactivating swap %s.",
1592 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",