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) {
67 if (!s->parameters_proc_swaps.what)
70 /* Remove this unit from the chain of swaps which share the
71 * same kernel swap device. */
72 swaps = UNIT(s)->manager->swaps_by_proc_swaps;
73 first = hashmap_get(swaps, s->parameters_proc_swaps.what);
74 LIST_REMOVE(same_proc_swaps, first, s);
77 hashmap_remove_and_replace(swaps, s->parameters_proc_swaps.what, first->parameters_proc_swaps.what, first);
79 hashmap_remove(swaps, s->parameters_proc_swaps.what);
81 free(s->parameters_proc_swaps.what);
82 s->parameters_proc_swaps.what = NULL;
84 s->from_proc_swaps = false;
87 static void swap_init(Unit *u) {
91 assert(UNIT(s)->load_state == UNIT_STUB);
93 s->timeout_usec = u->manager->default_timeout_start_usec;
95 exec_context_init(&s->exec_context);
96 s->exec_context.std_output = u->manager->default_std_output;
97 s->exec_context.std_error = u->manager->default_std_error;
98 kill_context_init(&s->kill_context);
99 cgroup_context_init(&s->cgroup_context);
101 s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
103 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
105 u->ignore_on_isolate = true;
108 static void swap_unwatch_control_pid(Swap *s) {
111 if (s->control_pid <= 0)
114 unit_unwatch_pid(UNIT(s), s->control_pid);
118 static void swap_done(Unit *u) {
123 swap_unset_proc_swaps(s);
128 free(s->parameters_fragment.what);
129 s->parameters_fragment.what = NULL;
131 exec_context_done(&s->exec_context, manager_is_reloading_or_reexecuting(u->manager));
132 exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
133 s->control_command = NULL;
135 cgroup_context_done(&s->cgroup_context);
137 swap_unwatch_control_pid(s);
139 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
142 static int swap_arm_timer(Swap *s) {
147 if (s->timeout_usec <= 0) {
148 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
152 if (s->timer_event_source) {
153 r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec);
157 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
160 return sd_event_add_monotonic(UNIT(s)->manager->event, now(CLOCK_MONOTONIC) + s->timeout_usec, 0, swap_dispatch_timer, s, &s->timer_event_source);
163 static int swap_add_device_links(Swap *s) {
171 if (s->from_fragment)
172 p = &s->parameters_fragment;
176 if (is_device_path(s->what))
177 return unit_add_node_link(UNIT(s), s->what, !p->noauto && UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
179 /* File based swap devices need to be ordered after
180 * systemd-remount-fs.service, since they might need a
181 * writable file system. */
182 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
185 static int swap_add_default_dependencies(Swap *s) {
186 bool nofail = false, noauto = false;
191 if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
194 if (detect_container(NULL) > 0)
197 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
201 if (s->from_fragment) {
202 SwapParameters *p = &s->parameters_fragment;
210 r = unit_add_dependency_by_name_inverse(UNIT(s), UNIT_WANTS, SPECIAL_SWAP_TARGET, NULL, true);
212 r = unit_add_two_dependencies_by_name_inverse(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SWAP_TARGET, NULL, true);
220 static int swap_verify(Swap *s) {
222 _cleanup_free_ char *e = NULL;
224 if (UNIT(s)->load_state != UNIT_LOADED)
227 e = unit_name_from_path(s->what, ".swap");
231 b = unit_has_name(UNIT(s), e);
233 log_error_unit(UNIT(s)->id, "%s: Value of \"What\" and unit name do not match, not loading.", UNIT(s)->id);
237 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
238 log_error_unit(UNIT(s)->id, "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.", UNIT(s)->id);
245 static int swap_load(Unit *u) {
250 assert(u->load_state == UNIT_STUB);
252 /* Load a .swap file */
253 r = unit_load_fragment_and_dropin_optional(u);
257 if (u->load_state == UNIT_LOADED) {
258 r = unit_add_exec_dependencies(u, &s->exec_context);
262 if (UNIT(s)->fragment_path)
263 s->from_fragment = true;
266 if (s->parameters_fragment.what)
267 s->what = strdup(s->parameters_fragment.what);
268 else if (s->parameters_proc_swaps.what)
269 s->what = strdup(s->parameters_proc_swaps.what);
271 s->what = unit_name_to_path(u->id);
277 path_kill_slashes(s->what);
279 if (!UNIT(s)->description) {
280 r = unit_set_description(u, s->what);
285 r = unit_require_mounts_for(UNIT(s), s->what);
289 r = swap_add_device_links(s);
293 r = unit_add_default_slice(u);
297 if (UNIT(s)->default_dependencies) {
298 r = swap_add_default_dependencies(s);
303 r = unit_exec_context_defaults(u, &s->exec_context);
308 return swap_verify(s);
311 static int swap_add_one(
314 const char *what_proc_swaps,
320 _cleanup_free_ char *e = NULL;
329 assert(what_proc_swaps);
331 e = unit_name_from_path(what, ".swap");
335 u = manager_get_unit(m, e);
338 SWAP(u)->from_proc_swaps &&
339 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
345 u = unit_new(m, sizeof(Swap));
349 r = unit_add_name(u, e);
353 SWAP(u)->what = strdup(what);
354 if (!SWAP(u)->what) {
359 unit_add_to_load_queue(u);
363 p = &SWAP(u)->parameters_proc_swaps;
366 p->what = strdup(what_proc_swaps);
372 r = hashmap_ensure_allocated(&m->swaps_by_proc_swaps, string_hash_func, string_compare_func);
376 first = hashmap_get(m->swaps_by_proc_swaps, p->what);
377 LIST_PREPEND(same_proc_swaps, first, SWAP(u));
379 r = hashmap_replace(m->swaps_by_proc_swaps, p->what, first);
385 SWAP(u)->is_active = true;
386 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
389 SWAP(u)->from_proc_swaps = true;
391 p->priority = priority;
395 unit_add_to_dbus_queue(u);
400 log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
408 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
409 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
410 struct udev_list_entry *item = NULL, *first = NULL;
417 r = swap_add_one(m, device, device, prio, false, false, set_flags);
421 /* If this is a block device, then let's add duplicates for
422 * all other names of this block device */
423 if (stat(device, &st) < 0 || !S_ISBLK(st.st_mode))
426 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
430 /* Add the main device node */
431 dn = udev_device_get_devnode(d);
432 if (dn && !streq(dn, device))
433 swap_add_one(m, dn, device, prio, false, false, set_flags);
435 /* Add additional units for all symlinks */
436 first = udev_device_get_devlinks_list_entry(d);
437 udev_list_entry_foreach(item, first) {
440 /* Don't bother with the /dev/block links */
441 p = udev_list_entry_get_name(item);
443 if (streq(p, device))
446 if (path_startswith(p, "/dev/block/"))
449 if (stat(p, &st) >= 0)
450 if (!S_ISBLK(st.st_mode) ||
451 st.st_rdev != udev_device_get_devnum(d))
454 swap_add_one(m, p, device, prio, false, false, set_flags);
460 static void swap_set_state(Swap *s, SwapState state) {
465 old_state = s->state;
468 if (state != SWAP_ACTIVATING &&
469 state != SWAP_ACTIVATING_SIGTERM &&
470 state != SWAP_ACTIVATING_SIGKILL &&
471 state != SWAP_ACTIVATING_DONE &&
472 state != SWAP_DEACTIVATING &&
473 state != SWAP_DEACTIVATING_SIGTERM &&
474 state != SWAP_DEACTIVATING_SIGKILL) {
475 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
476 swap_unwatch_control_pid(s);
477 s->control_command = NULL;
478 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
481 if (state != old_state)
482 log_debug_unit(UNIT(s)->id,
483 "%s changed %s -> %s",
485 swap_state_to_string(old_state),
486 swap_state_to_string(state));
488 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
491 static int swap_coldplug(Unit *u) {
493 SwapState new_state = SWAP_DEAD;
497 assert(s->state == SWAP_DEAD);
499 if (s->deserialized_state != s->state)
500 new_state = s->deserialized_state;
501 else if (s->from_proc_swaps)
502 new_state = SWAP_ACTIVE;
504 if (new_state == s->state)
507 if (new_state == SWAP_ACTIVATING ||
508 new_state == SWAP_ACTIVATING_SIGTERM ||
509 new_state == SWAP_ACTIVATING_SIGKILL ||
510 new_state == SWAP_ACTIVATING_DONE ||
511 new_state == SWAP_DEACTIVATING ||
512 new_state == SWAP_DEACTIVATING_SIGTERM ||
513 new_state == SWAP_DEACTIVATING_SIGKILL) {
515 if (s->control_pid <= 0)
518 r = unit_watch_pid(UNIT(s), s->control_pid);
522 r = swap_arm_timer(s);
527 swap_set_state(s, new_state);
531 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
538 if (s->from_proc_swaps)
539 p = &s->parameters_proc_swaps;
540 else if (s->from_fragment)
541 p = &s->parameters_fragment;
549 "%sFrom /proc/swaps: %s\n"
550 "%sFrom fragment: %s\n",
551 prefix, swap_state_to_string(s->state),
552 prefix, swap_result_to_string(s->result),
554 prefix, yes_no(s->from_proc_swaps),
555 prefix, yes_no(s->from_fragment));
563 prefix, yes_no(p->noauto),
564 prefix, yes_no(p->nofail));
566 if (s->control_pid > 0)
568 "%sControl PID: %lu\n",
569 prefix, (unsigned long) s->control_pid);
571 exec_context_dump(&s->exec_context, f, prefix);
572 kill_context_dump(&s->kill_context, f, prefix);
575 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
583 unit_realize_cgroup(UNIT(s));
585 r = swap_arm_timer(s);
593 UNIT(s)->manager->environment,
597 UNIT(s)->manager->confirm_spawn,
598 UNIT(s)->manager->cgroup_supported,
599 UNIT(s)->cgroup_path,
606 r = unit_watch_pid(UNIT(s), pid);
608 /* FIXME: we need to do something here */
616 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
621 static void swap_enter_dead(Swap *s, SwapResult f) {
624 if (f != SWAP_SUCCESS)
627 exec_context_tmp_dirs_done(&s->exec_context);
628 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
631 static void swap_enter_active(Swap *s, SwapResult f) {
634 if (f != SWAP_SUCCESS)
637 swap_set_state(s, SWAP_ACTIVE);
640 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
645 if (f != SWAP_SUCCESS)
648 r = unit_kill_context(
651 state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
659 r = swap_arm_timer(s);
663 swap_set_state(s, state);
665 swap_enter_dead(s, SWAP_SUCCESS);
670 log_warning_unit(UNIT(s)->id,
671 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
673 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
676 static void swap_enter_activating(Swap *s) {
681 s->control_command_id = SWAP_EXEC_ACTIVATE;
682 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
684 if (s->from_fragment)
685 priority = s->parameters_fragment.priority;
690 char p[DECIMAL_STR_MAX(int)];
692 sprintf(p, "%i", priority);
694 r = exec_command_set(
702 r = exec_command_set(
711 swap_unwatch_control_pid(s);
713 r = swap_spawn(s, s->control_command, &s->control_pid);
717 swap_set_state(s, SWAP_ACTIVATING);
722 log_warning_unit(UNIT(s)->id,
723 "%s failed to run 'swapon' task: %s",
724 UNIT(s)->id, strerror(-r));
725 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
728 static void swap_enter_deactivating(Swap *s) {
733 s->control_command_id = SWAP_EXEC_DEACTIVATE;
734 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
736 r = exec_command_set(s->control_command,
743 swap_unwatch_control_pid(s);
745 r = swap_spawn(s, s->control_command, &s->control_pid);
749 swap_set_state(s, SWAP_DEACTIVATING);
754 log_warning_unit(UNIT(s)->id,
755 "%s failed to run 'swapoff' task: %s",
756 UNIT(s)->id, strerror(-r));
757 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
760 static int swap_start(Unit *u) {
765 /* We cannot fulfill this request right now, try again later
768 if (s->state == SWAP_DEACTIVATING ||
769 s->state == SWAP_DEACTIVATING_SIGTERM ||
770 s->state == SWAP_DEACTIVATING_SIGKILL ||
771 s->state == SWAP_ACTIVATING_SIGTERM ||
772 s->state == SWAP_ACTIVATING_SIGKILL)
775 if (s->state == SWAP_ACTIVATING)
778 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
780 if (detect_container(NULL) > 0)
783 s->result = SWAP_SUCCESS;
784 swap_enter_activating(s);
788 static int swap_stop(Unit *u) {
793 if (s->state == SWAP_DEACTIVATING ||
794 s->state == SWAP_DEACTIVATING_SIGTERM ||
795 s->state == SWAP_DEACTIVATING_SIGKILL ||
796 s->state == SWAP_ACTIVATING_SIGTERM ||
797 s->state == SWAP_ACTIVATING_SIGKILL)
800 assert(s->state == SWAP_ACTIVATING ||
801 s->state == SWAP_ACTIVATING_DONE ||
802 s->state == SWAP_ACTIVE);
804 if (detect_container(NULL) > 0)
807 swap_enter_deactivating(s);
811 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
818 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
819 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
821 if (s->control_pid > 0)
822 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
824 if (s->control_command_id >= 0)
825 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
827 exec_context_serialize(&s->exec_context, UNIT(s), f);
832 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
838 if (streq(key, "state")) {
841 state = swap_state_from_string(value);
843 log_debug_unit(u->id, "Failed to parse state value %s", value);
845 s->deserialized_state = state;
846 } else if (streq(key, "result")) {
849 f = swap_result_from_string(value);
851 log_debug_unit(u->id, "Failed to parse result value %s", value);
852 else if (f != SWAP_SUCCESS)
854 } else if (streq(key, "control-pid")) {
857 if (parse_pid(value, &pid) < 0)
858 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
860 s->control_pid = pid;
862 } else if (streq(key, "control-command")) {
865 id = swap_exec_command_from_string(value);
867 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
869 s->control_command_id = id;
870 s->control_command = s->exec_command + id;
872 } else if (streq(key, "tmp-dir")) {
879 s->exec_context.tmp_dir = t;
880 } else if (streq(key, "var-tmp-dir")) {
887 s->exec_context.var_tmp_dir = t;
889 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
894 _pure_ static UnitActiveState swap_active_state(Unit *u) {
897 return state_translation_table[SWAP(u)->state];
900 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
903 return swap_state_to_string(SWAP(u)->state);
906 _pure_ static bool swap_check_gc(Unit *u) {
911 return s->from_proc_swaps;
914 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
921 if (pid != s->control_pid)
926 if (is_clean_exit(code, status, NULL))
928 else if (code == CLD_EXITED)
929 f = SWAP_FAILURE_EXIT_CODE;
930 else if (code == CLD_KILLED)
931 f = SWAP_FAILURE_SIGNAL;
932 else if (code == CLD_DUMPED)
933 f = SWAP_FAILURE_CORE_DUMP;
935 assert_not_reached("Unknown code");
937 if (f != SWAP_SUCCESS)
940 if (s->control_command) {
941 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
943 s->control_command = NULL;
944 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
947 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
949 "%s swap process exited, code=%s status=%i",
950 u->id, sigchld_code_to_string(code), status);
954 case SWAP_ACTIVATING:
955 case SWAP_ACTIVATING_DONE:
956 case SWAP_ACTIVATING_SIGTERM:
957 case SWAP_ACTIVATING_SIGKILL:
959 if (f == SWAP_SUCCESS)
960 swap_enter_active(s, f);
962 swap_enter_dead(s, f);
965 case SWAP_DEACTIVATING:
966 case SWAP_DEACTIVATING_SIGKILL:
967 case SWAP_DEACTIVATING_SIGTERM:
969 if (f == SWAP_SUCCESS)
970 swap_enter_dead(s, f);
972 swap_enter_dead(s, f);
976 assert_not_reached("Uh, control process died at wrong time.");
979 /* Notify clients about changed exit status */
980 unit_add_to_dbus_queue(u);
983 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
984 Swap *s = SWAP(userdata);
987 assert(s->timer_event_source == source);
991 case SWAP_ACTIVATING:
992 case SWAP_ACTIVATING_DONE:
993 log_warning_unit(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
994 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
997 case SWAP_DEACTIVATING:
998 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
999 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1002 case SWAP_ACTIVATING_SIGTERM:
1003 if (s->kill_context.send_sigkill) {
1004 log_warning_unit(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
1005 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1007 log_warning_unit(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1008 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1012 case SWAP_DEACTIVATING_SIGTERM:
1013 if (s->kill_context.send_sigkill) {
1014 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
1015 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1017 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1018 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1022 case SWAP_ACTIVATING_SIGKILL:
1023 case SWAP_DEACTIVATING_SIGKILL:
1024 log_warning_unit(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
1025 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1029 assert_not_reached("Timeout at wrong time.");
1035 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1041 rewind(m->proc_swaps);
1043 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1046 _cleanup_free_ char *dev = NULL, *d = NULL;
1049 k = fscanf(m->proc_swaps,
1050 "%ms " /* device/file */
1051 "%*s " /* type of swap */
1052 "%*s " /* swap size */
1054 "%i\n", /* priority */
1060 log_warning("Failed to parse /proc/swaps:%u", i);
1068 k = swap_process_new_swap(m, d, prio, set_flags);
1076 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1077 Manager *m = userdata;
1082 assert(revents & EPOLLPRI);
1084 r = swap_load_proc_swaps(m, true);
1086 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1088 /* Reset flags, just in case, for late calls */
1089 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1090 Swap *swap = SWAP(u);
1092 swap->is_active = swap->just_activated = false;
1098 manager_dispatch_load_queue(m);
1100 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1101 Swap *swap = SWAP(u);
1103 if (!swap->is_active) {
1104 /* This has just been deactivated */
1106 swap_unset_proc_swaps(swap);
1108 switch (swap->state) {
1111 swap_enter_dead(swap, SWAP_SUCCESS);
1116 swap_set_state(swap, swap->state);
1120 } else if (swap->just_activated) {
1122 /* New swap entry */
1124 switch (swap->state) {
1128 swap_enter_active(swap, SWAP_SUCCESS);
1131 case SWAP_ACTIVATING:
1132 swap_set_state(swap, SWAP_ACTIVATING_DONE);
1136 /* Nothing really changed, but let's
1137 * issue an notification call
1138 * nonetheless, in case somebody is
1139 * waiting for this. */
1140 swap_set_state(swap, swap->state);
1145 /* Reset the flags for later calls */
1146 swap->is_active = swap->just_activated = false;
1152 static Unit *swap_following(Unit *u) {
1154 Swap *other, *first = NULL;
1158 if (streq_ptr(s->what, s->parameters_proc_swaps.what))
1161 /* Make everybody follow the unit that's named after the swap
1162 * device in the kernel */
1164 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1165 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1168 LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
1169 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1178 static int swap_following_set(Unit *u, Set **_set) {
1179 Swap *s = SWAP(u), *other;
1186 if (LIST_JUST_US(same_proc_swaps, s)) {
1191 set = set_new(NULL, NULL);
1195 LIST_FOREACH_AFTER(same_proc_swaps, other, s) {
1196 r = set_put(set, other);
1201 LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
1202 r = set_put(set, other);
1215 static void swap_shutdown(Manager *m) {
1218 m->swap_event_source = sd_event_source_unref(m->swap_event_source);
1220 if (m->proc_swaps) {
1221 fclose(m->proc_swaps);
1222 m->proc_swaps = NULL;
1225 hashmap_free(m->swaps_by_proc_swaps);
1226 m->swaps_by_proc_swaps = NULL;
1229 static int swap_enumerate(Manager *m) {
1233 if (!m->proc_swaps) {
1234 m->proc_swaps = fopen("/proc/swaps", "re");
1236 return errno == ENOENT ? 0 : -errno;
1238 r = sd_event_add_io(m->event, fileno(m->proc_swaps), EPOLLPRI, swap_dispatch_io, m, &m->swap_event_source);
1242 /* Dispatch this before we dispatch SIGCHLD, so that
1243 * we always get the events from /proc/swaps before
1244 * the SIGCHLD of /sbin/swapon. */
1245 r = sd_event_source_set_priority(m->swap_event_source, -10);
1250 r = swap_load_proc_swaps(m, false);
1261 static void swap_reset_failed(Unit *u) {
1266 if (s->state == SWAP_FAILED)
1267 swap_set_state(s, SWAP_DEAD);
1269 s->result = SWAP_SUCCESS;
1272 static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1273 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1276 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1277 [SWAP_DEAD] = "dead",
1278 [SWAP_ACTIVATING] = "activating",
1279 [SWAP_ACTIVATING_DONE] = "activating-done",
1280 [SWAP_ACTIVE] = "active",
1281 [SWAP_DEACTIVATING] = "deactivating",
1282 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1283 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1284 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1285 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1286 [SWAP_FAILED] = "failed"
1289 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1291 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1292 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1293 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1296 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1298 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1299 [SWAP_SUCCESS] = "success",
1300 [SWAP_FAILURE_RESOURCES] = "resources",
1301 [SWAP_FAILURE_TIMEOUT] = "timeout",
1302 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1303 [SWAP_FAILURE_SIGNAL] = "signal",
1304 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1307 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1309 const UnitVTable swap_vtable = {
1310 .object_size = sizeof(Swap),
1311 .exec_context_offset = offsetof(Swap, exec_context),
1312 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1313 .kill_context_offset = offsetof(Swap, kill_context),
1319 .private_section = "Swap",
1322 .no_instances = true,
1328 .coldplug = swap_coldplug,
1332 .start = swap_start,
1337 .serialize = swap_serialize,
1338 .deserialize_item = swap_deserialize_item,
1340 .active_state = swap_active_state,
1341 .sub_state_to_string = swap_sub_state_to_string,
1343 .check_gc = swap_check_gc,
1345 .sigchld_event = swap_sigchld_event,
1347 .reset_failed = swap_reset_failed,
1349 .bus_interface = "org.freedesktop.systemd1.Swap",
1350 .bus_vtable = bus_swap_vtable,
1351 .bus_changing_properties = bus_swap_changing_properties,
1352 .bus_set_property = bus_swap_set_property,
1353 .bus_commit_properties = bus_swap_commit_properties,
1355 .following = swap_following,
1356 .following_set = swap_following_set,
1358 .enumerate = swap_enumerate,
1359 .shutdown = swap_shutdown,
1361 .status_message_formats = {
1362 .starting_stopping = {
1363 [0] = "Activating swap %s...",
1364 [1] = "Deactivating swap %s...",
1366 .finished_start_job = {
1367 [JOB_DONE] = "Activated swap %s.",
1368 [JOB_FAILED] = "Failed to activate swap %s.",
1369 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1370 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1372 .finished_stop_job = {
1373 [JOB_DONE] = "Deactivated swap %s.",
1374 [JOB_FAILED] = "Failed deactivating swap %s.",
1375 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",