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 (is_device_path(s->what))
200 return unit_add_node_link(UNIT(s), s->what, UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
202 /* File based swap devices need to be ordered after
203 * systemd-remount-fs.service, since they might need a
204 * writable file system. */
205 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
208 static int swap_add_default_dependencies(Swap *s) {
213 if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
216 if (detect_container(NULL) > 0)
219 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
223 if (!s->from_fragment)
224 /* The swap unit can either be for an alternative device name, in which
225 * case we don't need to add the dependency on swap.target because this unit
226 * is following a different unit which will have this dependency added,
227 * or it can be derived from /proc/swaps, in which case it was started
228 * manually, and should not become a dependency of swap.target. */
231 return unit_add_two_dependencies_by_name_inverse(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SWAP_TARGET, NULL, true);
234 static int swap_verify(Swap *s) {
236 _cleanup_free_ char *e = NULL;
238 if (UNIT(s)->load_state != UNIT_LOADED)
241 e = unit_name_from_path(s->what, ".swap");
245 b = unit_has_name(UNIT(s), e);
247 log_error_unit(UNIT(s)->id, "%s: Value of \"What\" and unit name do not match, not loading.", UNIT(s)->id);
251 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
252 log_error_unit(UNIT(s)->id, "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.", UNIT(s)->id);
259 static int swap_load_devnode(Swap *s) {
260 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
266 if (stat(s->what, &st) < 0 || !S_ISBLK(st.st_mode))
269 d = udev_device_new_from_devnum(UNIT(s)->manager->udev, 'b', st.st_rdev);
273 p = udev_device_get_devnode(d);
277 return swap_set_devnode(s, p);
280 static int swap_load(Unit *u) {
285 assert(u->load_state == UNIT_STUB);
287 /* Load a .swap file */
288 r = unit_load_fragment_and_dropin_optional(u);
292 if (u->load_state == UNIT_LOADED) {
294 if (UNIT(s)->fragment_path)
295 s->from_fragment = true;
298 if (s->parameters_fragment.what)
299 s->what = strdup(s->parameters_fragment.what);
300 else if (s->parameters_proc_swaps.what)
301 s->what = strdup(s->parameters_proc_swaps.what);
303 s->what = unit_name_to_path(u->id);
309 path_kill_slashes(s->what);
311 if (!UNIT(s)->description) {
312 r = unit_set_description(u, s->what);
317 r = unit_require_mounts_for(UNIT(s), s->what);
321 r = swap_add_device_links(s);
325 r = swap_load_devnode(s);
329 r = unit_patch_contexts(u);
333 r = unit_add_exec_dependencies(u, &s->exec_context);
337 r = unit_add_default_slice(u, &s->cgroup_context);
341 if (UNIT(s)->default_dependencies) {
342 r = swap_add_default_dependencies(s);
348 return swap_verify(s);
351 static int swap_add_one(
354 const char *what_proc_swaps,
358 _cleanup_free_ char *e = NULL;
366 assert(what_proc_swaps);
368 e = unit_name_from_path(what, ".swap");
372 u = manager_get_unit(m, e);
375 SWAP(u)->from_proc_swaps &&
376 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
382 u = unit_new(m, sizeof(Swap));
386 r = unit_add_name(u, e);
390 SWAP(u)->what = strdup(what);
391 if (!SWAP(u)->what) {
396 unit_add_to_load_queue(u);
400 p = &SWAP(u)->parameters_proc_swaps;
403 p->what = strdup(what_proc_swaps);
411 SWAP(u)->is_active = true;
412 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
415 SWAP(u)->from_proc_swaps = true;
417 p->priority = priority;
419 unit_add_to_dbus_queue(u);
424 log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
432 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
433 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
434 struct udev_list_entry *item = NULL, *first = NULL;
441 r = swap_add_one(m, device, device, prio, set_flags);
445 /* If this is a block device, then let's add duplicates for
446 * all other names of this block device */
447 if (stat(device, &st) < 0 || !S_ISBLK(st.st_mode))
450 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
454 /* Add the main device node */
455 dn = udev_device_get_devnode(d);
456 if (dn && !streq(dn, device))
457 swap_add_one(m, dn, device, prio, set_flags);
459 /* Add additional units for all symlinks */
460 first = udev_device_get_devlinks_list_entry(d);
461 udev_list_entry_foreach(item, first) {
464 /* Don't bother with the /dev/block links */
465 p = udev_list_entry_get_name(item);
467 if (streq(p, device))
470 if (path_startswith(p, "/dev/block/"))
473 if (stat(p, &st) >= 0)
474 if (!S_ISBLK(st.st_mode) ||
475 st.st_rdev != udev_device_get_devnum(d))
478 swap_add_one(m, p, device, prio, set_flags);
484 static void swap_set_state(Swap *s, SwapState state) {
489 old_state = s->state;
492 if (state != SWAP_ACTIVATING &&
493 state != SWAP_ACTIVATING_SIGTERM &&
494 state != SWAP_ACTIVATING_SIGKILL &&
495 state != SWAP_ACTIVATING_DONE &&
496 state != SWAP_DEACTIVATING &&
497 state != SWAP_DEACTIVATING_SIGTERM &&
498 state != SWAP_DEACTIVATING_SIGKILL) {
499 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
500 swap_unwatch_control_pid(s);
501 s->control_command = NULL;
502 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
505 if (state != old_state)
506 log_debug_unit(UNIT(s)->id,
507 "%s changed %s -> %s",
509 swap_state_to_string(old_state),
510 swap_state_to_string(state));
512 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
515 static int swap_coldplug(Unit *u) {
517 SwapState new_state = SWAP_DEAD;
521 assert(s->state == SWAP_DEAD);
523 if (s->deserialized_state != s->state)
524 new_state = s->deserialized_state;
525 else if (s->from_proc_swaps)
526 new_state = SWAP_ACTIVE;
528 if (new_state == s->state)
531 if (new_state == SWAP_ACTIVATING ||
532 new_state == SWAP_ACTIVATING_SIGTERM ||
533 new_state == SWAP_ACTIVATING_SIGKILL ||
534 new_state == SWAP_ACTIVATING_DONE ||
535 new_state == SWAP_DEACTIVATING ||
536 new_state == SWAP_DEACTIVATING_SIGTERM ||
537 new_state == SWAP_DEACTIVATING_SIGKILL) {
539 if (s->control_pid <= 0)
542 r = unit_watch_pid(UNIT(s), s->control_pid);
546 r = swap_arm_timer(s);
551 swap_set_state(s, new_state);
555 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
562 if (s->from_proc_swaps)
563 p = &s->parameters_proc_swaps;
564 else if (s->from_fragment)
565 p = &s->parameters_fragment;
573 "%sFrom /proc/swaps: %s\n"
574 "%sFrom fragment: %s\n",
575 prefix, swap_state_to_string(s->state),
576 prefix, swap_result_to_string(s->result),
578 prefix, yes_no(s->from_proc_swaps),
579 prefix, yes_no(s->from_fragment));
582 fprintf(f, "%sDevice Node: %s\n", prefix, s->devnode);
589 prefix, strempty(p->options));
591 if (s->control_pid > 0)
593 "%sControl PID: "PID_FMT"\n",
594 prefix, s->control_pid);
596 exec_context_dump(&s->exec_context, f, prefix);
597 kill_context_dump(&s->kill_context, f, prefix);
600 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
603 ExecParameters exec_params = {
604 .apply_permissions = true,
605 .apply_chroot = true,
606 .apply_tty_stdin = true,
613 unit_realize_cgroup(UNIT(s));
615 r = unit_setup_exec_runtime(UNIT(s));
619 r = swap_arm_timer(s);
623 exec_params.environment = UNIT(s)->manager->environment;
624 exec_params.confirm_spawn = UNIT(s)->manager->confirm_spawn;
625 exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
626 exec_params.cgroup_path = UNIT(s)->cgroup_path;
627 exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
628 exec_params.unit_id = UNIT(s)->id;
638 r = unit_watch_pid(UNIT(s), pid);
640 /* FIXME: we need to do something here */
648 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
653 static void swap_enter_dead(Swap *s, SwapResult f) {
656 if (f != SWAP_SUCCESS)
659 exec_runtime_destroy(s->exec_runtime);
660 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
662 exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
664 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
667 static void swap_enter_active(Swap *s, SwapResult f) {
670 if (f != SWAP_SUCCESS)
673 swap_set_state(s, SWAP_ACTIVE);
676 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
681 if (f != SWAP_SUCCESS)
684 r = unit_kill_context(
687 state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
695 r = swap_arm_timer(s);
699 swap_set_state(s, state);
700 } else if (state == SWAP_ACTIVATING_SIGTERM)
701 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_SUCCESS);
702 else if (state == SWAP_DEACTIVATING_SIGTERM)
703 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_SUCCESS);
705 swap_enter_dead(s, SWAP_SUCCESS);
710 log_warning_unit(UNIT(s)->id,
711 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
713 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
716 static int mount_find_pri(const char *options, int *ret) {
726 opt = mount_test_option(options, "pri");
730 opt += strlen("pri");
735 r = strtoul(opt + 1, &end, 10);
739 if (end == opt + 1 || (*end != ',' && *end != 0))
746 static int mount_find_discard(const char *options, char **ret) {
756 opt = mount_test_option(options, "discard");
760 opt += strlen("discard");
761 if (*opt == ',' || *opt == '\0')
767 len = strcspn(opt + 1, ",");
771 ans = strndup(opt + 1, len);
781 static void swap_enter_activating(Swap *s) {
782 _cleanup_free_ char *discard = NULL;
783 int r, priority = -1;
787 s->control_command_id = SWAP_EXEC_ACTIVATE;
788 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
790 if (s->from_fragment) {
791 mount_find_discard(s->parameters_fragment.options, &discard);
793 priority = s->parameters_fragment.priority;
795 mount_find_pri(s->parameters_fragment.options, &priority);
798 r = exec_command_set(s->control_command, "/sbin/swapon", NULL);
803 char p[DECIMAL_STR_MAX(int)];
805 sprintf(p, "%i", priority);
806 r = exec_command_append(s->control_command, "-p", p, NULL);
811 if (discard && !streq(discard, "none")) {
812 const char *discard_arg;
814 if (streq(discard, "all"))
815 discard_arg = "--discard";
817 discard_arg = strappenda("--discard=", discard);
819 r = exec_command_append(s->control_command, discard_arg, NULL);
824 r = exec_command_append(s->control_command, s->what, NULL);
828 swap_unwatch_control_pid(s);
830 r = swap_spawn(s, s->control_command, &s->control_pid);
834 swap_set_state(s, SWAP_ACTIVATING);
839 log_warning_unit(UNIT(s)->id,
840 "%s failed to run 'swapon' task: %s",
841 UNIT(s)->id, strerror(-r));
842 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
845 static void swap_enter_deactivating(Swap *s) {
850 s->control_command_id = SWAP_EXEC_DEACTIVATE;
851 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
853 r = exec_command_set(s->control_command,
860 swap_unwatch_control_pid(s);
862 r = swap_spawn(s, s->control_command, &s->control_pid);
866 swap_set_state(s, SWAP_DEACTIVATING);
871 log_warning_unit(UNIT(s)->id,
872 "%s failed to run 'swapoff' task: %s",
873 UNIT(s)->id, strerror(-r));
874 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
877 static int swap_start(Unit *u) {
882 /* We cannot fulfill this request right now, try again later
885 if (s->state == SWAP_DEACTIVATING ||
886 s->state == SWAP_DEACTIVATING_SIGTERM ||
887 s->state == SWAP_DEACTIVATING_SIGKILL ||
888 s->state == SWAP_ACTIVATING_SIGTERM ||
889 s->state == SWAP_ACTIVATING_SIGKILL)
892 if (s->state == SWAP_ACTIVATING)
895 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
897 if (detect_container(NULL) > 0)
900 s->result = SWAP_SUCCESS;
901 swap_enter_activating(s);
905 static int swap_stop(Unit *u) {
910 if (s->state == SWAP_DEACTIVATING ||
911 s->state == SWAP_DEACTIVATING_SIGTERM ||
912 s->state == SWAP_DEACTIVATING_SIGKILL ||
913 s->state == SWAP_ACTIVATING_SIGTERM ||
914 s->state == SWAP_ACTIVATING_SIGKILL)
917 assert(s->state == SWAP_ACTIVATING ||
918 s->state == SWAP_ACTIVATING_DONE ||
919 s->state == SWAP_ACTIVE);
921 if (detect_container(NULL) > 0)
924 swap_enter_deactivating(s);
928 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
935 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
936 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
938 if (s->control_pid > 0)
939 unit_serialize_item_format(u, f, "control-pid", PID_FMT, s->control_pid);
941 if (s->control_command_id >= 0)
942 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
947 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
953 if (streq(key, "state")) {
956 state = swap_state_from_string(value);
958 log_debug_unit(u->id, "Failed to parse state value %s", value);
960 s->deserialized_state = state;
961 } else if (streq(key, "result")) {
964 f = swap_result_from_string(value);
966 log_debug_unit(u->id, "Failed to parse result value %s", value);
967 else if (f != SWAP_SUCCESS)
969 } else if (streq(key, "control-pid")) {
972 if (parse_pid(value, &pid) < 0)
973 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
975 s->control_pid = pid;
977 } else if (streq(key, "control-command")) {
980 id = swap_exec_command_from_string(value);
982 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
984 s->control_command_id = id;
985 s->control_command = s->exec_command + id;
988 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
993 _pure_ static UnitActiveState swap_active_state(Unit *u) {
996 return state_translation_table[SWAP(u)->state];
999 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
1002 return swap_state_to_string(SWAP(u)->state);
1005 _pure_ static bool swap_check_gc(Unit *u) {
1010 return s->from_proc_swaps;
1013 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1020 if (pid != s->control_pid)
1025 if (is_clean_exit(code, status, NULL))
1027 else if (code == CLD_EXITED)
1028 f = SWAP_FAILURE_EXIT_CODE;
1029 else if (code == CLD_KILLED)
1030 f = SWAP_FAILURE_SIGNAL;
1031 else if (code == CLD_DUMPED)
1032 f = SWAP_FAILURE_CORE_DUMP;
1034 assert_not_reached("Unknown code");
1036 if (f != SWAP_SUCCESS)
1039 if (s->control_command) {
1040 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
1042 s->control_command = NULL;
1043 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
1046 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
1048 "%s swap process exited, code=%s status=%i",
1049 u->id, sigchld_code_to_string(code), status);
1053 case SWAP_ACTIVATING:
1054 case SWAP_ACTIVATING_DONE:
1055 case SWAP_ACTIVATING_SIGTERM:
1056 case SWAP_ACTIVATING_SIGKILL:
1058 if (f == SWAP_SUCCESS)
1059 swap_enter_active(s, f);
1061 swap_enter_dead(s, f);
1064 case SWAP_DEACTIVATING:
1065 case SWAP_DEACTIVATING_SIGKILL:
1066 case SWAP_DEACTIVATING_SIGTERM:
1068 swap_enter_dead(s, f);
1072 assert_not_reached("Uh, control process died at wrong time.");
1075 /* Notify clients about changed exit status */
1076 unit_add_to_dbus_queue(u);
1079 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1080 Swap *s = SWAP(userdata);
1083 assert(s->timer_event_source == source);
1087 case SWAP_ACTIVATING:
1088 case SWAP_ACTIVATING_DONE:
1089 log_warning_unit(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
1090 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1093 case SWAP_DEACTIVATING:
1094 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
1095 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1098 case SWAP_ACTIVATING_SIGTERM:
1099 if (s->kill_context.send_sigkill) {
1100 log_warning_unit(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
1101 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1103 log_warning_unit(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1104 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1108 case SWAP_DEACTIVATING_SIGTERM:
1109 if (s->kill_context.send_sigkill) {
1110 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
1111 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1113 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1114 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1118 case SWAP_ACTIVATING_SIGKILL:
1119 case SWAP_DEACTIVATING_SIGKILL:
1120 log_warning_unit(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
1121 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1125 assert_not_reached("Timeout at wrong time.");
1131 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1137 rewind(m->proc_swaps);
1139 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1142 _cleanup_free_ char *dev = NULL, *d = NULL;
1145 k = fscanf(m->proc_swaps,
1146 "%ms " /* device/file */
1147 "%*s " /* type of swap */
1148 "%*s " /* swap size */
1150 "%i\n", /* priority */
1156 log_warning("Failed to parse /proc/swaps:%u", i);
1164 k = swap_process_new_swap(m, d, prio, set_flags);
1172 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1173 Manager *m = userdata;
1178 assert(revents & EPOLLPRI);
1180 r = swap_load_proc_swaps(m, true);
1182 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1184 /* Reset flags, just in case, for late calls */
1185 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1186 Swap *swap = SWAP(u);
1188 swap->is_active = swap->just_activated = false;
1194 manager_dispatch_load_queue(m);
1196 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1197 Swap *swap = SWAP(u);
1199 if (!swap->is_active) {
1200 /* This has just been deactivated */
1202 swap_unset_proc_swaps(swap);
1204 switch (swap->state) {
1207 swap_enter_dead(swap, SWAP_SUCCESS);
1212 swap_set_state(swap, swap->state);
1216 } else if (swap->just_activated) {
1218 /* New swap entry */
1220 switch (swap->state) {
1224 swap_enter_active(swap, SWAP_SUCCESS);
1227 case SWAP_ACTIVATING:
1228 swap_set_state(swap, SWAP_ACTIVATING_DONE);
1232 /* Nothing really changed, but let's
1233 * issue an notification call
1234 * nonetheless, in case somebody is
1235 * waiting for this. */
1236 swap_set_state(swap, swap->state);
1241 /* Reset the flags for later calls */
1242 swap->is_active = swap->just_activated = false;
1248 static Unit *swap_following(Unit *u) {
1250 Swap *other, *first = NULL;
1254 /* If the user configured the swap through /etc/fstab or
1255 * a device unit, follow that. */
1257 if (s->from_fragment)
1260 LIST_FOREACH_AFTER(same_devnode, other, s)
1261 if (other->from_fragment)
1264 LIST_FOREACH_BEFORE(same_devnode, other, s)
1265 if (other->from_fragment)
1268 /* Otherwise make everybody follow the unit that's named after
1269 * the swap device in the kernel */
1271 if (streq_ptr(s->what, s->devnode))
1274 LIST_FOREACH_AFTER(same_devnode, other, s)
1275 if (streq_ptr(other->what, other->devnode))
1278 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1279 if (streq_ptr(other->what, other->devnode))
1285 /* Fall back to the first on the list */
1289 static int swap_following_set(Unit *u, Set **_set) {
1290 Swap *s = SWAP(u), *other;
1297 if (LIST_JUST_US(same_devnode, s)) {
1302 set = set_new(NULL);
1306 LIST_FOREACH_AFTER(same_devnode, other, s) {
1307 r = set_put(set, other);
1312 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1313 r = set_put(set, other);
1326 static void swap_shutdown(Manager *m) {
1329 m->swap_event_source = sd_event_source_unref(m->swap_event_source);
1331 if (m->proc_swaps) {
1332 fclose(m->proc_swaps);
1333 m->proc_swaps = NULL;
1336 hashmap_free(m->swaps_by_devnode);
1337 m->swaps_by_devnode = NULL;
1340 static int swap_enumerate(Manager *m) {
1345 if (!m->proc_swaps) {
1346 m->proc_swaps = fopen("/proc/swaps", "re");
1348 return errno == ENOENT ? 0 : -errno;
1350 r = sd_event_add_io(m->event, &m->swap_event_source, fileno(m->proc_swaps), EPOLLPRI, swap_dispatch_io, m);
1354 /* Dispatch this before we dispatch SIGCHLD, so that
1355 * we always get the events from /proc/swaps before
1356 * the SIGCHLD of /sbin/swapon. */
1357 r = sd_event_source_set_priority(m->swap_event_source, -10);
1362 r = swap_load_proc_swaps(m, false);
1373 int swap_process_new_device(Manager *m, struct udev_device *dev) {
1374 struct udev_list_entry *item = NULL, *first = NULL;
1375 _cleanup_free_ char *e = NULL;
1383 dn = udev_device_get_devnode(dev);
1387 e = unit_name_from_path(dn, ".swap");
1391 s = hashmap_get(m->units, e);
1393 r = swap_set_devnode(s, dn);
1395 first = udev_device_get_devlinks_list_entry(dev);
1396 udev_list_entry_foreach(item, first) {
1397 _cleanup_free_ char *n = NULL;
1399 n = unit_name_from_path(udev_list_entry_get_name(item), ".swap");
1403 s = hashmap_get(m->units, n);
1407 q = swap_set_devnode(s, dn);
1416 int swap_process_removed_device(Manager *m, struct udev_device *dev) {
1421 dn = udev_device_get_devnode(dev);
1425 while ((s = hashmap_get(m->swaps_by_devnode, dn))) {
1428 q = swap_set_devnode(s, NULL);
1436 static void swap_reset_failed(Unit *u) {
1441 if (s->state == SWAP_FAILED)
1442 swap_set_state(s, SWAP_DEAD);
1444 s->result = SWAP_SUCCESS;
1447 static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1448 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1451 static int swap_get_timeout(Unit *u, uint64_t *timeout) {
1455 if (!s->timer_event_source)
1458 r = sd_event_source_get_time(s->timer_event_source, timeout);
1465 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1466 [SWAP_DEAD] = "dead",
1467 [SWAP_ACTIVATING] = "activating",
1468 [SWAP_ACTIVATING_DONE] = "activating-done",
1469 [SWAP_ACTIVE] = "active",
1470 [SWAP_DEACTIVATING] = "deactivating",
1471 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1472 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1473 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1474 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1475 [SWAP_FAILED] = "failed"
1478 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1480 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1481 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1482 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1485 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1487 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1488 [SWAP_SUCCESS] = "success",
1489 [SWAP_FAILURE_RESOURCES] = "resources",
1490 [SWAP_FAILURE_TIMEOUT] = "timeout",
1491 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1492 [SWAP_FAILURE_SIGNAL] = "signal",
1493 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1496 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1498 const UnitVTable swap_vtable = {
1499 .object_size = sizeof(Swap),
1500 .exec_context_offset = offsetof(Swap, exec_context),
1501 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1502 .kill_context_offset = offsetof(Swap, kill_context),
1503 .exec_runtime_offset = offsetof(Swap, exec_runtime),
1509 .private_section = "Swap",
1512 .no_instances = true,
1518 .coldplug = swap_coldplug,
1522 .start = swap_start,
1527 .get_timeout = swap_get_timeout,
1529 .serialize = swap_serialize,
1530 .deserialize_item = swap_deserialize_item,
1532 .active_state = swap_active_state,
1533 .sub_state_to_string = swap_sub_state_to_string,
1535 .check_gc = swap_check_gc,
1537 .sigchld_event = swap_sigchld_event,
1539 .reset_failed = swap_reset_failed,
1541 .bus_interface = "org.freedesktop.systemd1.Swap",
1542 .bus_vtable = bus_swap_vtable,
1543 .bus_set_property = bus_swap_set_property,
1544 .bus_commit_properties = bus_swap_commit_properties,
1546 .following = swap_following,
1547 .following_set = swap_following_set,
1549 .enumerate = swap_enumerate,
1550 .shutdown = swap_shutdown,
1552 .status_message_formats = {
1553 .starting_stopping = {
1554 [0] = "Activating swap %s...",
1555 [1] = "Deactivating swap %s...",
1557 .finished_start_job = {
1558 [JOB_DONE] = "Activated swap %s.",
1559 [JOB_FAILED] = "Failed to activate swap %s.",
1560 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1561 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1563 .finished_stop_job = {
1564 [JOB_DONE] = "Deactivated swap %s.",
1565 [JOB_FAILED] = "Failed deactivating swap %s.",
1566 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",