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_monotonic(UNIT(s)->manager->event, &s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec, 0, swap_dispatch_timer, s);
185 static int swap_add_device_links(Swap *s) {
193 if (s->from_fragment)
194 p = &s->parameters_fragment;
198 if (is_device_path(s->what))
199 return unit_add_node_link(UNIT(s), s->what, !p->noauto && UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
201 /* File based swap devices need to be ordered after
202 * systemd-remount-fs.service, since they might need a
203 * writable file system. */
204 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
207 static int swap_add_default_dependencies(Swap *s) {
208 bool nofail = false, noauto = false;
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 SwapParameters *p = &s->parameters_fragment;
232 r = unit_add_dependency_by_name_inverse(UNIT(s), UNIT_WANTS, SPECIAL_SWAP_TARGET, NULL, true);
234 r = unit_add_two_dependencies_by_name_inverse(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SWAP_TARGET, NULL, true);
242 static int swap_verify(Swap *s) {
244 _cleanup_free_ char *e = NULL;
246 if (UNIT(s)->load_state != UNIT_LOADED)
249 e = unit_name_from_path(s->what, ".swap");
253 b = unit_has_name(UNIT(s), e);
255 log_error_unit(UNIT(s)->id, "%s: Value of \"What\" and unit name do not match, not loading.", UNIT(s)->id);
259 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
260 log_error_unit(UNIT(s)->id, "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.", UNIT(s)->id);
267 static int swap_load_devnode(Swap *s) {
268 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
274 if (stat(s->what, &st) < 0 || !S_ISBLK(st.st_mode))
277 d = udev_device_new_from_devnum(UNIT(s)->manager->udev, 'b', st.st_rdev);
281 p = udev_device_get_devnode(d);
285 return swap_set_devnode(s, p);
288 static int swap_load(Unit *u) {
293 assert(u->load_state == UNIT_STUB);
295 /* Load a .swap file */
296 r = unit_load_fragment_and_dropin_optional(u);
300 if (u->load_state == UNIT_LOADED) {
302 if (UNIT(s)->fragment_path)
303 s->from_fragment = true;
306 if (s->parameters_fragment.what)
307 s->what = strdup(s->parameters_fragment.what);
308 else if (s->parameters_proc_swaps.what)
309 s->what = strdup(s->parameters_proc_swaps.what);
311 s->what = unit_name_to_path(u->id);
317 path_kill_slashes(s->what);
319 if (!UNIT(s)->description) {
320 r = unit_set_description(u, s->what);
325 r = unit_require_mounts_for(UNIT(s), s->what);
329 r = swap_add_device_links(s);
333 r = swap_load_devnode(s);
337 r = unit_patch_contexts(u);
341 r = unit_add_exec_dependencies(u, &s->exec_context);
345 r = unit_add_default_slice(u, &s->cgroup_context);
349 if (UNIT(s)->default_dependencies) {
350 r = swap_add_default_dependencies(s);
356 return swap_verify(s);
359 static int swap_add_one(
362 const char *what_proc_swaps,
368 _cleanup_free_ char *e = NULL;
376 assert(what_proc_swaps);
378 e = unit_name_from_path(what, ".swap");
382 u = manager_get_unit(m, e);
385 SWAP(u)->from_proc_swaps &&
386 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
392 u = unit_new(m, sizeof(Swap));
396 r = unit_add_name(u, e);
400 SWAP(u)->what = strdup(what);
401 if (!SWAP(u)->what) {
406 unit_add_to_load_queue(u);
410 p = &SWAP(u)->parameters_proc_swaps;
413 p->what = strdup(what_proc_swaps);
421 SWAP(u)->is_active = true;
422 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
425 SWAP(u)->from_proc_swaps = true;
427 p->priority = priority;
431 unit_add_to_dbus_queue(u);
436 log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
444 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
445 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
446 struct udev_list_entry *item = NULL, *first = NULL;
453 r = swap_add_one(m, device, device, prio, false, false, set_flags);
457 /* If this is a block device, then let's add duplicates for
458 * all other names of this block device */
459 if (stat(device, &st) < 0 || !S_ISBLK(st.st_mode))
462 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
466 /* Add the main device node */
467 dn = udev_device_get_devnode(d);
468 if (dn && !streq(dn, device))
469 swap_add_one(m, dn, device, prio, false, false, set_flags);
471 /* Add additional units for all symlinks */
472 first = udev_device_get_devlinks_list_entry(d);
473 udev_list_entry_foreach(item, first) {
476 /* Don't bother with the /dev/block links */
477 p = udev_list_entry_get_name(item);
479 if (streq(p, device))
482 if (path_startswith(p, "/dev/block/"))
485 if (stat(p, &st) >= 0)
486 if (!S_ISBLK(st.st_mode) ||
487 st.st_rdev != udev_device_get_devnum(d))
490 swap_add_one(m, p, device, prio, false, false, set_flags);
496 static void swap_set_state(Swap *s, SwapState state) {
501 old_state = s->state;
504 if (state != SWAP_ACTIVATING &&
505 state != SWAP_ACTIVATING_SIGTERM &&
506 state != SWAP_ACTIVATING_SIGKILL &&
507 state != SWAP_ACTIVATING_DONE &&
508 state != SWAP_DEACTIVATING &&
509 state != SWAP_DEACTIVATING_SIGTERM &&
510 state != SWAP_DEACTIVATING_SIGKILL) {
511 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
512 swap_unwatch_control_pid(s);
513 s->control_command = NULL;
514 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
517 if (state != old_state)
518 log_debug_unit(UNIT(s)->id,
519 "%s changed %s -> %s",
521 swap_state_to_string(old_state),
522 swap_state_to_string(state));
524 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
527 static int swap_coldplug(Unit *u) {
529 SwapState new_state = SWAP_DEAD;
533 assert(s->state == SWAP_DEAD);
535 if (s->deserialized_state != s->state)
536 new_state = s->deserialized_state;
537 else if (s->from_proc_swaps)
538 new_state = SWAP_ACTIVE;
540 if (new_state == s->state)
543 if (new_state == SWAP_ACTIVATING ||
544 new_state == SWAP_ACTIVATING_SIGTERM ||
545 new_state == SWAP_ACTIVATING_SIGKILL ||
546 new_state == SWAP_ACTIVATING_DONE ||
547 new_state == SWAP_DEACTIVATING ||
548 new_state == SWAP_DEACTIVATING_SIGTERM ||
549 new_state == SWAP_DEACTIVATING_SIGKILL) {
551 if (s->control_pid <= 0)
554 r = unit_watch_pid(UNIT(s), s->control_pid);
558 r = swap_arm_timer(s);
563 swap_set_state(s, new_state);
567 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
574 if (s->from_proc_swaps)
575 p = &s->parameters_proc_swaps;
576 else if (s->from_fragment)
577 p = &s->parameters_fragment;
585 "%sFrom /proc/swaps: %s\n"
586 "%sFrom fragment: %s\n",
587 prefix, swap_state_to_string(s->state),
588 prefix, swap_result_to_string(s->result),
590 prefix, yes_no(s->from_proc_swaps),
591 prefix, yes_no(s->from_fragment));
594 fprintf(f, "%sDevice Node: %s\n", prefix, s->devnode);
602 prefix, yes_no(p->noauto),
603 prefix, yes_no(p->nofail));
605 if (s->control_pid > 0)
607 "%sControl PID: %lu\n",
608 prefix, (unsigned long) s->control_pid);
610 exec_context_dump(&s->exec_context, f, prefix);
611 kill_context_dump(&s->kill_context, f, prefix);
614 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
622 unit_realize_cgroup(UNIT(s));
624 r = unit_setup_exec_runtime(UNIT(s));
628 r = swap_arm_timer(s);
636 UNIT(s)->manager->environment,
640 UNIT(s)->manager->confirm_spawn,
641 UNIT(s)->manager->cgroup_supported,
642 UNIT(s)->cgroup_path,
643 manager_get_runtime_prefix(UNIT(s)->manager),
652 r = unit_watch_pid(UNIT(s), pid);
654 /* FIXME: we need to do something here */
662 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
667 static void swap_enter_dead(Swap *s, SwapResult f) {
670 if (f != SWAP_SUCCESS)
673 exec_runtime_destroy(s->exec_runtime);
674 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
676 exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
678 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
681 static void swap_enter_active(Swap *s, SwapResult f) {
684 if (f != SWAP_SUCCESS)
687 swap_set_state(s, SWAP_ACTIVE);
690 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
695 if (f != SWAP_SUCCESS)
698 r = unit_kill_context(
701 state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
709 r = swap_arm_timer(s);
713 swap_set_state(s, state);
714 } else if (state == SWAP_ACTIVATING_SIGTERM)
715 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_SUCCESS);
716 else if (state == SWAP_DEACTIVATING_SIGTERM)
717 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_SUCCESS);
719 swap_enter_dead(s, SWAP_SUCCESS);
724 log_warning_unit(UNIT(s)->id,
725 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
727 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
730 static void swap_enter_activating(Swap *s) {
735 s->control_command_id = SWAP_EXEC_ACTIVATE;
736 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
738 if (s->from_fragment)
739 priority = s->parameters_fragment.priority;
744 char p[DECIMAL_STR_MAX(int)];
746 sprintf(p, "%i", priority);
748 r = exec_command_set(
756 r = exec_command_set(
765 swap_unwatch_control_pid(s);
767 r = swap_spawn(s, s->control_command, &s->control_pid);
771 swap_set_state(s, SWAP_ACTIVATING);
776 log_warning_unit(UNIT(s)->id,
777 "%s failed to run 'swapon' task: %s",
778 UNIT(s)->id, strerror(-r));
779 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
782 static void swap_enter_deactivating(Swap *s) {
787 s->control_command_id = SWAP_EXEC_DEACTIVATE;
788 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
790 r = exec_command_set(s->control_command,
797 swap_unwatch_control_pid(s);
799 r = swap_spawn(s, s->control_command, &s->control_pid);
803 swap_set_state(s, SWAP_DEACTIVATING);
808 log_warning_unit(UNIT(s)->id,
809 "%s failed to run 'swapoff' task: %s",
810 UNIT(s)->id, strerror(-r));
811 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
814 static int swap_start(Unit *u) {
819 /* We cannot fulfill this request right now, try again later
822 if (s->state == SWAP_DEACTIVATING ||
823 s->state == SWAP_DEACTIVATING_SIGTERM ||
824 s->state == SWAP_DEACTIVATING_SIGKILL ||
825 s->state == SWAP_ACTIVATING_SIGTERM ||
826 s->state == SWAP_ACTIVATING_SIGKILL)
829 if (s->state == SWAP_ACTIVATING)
832 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
834 if (detect_container(NULL) > 0)
837 s->result = SWAP_SUCCESS;
838 swap_enter_activating(s);
842 static int swap_stop(Unit *u) {
847 if (s->state == SWAP_DEACTIVATING ||
848 s->state == SWAP_DEACTIVATING_SIGTERM ||
849 s->state == SWAP_DEACTIVATING_SIGKILL ||
850 s->state == SWAP_ACTIVATING_SIGTERM ||
851 s->state == SWAP_ACTIVATING_SIGKILL)
854 assert(s->state == SWAP_ACTIVATING ||
855 s->state == SWAP_ACTIVATING_DONE ||
856 s->state == SWAP_ACTIVE);
858 if (detect_container(NULL) > 0)
861 swap_enter_deactivating(s);
865 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
872 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
873 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
875 if (s->control_pid > 0)
876 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
878 if (s->control_command_id >= 0)
879 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
884 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
890 if (streq(key, "state")) {
893 state = swap_state_from_string(value);
895 log_debug_unit(u->id, "Failed to parse state value %s", value);
897 s->deserialized_state = state;
898 } else if (streq(key, "result")) {
901 f = swap_result_from_string(value);
903 log_debug_unit(u->id, "Failed to parse result value %s", value);
904 else if (f != SWAP_SUCCESS)
906 } else if (streq(key, "control-pid")) {
909 if (parse_pid(value, &pid) < 0)
910 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
912 s->control_pid = pid;
914 } else if (streq(key, "control-command")) {
917 id = swap_exec_command_from_string(value);
919 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
921 s->control_command_id = id;
922 s->control_command = s->exec_command + id;
925 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
930 _pure_ static UnitActiveState swap_active_state(Unit *u) {
933 return state_translation_table[SWAP(u)->state];
936 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
939 return swap_state_to_string(SWAP(u)->state);
942 _pure_ static bool swap_check_gc(Unit *u) {
947 return s->from_proc_swaps;
950 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
957 if (pid != s->control_pid)
962 if (is_clean_exit(code, status, NULL))
964 else if (code == CLD_EXITED)
965 f = SWAP_FAILURE_EXIT_CODE;
966 else if (code == CLD_KILLED)
967 f = SWAP_FAILURE_SIGNAL;
968 else if (code == CLD_DUMPED)
969 f = SWAP_FAILURE_CORE_DUMP;
971 assert_not_reached("Unknown code");
973 if (f != SWAP_SUCCESS)
976 if (s->control_command) {
977 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
979 s->control_command = NULL;
980 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
983 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
985 "%s swap process exited, code=%s status=%i",
986 u->id, sigchld_code_to_string(code), status);
990 case SWAP_ACTIVATING:
991 case SWAP_ACTIVATING_DONE:
992 case SWAP_ACTIVATING_SIGTERM:
993 case SWAP_ACTIVATING_SIGKILL:
995 if (f == SWAP_SUCCESS)
996 swap_enter_active(s, f);
998 swap_enter_dead(s, f);
1001 case SWAP_DEACTIVATING:
1002 case SWAP_DEACTIVATING_SIGKILL:
1003 case SWAP_DEACTIVATING_SIGTERM:
1005 swap_enter_dead(s, f);
1009 assert_not_reached("Uh, control process died at wrong time.");
1012 /* Notify clients about changed exit status */
1013 unit_add_to_dbus_queue(u);
1016 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1017 Swap *s = SWAP(userdata);
1020 assert(s->timer_event_source == source);
1024 case SWAP_ACTIVATING:
1025 case SWAP_ACTIVATING_DONE:
1026 log_warning_unit(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
1027 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1030 case SWAP_DEACTIVATING:
1031 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
1032 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1035 case SWAP_ACTIVATING_SIGTERM:
1036 if (s->kill_context.send_sigkill) {
1037 log_warning_unit(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
1038 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1040 log_warning_unit(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1041 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1045 case SWAP_DEACTIVATING_SIGTERM:
1046 if (s->kill_context.send_sigkill) {
1047 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
1048 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1050 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1051 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1055 case SWAP_ACTIVATING_SIGKILL:
1056 case SWAP_DEACTIVATING_SIGKILL:
1057 log_warning_unit(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
1058 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1062 assert_not_reached("Timeout at wrong time.");
1068 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1074 rewind(m->proc_swaps);
1076 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1079 _cleanup_free_ char *dev = NULL, *d = NULL;
1082 k = fscanf(m->proc_swaps,
1083 "%ms " /* device/file */
1084 "%*s " /* type of swap */
1085 "%*s " /* swap size */
1087 "%i\n", /* priority */
1093 log_warning("Failed to parse /proc/swaps:%u", i);
1101 k = swap_process_new_swap(m, d, prio, set_flags);
1109 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1110 Manager *m = userdata;
1115 assert(revents & EPOLLPRI);
1117 r = swap_load_proc_swaps(m, true);
1119 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1121 /* Reset flags, just in case, for late calls */
1122 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1123 Swap *swap = SWAP(u);
1125 swap->is_active = swap->just_activated = false;
1131 manager_dispatch_load_queue(m);
1133 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1134 Swap *swap = SWAP(u);
1136 if (!swap->is_active) {
1137 /* This has just been deactivated */
1139 swap_unset_proc_swaps(swap);
1141 switch (swap->state) {
1144 swap_enter_dead(swap, SWAP_SUCCESS);
1149 swap_set_state(swap, swap->state);
1153 } else if (swap->just_activated) {
1155 /* New swap entry */
1157 switch (swap->state) {
1161 swap_enter_active(swap, SWAP_SUCCESS);
1164 case SWAP_ACTIVATING:
1165 swap_set_state(swap, SWAP_ACTIVATING_DONE);
1169 /* Nothing really changed, but let's
1170 * issue an notification call
1171 * nonetheless, in case somebody is
1172 * waiting for this. */
1173 swap_set_state(swap, swap->state);
1178 /* Reset the flags for later calls */
1179 swap->is_active = swap->just_activated = false;
1185 static Unit *swap_following(Unit *u) {
1187 Swap *other, *first = NULL;
1191 if (streq_ptr(s->what, s->devnode))
1194 /* Make everybody follow the unit that's named after the swap
1195 * device in the kernel */
1197 LIST_FOREACH_AFTER(same_devnode, other, s)
1198 if (streq_ptr(other->what, other->devnode))
1201 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1202 if (streq_ptr(other->what, other->devnode))
1211 static int swap_following_set(Unit *u, Set **_set) {
1212 Swap *s = SWAP(u), *other;
1219 if (LIST_JUST_US(same_devnode, s)) {
1224 set = set_new(NULL, NULL);
1228 LIST_FOREACH_AFTER(same_devnode, other, s) {
1229 r = set_put(set, other);
1234 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1235 r = set_put(set, other);
1248 static void swap_shutdown(Manager *m) {
1251 m->swap_event_source = sd_event_source_unref(m->swap_event_source);
1253 if (m->proc_swaps) {
1254 fclose(m->proc_swaps);
1255 m->proc_swaps = NULL;
1258 hashmap_free(m->swaps_by_devnode);
1259 m->swaps_by_devnode = NULL;
1262 static int swap_enumerate(Manager *m) {
1267 if (!m->proc_swaps) {
1268 m->proc_swaps = fopen("/proc/swaps", "re");
1270 return errno == ENOENT ? 0 : -errno;
1272 r = sd_event_add_io(m->event, &m->swap_event_source, fileno(m->proc_swaps), EPOLLPRI, swap_dispatch_io, m);
1276 /* Dispatch this before we dispatch SIGCHLD, so that
1277 * we always get the events from /proc/swaps before
1278 * the SIGCHLD of /sbin/swapon. */
1279 r = sd_event_source_set_priority(m->swap_event_source, -10);
1284 r = swap_load_proc_swaps(m, false);
1295 int swap_process_new_device(Manager *m, struct udev_device *dev) {
1296 struct udev_list_entry *item = NULL, *first = NULL;
1297 _cleanup_free_ char *e = NULL;
1305 dn = udev_device_get_devnode(dev);
1309 e = unit_name_from_path(dn, ".swap");
1313 s = hashmap_get(m->units, e);
1315 r = swap_set_devnode(s, dn);
1317 first = udev_device_get_devlinks_list_entry(dev);
1318 udev_list_entry_foreach(item, first) {
1319 _cleanup_free_ char *n = NULL;
1321 n = unit_name_from_path(udev_list_entry_get_name(item), ".swap");
1325 s = hashmap_get(m->units, n);
1329 q = swap_set_devnode(s, dn);
1338 int swap_process_removed_device(Manager *m, struct udev_device *dev) {
1343 dn = udev_device_get_devnode(dev);
1347 while ((s = hashmap_get(m->swaps_by_devnode, dn))) {
1350 q = swap_set_devnode(s, NULL);
1358 static void swap_reset_failed(Unit *u) {
1363 if (s->state == SWAP_FAILED)
1364 swap_set_state(s, SWAP_DEAD);
1366 s->result = SWAP_SUCCESS;
1369 static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1370 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1373 static int swap_get_timeout(Unit *u, uint64_t *timeout) {
1377 if (!s->timer_event_source)
1380 r = sd_event_source_get_time(s->timer_event_source, timeout);
1387 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1388 [SWAP_DEAD] = "dead",
1389 [SWAP_ACTIVATING] = "activating",
1390 [SWAP_ACTIVATING_DONE] = "activating-done",
1391 [SWAP_ACTIVE] = "active",
1392 [SWAP_DEACTIVATING] = "deactivating",
1393 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1394 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1395 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1396 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1397 [SWAP_FAILED] = "failed"
1400 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1402 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1403 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1404 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1407 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1409 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1410 [SWAP_SUCCESS] = "success",
1411 [SWAP_FAILURE_RESOURCES] = "resources",
1412 [SWAP_FAILURE_TIMEOUT] = "timeout",
1413 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1414 [SWAP_FAILURE_SIGNAL] = "signal",
1415 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1418 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1420 const UnitVTable swap_vtable = {
1421 .object_size = sizeof(Swap),
1422 .exec_context_offset = offsetof(Swap, exec_context),
1423 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1424 .kill_context_offset = offsetof(Swap, kill_context),
1425 .exec_runtime_offset = offsetof(Swap, exec_runtime),
1431 .private_section = "Swap",
1434 .no_instances = true,
1440 .coldplug = swap_coldplug,
1444 .start = swap_start,
1449 .get_timeout = swap_get_timeout,
1451 .serialize = swap_serialize,
1452 .deserialize_item = swap_deserialize_item,
1454 .active_state = swap_active_state,
1455 .sub_state_to_string = swap_sub_state_to_string,
1457 .check_gc = swap_check_gc,
1459 .sigchld_event = swap_sigchld_event,
1461 .reset_failed = swap_reset_failed,
1463 .bus_interface = "org.freedesktop.systemd1.Swap",
1464 .bus_vtable = bus_swap_vtable,
1465 .bus_set_property = bus_swap_set_property,
1466 .bus_commit_properties = bus_swap_commit_properties,
1468 .following = swap_following,
1469 .following_set = swap_following_set,
1471 .enumerate = swap_enumerate,
1472 .shutdown = swap_shutdown,
1474 .status_message_formats = {
1475 .starting_stopping = {
1476 [0] = "Activating swap %s...",
1477 [1] = "Deactivating swap %s...",
1479 .finished_start_job = {
1480 [JOB_DONE] = "Activated swap %s.",
1481 [JOB_FAILED] = "Failed to activate swap %s.",
1482 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1483 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1485 .finished_stop_job = {
1486 [JOB_DONE] = "Deactivated swap %s.",
1487 [JOB_FAILED] = "Failed deactivating swap %s.",
1488 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",