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"
44 static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
45 [SWAP_DEAD] = UNIT_INACTIVE,
46 [SWAP_ACTIVATING] = UNIT_ACTIVATING,
47 [SWAP_ACTIVE] = UNIT_ACTIVE,
48 [SWAP_DEACTIVATING] = UNIT_DEACTIVATING,
49 [SWAP_ACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
50 [SWAP_ACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
51 [SWAP_DEACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
52 [SWAP_DEACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
53 [SWAP_FAILED] = UNIT_FAILED
56 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
57 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
59 static void swap_unset_proc_swaps(Swap *s) {
65 if (!s->parameters_proc_swaps.what)
68 /* Remove this unit from the chain of swaps which share the
69 * same kernel swap device. */
70 swaps = UNIT(s)->manager->swaps_by_proc_swaps;
71 first = hashmap_get(swaps, s->parameters_proc_swaps.what);
72 LIST_REMOVE(same_proc_swaps, first, s);
75 hashmap_remove_and_replace(swaps,
76 s->parameters_proc_swaps.what,
77 first->parameters_proc_swaps.what,
80 hashmap_remove(swaps, s->parameters_proc_swaps.what);
82 free(s->parameters_proc_swaps.what);
83 s->parameters_proc_swaps.what = NULL;
86 static void swap_init(Unit *u) {
90 assert(UNIT(s)->load_state == UNIT_STUB);
92 s->timeout_usec = u->manager->default_timeout_start_usec;
94 exec_context_init(&s->exec_context);
95 s->exec_context.std_output = u->manager->default_std_output;
96 s->exec_context.std_error = u->manager->default_std_error;
97 kill_context_init(&s->kill_context);
98 cgroup_context_init(&s->cgroup_context);
100 s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
102 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
104 UNIT(s)->ignore_on_isolate = true;
107 static void swap_unwatch_control_pid(Swap *s) {
110 if (s->control_pid <= 0)
113 unit_unwatch_pid(UNIT(s), s->control_pid);
117 static void swap_done(Unit *u) {
122 swap_unset_proc_swaps(s);
127 free(s->parameters_fragment.what);
128 s->parameters_fragment.what = NULL;
130 exec_context_done(&s->exec_context, manager_is_reloading_or_reexecuting(u->manager));
131 exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
132 s->control_command = NULL;
134 cgroup_context_done(&s->cgroup_context);
136 swap_unwatch_control_pid(s);
138 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
141 static int swap_arm_timer(Swap *s) {
146 if (s->timeout_usec <= 0) {
147 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
151 if (s->timer_event_source) {
152 r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec);
156 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
159 return sd_event_add_monotonic(UNIT(s)->manager->event, now(CLOCK_MONOTONIC) + s->timeout_usec, 0, swap_dispatch_timer, s, &s->timer_event_source);
162 static int swap_add_device_links(Swap *s) {
170 if (s->from_fragment)
171 p = &s->parameters_fragment;
175 if (is_device_path(s->what))
176 return unit_add_node_link(UNIT(s), s->what, !p->noauto &&
177 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),
211 UNIT_WANTS, SPECIAL_SWAP_TARGET, NULL, true);
213 r = unit_add_two_dependencies_by_name_inverse(UNIT(s),
214 UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SWAP_TARGET, NULL, true);
222 static int swap_verify(Swap *s) {
224 _cleanup_free_ char *e = NULL;
226 if (UNIT(s)->load_state != UNIT_LOADED)
229 e = unit_name_from_path(s->what, ".swap");
233 b = unit_has_name(UNIT(s), e);
235 log_error_unit(UNIT(s)->id,
236 "%s: Value of \"What\" and unit name do not match, not loading.",
241 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
242 log_error_unit(UNIT(s)->id,
243 "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.",
251 static int swap_load(Unit *u) {
256 assert(u->load_state == UNIT_STUB);
258 /* Load a .swap file */
259 r = unit_load_fragment_and_dropin_optional(u);
263 if (u->load_state == UNIT_LOADED) {
264 r = unit_add_exec_dependencies(u, &s->exec_context);
268 if (UNIT(s)->fragment_path)
269 s->from_fragment = true;
272 if (s->parameters_fragment.what)
273 s->what = strdup(s->parameters_fragment.what);
274 else if (s->parameters_proc_swaps.what)
275 s->what = strdup(s->parameters_proc_swaps.what);
277 s->what = unit_name_to_path(u->id);
283 path_kill_slashes(s->what);
285 if (!UNIT(s)->description)
286 if ((r = unit_set_description(u, s->what)) < 0)
289 r = unit_require_mounts_for(UNIT(s), s->what);
293 r = swap_add_device_links(s);
297 r = unit_add_default_slice(u);
301 if (UNIT(s)->default_dependencies) {
302 r = swap_add_default_dependencies(s);
307 r = unit_exec_context_defaults(u, &s->exec_context);
312 return swap_verify(s);
315 static int swap_add_one(
318 const char *what_proc_swaps,
325 _cleanup_free_ char *e = NULL;
334 assert(what_proc_swaps);
336 e = unit_name_from_path(what, ".swap");
340 u = manager_get_unit(m, e);
343 SWAP(u)->from_proc_swaps &&
344 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
350 u = unit_new(m, sizeof(Swap));
354 r = unit_add_name(u, e);
358 SWAP(u)->what = strdup(what);
359 if (!SWAP(u)->what) {
364 unit_add_to_load_queue(u);
368 p = &SWAP(u)->parameters_proc_swaps;
371 wp = strdup(what_proc_swaps);
377 if (!m->swaps_by_proc_swaps) {
378 m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func);
379 if (!m->swaps_by_proc_swaps) {
388 first = hashmap_get(m->swaps_by_proc_swaps, wp);
389 LIST_PREPEND(same_proc_swaps, first, SWAP(u));
391 r = hashmap_replace(m->swaps_by_proc_swaps, wp, first);
397 SWAP(u)->is_active = true;
398 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
401 SWAP(u)->from_proc_swaps = true;
403 p->priority = priority;
407 unit_add_to_dbus_queue(u);
412 log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
422 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
428 if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) {
429 struct udev_device *d;
431 struct udev_list_entry *item = NULL, *first = NULL;
433 /* So this is a proper swap device. Create swap units
434 * for all names this swap device is known under */
436 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
440 dn = udev_device_get_devnode(d);
441 /* Skip dn==device, since that case will be handled below */
442 if (dn && !streq(dn, device))
443 r = swap_add_one(m, dn, device, prio, false, false, set_flags);
445 /* Add additional units for all symlinks */
446 first = udev_device_get_devlinks_list_entry(d);
447 udev_list_entry_foreach(item, first) {
450 /* Don't bother with the /dev/block links */
451 p = udev_list_entry_get_name(item);
453 if (path_startswith(p, "/dev/block/"))
456 if (stat(p, &st) >= 0)
457 if ((!S_ISBLK(st.st_mode)) ||
458 st.st_rdev != udev_device_get_devnum(d))
461 k = swap_add_one(m, p, device, prio, false, false, set_flags);
466 udev_device_unref(d);
469 k = swap_add_one(m, device, device, prio, false, false, set_flags);
476 static void swap_set_state(Swap *s, SwapState state) {
481 old_state = s->state;
484 if (state != SWAP_ACTIVATING &&
485 state != SWAP_ACTIVATING_SIGTERM &&
486 state != SWAP_ACTIVATING_SIGKILL &&
487 state != SWAP_DEACTIVATING &&
488 state != SWAP_DEACTIVATING_SIGTERM &&
489 state != SWAP_DEACTIVATING_SIGKILL) {
490 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
491 swap_unwatch_control_pid(s);
492 s->control_command = NULL;
493 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
496 if (state != old_state)
497 log_debug_unit(UNIT(s)->id,
498 "%s changed %s -> %s",
500 swap_state_to_string(old_state),
501 swap_state_to_string(state));
503 unit_notify(UNIT(s), state_translation_table[old_state],
504 state_translation_table[state], true);
507 static int swap_coldplug(Unit *u) {
509 SwapState new_state = SWAP_DEAD;
513 assert(s->state == SWAP_DEAD);
515 if (s->deserialized_state != s->state)
516 new_state = s->deserialized_state;
517 else if (s->from_proc_swaps)
518 new_state = SWAP_ACTIVE;
520 if (new_state != s->state) {
522 if (new_state == SWAP_ACTIVATING ||
523 new_state == SWAP_ACTIVATING_SIGTERM ||
524 new_state == SWAP_ACTIVATING_SIGKILL ||
525 new_state == SWAP_DEACTIVATING ||
526 new_state == SWAP_DEACTIVATING_SIGTERM ||
527 new_state == SWAP_DEACTIVATING_SIGKILL) {
529 if (s->control_pid <= 0)
532 r = unit_watch_pid(UNIT(s), s->control_pid);
536 r = swap_arm_timer(s);
541 swap_set_state(s, new_state);
547 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
554 if (s->from_proc_swaps)
555 p = &s->parameters_proc_swaps;
556 else if (s->from_fragment)
557 p = &s->parameters_fragment;
565 "%sFrom /proc/swaps: %s\n"
566 "%sFrom fragment: %s\n",
567 prefix, swap_state_to_string(s->state),
568 prefix, swap_result_to_string(s->result),
570 prefix, yes_no(s->from_proc_swaps),
571 prefix, yes_no(s->from_fragment));
579 prefix, yes_no(p->noauto),
580 prefix, yes_no(p->nofail));
582 if (s->control_pid > 0)
584 "%sControl PID: %lu\n",
585 prefix, (unsigned long) s->control_pid);
587 exec_context_dump(&s->exec_context, f, prefix);
588 kill_context_dump(&s->kill_context, f, prefix);
591 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
599 unit_realize_cgroup(UNIT(s));
601 r = swap_arm_timer(s);
609 UNIT(s)->manager->environment,
613 UNIT(s)->manager->confirm_spawn,
614 UNIT(s)->manager->cgroup_supported,
615 UNIT(s)->cgroup_path,
622 r = unit_watch_pid(UNIT(s), pid);
624 /* FIXME: we need to do something here */
632 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
637 static void swap_enter_dead(Swap *s, SwapResult f) {
640 if (f != SWAP_SUCCESS)
643 exec_context_tmp_dirs_done(&s->exec_context);
644 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
647 static void swap_enter_active(Swap *s, SwapResult f) {
650 if (f != SWAP_SUCCESS)
653 swap_set_state(s, SWAP_ACTIVE);
656 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
661 if (f != SWAP_SUCCESS)
664 r = unit_kill_context(
667 state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
675 r = swap_arm_timer(s);
679 swap_set_state(s, state);
681 swap_enter_dead(s, SWAP_SUCCESS);
686 log_warning_unit(UNIT(s)->id,
687 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
689 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
692 static void swap_enter_activating(Swap *s) {
697 s->control_command_id = SWAP_EXEC_ACTIVATE;
698 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
700 if (s->from_fragment)
701 priority = s->parameters_fragment.priority;
708 snprintf(p, sizeof(p), "%i", priority);
711 r = exec_command_set(
719 r = exec_command_set(
728 swap_unwatch_control_pid(s);
730 r = swap_spawn(s, s->control_command, &s->control_pid);
734 swap_set_state(s, SWAP_ACTIVATING);
739 log_warning_unit(UNIT(s)->id,
740 "%s failed to run 'swapon' task: %s",
741 UNIT(s)->id, strerror(-r));
742 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
745 static void swap_enter_deactivating(Swap *s) {
750 s->control_command_id = SWAP_EXEC_DEACTIVATE;
751 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
753 r = exec_command_set(s->control_command,
760 swap_unwatch_control_pid(s);
762 r = swap_spawn(s, s->control_command, &s->control_pid);
766 swap_set_state(s, SWAP_DEACTIVATING);
771 log_warning_unit(UNIT(s)->id,
772 "%s failed to run 'swapoff' task: %s",
773 UNIT(s)->id, strerror(-r));
774 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
777 static int swap_start(Unit *u) {
782 /* We cannot fulfill this request right now, try again later
785 if (s->state == SWAP_DEACTIVATING ||
786 s->state == SWAP_DEACTIVATING_SIGTERM ||
787 s->state == SWAP_DEACTIVATING_SIGKILL ||
788 s->state == SWAP_ACTIVATING_SIGTERM ||
789 s->state == SWAP_ACTIVATING_SIGKILL)
792 if (s->state == SWAP_ACTIVATING)
795 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
797 if (detect_container(NULL) > 0)
800 s->result = SWAP_SUCCESS;
801 swap_enter_activating(s);
805 static int swap_stop(Unit *u) {
810 if (s->state == SWAP_DEACTIVATING ||
811 s->state == SWAP_DEACTIVATING_SIGTERM ||
812 s->state == SWAP_DEACTIVATING_SIGKILL ||
813 s->state == SWAP_ACTIVATING_SIGTERM ||
814 s->state == SWAP_ACTIVATING_SIGKILL)
817 assert(s->state == SWAP_ACTIVATING ||
818 s->state == SWAP_ACTIVE);
820 if (detect_container(NULL) > 0)
823 swap_enter_deactivating(s);
827 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
834 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
835 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
837 if (s->control_pid > 0)
838 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
840 if (s->control_command_id >= 0)
841 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
843 exec_context_serialize(&s->exec_context, UNIT(s), f);
848 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
854 if (streq(key, "state")) {
857 state = swap_state_from_string(value);
859 log_debug_unit(u->id, "Failed to parse state value %s", value);
861 s->deserialized_state = state;
862 } else if (streq(key, "result")) {
865 f = swap_result_from_string(value);
867 log_debug_unit(u->id, "Failed to parse result value %s", value);
868 else if (f != SWAP_SUCCESS)
870 } else if (streq(key, "control-pid")) {
873 if (parse_pid(value, &pid) < 0)
874 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
876 s->control_pid = pid;
878 } else if (streq(key, "control-command")) {
881 id = swap_exec_command_from_string(value);
883 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
885 s->control_command_id = id;
886 s->control_command = s->exec_command + id;
888 } else if (streq(key, "tmp-dir")) {
895 s->exec_context.tmp_dir = t;
896 } else if (streq(key, "var-tmp-dir")) {
903 s->exec_context.var_tmp_dir = t;
905 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
910 _pure_ static UnitActiveState swap_active_state(Unit *u) {
913 return state_translation_table[SWAP(u)->state];
916 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
919 return swap_state_to_string(SWAP(u)->state);
922 _pure_ static bool swap_check_gc(Unit *u) {
927 return s->from_proc_swaps;
930 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
937 if (pid != s->control_pid)
942 if (is_clean_exit(code, status, NULL))
944 else if (code == CLD_EXITED)
945 f = SWAP_FAILURE_EXIT_CODE;
946 else if (code == CLD_KILLED)
947 f = SWAP_FAILURE_SIGNAL;
948 else if (code == CLD_DUMPED)
949 f = SWAP_FAILURE_CORE_DUMP;
951 assert_not_reached("Unknown code");
953 if (f != SWAP_SUCCESS)
956 if (s->control_command) {
957 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
959 s->control_command = NULL;
960 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
963 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
965 "%s swap process exited, code=%s status=%i",
966 u->id, sigchld_code_to_string(code), status);
970 case SWAP_ACTIVATING:
971 case SWAP_ACTIVATING_SIGTERM:
972 case SWAP_ACTIVATING_SIGKILL:
974 if (f == SWAP_SUCCESS)
975 swap_enter_active(s, f);
977 swap_enter_dead(s, f);
980 case SWAP_DEACTIVATING:
981 case SWAP_DEACTIVATING_SIGKILL:
982 case SWAP_DEACTIVATING_SIGTERM:
984 if (f == SWAP_SUCCESS)
985 swap_enter_dead(s, f);
987 swap_enter_dead(s, f);
991 assert_not_reached("Uh, control process died at wrong time.");
994 /* Notify clients about changed exit status */
995 unit_add_to_dbus_queue(u);
997 /* Request a reload of /proc/swaps, so that following units
998 * can follow our state change */
999 u->manager->request_reload = true;
1002 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1003 Swap *s = SWAP(userdata);
1006 assert(s->timer_event_source == source);
1010 case SWAP_ACTIVATING:
1011 log_warning_unit(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
1012 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1015 case SWAP_DEACTIVATING:
1016 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
1017 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1020 case SWAP_ACTIVATING_SIGTERM:
1021 if (s->kill_context.send_sigkill) {
1022 log_warning_unit(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
1023 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1025 log_warning_unit(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1026 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1030 case SWAP_DEACTIVATING_SIGTERM:
1031 if (s->kill_context.send_sigkill) {
1032 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
1033 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1035 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1036 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1040 case SWAP_ACTIVATING_SIGKILL:
1041 case SWAP_DEACTIVATING_SIGKILL:
1042 log_warning_unit(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
1043 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1047 assert_not_reached("Timeout at wrong time.");
1053 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1059 rewind(m->proc_swaps);
1061 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1064 _cleanup_free_ char *dev = NULL, *d = NULL;
1067 k = fscanf(m->proc_swaps,
1068 "%ms " /* device/file */
1069 "%*s " /* type of swap */
1070 "%*s " /* swap size */
1072 "%i\n", /* priority */
1078 log_warning("Failed to parse /proc/swaps:%u", i);
1086 k = swap_process_new_swap(m, d, prio, set_flags);
1094 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1095 Manager *m = userdata;
1100 assert(revents & EPOLLPRI);
1102 r = swap_load_proc_swaps(m, true);
1104 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1106 /* Reset flags, just in case, for late calls */
1107 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1108 Swap *swap = SWAP(u);
1110 swap->is_active = swap->just_activated = false;
1116 manager_dispatch_load_queue(m);
1118 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1119 Swap *swap = SWAP(u);
1121 if (!swap->is_active) {
1122 /* This has just been deactivated */
1124 swap->from_proc_swaps = false;
1125 swap_unset_proc_swaps(swap);
1127 switch (swap->state) {
1130 swap_enter_dead(swap, SWAP_SUCCESS);
1134 swap_set_state(swap, swap->state);
1138 } else if (swap->just_activated) {
1140 /* New swap entry */
1142 switch (swap->state) {
1146 swap_enter_active(swap, SWAP_SUCCESS);
1150 /* Nothing really changed, but let's
1151 * issue an notification call
1152 * nonetheless, in case somebody is
1153 * waiting for this. */
1154 swap_set_state(swap, swap->state);
1159 /* Reset the flags for later calls */
1160 swap->is_active = swap->just_activated = false;
1166 static Unit *swap_following(Unit *u) {
1168 Swap *other, *first = NULL;
1172 if (streq_ptr(s->what, s->parameters_proc_swaps.what))
1175 /* Make everybody follow the unit that's named after the swap
1176 * device in the kernel */
1178 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1179 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1182 LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
1183 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1192 static int swap_following_set(Unit *u, Set **_set) {
1201 if (LIST_JUST_US(same_proc_swaps, s)) {
1206 if (!(set = set_new(NULL, NULL)))
1209 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1210 if ((r = set_put(set, other)) < 0)
1213 LIST_FOREACH_BEFORE(same_proc_swaps, other, s)
1214 if ((r = set_put(set, other)) < 0)
1225 static void swap_shutdown(Manager *m) {
1228 m->swap_event_source = sd_event_source_unref(m->swap_event_source);
1230 if (m->proc_swaps) {
1231 fclose(m->proc_swaps);
1232 m->proc_swaps = NULL;
1235 hashmap_free(m->swaps_by_proc_swaps);
1236 m->swaps_by_proc_swaps = NULL;
1239 static int swap_enumerate(Manager *m) {
1243 if (!m->proc_swaps) {
1244 m->proc_swaps = fopen("/proc/swaps", "re");
1246 return errno == ENOENT ? 0 : -errno;
1248 r = sd_event_add_io(m->event, fileno(m->proc_swaps), EPOLLPRI, swap_dispatch_io, m, &m->swap_event_source);
1253 r = swap_load_proc_swaps(m, false);
1264 static void swap_reset_failed(Unit *u) {
1269 if (s->state == SWAP_FAILED)
1270 swap_set_state(s, SWAP_DEAD);
1272 s->result = SWAP_SUCCESS;
1275 static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1276 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1279 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1280 [SWAP_DEAD] = "dead",
1281 [SWAP_ACTIVATING] = "activating",
1282 [SWAP_ACTIVE] = "active",
1283 [SWAP_DEACTIVATING] = "deactivating",
1284 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1285 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1286 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1287 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1288 [SWAP_FAILED] = "failed"
1291 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1293 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1294 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1295 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1298 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1300 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1301 [SWAP_SUCCESS] = "success",
1302 [SWAP_FAILURE_RESOURCES] = "resources",
1303 [SWAP_FAILURE_TIMEOUT] = "timeout",
1304 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1305 [SWAP_FAILURE_SIGNAL] = "signal",
1306 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1309 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1311 const UnitVTable swap_vtable = {
1312 .object_size = sizeof(Swap),
1313 .exec_context_offset = offsetof(Swap, exec_context),
1314 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1315 .kill_context_offset = offsetof(Swap, kill_context),
1321 .private_section = "Swap",
1324 .no_instances = true,
1330 .coldplug = swap_coldplug,
1334 .start = swap_start,
1339 .serialize = swap_serialize,
1340 .deserialize_item = swap_deserialize_item,
1342 .active_state = swap_active_state,
1343 .sub_state_to_string = swap_sub_state_to_string,
1345 .check_gc = swap_check_gc,
1347 .sigchld_event = swap_sigchld_event,
1349 .reset_failed = swap_reset_failed,
1351 .bus_interface = "org.freedesktop.systemd1.Swap",
1352 .bus_vtable = bus_swap_vtable,
1353 .bus_changing_properties = bus_swap_changing_properties,
1354 .bus_set_property = bus_swap_set_property,
1355 .bus_commit_properties = bus_swap_commit_properties,
1357 .following = swap_following,
1358 .following_set = swap_following_set,
1360 .enumerate = swap_enumerate,
1361 .shutdown = swap_shutdown,
1363 .status_message_formats = {
1364 .starting_stopping = {
1365 [0] = "Activating swap %s...",
1366 [1] = "Deactivating swap %s...",
1368 .finished_start_job = {
1369 [JOB_DONE] = "Activated swap %s.",
1370 [JOB_FAILED] = "Failed to activate swap %s.",
1371 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1372 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1374 .finished_stop_job = {
1375 [JOB_DONE] = "Deactivated swap %s.",
1376 [JOB_FAILED] = "Failed deactivating swap %s.",
1377 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",