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_func, string_compare_func);
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 exec_context_init(&s->exec_context);
122 s->exec_context.std_output = u->manager->default_std_output;
123 s->exec_context.std_error = u->manager->default_std_error;
124 kill_context_init(&s->kill_context);
125 cgroup_context_init(&s->cgroup_context);
127 unit_cgroup_context_init_defaults(u, &s->cgroup_context);
129 s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
131 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
133 u->ignore_on_isolate = true;
136 static void swap_unwatch_control_pid(Swap *s) {
139 if (s->control_pid <= 0)
142 unit_unwatch_pid(UNIT(s), s->control_pid);
146 static void swap_done(Unit *u) {
151 swap_unset_proc_swaps(s);
152 swap_set_devnode(s, NULL);
157 free(s->parameters_fragment.what);
158 s->parameters_fragment.what = NULL;
160 cgroup_context_done(&s->cgroup_context);
161 exec_context_done(&s->exec_context);
162 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
163 exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
164 s->control_command = NULL;
166 swap_unwatch_control_pid(s);
168 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
171 static int swap_arm_timer(Swap *s) {
176 if (s->timeout_usec <= 0) {
177 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
181 if (s->timer_event_source) {
182 r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec);
186 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
189 return sd_event_add_monotonic(UNIT(s)->manager->event, &s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec, 0, swap_dispatch_timer, s);
192 static int swap_add_device_links(Swap *s) {
200 if (s->from_fragment)
201 p = &s->parameters_fragment;
205 if (is_device_path(s->what))
206 return unit_add_node_link(UNIT(s), s->what, !p->noauto && UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
208 /* File based swap devices need to be ordered after
209 * systemd-remount-fs.service, since they might need a
210 * writable file system. */
211 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
214 static int swap_add_default_dependencies(Swap *s) {
215 bool nofail = false, noauto = false;
220 if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
223 if (detect_container(NULL) > 0)
226 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
230 if (s->from_fragment) {
231 SwapParameters *p = &s->parameters_fragment;
239 r = unit_add_dependency_by_name_inverse(UNIT(s), UNIT_WANTS, SPECIAL_SWAP_TARGET, NULL, true);
241 r = unit_add_two_dependencies_by_name_inverse(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SWAP_TARGET, NULL, true);
249 static int swap_verify(Swap *s) {
251 _cleanup_free_ char *e = NULL;
253 if (UNIT(s)->load_state != UNIT_LOADED)
256 e = unit_name_from_path(s->what, ".swap");
260 b = unit_has_name(UNIT(s), e);
262 log_error_unit(UNIT(s)->id, "%s: Value of \"What\" and unit name do not match, not loading.", UNIT(s)->id);
266 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
267 log_error_unit(UNIT(s)->id, "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.", UNIT(s)->id);
274 static int swap_load_devnode(Swap *s) {
275 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
281 if (stat(s->what, &st) < 0 || !S_ISBLK(st.st_mode))
284 d = udev_device_new_from_devnum(UNIT(s)->manager->udev, 'b', st.st_rdev);
288 p = udev_device_get_devnode(d);
292 return swap_set_devnode(s, p);
295 static int swap_load(Unit *u) {
300 assert(u->load_state == UNIT_STUB);
302 /* Load a .swap file */
303 r = unit_load_fragment_and_dropin_optional(u);
307 if (u->load_state == UNIT_LOADED) {
308 r = unit_add_exec_dependencies(u, &s->exec_context);
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_add_default_slice(u);
351 if (UNIT(s)->default_dependencies) {
352 r = swap_add_default_dependencies(s);
357 r = unit_exec_context_patch_defaults(u, &s->exec_context);
362 return swap_verify(s);
365 static int swap_add_one(
368 const char *what_proc_swaps,
374 _cleanup_free_ char *e = NULL;
382 assert(what_proc_swaps);
384 e = unit_name_from_path(what, ".swap");
388 u = manager_get_unit(m, e);
391 SWAP(u)->from_proc_swaps &&
392 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
398 u = unit_new(m, sizeof(Swap));
402 r = unit_add_name(u, e);
406 SWAP(u)->what = strdup(what);
407 if (!SWAP(u)->what) {
412 unit_add_to_load_queue(u);
416 p = &SWAP(u)->parameters_proc_swaps;
419 p->what = strdup(what_proc_swaps);
427 SWAP(u)->is_active = true;
428 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
431 SWAP(u)->from_proc_swaps = true;
433 p->priority = priority;
437 unit_add_to_dbus_queue(u);
442 log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
450 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
451 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
452 struct udev_list_entry *item = NULL, *first = NULL;
459 r = swap_add_one(m, device, device, prio, false, false, set_flags);
463 /* If this is a block device, then let's add duplicates for
464 * all other names of this block device */
465 if (stat(device, &st) < 0 || !S_ISBLK(st.st_mode))
468 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
472 /* Add the main device node */
473 dn = udev_device_get_devnode(d);
474 if (dn && !streq(dn, device))
475 swap_add_one(m, dn, device, prio, false, false, set_flags);
477 /* Add additional units for all symlinks */
478 first = udev_device_get_devlinks_list_entry(d);
479 udev_list_entry_foreach(item, first) {
482 /* Don't bother with the /dev/block links */
483 p = udev_list_entry_get_name(item);
485 if (streq(p, device))
488 if (path_startswith(p, "/dev/block/"))
491 if (stat(p, &st) >= 0)
492 if (!S_ISBLK(st.st_mode) ||
493 st.st_rdev != udev_device_get_devnum(d))
496 swap_add_one(m, p, device, prio, false, false, set_flags);
502 static void swap_set_state(Swap *s, SwapState state) {
507 old_state = s->state;
510 if (state != SWAP_ACTIVATING &&
511 state != SWAP_ACTIVATING_SIGTERM &&
512 state != SWAP_ACTIVATING_SIGKILL &&
513 state != SWAP_ACTIVATING_DONE &&
514 state != SWAP_DEACTIVATING &&
515 state != SWAP_DEACTIVATING_SIGTERM &&
516 state != SWAP_DEACTIVATING_SIGKILL) {
517 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
518 swap_unwatch_control_pid(s);
519 s->control_command = NULL;
520 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
523 if (state != old_state)
524 log_debug_unit(UNIT(s)->id,
525 "%s changed %s -> %s",
527 swap_state_to_string(old_state),
528 swap_state_to_string(state));
530 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
533 static int swap_coldplug(Unit *u) {
535 SwapState new_state = SWAP_DEAD;
539 assert(s->state == SWAP_DEAD);
541 if (s->deserialized_state != s->state)
542 new_state = s->deserialized_state;
543 else if (s->from_proc_swaps)
544 new_state = SWAP_ACTIVE;
546 if (new_state == s->state)
549 if (new_state == SWAP_ACTIVATING ||
550 new_state == SWAP_ACTIVATING_SIGTERM ||
551 new_state == SWAP_ACTIVATING_SIGKILL ||
552 new_state == SWAP_ACTIVATING_DONE ||
553 new_state == SWAP_DEACTIVATING ||
554 new_state == SWAP_DEACTIVATING_SIGTERM ||
555 new_state == SWAP_DEACTIVATING_SIGKILL) {
557 if (s->control_pid <= 0)
560 r = unit_watch_pid(UNIT(s), s->control_pid);
564 r = swap_arm_timer(s);
569 swap_set_state(s, new_state);
573 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
580 if (s->from_proc_swaps)
581 p = &s->parameters_proc_swaps;
582 else if (s->from_fragment)
583 p = &s->parameters_fragment;
591 "%sFrom /proc/swaps: %s\n"
592 "%sFrom fragment: %s\n",
593 prefix, swap_state_to_string(s->state),
594 prefix, swap_result_to_string(s->result),
596 prefix, yes_no(s->from_proc_swaps),
597 prefix, yes_no(s->from_fragment));
600 fprintf(f, "%sDevice Node: %s\n", prefix, s->devnode);
608 prefix, yes_no(p->noauto),
609 prefix, yes_no(p->nofail));
611 if (s->control_pid > 0)
613 "%sControl PID: %lu\n",
614 prefix, (unsigned long) s->control_pid);
616 exec_context_dump(&s->exec_context, f, prefix);
617 kill_context_dump(&s->kill_context, f, prefix);
620 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
628 unit_realize_cgroup(UNIT(s));
630 r = unit_setup_exec_runtime(UNIT(s));
634 r = swap_arm_timer(s);
642 UNIT(s)->manager->environment,
646 UNIT(s)->manager->confirm_spawn,
647 UNIT(s)->manager->cgroup_supported,
648 UNIT(s)->cgroup_path,
649 manager_get_runtime_prefix(UNIT(s)->manager),
658 r = unit_watch_pid(UNIT(s), pid);
660 /* FIXME: we need to do something here */
668 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
673 static void swap_enter_dead(Swap *s, SwapResult f) {
676 if (f != SWAP_SUCCESS)
679 exec_runtime_destroy(s->exec_runtime);
680 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
682 exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
684 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
687 static void swap_enter_active(Swap *s, SwapResult f) {
690 if (f != SWAP_SUCCESS)
693 swap_set_state(s, SWAP_ACTIVE);
696 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
701 if (f != SWAP_SUCCESS)
704 r = unit_kill_context(
707 state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
715 r = swap_arm_timer(s);
719 swap_set_state(s, state);
720 } else if (state == SWAP_ACTIVATING_SIGTERM)
721 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_SUCCESS);
722 else if (state == SWAP_DEACTIVATING_SIGTERM)
723 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_SUCCESS);
725 swap_enter_dead(s, SWAP_SUCCESS);
730 log_warning_unit(UNIT(s)->id,
731 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
733 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
736 static void swap_enter_activating(Swap *s) {
741 s->control_command_id = SWAP_EXEC_ACTIVATE;
742 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
744 if (s->from_fragment)
745 priority = s->parameters_fragment.priority;
750 char p[DECIMAL_STR_MAX(int)];
752 sprintf(p, "%i", priority);
754 r = exec_command_set(
762 r = exec_command_set(
771 swap_unwatch_control_pid(s);
773 r = swap_spawn(s, s->control_command, &s->control_pid);
777 swap_set_state(s, SWAP_ACTIVATING);
782 log_warning_unit(UNIT(s)->id,
783 "%s failed to run 'swapon' task: %s",
784 UNIT(s)->id, strerror(-r));
785 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
788 static void swap_enter_deactivating(Swap *s) {
793 s->control_command_id = SWAP_EXEC_DEACTIVATE;
794 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
796 r = exec_command_set(s->control_command,
803 swap_unwatch_control_pid(s);
805 r = swap_spawn(s, s->control_command, &s->control_pid);
809 swap_set_state(s, SWAP_DEACTIVATING);
814 log_warning_unit(UNIT(s)->id,
815 "%s failed to run 'swapoff' task: %s",
816 UNIT(s)->id, strerror(-r));
817 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
820 static int swap_start(Unit *u) {
825 /* We cannot fulfill this request right now, try again later
828 if (s->state == SWAP_DEACTIVATING ||
829 s->state == SWAP_DEACTIVATING_SIGTERM ||
830 s->state == SWAP_DEACTIVATING_SIGKILL ||
831 s->state == SWAP_ACTIVATING_SIGTERM ||
832 s->state == SWAP_ACTIVATING_SIGKILL)
835 if (s->state == SWAP_ACTIVATING)
838 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
840 if (detect_container(NULL) > 0)
843 s->result = SWAP_SUCCESS;
844 swap_enter_activating(s);
848 static int swap_stop(Unit *u) {
853 if (s->state == SWAP_DEACTIVATING ||
854 s->state == SWAP_DEACTIVATING_SIGTERM ||
855 s->state == SWAP_DEACTIVATING_SIGKILL ||
856 s->state == SWAP_ACTIVATING_SIGTERM ||
857 s->state == SWAP_ACTIVATING_SIGKILL)
860 assert(s->state == SWAP_ACTIVATING ||
861 s->state == SWAP_ACTIVATING_DONE ||
862 s->state == SWAP_ACTIVE);
864 if (detect_container(NULL) > 0)
867 swap_enter_deactivating(s);
871 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
878 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
879 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
881 if (s->control_pid > 0)
882 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
884 if (s->control_command_id >= 0)
885 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
890 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
896 if (streq(key, "state")) {
899 state = swap_state_from_string(value);
901 log_debug_unit(u->id, "Failed to parse state value %s", value);
903 s->deserialized_state = state;
904 } else if (streq(key, "result")) {
907 f = swap_result_from_string(value);
909 log_debug_unit(u->id, "Failed to parse result value %s", value);
910 else if (f != SWAP_SUCCESS)
912 } else if (streq(key, "control-pid")) {
915 if (parse_pid(value, &pid) < 0)
916 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
918 s->control_pid = pid;
920 } else if (streq(key, "control-command")) {
923 id = swap_exec_command_from_string(value);
925 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
927 s->control_command_id = id;
928 s->control_command = s->exec_command + id;
931 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
936 _pure_ static UnitActiveState swap_active_state(Unit *u) {
939 return state_translation_table[SWAP(u)->state];
942 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
945 return swap_state_to_string(SWAP(u)->state);
948 _pure_ static bool swap_check_gc(Unit *u) {
953 return s->from_proc_swaps;
956 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
963 if (pid != s->control_pid)
968 if (is_clean_exit(code, status, NULL))
970 else if (code == CLD_EXITED)
971 f = SWAP_FAILURE_EXIT_CODE;
972 else if (code == CLD_KILLED)
973 f = SWAP_FAILURE_SIGNAL;
974 else if (code == CLD_DUMPED)
975 f = SWAP_FAILURE_CORE_DUMP;
977 assert_not_reached("Unknown code");
979 if (f != SWAP_SUCCESS)
982 if (s->control_command) {
983 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
985 s->control_command = NULL;
986 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
989 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
991 "%s swap process exited, code=%s status=%i",
992 u->id, sigchld_code_to_string(code), status);
996 case SWAP_ACTIVATING:
997 case SWAP_ACTIVATING_DONE:
998 case SWAP_ACTIVATING_SIGTERM:
999 case SWAP_ACTIVATING_SIGKILL:
1001 if (f == SWAP_SUCCESS)
1002 swap_enter_active(s, f);
1004 swap_enter_dead(s, f);
1007 case SWAP_DEACTIVATING:
1008 case SWAP_DEACTIVATING_SIGKILL:
1009 case SWAP_DEACTIVATING_SIGTERM:
1011 swap_enter_dead(s, f);
1015 assert_not_reached("Uh, control process died at wrong time.");
1018 /* Notify clients about changed exit status */
1019 unit_add_to_dbus_queue(u);
1022 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1023 Swap *s = SWAP(userdata);
1026 assert(s->timer_event_source == source);
1030 case SWAP_ACTIVATING:
1031 case SWAP_ACTIVATING_DONE:
1032 log_warning_unit(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
1033 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1036 case SWAP_DEACTIVATING:
1037 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
1038 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1041 case SWAP_ACTIVATING_SIGTERM:
1042 if (s->kill_context.send_sigkill) {
1043 log_warning_unit(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
1044 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1046 log_warning_unit(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1047 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1051 case SWAP_DEACTIVATING_SIGTERM:
1052 if (s->kill_context.send_sigkill) {
1053 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
1054 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1056 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1057 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1061 case SWAP_ACTIVATING_SIGKILL:
1062 case SWAP_DEACTIVATING_SIGKILL:
1063 log_warning_unit(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
1064 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1068 assert_not_reached("Timeout at wrong time.");
1074 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1080 rewind(m->proc_swaps);
1082 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1085 _cleanup_free_ char *dev = NULL, *d = NULL;
1088 k = fscanf(m->proc_swaps,
1089 "%ms " /* device/file */
1090 "%*s " /* type of swap */
1091 "%*s " /* swap size */
1093 "%i\n", /* priority */
1099 log_warning("Failed to parse /proc/swaps:%u", i);
1107 k = swap_process_new_swap(m, d, prio, set_flags);
1115 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1116 Manager *m = userdata;
1121 assert(revents & EPOLLPRI);
1123 r = swap_load_proc_swaps(m, true);
1125 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1127 /* Reset flags, just in case, for late calls */
1128 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1129 Swap *swap = SWAP(u);
1131 swap->is_active = swap->just_activated = false;
1137 manager_dispatch_load_queue(m);
1139 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1140 Swap *swap = SWAP(u);
1142 if (!swap->is_active) {
1143 /* This has just been deactivated */
1145 swap_unset_proc_swaps(swap);
1147 switch (swap->state) {
1150 swap_enter_dead(swap, SWAP_SUCCESS);
1155 swap_set_state(swap, swap->state);
1159 } else if (swap->just_activated) {
1161 /* New swap entry */
1163 switch (swap->state) {
1167 swap_enter_active(swap, SWAP_SUCCESS);
1170 case SWAP_ACTIVATING:
1171 swap_set_state(swap, SWAP_ACTIVATING_DONE);
1175 /* Nothing really changed, but let's
1176 * issue an notification call
1177 * nonetheless, in case somebody is
1178 * waiting for this. */
1179 swap_set_state(swap, swap->state);
1184 /* Reset the flags for later calls */
1185 swap->is_active = swap->just_activated = false;
1191 static Unit *swap_following(Unit *u) {
1193 Swap *other, *first = NULL;
1197 if (streq_ptr(s->what, s->devnode))
1200 /* Make everybody follow the unit that's named after the swap
1201 * device in the kernel */
1203 LIST_FOREACH_AFTER(same_devnode, other, s)
1204 if (streq_ptr(other->what, other->devnode))
1207 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1208 if (streq_ptr(other->what, other->devnode))
1217 static int swap_following_set(Unit *u, Set **_set) {
1218 Swap *s = SWAP(u), *other;
1225 if (LIST_JUST_US(same_devnode, s)) {
1230 set = set_new(NULL, NULL);
1234 LIST_FOREACH_AFTER(same_devnode, other, s) {
1235 r = set_put(set, other);
1240 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1241 r = set_put(set, other);
1254 static void swap_shutdown(Manager *m) {
1257 m->swap_event_source = sd_event_source_unref(m->swap_event_source);
1259 if (m->proc_swaps) {
1260 fclose(m->proc_swaps);
1261 m->proc_swaps = NULL;
1264 hashmap_free(m->swaps_by_devnode);
1265 m->swaps_by_devnode = NULL;
1268 static int swap_enumerate(Manager *m) {
1273 if (!m->proc_swaps) {
1274 m->proc_swaps = fopen("/proc/swaps", "re");
1276 return errno == ENOENT ? 0 : -errno;
1278 r = sd_event_add_io(m->event, &m->swap_event_source, fileno(m->proc_swaps), EPOLLPRI, swap_dispatch_io, m);
1282 /* Dispatch this before we dispatch SIGCHLD, so that
1283 * we always get the events from /proc/swaps before
1284 * the SIGCHLD of /sbin/swapon. */
1285 r = sd_event_source_set_priority(m->swap_event_source, -10);
1290 r = swap_load_proc_swaps(m, false);
1301 int swap_process_new_device(Manager *m, struct udev_device *dev) {
1302 struct udev_list_entry *item = NULL, *first = NULL;
1303 _cleanup_free_ char *e = NULL;
1311 dn = udev_device_get_devnode(dev);
1315 e = unit_name_from_path(dn, ".swap");
1319 s = hashmap_get(m->units, e);
1321 r = swap_set_devnode(s, dn);
1323 first = udev_device_get_devlinks_list_entry(dev);
1324 udev_list_entry_foreach(item, first) {
1325 _cleanup_free_ char *n = NULL;
1327 n = unit_name_from_path(udev_list_entry_get_name(item), ".swap");
1331 s = hashmap_get(m->units, n);
1335 q = swap_set_devnode(s, dn);
1344 int swap_process_removed_device(Manager *m, struct udev_device *dev) {
1349 dn = udev_device_get_devnode(dev);
1353 while ((s = hashmap_get(m->swaps_by_devnode, dn))) {
1356 q = swap_set_devnode(s, NULL);
1364 static void swap_reset_failed(Unit *u) {
1369 if (s->state == SWAP_FAILED)
1370 swap_set_state(s, SWAP_DEAD);
1372 s->result = SWAP_SUCCESS;
1375 static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1376 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1379 static int swap_get_timeout(Unit *u, uint64_t *timeout) {
1383 if (!s->timer_event_source)
1386 r = sd_event_source_get_time(s->timer_event_source, timeout);
1393 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1394 [SWAP_DEAD] = "dead",
1395 [SWAP_ACTIVATING] = "activating",
1396 [SWAP_ACTIVATING_DONE] = "activating-done",
1397 [SWAP_ACTIVE] = "active",
1398 [SWAP_DEACTIVATING] = "deactivating",
1399 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1400 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1401 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1402 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1403 [SWAP_FAILED] = "failed"
1406 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1408 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1409 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1410 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1413 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1415 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1416 [SWAP_SUCCESS] = "success",
1417 [SWAP_FAILURE_RESOURCES] = "resources",
1418 [SWAP_FAILURE_TIMEOUT] = "timeout",
1419 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1420 [SWAP_FAILURE_SIGNAL] = "signal",
1421 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1424 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1426 const UnitVTable swap_vtable = {
1427 .object_size = sizeof(Swap),
1428 .exec_context_offset = offsetof(Swap, exec_context),
1429 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1430 .kill_context_offset = offsetof(Swap, kill_context),
1431 .exec_runtime_offset = offsetof(Swap, exec_runtime),
1437 .private_section = "Swap",
1440 .no_instances = true,
1446 .coldplug = swap_coldplug,
1450 .start = swap_start,
1455 .get_timeout = swap_get_timeout,
1457 .serialize = swap_serialize,
1458 .deserialize_item = swap_deserialize_item,
1460 .active_state = swap_active_state,
1461 .sub_state_to_string = swap_sub_state_to_string,
1463 .check_gc = swap_check_gc,
1465 .sigchld_event = swap_sigchld_event,
1467 .reset_failed = swap_reset_failed,
1469 .bus_interface = "org.freedesktop.systemd1.Swap",
1470 .bus_vtable = bus_swap_vtable,
1471 .bus_set_property = bus_swap_set_property,
1472 .bus_commit_properties = bus_swap_commit_properties,
1474 .following = swap_following,
1475 .following_set = swap_following_set,
1477 .enumerate = swap_enumerate,
1478 .shutdown = swap_shutdown,
1480 .status_message_formats = {
1481 .starting_stopping = {
1482 [0] = "Activating swap %s...",
1483 [1] = "Deactivating swap %s...",
1485 .finished_start_job = {
1486 [JOB_DONE] = "Activated swap %s.",
1487 [JOB_FAILED] = "Failed to activate swap %s.",
1488 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1489 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1491 .finished_stop_job = {
1492 [JOB_DONE] = "Deactivated swap %s.",
1493 [JOB_FAILED] = "Failed deactivating swap %s.",
1494 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",