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 s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
129 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
131 u->ignore_on_isolate = true;
134 static void swap_unwatch_control_pid(Swap *s) {
137 if (s->control_pid <= 0)
140 unit_unwatch_pid(UNIT(s), s->control_pid);
144 static void swap_done(Unit *u) {
149 swap_unset_proc_swaps(s);
150 swap_set_devnode(s, NULL);
155 free(s->parameters_fragment.what);
156 s->parameters_fragment.what = NULL;
158 cgroup_context_done(&s->cgroup_context);
159 exec_context_done(&s->exec_context);
160 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
161 exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
162 s->control_command = NULL;
164 swap_unwatch_control_pid(s);
166 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
169 static int swap_arm_timer(Swap *s) {
174 if (s->timeout_usec <= 0) {
175 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
179 if (s->timer_event_source) {
180 r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec);
184 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
187 return sd_event_add_monotonic(UNIT(s)->manager->event, &s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec, 0, 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) {
306 r = unit_add_exec_dependencies(u, &s->exec_context);
310 if (UNIT(s)->fragment_path)
311 s->from_fragment = true;
314 if (s->parameters_fragment.what)
315 s->what = strdup(s->parameters_fragment.what);
316 else if (s->parameters_proc_swaps.what)
317 s->what = strdup(s->parameters_proc_swaps.what);
319 s->what = unit_name_to_path(u->id);
325 path_kill_slashes(s->what);
327 if (!UNIT(s)->description) {
328 r = unit_set_description(u, s->what);
333 r = unit_require_mounts_for(UNIT(s), s->what);
337 r = swap_add_device_links(s);
341 r = swap_load_devnode(s);
345 r = unit_add_default_slice(u);
349 if (UNIT(s)->default_dependencies) {
350 r = swap_add_default_dependencies(s);
355 r = unit_exec_context_defaults(u, &s->exec_context);
360 return swap_verify(s);
363 static int swap_add_one(
366 const char *what_proc_swaps,
372 _cleanup_free_ char *e = NULL;
380 assert(what_proc_swaps);
382 e = unit_name_from_path(what, ".swap");
386 u = manager_get_unit(m, e);
389 SWAP(u)->from_proc_swaps &&
390 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
396 u = unit_new(m, sizeof(Swap));
400 r = unit_add_name(u, e);
404 SWAP(u)->what = strdup(what);
405 if (!SWAP(u)->what) {
410 unit_add_to_load_queue(u);
414 p = &SWAP(u)->parameters_proc_swaps;
417 p->what = strdup(what_proc_swaps);
425 SWAP(u)->is_active = true;
426 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
429 SWAP(u)->from_proc_swaps = true;
431 p->priority = priority;
435 unit_add_to_dbus_queue(u);
440 log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
448 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
449 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
450 struct udev_list_entry *item = NULL, *first = NULL;
457 r = swap_add_one(m, device, device, prio, false, false, set_flags);
461 /* If this is a block device, then let's add duplicates for
462 * all other names of this block device */
463 if (stat(device, &st) < 0 || !S_ISBLK(st.st_mode))
466 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
470 /* Add the main device node */
471 dn = udev_device_get_devnode(d);
472 if (dn && !streq(dn, device))
473 swap_add_one(m, dn, device, prio, false, false, set_flags);
475 /* Add additional units for all symlinks */
476 first = udev_device_get_devlinks_list_entry(d);
477 udev_list_entry_foreach(item, first) {
480 /* Don't bother with the /dev/block links */
481 p = udev_list_entry_get_name(item);
483 if (streq(p, device))
486 if (path_startswith(p, "/dev/block/"))
489 if (stat(p, &st) >= 0)
490 if (!S_ISBLK(st.st_mode) ||
491 st.st_rdev != udev_device_get_devnum(d))
494 swap_add_one(m, p, device, prio, false, false, set_flags);
500 static void swap_set_state(Swap *s, SwapState state) {
505 old_state = s->state;
508 if (state != SWAP_ACTIVATING &&
509 state != SWAP_ACTIVATING_SIGTERM &&
510 state != SWAP_ACTIVATING_SIGKILL &&
511 state != SWAP_ACTIVATING_DONE &&
512 state != SWAP_DEACTIVATING &&
513 state != SWAP_DEACTIVATING_SIGTERM &&
514 state != SWAP_DEACTIVATING_SIGKILL) {
515 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
516 swap_unwatch_control_pid(s);
517 s->control_command = NULL;
518 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
521 if (state != old_state)
522 log_debug_unit(UNIT(s)->id,
523 "%s changed %s -> %s",
525 swap_state_to_string(old_state),
526 swap_state_to_string(state));
528 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
531 static int swap_coldplug(Unit *u) {
533 SwapState new_state = SWAP_DEAD;
537 assert(s->state == SWAP_DEAD);
539 if (s->deserialized_state != s->state)
540 new_state = s->deserialized_state;
541 else if (s->from_proc_swaps)
542 new_state = SWAP_ACTIVE;
544 if (new_state == s->state)
547 if (new_state == SWAP_ACTIVATING ||
548 new_state == SWAP_ACTIVATING_SIGTERM ||
549 new_state == SWAP_ACTIVATING_SIGKILL ||
550 new_state == SWAP_ACTIVATING_DONE ||
551 new_state == SWAP_DEACTIVATING ||
552 new_state == SWAP_DEACTIVATING_SIGTERM ||
553 new_state == SWAP_DEACTIVATING_SIGKILL) {
555 if (s->control_pid <= 0)
558 r = unit_watch_pid(UNIT(s), s->control_pid);
562 r = swap_arm_timer(s);
567 swap_set_state(s, new_state);
571 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
578 if (s->from_proc_swaps)
579 p = &s->parameters_proc_swaps;
580 else if (s->from_fragment)
581 p = &s->parameters_fragment;
589 "%sFrom /proc/swaps: %s\n"
590 "%sFrom fragment: %s\n",
591 prefix, swap_state_to_string(s->state),
592 prefix, swap_result_to_string(s->result),
594 prefix, yes_no(s->from_proc_swaps),
595 prefix, yes_no(s->from_fragment));
598 fprintf(f, "%sDevice Node: %s\n", prefix, s->devnode);
606 prefix, yes_no(p->noauto),
607 prefix, yes_no(p->nofail));
609 if (s->control_pid > 0)
611 "%sControl PID: %lu\n",
612 prefix, (unsigned long) s->control_pid);
614 exec_context_dump(&s->exec_context, f, prefix);
615 kill_context_dump(&s->kill_context, f, prefix);
618 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
626 unit_realize_cgroup(UNIT(s));
628 r = unit_setup_exec_runtime(UNIT(s));
632 r = swap_arm_timer(s);
640 UNIT(s)->manager->environment,
644 UNIT(s)->manager->confirm_spawn,
645 UNIT(s)->manager->cgroup_supported,
646 UNIT(s)->cgroup_path,
655 r = unit_watch_pid(UNIT(s), pid);
657 /* FIXME: we need to do something here */
665 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
670 static void swap_enter_dead(Swap *s, SwapResult f) {
673 if (f != SWAP_SUCCESS)
676 exec_runtime_destroy(s->exec_runtime);
677 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
679 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
682 static void swap_enter_active(Swap *s, SwapResult f) {
685 if (f != SWAP_SUCCESS)
688 swap_set_state(s, SWAP_ACTIVE);
691 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
696 if (f != SWAP_SUCCESS)
699 r = unit_kill_context(
702 state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
710 r = swap_arm_timer(s);
714 swap_set_state(s, state);
715 } else if (state == SWAP_ACTIVATING_SIGTERM)
716 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_SUCCESS);
717 else if (state == SWAP_DEACTIVATING_SIGTERM)
718 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_SUCCESS);
720 swap_enter_dead(s, SWAP_SUCCESS);
725 log_warning_unit(UNIT(s)->id,
726 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
728 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
731 static void swap_enter_activating(Swap *s) {
736 s->control_command_id = SWAP_EXEC_ACTIVATE;
737 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
739 if (s->from_fragment)
740 priority = s->parameters_fragment.priority;
745 char p[DECIMAL_STR_MAX(int)];
747 sprintf(p, "%i", priority);
749 r = exec_command_set(
757 r = exec_command_set(
766 swap_unwatch_control_pid(s);
768 r = swap_spawn(s, s->control_command, &s->control_pid);
772 swap_set_state(s, SWAP_ACTIVATING);
777 log_warning_unit(UNIT(s)->id,
778 "%s failed to run 'swapon' task: %s",
779 UNIT(s)->id, strerror(-r));
780 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
783 static void swap_enter_deactivating(Swap *s) {
788 s->control_command_id = SWAP_EXEC_DEACTIVATE;
789 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
791 r = exec_command_set(s->control_command,
798 swap_unwatch_control_pid(s);
800 r = swap_spawn(s, s->control_command, &s->control_pid);
804 swap_set_state(s, SWAP_DEACTIVATING);
809 log_warning_unit(UNIT(s)->id,
810 "%s failed to run 'swapoff' task: %s",
811 UNIT(s)->id, strerror(-r));
812 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
815 static int swap_start(Unit *u) {
820 /* We cannot fulfill this request right now, try again later
823 if (s->state == SWAP_DEACTIVATING ||
824 s->state == SWAP_DEACTIVATING_SIGTERM ||
825 s->state == SWAP_DEACTIVATING_SIGKILL ||
826 s->state == SWAP_ACTIVATING_SIGTERM ||
827 s->state == SWAP_ACTIVATING_SIGKILL)
830 if (s->state == SWAP_ACTIVATING)
833 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
835 if (detect_container(NULL) > 0)
838 s->result = SWAP_SUCCESS;
839 swap_enter_activating(s);
843 static int swap_stop(Unit *u) {
848 if (s->state == SWAP_DEACTIVATING ||
849 s->state == SWAP_DEACTIVATING_SIGTERM ||
850 s->state == SWAP_DEACTIVATING_SIGKILL ||
851 s->state == SWAP_ACTIVATING_SIGTERM ||
852 s->state == SWAP_ACTIVATING_SIGKILL)
855 assert(s->state == SWAP_ACTIVATING ||
856 s->state == SWAP_ACTIVATING_DONE ||
857 s->state == SWAP_ACTIVE);
859 if (detect_container(NULL) > 0)
862 swap_enter_deactivating(s);
866 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
873 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
874 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
876 if (s->control_pid > 0)
877 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
879 if (s->control_command_id >= 0)
880 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
885 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
891 if (streq(key, "state")) {
894 state = swap_state_from_string(value);
896 log_debug_unit(u->id, "Failed to parse state value %s", value);
898 s->deserialized_state = state;
899 } else if (streq(key, "result")) {
902 f = swap_result_from_string(value);
904 log_debug_unit(u->id, "Failed to parse result value %s", value);
905 else if (f != SWAP_SUCCESS)
907 } else if (streq(key, "control-pid")) {
910 if (parse_pid(value, &pid) < 0)
911 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
913 s->control_pid = pid;
915 } else if (streq(key, "control-command")) {
918 id = swap_exec_command_from_string(value);
920 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
922 s->control_command_id = id;
923 s->control_command = s->exec_command + id;
926 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
931 _pure_ static UnitActiveState swap_active_state(Unit *u) {
934 return state_translation_table[SWAP(u)->state];
937 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
940 return swap_state_to_string(SWAP(u)->state);
943 _pure_ static bool swap_check_gc(Unit *u) {
948 return s->from_proc_swaps;
951 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
958 if (pid != s->control_pid)
963 if (is_clean_exit(code, status, NULL))
965 else if (code == CLD_EXITED)
966 f = SWAP_FAILURE_EXIT_CODE;
967 else if (code == CLD_KILLED)
968 f = SWAP_FAILURE_SIGNAL;
969 else if (code == CLD_DUMPED)
970 f = SWAP_FAILURE_CORE_DUMP;
972 assert_not_reached("Unknown code");
974 if (f != SWAP_SUCCESS)
977 if (s->control_command) {
978 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
980 s->control_command = NULL;
981 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
984 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
986 "%s swap process exited, code=%s status=%i",
987 u->id, sigchld_code_to_string(code), status);
991 case SWAP_ACTIVATING:
992 case SWAP_ACTIVATING_DONE:
993 case SWAP_ACTIVATING_SIGTERM:
994 case SWAP_ACTIVATING_SIGKILL:
996 if (f == SWAP_SUCCESS)
997 swap_enter_active(s, f);
999 swap_enter_dead(s, f);
1002 case SWAP_DEACTIVATING:
1003 case SWAP_DEACTIVATING_SIGKILL:
1004 case SWAP_DEACTIVATING_SIGTERM:
1006 swap_enter_dead(s, f);
1010 assert_not_reached("Uh, control process died at wrong time.");
1013 /* Notify clients about changed exit status */
1014 unit_add_to_dbus_queue(u);
1017 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1018 Swap *s = SWAP(userdata);
1021 assert(s->timer_event_source == source);
1025 case SWAP_ACTIVATING:
1026 case SWAP_ACTIVATING_DONE:
1027 log_warning_unit(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
1028 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1031 case SWAP_DEACTIVATING:
1032 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
1033 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1036 case SWAP_ACTIVATING_SIGTERM:
1037 if (s->kill_context.send_sigkill) {
1038 log_warning_unit(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
1039 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1041 log_warning_unit(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1042 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1046 case SWAP_DEACTIVATING_SIGTERM:
1047 if (s->kill_context.send_sigkill) {
1048 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
1049 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1051 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1052 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1056 case SWAP_ACTIVATING_SIGKILL:
1057 case SWAP_DEACTIVATING_SIGKILL:
1058 log_warning_unit(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
1059 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1063 assert_not_reached("Timeout at wrong time.");
1069 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1075 rewind(m->proc_swaps);
1077 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1080 _cleanup_free_ char *dev = NULL, *d = NULL;
1083 k = fscanf(m->proc_swaps,
1084 "%ms " /* device/file */
1085 "%*s " /* type of swap */
1086 "%*s " /* swap size */
1088 "%i\n", /* priority */
1094 log_warning("Failed to parse /proc/swaps:%u", i);
1102 k = swap_process_new_swap(m, d, prio, set_flags);
1110 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1111 Manager *m = userdata;
1116 assert(revents & EPOLLPRI);
1118 r = swap_load_proc_swaps(m, true);
1120 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1122 /* Reset flags, just in case, for late calls */
1123 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1124 Swap *swap = SWAP(u);
1126 swap->is_active = swap->just_activated = false;
1132 manager_dispatch_load_queue(m);
1134 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1135 Swap *swap = SWAP(u);
1137 if (!swap->is_active) {
1138 /* This has just been deactivated */
1140 swap_unset_proc_swaps(swap);
1142 switch (swap->state) {
1145 swap_enter_dead(swap, SWAP_SUCCESS);
1150 swap_set_state(swap, swap->state);
1154 } else if (swap->just_activated) {
1156 /* New swap entry */
1158 switch (swap->state) {
1162 swap_enter_active(swap, SWAP_SUCCESS);
1165 case SWAP_ACTIVATING:
1166 swap_set_state(swap, SWAP_ACTIVATING_DONE);
1170 /* Nothing really changed, but let's
1171 * issue an notification call
1172 * nonetheless, in case somebody is
1173 * waiting for this. */
1174 swap_set_state(swap, swap->state);
1179 /* Reset the flags for later calls */
1180 swap->is_active = swap->just_activated = false;
1186 static Unit *swap_following(Unit *u) {
1188 Swap *other, *first = NULL;
1192 if (streq_ptr(s->what, s->devnode))
1195 /* Make everybody follow the unit that's named after the swap
1196 * device in the kernel */
1198 LIST_FOREACH_AFTER(same_devnode, other, s)
1199 if (streq_ptr(other->what, other->devnode))
1202 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1203 if (streq_ptr(other->what, other->devnode))
1212 static int swap_following_set(Unit *u, Set **_set) {
1213 Swap *s = SWAP(u), *other;
1220 if (LIST_JUST_US(same_devnode, s)) {
1225 set = set_new(NULL, NULL);
1229 LIST_FOREACH_AFTER(same_devnode, other, s) {
1230 r = set_put(set, other);
1235 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1236 r = set_put(set, other);
1249 static void swap_shutdown(Manager *m) {
1252 m->swap_event_source = sd_event_source_unref(m->swap_event_source);
1254 if (m->proc_swaps) {
1255 fclose(m->proc_swaps);
1256 m->proc_swaps = NULL;
1259 hashmap_free(m->swaps_by_devnode);
1260 m->swaps_by_devnode = NULL;
1263 static int swap_enumerate(Manager *m) {
1268 if (!m->proc_swaps) {
1269 m->proc_swaps = fopen("/proc/swaps", "re");
1271 return errno == ENOENT ? 0 : -errno;
1273 r = sd_event_add_io(m->event, &m->swap_event_source, fileno(m->proc_swaps), EPOLLPRI, swap_dispatch_io, m);
1277 /* Dispatch this before we dispatch SIGCHLD, so that
1278 * we always get the events from /proc/swaps before
1279 * the SIGCHLD of /sbin/swapon. */
1280 r = sd_event_source_set_priority(m->swap_event_source, -10);
1285 r = swap_load_proc_swaps(m, false);
1296 int swap_process_new_device(Manager *m, struct udev_device *dev) {
1297 struct udev_list_entry *item = NULL, *first = NULL;
1298 _cleanup_free_ char *e = NULL;
1306 dn = udev_device_get_devnode(dev);
1310 e = unit_name_from_path(dn, ".swap");
1314 s = hashmap_get(m->units, e);
1316 r = swap_set_devnode(s, dn);
1318 first = udev_device_get_devlinks_list_entry(dev);
1319 udev_list_entry_foreach(item, first) {
1320 _cleanup_free_ char *n = NULL;
1322 n = unit_name_from_path(udev_list_entry_get_name(item), ".swap");
1326 s = hashmap_get(m->units, n);
1330 q = swap_set_devnode(s, dn);
1339 int swap_process_removed_device(Manager *m, struct udev_device *dev) {
1344 dn = udev_device_get_devnode(dev);
1348 while ((s = hashmap_get(m->swaps_by_devnode, dn))) {
1351 q = swap_set_devnode(s, NULL);
1359 static void swap_reset_failed(Unit *u) {
1364 if (s->state == SWAP_FAILED)
1365 swap_set_state(s, SWAP_DEAD);
1367 s->result = SWAP_SUCCESS;
1370 static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1371 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1374 static int swap_get_timeout(Unit *u, uint64_t *timeout) {
1378 if (!s->timer_event_source)
1381 r = sd_event_source_get_time(s->timer_event_source, timeout);
1388 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1389 [SWAP_DEAD] = "dead",
1390 [SWAP_ACTIVATING] = "activating",
1391 [SWAP_ACTIVATING_DONE] = "activating-done",
1392 [SWAP_ACTIVE] = "active",
1393 [SWAP_DEACTIVATING] = "deactivating",
1394 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1395 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1396 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1397 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1398 [SWAP_FAILED] = "failed"
1401 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1403 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1404 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1405 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1408 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1410 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1411 [SWAP_SUCCESS] = "success",
1412 [SWAP_FAILURE_RESOURCES] = "resources",
1413 [SWAP_FAILURE_TIMEOUT] = "timeout",
1414 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1415 [SWAP_FAILURE_SIGNAL] = "signal",
1416 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1419 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1421 const UnitVTable swap_vtable = {
1422 .object_size = sizeof(Swap),
1423 .exec_context_offset = offsetof(Swap, exec_context),
1424 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1425 .kill_context_offset = offsetof(Swap, kill_context),
1426 .exec_runtime_offset = offsetof(Swap, exec_runtime),
1432 .private_section = "Swap",
1435 .no_instances = true,
1441 .coldplug = swap_coldplug,
1445 .start = swap_start,
1450 .get_timeout = swap_get_timeout,
1452 .serialize = swap_serialize,
1453 .deserialize_item = swap_deserialize_item,
1455 .active_state = swap_active_state,
1456 .sub_state_to_string = swap_sub_state_to_string,
1458 .check_gc = swap_check_gc,
1460 .sigchld_event = swap_sigchld_event,
1462 .reset_failed = swap_reset_failed,
1464 .bus_interface = "org.freedesktop.systemd1.Swap",
1465 .bus_vtable = bus_swap_vtable,
1466 .bus_set_property = bus_swap_set_property,
1467 .bus_commit_properties = bus_swap_commit_properties,
1469 .following = swap_following,
1470 .following_set = swap_following_set,
1472 .enumerate = swap_enumerate,
1473 .shutdown = swap_shutdown,
1475 .status_message_formats = {
1476 .starting_stopping = {
1477 [0] = "Activating swap %s...",
1478 [1] = "Deactivating swap %s...",
1480 .finished_start_job = {
1481 [JOB_DONE] = "Activated swap %s.",
1482 [JOB_FAILED] = "Failed to activate swap %s.",
1483 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1484 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1486 .finished_stop_job = {
1487 [JOB_DONE] = "Deactivated swap %s.",
1488 [JOB_FAILED] = "Failed deactivating swap %s.",
1489 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",