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);
96 s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
98 s->timer_watch.type = WATCH_INVALID;
100 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
102 UNIT(s)->ignore_on_isolate = true;
105 static void swap_unwatch_control_pid(Swap *s) {
108 if (s->control_pid <= 0)
111 unit_unwatch_pid(UNIT(s), s->control_pid);
115 static void swap_done(Unit *u) {
120 swap_unset_proc_swaps(s);
125 free(s->parameters_fragment.what);
126 s->parameters_fragment.what = NULL;
128 exec_context_done(&s->exec_context);
129 exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
130 s->control_command = NULL;
132 swap_unwatch_control_pid(s);
134 unit_unwatch_timer(u, &s->timer_watch);
137 int swap_add_one_mount_link(Swap *s, Mount *m) {
143 if (UNIT(s)->load_state != UNIT_LOADED ||
144 UNIT(m)->load_state != UNIT_LOADED)
147 if (is_device_path(s->what))
150 if (!path_startswith(s->what, m->where))
153 r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
160 static int swap_add_mount_links(Swap *s) {
166 LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT])
167 if ((r = swap_add_one_mount_link(s, MOUNT(other))) < 0)
173 static int swap_add_device_links(Swap *s) {
181 if (s->from_fragment)
182 p = &s->parameters_fragment;
186 if (is_device_path(s->what))
187 return unit_add_node_link(UNIT(s), s->what,
188 !p->noauto && p->nofail &&
189 UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
191 /* File based swap devices need to be ordered after
192 * systemd-remount-fs.service, since they might need a
193 * writable file system. */
194 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
197 static int swap_add_default_dependencies(Swap *s) {
202 if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
205 if (detect_container(NULL) > 0)
208 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
215 static int swap_verify(Swap *s) {
217 char _cleanup_free_ *e = NULL;
219 if (UNIT(s)->load_state != UNIT_LOADED)
222 e = unit_name_from_path(s->what, ".swap");
226 b = unit_has_name(UNIT(s), e);
228 log_error_unit(UNIT(s)->id,
229 "%s: Value of \"What\" and unit name do not match, not loading.",
234 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
235 log_error_unit(UNIT(s)->id,
236 "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.",
244 static int swap_load(Unit *u) {
249 assert(u->load_state == UNIT_STUB);
251 /* Load a .swap file */
252 r = unit_load_fragment_and_dropin_optional(u);
256 if (u->load_state == UNIT_LOADED) {
257 r = unit_add_exec_dependencies(u, &s->exec_context);
261 if (UNIT(s)->fragment_path)
262 s->from_fragment = true;
265 if (s->parameters_fragment.what)
266 s->what = strdup(s->parameters_fragment.what);
267 else if (s->parameters_proc_swaps.what)
268 s->what = strdup(s->parameters_proc_swaps.what);
270 s->what = unit_name_to_path(u->id);
276 path_kill_slashes(s->what);
278 if (!UNIT(s)->description)
279 if ((r = unit_set_description(u, s->what)) < 0)
282 r = swap_add_device_links(s);
286 r = swap_add_mount_links(s);
290 r = unit_add_default_cgroups(u);
294 if (UNIT(s)->default_dependencies) {
295 r = swap_add_default_dependencies(s);
300 r = unit_exec_context_defaults(u, &s->exec_context);
305 return swap_verify(s);
308 static int swap_add_one(
311 const char *what_proc_swaps,
318 char _cleanup_free_ *e = NULL;
327 assert(what_proc_swaps);
329 e = unit_name_from_path(what, ".swap");
333 u = manager_get_unit(m, e);
336 SWAP(u)->from_proc_swaps &&
337 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
343 u = unit_new(m, sizeof(Swap));
347 r = unit_add_name(u, e);
351 SWAP(u)->what = strdup(what);
352 if (!SWAP(u)->what) {
357 unit_add_to_load_queue(u);
361 p = &SWAP(u)->parameters_proc_swaps;
364 wp = strdup(what_proc_swaps);
370 if (!m->swaps_by_proc_swaps) {
371 m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func);
372 if (!m->swaps_by_proc_swaps) {
381 first = hashmap_get(m->swaps_by_proc_swaps, wp);
382 LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u));
384 r = hashmap_replace(m->swaps_by_proc_swaps, wp, first);
390 SWAP(u)->is_active = true;
391 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
394 SWAP(u)->from_proc_swaps = true;
396 p->priority = priority;
400 unit_add_to_dbus_queue(u);
405 log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
415 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
421 if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) {
422 struct udev_device *d;
424 struct udev_list_entry *item = NULL, *first = NULL;
426 /* So this is a proper swap device. Create swap units
427 * for all names this swap device is known under */
429 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
433 dn = udev_device_get_devnode(d);
434 /* Skip dn==device, since that case will be handled below */
435 if (dn && !streq(dn, device))
436 r = swap_add_one(m, dn, device, prio, false, false, set_flags);
438 /* Add additional units for all symlinks */
439 first = udev_device_get_devlinks_list_entry(d);
440 udev_list_entry_foreach(item, first) {
443 /* Don't bother with the /dev/block links */
444 p = udev_list_entry_get_name(item);
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 k = swap_add_one(m, p, device, prio, false, false, set_flags);
459 udev_device_unref(d);
462 k = swap_add_one(m, device, device, prio, false, false, set_flags);
469 static void swap_set_state(Swap *s, SwapState state) {
474 old_state = s->state;
477 if (state != SWAP_ACTIVATING &&
478 state != SWAP_ACTIVATING_SIGTERM &&
479 state != SWAP_ACTIVATING_SIGKILL &&
480 state != SWAP_DEACTIVATING &&
481 state != SWAP_DEACTIVATING_SIGTERM &&
482 state != SWAP_DEACTIVATING_SIGKILL) {
483 unit_unwatch_timer(UNIT(s), &s->timer_watch);
484 swap_unwatch_control_pid(s);
485 s->control_command = NULL;
486 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
489 if (state != old_state)
490 log_debug_unit(UNIT(s)->id,
491 "%s changed %s -> %s",
493 swap_state_to_string(old_state),
494 swap_state_to_string(state));
496 unit_notify(UNIT(s), state_translation_table[old_state],
497 state_translation_table[state], true);
500 static int swap_coldplug(Unit *u) {
502 SwapState new_state = SWAP_DEAD;
506 assert(s->state == SWAP_DEAD);
508 if (s->deserialized_state != s->state)
509 new_state = s->deserialized_state;
510 else if (s->from_proc_swaps)
511 new_state = SWAP_ACTIVE;
513 if (new_state != s->state) {
515 if (new_state == SWAP_ACTIVATING ||
516 new_state == SWAP_ACTIVATING_SIGTERM ||
517 new_state == SWAP_ACTIVATING_SIGKILL ||
518 new_state == SWAP_DEACTIVATING ||
519 new_state == SWAP_DEACTIVATING_SIGTERM ||
520 new_state == SWAP_DEACTIVATING_SIGKILL) {
522 if (s->control_pid <= 0)
525 r = unit_watch_pid(UNIT(s), s->control_pid);
529 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
534 swap_set_state(s, new_state);
540 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
547 if (s->from_proc_swaps)
548 p = &s->parameters_proc_swaps;
549 else if (s->from_fragment)
550 p = &s->parameters_fragment;
558 "%sFrom /proc/swaps: %s\n"
559 "%sFrom fragment: %s\n",
560 prefix, swap_state_to_string(s->state),
561 prefix, swap_result_to_string(s->result),
563 prefix, yes_no(s->from_proc_swaps),
564 prefix, yes_no(s->from_fragment));
572 prefix, yes_no(p->noauto),
573 prefix, yes_no(p->nofail));
575 if (s->control_pid > 0)
577 "%sControl PID: %lu\n",
578 prefix, (unsigned long) s->control_pid);
580 exec_context_dump(&s->exec_context, f, prefix);
581 kill_context_dump(&s->kill_context, f, prefix);
584 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
592 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
600 UNIT(s)->manager->environment,
604 UNIT(s)->manager->confirm_spawn,
605 UNIT(s)->cgroup_bondings,
606 UNIT(s)->cgroup_attributes,
614 r = unit_watch_pid(UNIT(s), pid);
616 /* FIXME: we need to do something here */
624 unit_unwatch_timer(UNIT(s), &s->timer_watch);
629 static void swap_enter_dead(Swap *s, SwapResult f) {
632 if (f != SWAP_SUCCESS)
635 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
638 static void swap_enter_active(Swap *s, SwapResult f) {
641 if (f != SWAP_SUCCESS)
644 swap_set_state(s, SWAP_ACTIVE);
647 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
652 if (f != SWAP_SUCCESS)
655 r = unit_kill_context(
658 state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
666 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
670 swap_set_state(s, state);
672 swap_enter_dead(s, SWAP_SUCCESS);
677 log_warning_unit(UNIT(s)->id,
678 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
680 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
683 static void swap_enter_activating(Swap *s) {
688 s->control_command_id = SWAP_EXEC_ACTIVATE;
689 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
691 if (s->from_fragment)
692 priority = s->parameters_fragment.priority;
699 snprintf(p, sizeof(p), "%i", priority);
702 r = exec_command_set(
710 r = exec_command_set(
719 swap_unwatch_control_pid(s);
721 r = swap_spawn(s, s->control_command, &s->control_pid);
725 swap_set_state(s, SWAP_ACTIVATING);
730 log_warning_unit(UNIT(s)->id,
731 "%s failed to run 'swapon' task: %s",
732 UNIT(s)->id, strerror(-r));
733 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
736 static void swap_enter_deactivating(Swap *s) {
741 s->control_command_id = SWAP_EXEC_DEACTIVATE;
742 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
744 r = exec_command_set(s->control_command,
751 swap_unwatch_control_pid(s);
753 r = swap_spawn(s, s->control_command, &s->control_pid);
757 swap_set_state(s, SWAP_DEACTIVATING);
762 log_warning_unit(UNIT(s)->id,
763 "%s failed to run 'swapoff' task: %s",
764 UNIT(s)->id, strerror(-r));
765 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
768 static int swap_start(Unit *u) {
773 /* We cannot fulfill this request right now, try again later
776 if (s->state == SWAP_DEACTIVATING ||
777 s->state == SWAP_DEACTIVATING_SIGTERM ||
778 s->state == SWAP_DEACTIVATING_SIGKILL ||
779 s->state == SWAP_ACTIVATING_SIGTERM ||
780 s->state == SWAP_ACTIVATING_SIGKILL)
783 if (s->state == SWAP_ACTIVATING)
786 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
788 if (detect_container(NULL) > 0)
791 s->result = SWAP_SUCCESS;
792 swap_enter_activating(s);
796 static int swap_stop(Unit *u) {
801 if (s->state == SWAP_DEACTIVATING ||
802 s->state == SWAP_DEACTIVATING_SIGTERM ||
803 s->state == SWAP_DEACTIVATING_SIGKILL ||
804 s->state == SWAP_ACTIVATING_SIGTERM ||
805 s->state == SWAP_ACTIVATING_SIGKILL)
808 assert(s->state == SWAP_ACTIVATING ||
809 s->state == SWAP_ACTIVE);
811 if (detect_container(NULL) > 0)
814 swap_enter_deactivating(s);
818 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
825 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
826 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
828 if (s->control_pid > 0)
829 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
831 if (s->control_command_id >= 0)
832 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
837 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
843 if (streq(key, "state")) {
846 state = swap_state_from_string(value);
848 log_debug_unit(u->id, "Failed to parse state value %s", value);
850 s->deserialized_state = state;
851 } else if (streq(key, "result")) {
854 f = swap_result_from_string(value);
856 log_debug_unit(u->id, "Failed to parse result value %s", value);
857 else if (f != SWAP_SUCCESS)
859 } else if (streq(key, "control-pid")) {
862 if (parse_pid(value, &pid) < 0)
863 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
865 s->control_pid = pid;
867 } else if (streq(key, "control-command")) {
870 id = swap_exec_command_from_string(value);
872 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
874 s->control_command_id = id;
875 s->control_command = s->exec_command + id;
879 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
884 static UnitActiveState swap_active_state(Unit *u) {
887 return state_translation_table[SWAP(u)->state];
890 static const char *swap_sub_state_to_string(Unit *u) {
893 return swap_state_to_string(SWAP(u)->state);
896 static bool swap_check_gc(Unit *u) {
901 return s->from_proc_swaps;
904 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
911 if (pid != s->control_pid)
916 if (is_clean_exit(code, status, NULL))
918 else if (code == CLD_EXITED)
919 f = SWAP_FAILURE_EXIT_CODE;
920 else if (code == CLD_KILLED)
921 f = SWAP_FAILURE_SIGNAL;
922 else if (code == CLD_DUMPED)
923 f = SWAP_FAILURE_CORE_DUMP;
925 assert_not_reached("Unknown code");
927 if (f != SWAP_SUCCESS)
930 if (s->control_command) {
931 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
933 s->control_command = NULL;
934 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
937 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
939 "%s swap process exited, code=%s status=%i",
940 u->id, sigchld_code_to_string(code), status);
944 case SWAP_ACTIVATING:
945 case SWAP_ACTIVATING_SIGTERM:
946 case SWAP_ACTIVATING_SIGKILL:
948 if (f == SWAP_SUCCESS)
949 swap_enter_active(s, f);
951 swap_enter_dead(s, f);
954 case SWAP_DEACTIVATING:
955 case SWAP_DEACTIVATING_SIGKILL:
956 case SWAP_DEACTIVATING_SIGTERM:
958 if (f == SWAP_SUCCESS)
959 swap_enter_dead(s, f);
961 swap_enter_dead(s, f);
965 assert_not_reached("Uh, control process died at wrong time.");
968 /* Notify clients about changed exit status */
969 unit_add_to_dbus_queue(u);
971 /* Request a reload of /proc/swaps, so that following units
972 * can follow our state change */
973 u->manager->request_reload = true;
976 static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
980 assert(elapsed == 1);
981 assert(w == &s->timer_watch);
985 case SWAP_ACTIVATING:
986 log_warning_unit(u->id, "%s activation timed out. Stopping.", u->id);
987 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
990 case SWAP_DEACTIVATING:
991 log_warning_unit(u->id, "%s deactivation timed out. Stopping.", u->id);
992 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
995 case SWAP_ACTIVATING_SIGTERM:
996 if (s->kill_context.send_sigkill) {
997 log_warning_unit(u->id, "%s activation timed out. Killing.", u->id);
998 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1000 log_warning_unit(u->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", u->id);
1001 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1005 case SWAP_DEACTIVATING_SIGTERM:
1006 if (s->kill_context.send_sigkill) {
1007 log_warning_unit(u->id, "%s deactivation timed out. Killing.", u->id);
1008 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1010 log_warning_unit(u->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id);
1011 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1015 case SWAP_ACTIVATING_SIGKILL:
1016 case SWAP_DEACTIVATING_SIGKILL:
1017 log_warning_unit(u->id, "%s swap process still around after SIGKILL. Ignoring.", u->id);
1018 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1022 assert_not_reached("Timeout at wrong time.");
1026 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1032 rewind(m->proc_swaps);
1034 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1037 char *dev = NULL, *d;
1040 k = fscanf(m->proc_swaps,
1041 "%ms " /* device/file */
1042 "%*s " /* type of swap */
1043 "%*s " /* swap size */
1045 "%i\n", /* priority */
1051 log_warning("Failed to parse /proc/swaps:%u", i);
1062 k = swap_process_new_swap(m, d, prio, set_flags);
1072 int swap_dispatch_reload(Manager *m) {
1073 /* This function should go as soon as the kernel properly notifies us */
1075 if (_likely_(!m->request_reload))
1078 m->request_reload = false;
1080 return swap_fd_event(m, EPOLLPRI);
1083 int swap_fd_event(Manager *m, int events) {
1088 assert(events & EPOLLPRI);
1090 r = swap_load_proc_swaps(m, true);
1092 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1094 /* Reset flags, just in case, for late calls */
1095 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1096 Swap *swap = SWAP(u);
1098 swap->is_active = swap->just_activated = false;
1104 manager_dispatch_load_queue(m);
1106 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1107 Swap *swap = SWAP(u);
1109 if (!swap->is_active) {
1110 /* This has just been deactivated */
1112 swap->from_proc_swaps = false;
1113 swap_unset_proc_swaps(swap);
1115 switch (swap->state) {
1118 swap_enter_dead(swap, SWAP_SUCCESS);
1122 swap_set_state(swap, swap->state);
1126 } else if (swap->just_activated) {
1128 /* New swap entry */
1130 switch (swap->state) {
1134 swap_enter_active(swap, SWAP_SUCCESS);
1138 /* Nothing really changed, but let's
1139 * issue an notification call
1140 * nonetheless, in case somebody is
1141 * waiting for this. */
1142 swap_set_state(swap, swap->state);
1147 /* Reset the flags for later calls */
1148 swap->is_active = swap->just_activated = false;
1154 static Unit *swap_following(Unit *u) {
1156 Swap *other, *first = NULL;
1160 if (streq_ptr(s->what, s->parameters_proc_swaps.what))
1163 /* Make everybody follow the unit that's named after the swap
1164 * device in the kernel */
1166 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1167 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1170 LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
1171 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1180 static int swap_following_set(Unit *u, Set **_set) {
1189 if (LIST_JUST_US(same_proc_swaps, s)) {
1194 if (!(set = set_new(NULL, NULL)))
1197 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1198 if ((r = set_put(set, other)) < 0)
1201 LIST_FOREACH_BEFORE(same_proc_swaps, other, s)
1202 if ((r = set_put(set, other)) < 0)
1213 static void swap_shutdown(Manager *m) {
1216 if (m->proc_swaps) {
1217 fclose(m->proc_swaps);
1218 m->proc_swaps = NULL;
1221 hashmap_free(m->swaps_by_proc_swaps);
1222 m->swaps_by_proc_swaps = NULL;
1225 static int swap_enumerate(Manager *m) {
1227 struct epoll_event ev;
1230 if (!m->proc_swaps) {
1231 m->proc_swaps = fopen("/proc/swaps", "re");
1233 return (errno == ENOENT) ? 0 : -errno;
1235 m->swap_watch.type = WATCH_SWAP;
1236 m->swap_watch.fd = fileno(m->proc_swaps);
1239 ev.events = EPOLLPRI;
1240 ev.data.ptr = &m->swap_watch;
1242 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
1246 r = swap_load_proc_swaps(m, false);
1253 static void swap_reset_failed(Unit *u) {
1258 if (s->state == SWAP_FAILED)
1259 swap_set_state(s, SWAP_DEAD);
1261 s->result = SWAP_SUCCESS;
1264 static int swap_kill(Unit *u, KillWho who, int signo, DBusError *error) {
1267 Set *pid_set = NULL;
1271 if (who == KILL_MAIN) {
1272 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Swap units have no main processes");
1276 if (s->control_pid <= 0 && who == KILL_CONTROL) {
1277 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
1281 if (who == KILL_CONTROL || who == KILL_ALL)
1282 if (s->control_pid > 0)
1283 if (kill(s->control_pid, signo) < 0)
1286 if (who == KILL_ALL) {
1289 pid_set = set_new(trivial_hash_func, trivial_compare_func);
1293 /* Exclude the control pid from being killed via the cgroup */
1294 if (s->control_pid > 0) {
1295 q = set_put(pid_set, LONG_TO_PTR(s->control_pid));
1302 q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
1303 if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
1314 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1315 [SWAP_DEAD] = "dead",
1316 [SWAP_ACTIVATING] = "activating",
1317 [SWAP_ACTIVE] = "active",
1318 [SWAP_DEACTIVATING] = "deactivating",
1319 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1320 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1321 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1322 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1323 [SWAP_FAILED] = "failed"
1326 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1328 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1329 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1330 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1333 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1335 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1336 [SWAP_SUCCESS] = "success",
1337 [SWAP_FAILURE_RESOURCES] = "resources",
1338 [SWAP_FAILURE_TIMEOUT] = "timeout",
1339 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1340 [SWAP_FAILURE_SIGNAL] = "signal",
1341 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1344 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1346 const UnitVTable swap_vtable = {
1347 .object_size = sizeof(Swap),
1354 .exec_context_offset = offsetof(Swap, exec_context),
1355 .exec_section = "Swap",
1358 .no_instances = true,
1364 .coldplug = swap_coldplug,
1368 .start = swap_start,
1373 .serialize = swap_serialize,
1374 .deserialize_item = swap_deserialize_item,
1376 .active_state = swap_active_state,
1377 .sub_state_to_string = swap_sub_state_to_string,
1379 .check_gc = swap_check_gc,
1381 .sigchld_event = swap_sigchld_event,
1382 .timer_event = swap_timer_event,
1384 .reset_failed = swap_reset_failed,
1386 .bus_interface = "org.freedesktop.systemd1.Swap",
1387 .bus_message_handler = bus_swap_message_handler,
1388 .bus_invalidating_properties = bus_swap_invalidating_properties,
1390 .following = swap_following,
1391 .following_set = swap_following_set,
1393 .enumerate = swap_enumerate,
1394 .shutdown = swap_shutdown,
1396 .status_message_formats = {
1397 .starting_stopping = {
1398 [0] = "Activating swap %s...",
1399 [1] = "Deactivating swap %s...",
1401 .finished_start_job = {
1402 [JOB_DONE] = "Activated swap %s.",
1403 [JOB_FAILED] = "Failed to activate swap %s.",
1404 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1405 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1407 .finished_stop_job = {
1408 [JOB_DONE] = "Deactivated swap %s.",
1409 [JOB_FAILED] = "Failed deactivating swap %s.",
1410 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",