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 void swap_unset_proc_swaps(Swap *s) {
62 if (!s->parameters_proc_swaps.what)
65 /* Remove this unit from the chain of swaps which share the
66 * same kernel swap device. */
67 swaps = UNIT(s)->manager->swaps_by_proc_swaps;
68 first = hashmap_get(swaps, s->parameters_proc_swaps.what);
69 LIST_REMOVE(Swap, same_proc_swaps, first, s);
72 hashmap_remove_and_replace(swaps,
73 s->parameters_proc_swaps.what,
74 first->parameters_proc_swaps.what,
77 hashmap_remove(swaps, s->parameters_proc_swaps.what);
79 free(s->parameters_proc_swaps.what);
80 s->parameters_proc_swaps.what = NULL;
83 static void swap_init(Unit *u) {
87 assert(UNIT(s)->load_state == UNIT_STUB);
89 s->timeout_usec = DEFAULT_TIMEOUT_USEC;
91 exec_context_init(&s->exec_context);
92 s->exec_context.std_output = u->manager->default_std_output;
93 s->exec_context.std_error = u->manager->default_std_error;
94 kill_context_init(&s->kill_context);
95 cgroup_context_init(&s->cgroup_context);
97 s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
99 s->timer_watch.type = WATCH_INVALID;
101 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
103 UNIT(s)->ignore_on_isolate = true;
106 static void swap_unwatch_control_pid(Swap *s) {
109 if (s->control_pid <= 0)
112 unit_unwatch_pid(UNIT(s), s->control_pid);
116 static void swap_done(Unit *u) {
121 swap_unset_proc_swaps(s);
126 free(s->parameters_fragment.what);
127 s->parameters_fragment.what = NULL;
129 exec_context_done(&s->exec_context, manager_is_reloading_or_reexecuting(u->manager));
130 exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
131 s->control_command = NULL;
133 cgroup_context_done(&s->cgroup_context);
135 swap_unwatch_control_pid(s);
137 unit_unwatch_timer(u, &s->timer_watch);
140 int swap_add_one_mount_link(Swap *s, Mount *m) {
146 if (UNIT(s)->load_state != UNIT_LOADED ||
147 UNIT(m)->load_state != UNIT_LOADED)
150 if (is_device_path(s->what))
153 if (!path_startswith(s->what, m->where))
156 r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
163 static int swap_add_mount_links(Swap *s) {
169 LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT])
170 if ((r = swap_add_one_mount_link(s, MOUNT(other))) < 0)
176 static int swap_add_device_links(Swap *s) {
184 if (s->from_fragment)
185 p = &s->parameters_fragment;
189 if (is_device_path(s->what))
190 return unit_add_node_link(UNIT(s), s->what, !p->noauto &&
191 UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
193 /* File based swap devices need to be ordered after
194 * systemd-remount-fs.service, since they might need a
195 * writable file system. */
196 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
199 static int swap_add_default_dependencies(Swap *s) {
200 bool nofail = false, noauto = false;
205 if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
208 if (detect_container(NULL) > 0)
211 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
215 if (s->from_fragment) {
216 SwapParameters *p = &s->parameters_fragment;
223 r = unit_add_two_dependencies_by_name_inverse(UNIT(s), UNIT_AFTER, (nofail ? UNIT_WANTS : UNIT_REQUIRES),
224 SPECIAL_SWAP_TARGET, NULL, true);
232 static int swap_verify(Swap *s) {
234 _cleanup_free_ char *e = NULL;
236 if (UNIT(s)->load_state != UNIT_LOADED)
239 e = unit_name_from_path(s->what, ".swap");
243 b = unit_has_name(UNIT(s), e);
245 log_error_unit(UNIT(s)->id,
246 "%s: Value of \"What\" and unit name do not match, not loading.",
251 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
252 log_error_unit(UNIT(s)->id,
253 "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.",
261 static int swap_load(Unit *u) {
266 assert(u->load_state == UNIT_STUB);
268 /* Load a .swap file */
269 r = unit_load_fragment_and_dropin_optional(u);
273 if (u->load_state == UNIT_LOADED) {
274 r = unit_add_exec_dependencies(u, &s->exec_context);
278 if (UNIT(s)->fragment_path)
279 s->from_fragment = true;
282 if (s->parameters_fragment.what)
283 s->what = strdup(s->parameters_fragment.what);
284 else if (s->parameters_proc_swaps.what)
285 s->what = strdup(s->parameters_proc_swaps.what);
287 s->what = unit_name_to_path(u->id);
293 path_kill_slashes(s->what);
295 if (!UNIT(s)->description)
296 if ((r = unit_set_description(u, s->what)) < 0)
299 r = swap_add_device_links(s);
303 r = swap_add_mount_links(s);
307 r = unit_add_default_slice(u);
311 if (UNIT(s)->default_dependencies) {
312 r = swap_add_default_dependencies(s);
317 r = unit_exec_context_defaults(u, &s->exec_context);
322 return swap_verify(s);
325 static int swap_add_one(
328 const char *what_proc_swaps,
335 _cleanup_free_ char *e = NULL;
344 assert(what_proc_swaps);
346 e = unit_name_from_path(what, ".swap");
350 u = manager_get_unit(m, e);
353 SWAP(u)->from_proc_swaps &&
354 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
360 u = unit_new(m, sizeof(Swap));
364 r = unit_add_name(u, e);
368 SWAP(u)->what = strdup(what);
369 if (!SWAP(u)->what) {
374 unit_add_to_load_queue(u);
378 p = &SWAP(u)->parameters_proc_swaps;
381 wp = strdup(what_proc_swaps);
387 if (!m->swaps_by_proc_swaps) {
388 m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func);
389 if (!m->swaps_by_proc_swaps) {
398 first = hashmap_get(m->swaps_by_proc_swaps, wp);
399 LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u));
401 r = hashmap_replace(m->swaps_by_proc_swaps, wp, first);
407 SWAP(u)->is_active = true;
408 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
411 SWAP(u)->from_proc_swaps = true;
413 p->priority = priority;
417 unit_add_to_dbus_queue(u);
422 log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
432 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
438 if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) {
439 struct udev_device *d;
441 struct udev_list_entry *item = NULL, *first = NULL;
443 /* So this is a proper swap device. Create swap units
444 * for all names this swap device is known under */
446 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
450 dn = udev_device_get_devnode(d);
451 /* Skip dn==device, since that case will be handled below */
452 if (dn && !streq(dn, device))
453 r = swap_add_one(m, dn, device, prio, false, false, set_flags);
455 /* Add additional units for all symlinks */
456 first = udev_device_get_devlinks_list_entry(d);
457 udev_list_entry_foreach(item, first) {
460 /* Don't bother with the /dev/block links */
461 p = udev_list_entry_get_name(item);
463 if (path_startswith(p, "/dev/block/"))
466 if (stat(p, &st) >= 0)
467 if ((!S_ISBLK(st.st_mode)) ||
468 st.st_rdev != udev_device_get_devnum(d))
471 k = swap_add_one(m, p, device, prio, false, false, set_flags);
476 udev_device_unref(d);
479 k = swap_add_one(m, device, device, prio, false, false, set_flags);
486 static void swap_set_state(Swap *s, SwapState state) {
491 old_state = s->state;
494 if (state != SWAP_ACTIVATING &&
495 state != SWAP_ACTIVATING_SIGTERM &&
496 state != SWAP_ACTIVATING_SIGKILL &&
497 state != SWAP_DEACTIVATING &&
498 state != SWAP_DEACTIVATING_SIGTERM &&
499 state != SWAP_DEACTIVATING_SIGKILL) {
500 unit_unwatch_timer(UNIT(s), &s->timer_watch);
501 swap_unwatch_control_pid(s);
502 s->control_command = NULL;
503 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
506 if (state != old_state)
507 log_debug_unit(UNIT(s)->id,
508 "%s changed %s -> %s",
510 swap_state_to_string(old_state),
511 swap_state_to_string(state));
513 unit_notify(UNIT(s), state_translation_table[old_state],
514 state_translation_table[state], true);
517 static int swap_coldplug(Unit *u) {
519 SwapState new_state = SWAP_DEAD;
523 assert(s->state == SWAP_DEAD);
525 if (s->deserialized_state != s->state)
526 new_state = s->deserialized_state;
527 else if (s->from_proc_swaps)
528 new_state = SWAP_ACTIVE;
530 if (new_state != s->state) {
532 if (new_state == SWAP_ACTIVATING ||
533 new_state == SWAP_ACTIVATING_SIGTERM ||
534 new_state == SWAP_ACTIVATING_SIGKILL ||
535 new_state == SWAP_DEACTIVATING ||
536 new_state == SWAP_DEACTIVATING_SIGTERM ||
537 new_state == SWAP_DEACTIVATING_SIGKILL) {
539 if (s->control_pid <= 0)
542 r = unit_watch_pid(UNIT(s), s->control_pid);
546 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
551 swap_set_state(s, new_state);
557 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
564 if (s->from_proc_swaps)
565 p = &s->parameters_proc_swaps;
566 else if (s->from_fragment)
567 p = &s->parameters_fragment;
575 "%sFrom /proc/swaps: %s\n"
576 "%sFrom fragment: %s\n",
577 prefix, swap_state_to_string(s->state),
578 prefix, swap_result_to_string(s->result),
580 prefix, yes_no(s->from_proc_swaps),
581 prefix, yes_no(s->from_fragment));
589 prefix, yes_no(p->noauto),
590 prefix, yes_no(p->nofail));
592 if (s->control_pid > 0)
594 "%sControl PID: %lu\n",
595 prefix, (unsigned long) s->control_pid);
597 exec_context_dump(&s->exec_context, f, prefix);
598 kill_context_dump(&s->kill_context, f, prefix);
601 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
609 unit_realize_cgroup(UNIT(s));
611 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
619 UNIT(s)->manager->environment,
623 UNIT(s)->manager->confirm_spawn,
624 UNIT(s)->cgroup_mask,
625 UNIT(s)->cgroup_path,
632 r = unit_watch_pid(UNIT(s), pid);
634 /* FIXME: we need to do something here */
642 unit_unwatch_timer(UNIT(s), &s->timer_watch);
647 static void swap_enter_dead(Swap *s, SwapResult f) {
650 if (f != SWAP_SUCCESS)
653 exec_context_tmp_dirs_done(&s->exec_context);
654 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
657 static void swap_enter_active(Swap *s, SwapResult f) {
660 if (f != SWAP_SUCCESS)
663 swap_set_state(s, SWAP_ACTIVE);
666 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
671 if (f != SWAP_SUCCESS)
674 r = unit_kill_context(
677 state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
685 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
689 swap_set_state(s, state);
691 swap_enter_dead(s, SWAP_SUCCESS);
696 log_warning_unit(UNIT(s)->id,
697 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
699 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
702 static void swap_enter_activating(Swap *s) {
707 s->control_command_id = SWAP_EXEC_ACTIVATE;
708 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
710 if (s->from_fragment)
711 priority = s->parameters_fragment.priority;
718 snprintf(p, sizeof(p), "%i", priority);
721 r = exec_command_set(
729 r = exec_command_set(
738 swap_unwatch_control_pid(s);
740 r = swap_spawn(s, s->control_command, &s->control_pid);
744 swap_set_state(s, SWAP_ACTIVATING);
749 log_warning_unit(UNIT(s)->id,
750 "%s failed to run 'swapon' task: %s",
751 UNIT(s)->id, strerror(-r));
752 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
755 static void swap_enter_deactivating(Swap *s) {
760 s->control_command_id = SWAP_EXEC_DEACTIVATE;
761 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
763 r = exec_command_set(s->control_command,
770 swap_unwatch_control_pid(s);
772 r = swap_spawn(s, s->control_command, &s->control_pid);
776 swap_set_state(s, SWAP_DEACTIVATING);
781 log_warning_unit(UNIT(s)->id,
782 "%s failed to run 'swapoff' task: %s",
783 UNIT(s)->id, strerror(-r));
784 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
787 static int swap_start(Unit *u) {
792 /* We cannot fulfill this request right now, try again later
795 if (s->state == SWAP_DEACTIVATING ||
796 s->state == SWAP_DEACTIVATING_SIGTERM ||
797 s->state == SWAP_DEACTIVATING_SIGKILL ||
798 s->state == SWAP_ACTIVATING_SIGTERM ||
799 s->state == SWAP_ACTIVATING_SIGKILL)
802 if (s->state == SWAP_ACTIVATING)
805 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
807 if (detect_container(NULL) > 0)
810 s->result = SWAP_SUCCESS;
811 swap_enter_activating(s);
815 static int swap_stop(Unit *u) {
820 if (s->state == SWAP_DEACTIVATING ||
821 s->state == SWAP_DEACTIVATING_SIGTERM ||
822 s->state == SWAP_DEACTIVATING_SIGKILL ||
823 s->state == SWAP_ACTIVATING_SIGTERM ||
824 s->state == SWAP_ACTIVATING_SIGKILL)
827 assert(s->state == SWAP_ACTIVATING ||
828 s->state == SWAP_ACTIVE);
830 if (detect_container(NULL) > 0)
833 swap_enter_deactivating(s);
837 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
844 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
845 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
847 if (s->control_pid > 0)
848 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
850 if (s->control_command_id >= 0)
851 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
853 exec_context_serialize(&s->exec_context, UNIT(s), f);
858 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
864 if (streq(key, "state")) {
867 state = swap_state_from_string(value);
869 log_debug_unit(u->id, "Failed to parse state value %s", value);
871 s->deserialized_state = state;
872 } else if (streq(key, "result")) {
875 f = swap_result_from_string(value);
877 log_debug_unit(u->id, "Failed to parse result value %s", value);
878 else if (f != SWAP_SUCCESS)
880 } else if (streq(key, "control-pid")) {
883 if (parse_pid(value, &pid) < 0)
884 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
886 s->control_pid = pid;
888 } else if (streq(key, "control-command")) {
891 id = swap_exec_command_from_string(value);
893 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
895 s->control_command_id = id;
896 s->control_command = s->exec_command + id;
898 } else if (streq(key, "tmp-dir")) {
905 s->exec_context.tmp_dir = t;
906 } else if (streq(key, "var-tmp-dir")) {
913 s->exec_context.var_tmp_dir = t;
915 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
920 _pure_ static UnitActiveState swap_active_state(Unit *u) {
923 return state_translation_table[SWAP(u)->state];
926 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
929 return swap_state_to_string(SWAP(u)->state);
932 _pure_ static bool swap_check_gc(Unit *u) {
937 return s->from_proc_swaps;
940 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
947 if (pid != s->control_pid)
952 if (is_clean_exit(code, status, NULL))
954 else if (code == CLD_EXITED)
955 f = SWAP_FAILURE_EXIT_CODE;
956 else if (code == CLD_KILLED)
957 f = SWAP_FAILURE_SIGNAL;
958 else if (code == CLD_DUMPED)
959 f = SWAP_FAILURE_CORE_DUMP;
961 assert_not_reached("Unknown code");
963 if (f != SWAP_SUCCESS)
966 if (s->control_command) {
967 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
969 s->control_command = NULL;
970 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
973 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
975 "%s swap process exited, code=%s status=%i",
976 u->id, sigchld_code_to_string(code), status);
980 case SWAP_ACTIVATING:
981 case SWAP_ACTIVATING_SIGTERM:
982 case SWAP_ACTIVATING_SIGKILL:
984 if (f == SWAP_SUCCESS)
985 swap_enter_active(s, f);
987 swap_enter_dead(s, f);
990 case SWAP_DEACTIVATING:
991 case SWAP_DEACTIVATING_SIGKILL:
992 case SWAP_DEACTIVATING_SIGTERM:
994 if (f == SWAP_SUCCESS)
995 swap_enter_dead(s, f);
997 swap_enter_dead(s, f);
1001 assert_not_reached("Uh, control process died at wrong time.");
1004 /* Notify clients about changed exit status */
1005 unit_add_to_dbus_queue(u);
1007 /* Request a reload of /proc/swaps, so that following units
1008 * can follow our state change */
1009 u->manager->request_reload = true;
1012 static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
1016 assert(elapsed == 1);
1017 assert(w == &s->timer_watch);
1021 case SWAP_ACTIVATING:
1022 log_warning_unit(u->id, "%s activation timed out. Stopping.", u->id);
1023 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1026 case SWAP_DEACTIVATING:
1027 log_warning_unit(u->id, "%s deactivation timed out. Stopping.", u->id);
1028 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1031 case SWAP_ACTIVATING_SIGTERM:
1032 if (s->kill_context.send_sigkill) {
1033 log_warning_unit(u->id, "%s activation timed out. Killing.", u->id);
1034 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1036 log_warning_unit(u->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", u->id);
1037 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1041 case SWAP_DEACTIVATING_SIGTERM:
1042 if (s->kill_context.send_sigkill) {
1043 log_warning_unit(u->id, "%s deactivation timed out. Killing.", u->id);
1044 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1046 log_warning_unit(u->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id);
1047 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1051 case SWAP_ACTIVATING_SIGKILL:
1052 case SWAP_DEACTIVATING_SIGKILL:
1053 log_warning_unit(u->id, "%s swap process still around after SIGKILL. Ignoring.", u->id);
1054 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1058 assert_not_reached("Timeout at wrong time.");
1062 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1068 rewind(m->proc_swaps);
1070 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1073 char *dev = NULL, *d;
1076 k = fscanf(m->proc_swaps,
1077 "%ms " /* device/file */
1078 "%*s " /* type of swap */
1079 "%*s " /* swap size */
1081 "%i\n", /* priority */
1087 log_warning("Failed to parse /proc/swaps:%u", i);
1098 k = swap_process_new_swap(m, d, prio, set_flags);
1108 int swap_dispatch_reload(Manager *m) {
1109 /* This function should go as soon as the kernel properly notifies us */
1111 if (_likely_(!m->request_reload))
1114 m->request_reload = false;
1116 return swap_fd_event(m, EPOLLPRI);
1119 int swap_fd_event(Manager *m, int events) {
1124 assert(events & EPOLLPRI);
1126 r = swap_load_proc_swaps(m, true);
1128 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1130 /* Reset flags, just in case, for late calls */
1131 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1132 Swap *swap = SWAP(u);
1134 swap->is_active = swap->just_activated = false;
1140 manager_dispatch_load_queue(m);
1142 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1143 Swap *swap = SWAP(u);
1145 if (!swap->is_active) {
1146 /* This has just been deactivated */
1148 swap->from_proc_swaps = false;
1149 swap_unset_proc_swaps(swap);
1151 switch (swap->state) {
1154 swap_enter_dead(swap, SWAP_SUCCESS);
1158 swap_set_state(swap, swap->state);
1162 } else if (swap->just_activated) {
1164 /* New swap entry */
1166 switch (swap->state) {
1170 swap_enter_active(swap, SWAP_SUCCESS);
1174 /* Nothing really changed, but let's
1175 * issue an notification call
1176 * nonetheless, in case somebody is
1177 * waiting for this. */
1178 swap_set_state(swap, swap->state);
1183 /* Reset the flags for later calls */
1184 swap->is_active = swap->just_activated = false;
1190 static Unit *swap_following(Unit *u) {
1192 Swap *other, *first = NULL;
1196 if (streq_ptr(s->what, s->parameters_proc_swaps.what))
1199 /* Make everybody follow the unit that's named after the swap
1200 * device in the kernel */
1202 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1203 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1206 LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
1207 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1216 static int swap_following_set(Unit *u, Set **_set) {
1225 if (LIST_JUST_US(same_proc_swaps, s)) {
1230 if (!(set = set_new(NULL, NULL)))
1233 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1234 if ((r = set_put(set, other)) < 0)
1237 LIST_FOREACH_BEFORE(same_proc_swaps, other, s)
1238 if ((r = set_put(set, other)) < 0)
1249 static void swap_shutdown(Manager *m) {
1252 if (m->proc_swaps) {
1253 fclose(m->proc_swaps);
1254 m->proc_swaps = NULL;
1257 hashmap_free(m->swaps_by_proc_swaps);
1258 m->swaps_by_proc_swaps = NULL;
1261 static int swap_enumerate(Manager *m) {
1265 if (!m->proc_swaps) {
1266 struct epoll_event ev = {
1268 .data.ptr = &m->swap_watch,
1271 m->proc_swaps = fopen("/proc/swaps", "re");
1273 return (errno == ENOENT) ? 0 : -errno;
1275 m->swap_watch.type = WATCH_SWAP;
1276 m->swap_watch.fd = fileno(m->proc_swaps);
1278 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
1282 r = swap_load_proc_swaps(m, false);
1289 static void swap_reset_failed(Unit *u) {
1294 if (s->state == SWAP_FAILED)
1295 swap_set_state(s, SWAP_DEAD);
1297 s->result = SWAP_SUCCESS;
1300 static int swap_kill(Unit *u, KillWho who, int signo, DBusError *error) {
1301 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1304 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1305 [SWAP_DEAD] = "dead",
1306 [SWAP_ACTIVATING] = "activating",
1307 [SWAP_ACTIVE] = "active",
1308 [SWAP_DEACTIVATING] = "deactivating",
1309 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1310 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1311 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1312 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1313 [SWAP_FAILED] = "failed"
1316 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1318 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1319 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1320 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1323 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1325 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1326 [SWAP_SUCCESS] = "success",
1327 [SWAP_FAILURE_RESOURCES] = "resources",
1328 [SWAP_FAILURE_TIMEOUT] = "timeout",
1329 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1330 [SWAP_FAILURE_SIGNAL] = "signal",
1331 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1334 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1336 const UnitVTable swap_vtable = {
1337 .object_size = sizeof(Swap),
1344 .private_section = "Swap",
1345 .exec_context_offset = offsetof(Swap, exec_context),
1346 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1349 .no_instances = true,
1355 .coldplug = swap_coldplug,
1359 .start = swap_start,
1364 .serialize = swap_serialize,
1365 .deserialize_item = swap_deserialize_item,
1367 .active_state = swap_active_state,
1368 .sub_state_to_string = swap_sub_state_to_string,
1370 .check_gc = swap_check_gc,
1372 .sigchld_event = swap_sigchld_event,
1373 .timer_event = swap_timer_event,
1375 .reset_failed = swap_reset_failed,
1377 .bus_interface = "org.freedesktop.systemd1.Swap",
1378 .bus_message_handler = bus_swap_message_handler,
1379 .bus_invalidating_properties = bus_swap_invalidating_properties,
1380 .bus_set_property = bus_swap_set_property,
1381 .bus_commit_properties = bus_swap_commit_properties,
1383 .following = swap_following,
1384 .following_set = swap_following_set,
1386 .enumerate = swap_enumerate,
1387 .shutdown = swap_shutdown,
1389 .status_message_formats = {
1390 .starting_stopping = {
1391 [0] = "Activating swap %s...",
1392 [1] = "Deactivating swap %s...",
1394 .finished_start_job = {
1395 [JOB_DONE] = "Activated swap %s.",
1396 [JOB_FAILED] = "Failed to activate swap %s.",
1397 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1398 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1400 .finished_stop_job = {
1401 [JOB_DONE] = "Deactivated swap %s.",
1402 [JOB_FAILED] = "Failed deactivating swap %s.",
1403 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",