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 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 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
156 exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
157 s->control_command = NULL;
159 swap_unwatch_control_pid(s);
161 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
164 static int swap_arm_timer(Swap *s) {
169 if (s->timeout_usec <= 0) {
170 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
174 if (s->timer_event_source) {
175 r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec);
179 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
182 return sd_event_add_time(
183 UNIT(s)->manager->event,
184 &s->timer_event_source,
186 now(CLOCK_MONOTONIC) + s->timeout_usec, 0,
187 swap_dispatch_timer, s);
190 static int swap_add_device_links(Swap *s) {
198 if (s->from_fragment)
199 p = &s->parameters_fragment;
203 if (is_device_path(s->what))
204 return unit_add_node_link(UNIT(s), s->what, !p->noauto && UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
206 /* File based swap devices need to be ordered after
207 * systemd-remount-fs.service, since they might need a
208 * writable file system. */
209 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
212 static int swap_add_default_dependencies(Swap *s) {
213 bool nofail = false, noauto = false;
218 if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
221 if (detect_container(NULL) > 0)
224 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
228 if (s->from_fragment) {
229 SwapParameters *p = &s->parameters_fragment;
237 r = unit_add_dependency_by_name_inverse(UNIT(s), UNIT_WANTS, SPECIAL_SWAP_TARGET, NULL, true);
239 r = unit_add_two_dependencies_by_name_inverse(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SWAP_TARGET, NULL, true);
247 static int swap_verify(Swap *s) {
249 _cleanup_free_ char *e = NULL;
251 if (UNIT(s)->load_state != UNIT_LOADED)
254 e = unit_name_from_path(s->what, ".swap");
258 b = unit_has_name(UNIT(s), e);
260 log_error_unit(UNIT(s)->id, "%s: Value of \"What\" and unit name do not match, not loading.", UNIT(s)->id);
264 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
265 log_error_unit(UNIT(s)->id, "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.", UNIT(s)->id);
272 static int swap_load_devnode(Swap *s) {
273 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
279 if (stat(s->what, &st) < 0 || !S_ISBLK(st.st_mode))
282 d = udev_device_new_from_devnum(UNIT(s)->manager->udev, 'b', st.st_rdev);
286 p = udev_device_get_devnode(d);
290 return swap_set_devnode(s, p);
293 static int swap_load(Unit *u) {
298 assert(u->load_state == UNIT_STUB);
300 /* Load a .swap file */
301 r = unit_load_fragment_and_dropin_optional(u);
305 if (u->load_state == UNIT_LOADED) {
307 if (UNIT(s)->fragment_path)
308 s->from_fragment = true;
311 if (s->parameters_fragment.what)
312 s->what = strdup(s->parameters_fragment.what);
313 else if (s->parameters_proc_swaps.what)
314 s->what = strdup(s->parameters_proc_swaps.what);
316 s->what = unit_name_to_path(u->id);
322 path_kill_slashes(s->what);
324 if (!UNIT(s)->description) {
325 r = unit_set_description(u, s->what);
330 r = unit_require_mounts_for(UNIT(s), s->what);
334 r = swap_add_device_links(s);
338 r = swap_load_devnode(s);
342 r = unit_patch_contexts(u);
346 r = unit_add_exec_dependencies(u, &s->exec_context);
350 r = unit_add_default_slice(u, &s->cgroup_context);
354 if (UNIT(s)->default_dependencies) {
355 r = swap_add_default_dependencies(s);
361 return swap_verify(s);
364 static int swap_add_one(
367 const char *what_proc_swaps,
373 _cleanup_free_ char *e = NULL;
381 assert(what_proc_swaps);
383 e = unit_name_from_path(what, ".swap");
387 u = manager_get_unit(m, e);
390 SWAP(u)->from_proc_swaps &&
391 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
397 u = unit_new(m, sizeof(Swap));
401 r = unit_add_name(u, e);
405 SWAP(u)->what = strdup(what);
406 if (!SWAP(u)->what) {
411 unit_add_to_load_queue(u);
415 p = &SWAP(u)->parameters_proc_swaps;
418 p->what = strdup(what_proc_swaps);
426 SWAP(u)->is_active = true;
427 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
430 SWAP(u)->from_proc_swaps = true;
432 p->priority = priority;
436 unit_add_to_dbus_queue(u);
441 log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
449 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
450 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
451 struct udev_list_entry *item = NULL, *first = NULL;
458 r = swap_add_one(m, device, device, prio, false, false, set_flags);
462 /* If this is a block device, then let's add duplicates for
463 * all other names of this block device */
464 if (stat(device, &st) < 0 || !S_ISBLK(st.st_mode))
467 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
471 /* Add the main device node */
472 dn = udev_device_get_devnode(d);
473 if (dn && !streq(dn, device))
474 swap_add_one(m, dn, device, prio, false, false, set_flags);
476 /* Add additional units for all symlinks */
477 first = udev_device_get_devlinks_list_entry(d);
478 udev_list_entry_foreach(item, first) {
481 /* Don't bother with the /dev/block links */
482 p = udev_list_entry_get_name(item);
484 if (streq(p, device))
487 if (path_startswith(p, "/dev/block/"))
490 if (stat(p, &st) >= 0)
491 if (!S_ISBLK(st.st_mode) ||
492 st.st_rdev != udev_device_get_devnum(d))
495 swap_add_one(m, p, device, prio, false, false, set_flags);
501 static void swap_set_state(Swap *s, SwapState state) {
506 old_state = s->state;
509 if (state != SWAP_ACTIVATING &&
510 state != SWAP_ACTIVATING_SIGTERM &&
511 state != SWAP_ACTIVATING_SIGKILL &&
512 state != SWAP_ACTIVATING_DONE &&
513 state != SWAP_DEACTIVATING &&
514 state != SWAP_DEACTIVATING_SIGTERM &&
515 state != SWAP_DEACTIVATING_SIGKILL) {
516 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
517 swap_unwatch_control_pid(s);
518 s->control_command = NULL;
519 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
522 if (state != old_state)
523 log_debug_unit(UNIT(s)->id,
524 "%s changed %s -> %s",
526 swap_state_to_string(old_state),
527 swap_state_to_string(state));
529 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
532 static int swap_coldplug(Unit *u) {
534 SwapState new_state = SWAP_DEAD;
538 assert(s->state == SWAP_DEAD);
540 if (s->deserialized_state != s->state)
541 new_state = s->deserialized_state;
542 else if (s->from_proc_swaps)
543 new_state = SWAP_ACTIVE;
545 if (new_state == s->state)
548 if (new_state == SWAP_ACTIVATING ||
549 new_state == SWAP_ACTIVATING_SIGTERM ||
550 new_state == SWAP_ACTIVATING_SIGKILL ||
551 new_state == SWAP_ACTIVATING_DONE ||
552 new_state == SWAP_DEACTIVATING ||
553 new_state == SWAP_DEACTIVATING_SIGTERM ||
554 new_state == SWAP_DEACTIVATING_SIGKILL) {
556 if (s->control_pid <= 0)
559 r = unit_watch_pid(UNIT(s), s->control_pid);
563 r = swap_arm_timer(s);
568 swap_set_state(s, new_state);
572 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
579 if (s->from_proc_swaps)
580 p = &s->parameters_proc_swaps;
581 else if (s->from_fragment)
582 p = &s->parameters_fragment;
590 "%sFrom /proc/swaps: %s\n"
591 "%sFrom fragment: %s\n",
592 prefix, swap_state_to_string(s->state),
593 prefix, swap_result_to_string(s->result),
595 prefix, yes_no(s->from_proc_swaps),
596 prefix, yes_no(s->from_fragment));
599 fprintf(f, "%sDevice Node: %s\n", prefix, s->devnode);
607 prefix, yes_no(p->noauto),
608 prefix, yes_no(p->nofail));
610 if (s->control_pid > 0)
612 "%sControl PID: "PID_FMT"\n",
613 prefix, s->control_pid);
615 exec_context_dump(&s->exec_context, f, prefix);
616 kill_context_dump(&s->kill_context, f, prefix);
619 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
627 unit_realize_cgroup(UNIT(s));
629 r = unit_setup_exec_runtime(UNIT(s));
633 r = swap_arm_timer(s);
641 UNIT(s)->manager->environment,
645 UNIT(s)->manager->confirm_spawn,
646 UNIT(s)->manager->cgroup_supported,
647 UNIT(s)->cgroup_path,
648 manager_get_runtime_prefix(UNIT(s)->manager),
657 r = unit_watch_pid(UNIT(s), pid);
659 /* FIXME: we need to do something here */
667 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
672 static void swap_enter_dead(Swap *s, SwapResult f) {
675 if (f != SWAP_SUCCESS)
678 exec_runtime_destroy(s->exec_runtime);
679 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
681 exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
683 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
686 static void swap_enter_active(Swap *s, SwapResult f) {
689 if (f != SWAP_SUCCESS)
692 swap_set_state(s, SWAP_ACTIVE);
695 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
700 if (f != SWAP_SUCCESS)
703 r = unit_kill_context(
706 state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
714 r = swap_arm_timer(s);
718 swap_set_state(s, state);
719 } else if (state == SWAP_ACTIVATING_SIGTERM)
720 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_SUCCESS);
721 else if (state == SWAP_DEACTIVATING_SIGTERM)
722 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_SUCCESS);
724 swap_enter_dead(s, SWAP_SUCCESS);
729 log_warning_unit(UNIT(s)->id,
730 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
732 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
735 static void swap_enter_activating(Swap *s) {
740 s->control_command_id = SWAP_EXEC_ACTIVATE;
741 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
743 if (s->from_fragment)
744 priority = s->parameters_fragment.priority;
749 char p[DECIMAL_STR_MAX(int)];
751 sprintf(p, "%i", priority);
753 r = exec_command_set(
761 r = exec_command_set(
770 swap_unwatch_control_pid(s);
772 r = swap_spawn(s, s->control_command, &s->control_pid);
776 swap_set_state(s, SWAP_ACTIVATING);
781 log_warning_unit(UNIT(s)->id,
782 "%s failed to run 'swapon' task: %s",
783 UNIT(s)->id, strerror(-r));
784 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
787 static void swap_enter_deactivating(Swap *s) {
792 s->control_command_id = SWAP_EXEC_DEACTIVATE;
793 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
795 r = exec_command_set(s->control_command,
802 swap_unwatch_control_pid(s);
804 r = swap_spawn(s, s->control_command, &s->control_pid);
808 swap_set_state(s, SWAP_DEACTIVATING);
813 log_warning_unit(UNIT(s)->id,
814 "%s failed to run 'swapoff' task: %s",
815 UNIT(s)->id, strerror(-r));
816 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
819 static int swap_start(Unit *u) {
824 /* We cannot fulfill this request right now, try again later
827 if (s->state == SWAP_DEACTIVATING ||
828 s->state == SWAP_DEACTIVATING_SIGTERM ||
829 s->state == SWAP_DEACTIVATING_SIGKILL ||
830 s->state == SWAP_ACTIVATING_SIGTERM ||
831 s->state == SWAP_ACTIVATING_SIGKILL)
834 if (s->state == SWAP_ACTIVATING)
837 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
839 if (detect_container(NULL) > 0)
842 s->result = SWAP_SUCCESS;
843 swap_enter_activating(s);
847 static int swap_stop(Unit *u) {
852 if (s->state == SWAP_DEACTIVATING ||
853 s->state == SWAP_DEACTIVATING_SIGTERM ||
854 s->state == SWAP_DEACTIVATING_SIGKILL ||
855 s->state == SWAP_ACTIVATING_SIGTERM ||
856 s->state == SWAP_ACTIVATING_SIGKILL)
859 assert(s->state == SWAP_ACTIVATING ||
860 s->state == SWAP_ACTIVATING_DONE ||
861 s->state == SWAP_ACTIVE);
863 if (detect_container(NULL) > 0)
866 swap_enter_deactivating(s);
870 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
877 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
878 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
880 if (s->control_pid > 0)
881 unit_serialize_item_format(u, f, "control-pid", PID_FMT, s->control_pid);
883 if (s->control_command_id >= 0)
884 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
889 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
895 if (streq(key, "state")) {
898 state = swap_state_from_string(value);
900 log_debug_unit(u->id, "Failed to parse state value %s", value);
902 s->deserialized_state = state;
903 } else if (streq(key, "result")) {
906 f = swap_result_from_string(value);
908 log_debug_unit(u->id, "Failed to parse result value %s", value);
909 else if (f != SWAP_SUCCESS)
911 } else if (streq(key, "control-pid")) {
914 if (parse_pid(value, &pid) < 0)
915 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
917 s->control_pid = pid;
919 } else if (streq(key, "control-command")) {
922 id = swap_exec_command_from_string(value);
924 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
926 s->control_command_id = id;
927 s->control_command = s->exec_command + id;
930 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
935 _pure_ static UnitActiveState swap_active_state(Unit *u) {
938 return state_translation_table[SWAP(u)->state];
941 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
944 return swap_state_to_string(SWAP(u)->state);
947 _pure_ static bool swap_check_gc(Unit *u) {
952 return s->from_proc_swaps;
955 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
962 if (pid != s->control_pid)
967 if (is_clean_exit(code, status, NULL))
969 else if (code == CLD_EXITED)
970 f = SWAP_FAILURE_EXIT_CODE;
971 else if (code == CLD_KILLED)
972 f = SWAP_FAILURE_SIGNAL;
973 else if (code == CLD_DUMPED)
974 f = SWAP_FAILURE_CORE_DUMP;
976 assert_not_reached("Unknown code");
978 if (f != SWAP_SUCCESS)
981 if (s->control_command) {
982 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
984 s->control_command = NULL;
985 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
988 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
990 "%s swap process exited, code=%s status=%i",
991 u->id, sigchld_code_to_string(code), status);
995 case SWAP_ACTIVATING:
996 case SWAP_ACTIVATING_DONE:
997 case SWAP_ACTIVATING_SIGTERM:
998 case SWAP_ACTIVATING_SIGKILL:
1000 if (f == SWAP_SUCCESS)
1001 swap_enter_active(s, f);
1003 swap_enter_dead(s, f);
1006 case SWAP_DEACTIVATING:
1007 case SWAP_DEACTIVATING_SIGKILL:
1008 case SWAP_DEACTIVATING_SIGTERM:
1010 swap_enter_dead(s, f);
1014 assert_not_reached("Uh, control process died at wrong time.");
1017 /* Notify clients about changed exit status */
1018 unit_add_to_dbus_queue(u);
1021 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1022 Swap *s = SWAP(userdata);
1025 assert(s->timer_event_source == source);
1029 case SWAP_ACTIVATING:
1030 case SWAP_ACTIVATING_DONE:
1031 log_warning_unit(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
1032 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1035 case SWAP_DEACTIVATING:
1036 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
1037 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1040 case SWAP_ACTIVATING_SIGTERM:
1041 if (s->kill_context.send_sigkill) {
1042 log_warning_unit(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
1043 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1045 log_warning_unit(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1046 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1050 case SWAP_DEACTIVATING_SIGTERM:
1051 if (s->kill_context.send_sigkill) {
1052 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
1053 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1055 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1056 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1060 case SWAP_ACTIVATING_SIGKILL:
1061 case SWAP_DEACTIVATING_SIGKILL:
1062 log_warning_unit(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
1063 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1067 assert_not_reached("Timeout at wrong time.");
1073 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1079 rewind(m->proc_swaps);
1081 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1084 _cleanup_free_ char *dev = NULL, *d = NULL;
1087 k = fscanf(m->proc_swaps,
1088 "%ms " /* device/file */
1089 "%*s " /* type of swap */
1090 "%*s " /* swap size */
1092 "%i\n", /* priority */
1098 log_warning("Failed to parse /proc/swaps:%u", i);
1106 k = swap_process_new_swap(m, d, prio, set_flags);
1114 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1115 Manager *m = userdata;
1120 assert(revents & EPOLLPRI);
1122 r = swap_load_proc_swaps(m, true);
1124 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1126 /* Reset flags, just in case, for late calls */
1127 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1128 Swap *swap = SWAP(u);
1130 swap->is_active = swap->just_activated = false;
1136 manager_dispatch_load_queue(m);
1138 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1139 Swap *swap = SWAP(u);
1141 if (!swap->is_active) {
1142 /* This has just been deactivated */
1144 swap_unset_proc_swaps(swap);
1146 switch (swap->state) {
1149 swap_enter_dead(swap, SWAP_SUCCESS);
1154 swap_set_state(swap, swap->state);
1158 } else if (swap->just_activated) {
1160 /* New swap entry */
1162 switch (swap->state) {
1166 swap_enter_active(swap, SWAP_SUCCESS);
1169 case SWAP_ACTIVATING:
1170 swap_set_state(swap, SWAP_ACTIVATING_DONE);
1174 /* Nothing really changed, but let's
1175 * issue an notification call
1176 * nonetheless, in case somebody is
1177 * waiting for this. */
1178 swap_set_state(swap, swap->state);
1183 /* Reset the flags for later calls */
1184 swap->is_active = swap->just_activated = false;
1190 static Unit *swap_following(Unit *u) {
1192 Swap *other, *first = NULL;
1196 if (streq_ptr(s->what, s->devnode))
1199 /* Make everybody follow the unit that's named after the swap
1200 * device in the kernel */
1202 LIST_FOREACH_AFTER(same_devnode, other, s)
1203 if (streq_ptr(other->what, other->devnode))
1206 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1207 if (streq_ptr(other->what, other->devnode))
1216 static int swap_following_set(Unit *u, Set **_set) {
1217 Swap *s = SWAP(u), *other;
1224 if (LIST_JUST_US(same_devnode, s)) {
1229 set = set_new(NULL, NULL);
1233 LIST_FOREACH_AFTER(same_devnode, other, s) {
1234 r = set_put(set, other);
1239 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1240 r = set_put(set, other);
1253 static void swap_shutdown(Manager *m) {
1256 m->swap_event_source = sd_event_source_unref(m->swap_event_source);
1258 if (m->proc_swaps) {
1259 fclose(m->proc_swaps);
1260 m->proc_swaps = NULL;
1263 hashmap_free(m->swaps_by_devnode);
1264 m->swaps_by_devnode = NULL;
1267 static int swap_enumerate(Manager *m) {
1272 if (!m->proc_swaps) {
1273 m->proc_swaps = fopen("/proc/swaps", "re");
1275 return errno == ENOENT ? 0 : -errno;
1277 r = sd_event_add_io(m->event, &m->swap_event_source, fileno(m->proc_swaps), EPOLLPRI, swap_dispatch_io, m);
1281 /* Dispatch this before we dispatch SIGCHLD, so that
1282 * we always get the events from /proc/swaps before
1283 * the SIGCHLD of /sbin/swapon. */
1284 r = sd_event_source_set_priority(m->swap_event_source, -10);
1289 r = swap_load_proc_swaps(m, false);
1300 int swap_process_new_device(Manager *m, struct udev_device *dev) {
1301 struct udev_list_entry *item = NULL, *first = NULL;
1302 _cleanup_free_ char *e = NULL;
1310 dn = udev_device_get_devnode(dev);
1314 e = unit_name_from_path(dn, ".swap");
1318 s = hashmap_get(m->units, e);
1320 r = swap_set_devnode(s, dn);
1322 first = udev_device_get_devlinks_list_entry(dev);
1323 udev_list_entry_foreach(item, first) {
1324 _cleanup_free_ char *n = NULL;
1326 n = unit_name_from_path(udev_list_entry_get_name(item), ".swap");
1330 s = hashmap_get(m->units, n);
1334 q = swap_set_devnode(s, dn);
1343 int swap_process_removed_device(Manager *m, struct udev_device *dev) {
1348 dn = udev_device_get_devnode(dev);
1352 while ((s = hashmap_get(m->swaps_by_devnode, dn))) {
1355 q = swap_set_devnode(s, NULL);
1363 static void swap_reset_failed(Unit *u) {
1368 if (s->state == SWAP_FAILED)
1369 swap_set_state(s, SWAP_DEAD);
1371 s->result = SWAP_SUCCESS;
1374 static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1375 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1378 static int swap_get_timeout(Unit *u, uint64_t *timeout) {
1382 if (!s->timer_event_source)
1385 r = sd_event_source_get_time(s->timer_event_source, timeout);
1392 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1393 [SWAP_DEAD] = "dead",
1394 [SWAP_ACTIVATING] = "activating",
1395 [SWAP_ACTIVATING_DONE] = "activating-done",
1396 [SWAP_ACTIVE] = "active",
1397 [SWAP_DEACTIVATING] = "deactivating",
1398 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1399 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1400 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1401 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1402 [SWAP_FAILED] = "failed"
1405 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1407 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1408 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1409 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1412 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1414 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1415 [SWAP_SUCCESS] = "success",
1416 [SWAP_FAILURE_RESOURCES] = "resources",
1417 [SWAP_FAILURE_TIMEOUT] = "timeout",
1418 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1419 [SWAP_FAILURE_SIGNAL] = "signal",
1420 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1423 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1425 const UnitVTable swap_vtable = {
1426 .object_size = sizeof(Swap),
1427 .exec_context_offset = offsetof(Swap, exec_context),
1428 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1429 .kill_context_offset = offsetof(Swap, kill_context),
1430 .exec_runtime_offset = offsetof(Swap, exec_runtime),
1436 .private_section = "Swap",
1439 .no_instances = true,
1445 .coldplug = swap_coldplug,
1449 .start = swap_start,
1454 .get_timeout = swap_get_timeout,
1456 .serialize = swap_serialize,
1457 .deserialize_item = swap_deserialize_item,
1459 .active_state = swap_active_state,
1460 .sub_state_to_string = swap_sub_state_to_string,
1462 .check_gc = swap_check_gc,
1464 .sigchld_event = swap_sigchld_event,
1466 .reset_failed = swap_reset_failed,
1468 .bus_interface = "org.freedesktop.systemd1.Swap",
1469 .bus_vtable = bus_swap_vtable,
1470 .bus_set_property = bus_swap_set_property,
1471 .bus_commit_properties = bus_swap_commit_properties,
1473 .following = swap_following,
1474 .following_set = swap_following_set,
1476 .enumerate = swap_enumerate,
1477 .shutdown = swap_shutdown,
1479 .status_message_formats = {
1480 .starting_stopping = {
1481 [0] = "Activating swap %s...",
1482 [1] = "Deactivating swap %s...",
1484 .finished_start_job = {
1485 [JOB_DONE] = "Activated swap %s.",
1486 [JOB_FAILED] = "Failed to activate swap %s.",
1487 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1488 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1490 .finished_stop_job = {
1491 [JOB_DONE] = "Deactivated swap %s.",
1492 [JOB_FAILED] = "Failed deactivating swap %s.",
1493 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",