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.discard);
156 s->parameters_fragment.discard = 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, p->discard ?: "none");
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 void swap_enter_activating(Swap *s) {
748 s->control_command_id = SWAP_EXEC_ACTIVATE;
749 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
751 if (s->from_fragment) {
752 priority = s->parameters_fragment.priority;
753 discard = s->parameters_fragment.discard;
759 r = exec_command_set(s->control_command, "/sbin/swapon", NULL);
764 char p[DECIMAL_STR_MAX(int)];
766 sprintf(p, "%i", priority);
767 r = exec_command_append(s->control_command, "-p", p, NULL);
772 if (discard && !streq(discard, "none")) {
773 const char *discard_arg = "--discard";
775 if (!streq(discard, "all"))
776 discard_arg = strappenda("--discard=", discard);
778 r = exec_command_append(s->control_command, discard_arg, NULL);
783 r = exec_command_append(s->control_command, s->what, NULL);
787 swap_unwatch_control_pid(s);
789 r = swap_spawn(s, s->control_command, &s->control_pid);
793 swap_set_state(s, SWAP_ACTIVATING);
798 log_warning_unit(UNIT(s)->id,
799 "%s failed to run 'swapon' task: %s",
800 UNIT(s)->id, strerror(-r));
801 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
804 static void swap_enter_deactivating(Swap *s) {
809 s->control_command_id = SWAP_EXEC_DEACTIVATE;
810 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
812 r = exec_command_set(s->control_command,
819 swap_unwatch_control_pid(s);
821 r = swap_spawn(s, s->control_command, &s->control_pid);
825 swap_set_state(s, SWAP_DEACTIVATING);
830 log_warning_unit(UNIT(s)->id,
831 "%s failed to run 'swapoff' task: %s",
832 UNIT(s)->id, strerror(-r));
833 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
836 static int swap_start(Unit *u) {
841 /* We cannot fulfill this request right now, try again later
844 if (s->state == SWAP_DEACTIVATING ||
845 s->state == SWAP_DEACTIVATING_SIGTERM ||
846 s->state == SWAP_DEACTIVATING_SIGKILL ||
847 s->state == SWAP_ACTIVATING_SIGTERM ||
848 s->state == SWAP_ACTIVATING_SIGKILL)
851 if (s->state == SWAP_ACTIVATING)
854 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
856 if (detect_container(NULL) > 0)
859 s->result = SWAP_SUCCESS;
860 swap_enter_activating(s);
864 static int swap_stop(Unit *u) {
869 if (s->state == SWAP_DEACTIVATING ||
870 s->state == SWAP_DEACTIVATING_SIGTERM ||
871 s->state == SWAP_DEACTIVATING_SIGKILL ||
872 s->state == SWAP_ACTIVATING_SIGTERM ||
873 s->state == SWAP_ACTIVATING_SIGKILL)
876 assert(s->state == SWAP_ACTIVATING ||
877 s->state == SWAP_ACTIVATING_DONE ||
878 s->state == SWAP_ACTIVE);
880 if (detect_container(NULL) > 0)
883 swap_enter_deactivating(s);
887 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
894 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
895 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
897 if (s->control_pid > 0)
898 unit_serialize_item_format(u, f, "control-pid", PID_FMT, s->control_pid);
900 if (s->control_command_id >= 0)
901 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
906 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
912 if (streq(key, "state")) {
915 state = swap_state_from_string(value);
917 log_debug_unit(u->id, "Failed to parse state value %s", value);
919 s->deserialized_state = state;
920 } else if (streq(key, "result")) {
923 f = swap_result_from_string(value);
925 log_debug_unit(u->id, "Failed to parse result value %s", value);
926 else if (f != SWAP_SUCCESS)
928 } else if (streq(key, "control-pid")) {
931 if (parse_pid(value, &pid) < 0)
932 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
934 s->control_pid = pid;
936 } else if (streq(key, "control-command")) {
939 id = swap_exec_command_from_string(value);
941 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
943 s->control_command_id = id;
944 s->control_command = s->exec_command + id;
947 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
952 _pure_ static UnitActiveState swap_active_state(Unit *u) {
955 return state_translation_table[SWAP(u)->state];
958 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
961 return swap_state_to_string(SWAP(u)->state);
964 _pure_ static bool swap_check_gc(Unit *u) {
969 return s->from_proc_swaps;
972 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
979 if (pid != s->control_pid)
984 if (is_clean_exit(code, status, NULL))
986 else if (code == CLD_EXITED)
987 f = SWAP_FAILURE_EXIT_CODE;
988 else if (code == CLD_KILLED)
989 f = SWAP_FAILURE_SIGNAL;
990 else if (code == CLD_DUMPED)
991 f = SWAP_FAILURE_CORE_DUMP;
993 assert_not_reached("Unknown code");
995 if (f != SWAP_SUCCESS)
998 if (s->control_command) {
999 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
1001 s->control_command = NULL;
1002 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
1005 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
1007 "%s swap process exited, code=%s status=%i",
1008 u->id, sigchld_code_to_string(code), status);
1012 case SWAP_ACTIVATING:
1013 case SWAP_ACTIVATING_DONE:
1014 case SWAP_ACTIVATING_SIGTERM:
1015 case SWAP_ACTIVATING_SIGKILL:
1017 if (f == SWAP_SUCCESS)
1018 swap_enter_active(s, f);
1020 swap_enter_dead(s, f);
1023 case SWAP_DEACTIVATING:
1024 case SWAP_DEACTIVATING_SIGKILL:
1025 case SWAP_DEACTIVATING_SIGTERM:
1027 swap_enter_dead(s, f);
1031 assert_not_reached("Uh, control process died at wrong time.");
1034 /* Notify clients about changed exit status */
1035 unit_add_to_dbus_queue(u);
1038 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1039 Swap *s = SWAP(userdata);
1042 assert(s->timer_event_source == source);
1046 case SWAP_ACTIVATING:
1047 case SWAP_ACTIVATING_DONE:
1048 log_warning_unit(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
1049 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1052 case SWAP_DEACTIVATING:
1053 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
1054 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1057 case SWAP_ACTIVATING_SIGTERM:
1058 if (s->kill_context.send_sigkill) {
1059 log_warning_unit(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
1060 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1062 log_warning_unit(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1063 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1067 case SWAP_DEACTIVATING_SIGTERM:
1068 if (s->kill_context.send_sigkill) {
1069 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
1070 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1072 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1073 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1077 case SWAP_ACTIVATING_SIGKILL:
1078 case SWAP_DEACTIVATING_SIGKILL:
1079 log_warning_unit(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
1080 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1084 assert_not_reached("Timeout at wrong time.");
1090 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1096 rewind(m->proc_swaps);
1098 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1101 _cleanup_free_ char *dev = NULL, *d = NULL;
1104 k = fscanf(m->proc_swaps,
1105 "%ms " /* device/file */
1106 "%*s " /* type of swap */
1107 "%*s " /* swap size */
1109 "%i\n", /* priority */
1115 log_warning("Failed to parse /proc/swaps:%u", i);
1123 k = swap_process_new_swap(m, d, prio, set_flags);
1131 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1132 Manager *m = userdata;
1137 assert(revents & EPOLLPRI);
1139 r = swap_load_proc_swaps(m, true);
1141 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1143 /* Reset flags, just in case, for late calls */
1144 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1145 Swap *swap = SWAP(u);
1147 swap->is_active = swap->just_activated = false;
1153 manager_dispatch_load_queue(m);
1155 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1156 Swap *swap = SWAP(u);
1158 if (!swap->is_active) {
1159 /* This has just been deactivated */
1161 swap_unset_proc_swaps(swap);
1163 switch (swap->state) {
1166 swap_enter_dead(swap, SWAP_SUCCESS);
1171 swap_set_state(swap, swap->state);
1175 } else if (swap->just_activated) {
1177 /* New swap entry */
1179 switch (swap->state) {
1183 swap_enter_active(swap, SWAP_SUCCESS);
1186 case SWAP_ACTIVATING:
1187 swap_set_state(swap, SWAP_ACTIVATING_DONE);
1191 /* Nothing really changed, but let's
1192 * issue an notification call
1193 * nonetheless, in case somebody is
1194 * waiting for this. */
1195 swap_set_state(swap, swap->state);
1200 /* Reset the flags for later calls */
1201 swap->is_active = swap->just_activated = false;
1207 static Unit *swap_following(Unit *u) {
1209 Swap *other, *first = NULL;
1213 /* If the user configured the swap through /etc/fstab or
1214 * a device unit, follow that. */
1216 if (s->from_fragment)
1219 LIST_FOREACH_AFTER(same_devnode, other, s)
1220 if (other->from_fragment)
1223 LIST_FOREACH_BEFORE(same_devnode, other, s)
1224 if (other->from_fragment)
1227 /* Otherwise make everybody follow the unit that's named after
1228 * the swap device in the kernel */
1230 if (streq_ptr(s->what, s->devnode))
1233 LIST_FOREACH_AFTER(same_devnode, other, s)
1234 if (streq_ptr(other->what, other->devnode))
1237 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1238 if (streq_ptr(other->what, other->devnode))
1244 /* Fall back to the first on the list */
1248 static int swap_following_set(Unit *u, Set **_set) {
1249 Swap *s = SWAP(u), *other;
1256 if (LIST_JUST_US(same_devnode, s)) {
1261 set = set_new(NULL);
1265 LIST_FOREACH_AFTER(same_devnode, other, s) {
1266 r = set_put(set, other);
1271 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1272 r = set_put(set, other);
1285 static void swap_shutdown(Manager *m) {
1288 m->swap_event_source = sd_event_source_unref(m->swap_event_source);
1290 if (m->proc_swaps) {
1291 fclose(m->proc_swaps);
1292 m->proc_swaps = NULL;
1295 hashmap_free(m->swaps_by_devnode);
1296 m->swaps_by_devnode = NULL;
1299 static int swap_enumerate(Manager *m) {
1304 if (!m->proc_swaps) {
1305 m->proc_swaps = fopen("/proc/swaps", "re");
1307 return errno == ENOENT ? 0 : -errno;
1309 r = sd_event_add_io(m->event, &m->swap_event_source, fileno(m->proc_swaps), EPOLLPRI, swap_dispatch_io, m);
1313 /* Dispatch this before we dispatch SIGCHLD, so that
1314 * we always get the events from /proc/swaps before
1315 * the SIGCHLD of /sbin/swapon. */
1316 r = sd_event_source_set_priority(m->swap_event_source, -10);
1321 r = swap_load_proc_swaps(m, false);
1332 int swap_process_new_device(Manager *m, struct udev_device *dev) {
1333 struct udev_list_entry *item = NULL, *first = NULL;
1334 _cleanup_free_ char *e = NULL;
1342 dn = udev_device_get_devnode(dev);
1346 e = unit_name_from_path(dn, ".swap");
1350 s = hashmap_get(m->units, e);
1352 r = swap_set_devnode(s, dn);
1354 first = udev_device_get_devlinks_list_entry(dev);
1355 udev_list_entry_foreach(item, first) {
1356 _cleanup_free_ char *n = NULL;
1358 n = unit_name_from_path(udev_list_entry_get_name(item), ".swap");
1362 s = hashmap_get(m->units, n);
1366 q = swap_set_devnode(s, dn);
1375 int swap_process_removed_device(Manager *m, struct udev_device *dev) {
1380 dn = udev_device_get_devnode(dev);
1384 while ((s = hashmap_get(m->swaps_by_devnode, dn))) {
1387 q = swap_set_devnode(s, NULL);
1395 static void swap_reset_failed(Unit *u) {
1400 if (s->state == SWAP_FAILED)
1401 swap_set_state(s, SWAP_DEAD);
1403 s->result = SWAP_SUCCESS;
1406 static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1407 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1410 static int swap_get_timeout(Unit *u, uint64_t *timeout) {
1414 if (!s->timer_event_source)
1417 r = sd_event_source_get_time(s->timer_event_source, timeout);
1424 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1425 [SWAP_DEAD] = "dead",
1426 [SWAP_ACTIVATING] = "activating",
1427 [SWAP_ACTIVATING_DONE] = "activating-done",
1428 [SWAP_ACTIVE] = "active",
1429 [SWAP_DEACTIVATING] = "deactivating",
1430 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1431 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1432 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1433 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1434 [SWAP_FAILED] = "failed"
1437 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1439 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1440 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1441 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1444 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1446 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1447 [SWAP_SUCCESS] = "success",
1448 [SWAP_FAILURE_RESOURCES] = "resources",
1449 [SWAP_FAILURE_TIMEOUT] = "timeout",
1450 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1451 [SWAP_FAILURE_SIGNAL] = "signal",
1452 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1455 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1457 const UnitVTable swap_vtable = {
1458 .object_size = sizeof(Swap),
1459 .exec_context_offset = offsetof(Swap, exec_context),
1460 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1461 .kill_context_offset = offsetof(Swap, kill_context),
1462 .exec_runtime_offset = offsetof(Swap, exec_runtime),
1468 .private_section = "Swap",
1471 .no_instances = true,
1477 .coldplug = swap_coldplug,
1481 .start = swap_start,
1486 .get_timeout = swap_get_timeout,
1488 .serialize = swap_serialize,
1489 .deserialize_item = swap_deserialize_item,
1491 .active_state = swap_active_state,
1492 .sub_state_to_string = swap_sub_state_to_string,
1494 .check_gc = swap_check_gc,
1496 .sigchld_event = swap_sigchld_event,
1498 .reset_failed = swap_reset_failed,
1500 .bus_interface = "org.freedesktop.systemd1.Swap",
1501 .bus_vtable = bus_swap_vtable,
1502 .bus_set_property = bus_swap_set_property,
1503 .bus_commit_properties = bus_swap_commit_properties,
1505 .following = swap_following,
1506 .following_set = swap_following_set,
1508 .enumerate = swap_enumerate,
1509 .shutdown = swap_shutdown,
1511 .status_message_formats = {
1512 .starting_stopping = {
1513 [0] = "Activating swap %s...",
1514 [1] = "Deactivating swap %s...",
1516 .finished_start_job = {
1517 [JOB_DONE] = "Activated swap %s.",
1518 [JOB_FAILED] = "Failed to activate swap %s.",
1519 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1520 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1522 .finished_stop_job = {
1523 [JOB_DONE] = "Deactivated swap %s.",
1524 [JOB_FAILED] = "Failed deactivating swap %s.",
1525 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",