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 static int swap_add_device_links(Swap *s) {
148 if (s->from_fragment)
149 p = &s->parameters_fragment;
153 if (is_device_path(s->what))
154 return unit_add_node_link(UNIT(s), s->what, !p->noauto &&
155 UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
157 /* File based swap devices need to be ordered after
158 * systemd-remount-fs.service, since they might need a
159 * writable file system. */
160 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
163 static int swap_add_default_dependencies(Swap *s) {
164 bool nofail = false, noauto = false;
169 if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
172 if (detect_container(NULL) > 0)
175 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
179 if (s->from_fragment) {
180 SwapParameters *p = &s->parameters_fragment;
188 r = unit_add_dependency_by_name_inverse(UNIT(s),
189 UNIT_WANTS, SPECIAL_SWAP_TARGET, NULL, true);
191 r = unit_add_two_dependencies_by_name_inverse(UNIT(s),
192 UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SWAP_TARGET, NULL, true);
200 static int swap_verify(Swap *s) {
202 _cleanup_free_ char *e = NULL;
204 if (UNIT(s)->load_state != UNIT_LOADED)
207 e = unit_name_from_path(s->what, ".swap");
211 b = unit_has_name(UNIT(s), e);
213 log_error_unit(UNIT(s)->id,
214 "%s: Value of \"What\" and unit name do not match, not loading.",
219 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
220 log_error_unit(UNIT(s)->id,
221 "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.",
229 static int swap_load(Unit *u) {
234 assert(u->load_state == UNIT_STUB);
236 /* Load a .swap file */
237 r = unit_load_fragment_and_dropin_optional(u);
241 if (u->load_state == UNIT_LOADED) {
242 r = unit_add_exec_dependencies(u, &s->exec_context);
246 if (UNIT(s)->fragment_path)
247 s->from_fragment = true;
250 if (s->parameters_fragment.what)
251 s->what = strdup(s->parameters_fragment.what);
252 else if (s->parameters_proc_swaps.what)
253 s->what = strdup(s->parameters_proc_swaps.what);
255 s->what = unit_name_to_path(u->id);
261 path_kill_slashes(s->what);
263 if (!UNIT(s)->description)
264 if ((r = unit_set_description(u, s->what)) < 0)
267 r = unit_require_mounts_for(UNIT(s), s->what);
271 r = swap_add_device_links(s);
275 r = unit_add_default_slice(u);
279 if (UNIT(s)->default_dependencies) {
280 r = swap_add_default_dependencies(s);
285 r = unit_exec_context_defaults(u, &s->exec_context);
290 return swap_verify(s);
293 static int swap_add_one(
296 const char *what_proc_swaps,
303 _cleanup_free_ char *e = NULL;
312 assert(what_proc_swaps);
314 e = unit_name_from_path(what, ".swap");
318 u = manager_get_unit(m, e);
321 SWAP(u)->from_proc_swaps &&
322 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
328 u = unit_new(m, sizeof(Swap));
332 r = unit_add_name(u, e);
336 SWAP(u)->what = strdup(what);
337 if (!SWAP(u)->what) {
342 unit_add_to_load_queue(u);
346 p = &SWAP(u)->parameters_proc_swaps;
349 wp = strdup(what_proc_swaps);
355 if (!m->swaps_by_proc_swaps) {
356 m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func);
357 if (!m->swaps_by_proc_swaps) {
366 first = hashmap_get(m->swaps_by_proc_swaps, wp);
367 LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u));
369 r = hashmap_replace(m->swaps_by_proc_swaps, wp, first);
375 SWAP(u)->is_active = true;
376 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
379 SWAP(u)->from_proc_swaps = true;
381 p->priority = priority;
385 unit_add_to_dbus_queue(u);
390 log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
400 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
406 if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) {
407 struct udev_device *d;
409 struct udev_list_entry *item = NULL, *first = NULL;
411 /* So this is a proper swap device. Create swap units
412 * for all names this swap device is known under */
414 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
418 dn = udev_device_get_devnode(d);
419 /* Skip dn==device, since that case will be handled below */
420 if (dn && !streq(dn, device))
421 r = swap_add_one(m, dn, device, prio, false, false, set_flags);
423 /* Add additional units for all symlinks */
424 first = udev_device_get_devlinks_list_entry(d);
425 udev_list_entry_foreach(item, first) {
428 /* Don't bother with the /dev/block links */
429 p = udev_list_entry_get_name(item);
431 if (path_startswith(p, "/dev/block/"))
434 if (stat(p, &st) >= 0)
435 if ((!S_ISBLK(st.st_mode)) ||
436 st.st_rdev != udev_device_get_devnum(d))
439 k = swap_add_one(m, p, device, prio, false, false, set_flags);
444 udev_device_unref(d);
447 k = swap_add_one(m, device, device, prio, false, false, set_flags);
454 static void swap_set_state(Swap *s, SwapState state) {
459 old_state = s->state;
462 if (state != SWAP_ACTIVATING &&
463 state != SWAP_ACTIVATING_SIGTERM &&
464 state != SWAP_ACTIVATING_SIGKILL &&
465 state != SWAP_DEACTIVATING &&
466 state != SWAP_DEACTIVATING_SIGTERM &&
467 state != SWAP_DEACTIVATING_SIGKILL) {
468 unit_unwatch_timer(UNIT(s), &s->timer_watch);
469 swap_unwatch_control_pid(s);
470 s->control_command = NULL;
471 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
474 if (state != old_state)
475 log_debug_unit(UNIT(s)->id,
476 "%s changed %s -> %s",
478 swap_state_to_string(old_state),
479 swap_state_to_string(state));
481 unit_notify(UNIT(s), state_translation_table[old_state],
482 state_translation_table[state], true);
485 static int swap_coldplug(Unit *u) {
487 SwapState new_state = SWAP_DEAD;
491 assert(s->state == SWAP_DEAD);
493 if (s->deserialized_state != s->state)
494 new_state = s->deserialized_state;
495 else if (s->from_proc_swaps)
496 new_state = SWAP_ACTIVE;
498 if (new_state != s->state) {
500 if (new_state == SWAP_ACTIVATING ||
501 new_state == SWAP_ACTIVATING_SIGTERM ||
502 new_state == SWAP_ACTIVATING_SIGKILL ||
503 new_state == SWAP_DEACTIVATING ||
504 new_state == SWAP_DEACTIVATING_SIGTERM ||
505 new_state == SWAP_DEACTIVATING_SIGKILL) {
507 if (s->control_pid <= 0)
510 r = unit_watch_pid(UNIT(s), s->control_pid);
514 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
519 swap_set_state(s, new_state);
525 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
532 if (s->from_proc_swaps)
533 p = &s->parameters_proc_swaps;
534 else if (s->from_fragment)
535 p = &s->parameters_fragment;
543 "%sFrom /proc/swaps: %s\n"
544 "%sFrom fragment: %s\n",
545 prefix, swap_state_to_string(s->state),
546 prefix, swap_result_to_string(s->result),
548 prefix, yes_no(s->from_proc_swaps),
549 prefix, yes_no(s->from_fragment));
557 prefix, yes_no(p->noauto),
558 prefix, yes_no(p->nofail));
560 if (s->control_pid > 0)
562 "%sControl PID: %lu\n",
563 prefix, (unsigned long) s->control_pid);
565 exec_context_dump(&s->exec_context, f, prefix);
566 kill_context_dump(&s->kill_context, f, prefix);
569 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
577 unit_realize_cgroup(UNIT(s));
579 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
587 UNIT(s)->manager->environment,
591 UNIT(s)->manager->confirm_spawn,
592 UNIT(s)->manager->cgroup_supported,
593 UNIT(s)->cgroup_path,
600 r = unit_watch_pid(UNIT(s), pid);
602 /* FIXME: we need to do something here */
610 unit_unwatch_timer(UNIT(s), &s->timer_watch);
615 static void swap_enter_dead(Swap *s, SwapResult f) {
618 if (f != SWAP_SUCCESS)
621 exec_context_tmp_dirs_done(&s->exec_context);
622 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
625 static void swap_enter_active(Swap *s, SwapResult f) {
628 if (f != SWAP_SUCCESS)
631 swap_set_state(s, SWAP_ACTIVE);
634 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
639 if (f != SWAP_SUCCESS)
642 r = unit_kill_context(
645 state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
653 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
657 swap_set_state(s, state);
659 swap_enter_dead(s, SWAP_SUCCESS);
664 log_warning_unit(UNIT(s)->id,
665 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
667 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
670 static void swap_enter_activating(Swap *s) {
675 s->control_command_id = SWAP_EXEC_ACTIVATE;
676 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
678 if (s->from_fragment)
679 priority = s->parameters_fragment.priority;
686 snprintf(p, sizeof(p), "%i", priority);
689 r = exec_command_set(
697 r = exec_command_set(
706 swap_unwatch_control_pid(s);
708 r = swap_spawn(s, s->control_command, &s->control_pid);
712 swap_set_state(s, SWAP_ACTIVATING);
717 log_warning_unit(UNIT(s)->id,
718 "%s failed to run 'swapon' task: %s",
719 UNIT(s)->id, strerror(-r));
720 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
723 static void swap_enter_deactivating(Swap *s) {
728 s->control_command_id = SWAP_EXEC_DEACTIVATE;
729 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
731 r = exec_command_set(s->control_command,
738 swap_unwatch_control_pid(s);
740 r = swap_spawn(s, s->control_command, &s->control_pid);
744 swap_set_state(s, SWAP_DEACTIVATING);
749 log_warning_unit(UNIT(s)->id,
750 "%s failed to run 'swapoff' task: %s",
751 UNIT(s)->id, strerror(-r));
752 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
755 static int swap_start(Unit *u) {
760 /* We cannot fulfill this request right now, try again later
763 if (s->state == SWAP_DEACTIVATING ||
764 s->state == SWAP_DEACTIVATING_SIGTERM ||
765 s->state == SWAP_DEACTIVATING_SIGKILL ||
766 s->state == SWAP_ACTIVATING_SIGTERM ||
767 s->state == SWAP_ACTIVATING_SIGKILL)
770 if (s->state == SWAP_ACTIVATING)
773 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
775 if (detect_container(NULL) > 0)
778 s->result = SWAP_SUCCESS;
779 swap_enter_activating(s);
783 static int swap_stop(Unit *u) {
788 if (s->state == SWAP_DEACTIVATING ||
789 s->state == SWAP_DEACTIVATING_SIGTERM ||
790 s->state == SWAP_DEACTIVATING_SIGKILL ||
791 s->state == SWAP_ACTIVATING_SIGTERM ||
792 s->state == SWAP_ACTIVATING_SIGKILL)
795 assert(s->state == SWAP_ACTIVATING ||
796 s->state == SWAP_ACTIVE);
798 if (detect_container(NULL) > 0)
801 swap_enter_deactivating(s);
805 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
812 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
813 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
815 if (s->control_pid > 0)
816 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
818 if (s->control_command_id >= 0)
819 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
821 exec_context_serialize(&s->exec_context, UNIT(s), f);
826 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
832 if (streq(key, "state")) {
835 state = swap_state_from_string(value);
837 log_debug_unit(u->id, "Failed to parse state value %s", value);
839 s->deserialized_state = state;
840 } else if (streq(key, "result")) {
843 f = swap_result_from_string(value);
845 log_debug_unit(u->id, "Failed to parse result value %s", value);
846 else if (f != SWAP_SUCCESS)
848 } else if (streq(key, "control-pid")) {
851 if (parse_pid(value, &pid) < 0)
852 log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
854 s->control_pid = pid;
856 } else if (streq(key, "control-command")) {
859 id = swap_exec_command_from_string(value);
861 log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
863 s->control_command_id = id;
864 s->control_command = s->exec_command + id;
866 } else if (streq(key, "tmp-dir")) {
873 s->exec_context.tmp_dir = t;
874 } else if (streq(key, "var-tmp-dir")) {
881 s->exec_context.var_tmp_dir = t;
883 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
888 _pure_ static UnitActiveState swap_active_state(Unit *u) {
891 return state_translation_table[SWAP(u)->state];
894 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
897 return swap_state_to_string(SWAP(u)->state);
900 _pure_ static bool swap_check_gc(Unit *u) {
905 return s->from_proc_swaps;
908 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
915 if (pid != s->control_pid)
920 if (is_clean_exit(code, status, NULL))
922 else if (code == CLD_EXITED)
923 f = SWAP_FAILURE_EXIT_CODE;
924 else if (code == CLD_KILLED)
925 f = SWAP_FAILURE_SIGNAL;
926 else if (code == CLD_DUMPED)
927 f = SWAP_FAILURE_CORE_DUMP;
929 assert_not_reached("Unknown code");
931 if (f != SWAP_SUCCESS)
934 if (s->control_command) {
935 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
937 s->control_command = NULL;
938 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
941 log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
943 "%s swap process exited, code=%s status=%i",
944 u->id, sigchld_code_to_string(code), status);
948 case SWAP_ACTIVATING:
949 case SWAP_ACTIVATING_SIGTERM:
950 case SWAP_ACTIVATING_SIGKILL:
952 if (f == SWAP_SUCCESS)
953 swap_enter_active(s, f);
955 swap_enter_dead(s, f);
958 case SWAP_DEACTIVATING:
959 case SWAP_DEACTIVATING_SIGKILL:
960 case SWAP_DEACTIVATING_SIGTERM:
962 if (f == SWAP_SUCCESS)
963 swap_enter_dead(s, f);
965 swap_enter_dead(s, f);
969 assert_not_reached("Uh, control process died at wrong time.");
972 /* Notify clients about changed exit status */
973 unit_add_to_dbus_queue(u);
975 /* Request a reload of /proc/swaps, so that following units
976 * can follow our state change */
977 u->manager->request_reload = true;
980 static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
984 assert(elapsed == 1);
985 assert(w == &s->timer_watch);
989 case SWAP_ACTIVATING:
990 log_warning_unit(u->id, "%s activation timed out. Stopping.", u->id);
991 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
994 case SWAP_DEACTIVATING:
995 log_warning_unit(u->id, "%s deactivation timed out. Stopping.", u->id);
996 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
999 case SWAP_ACTIVATING_SIGTERM:
1000 if (s->kill_context.send_sigkill) {
1001 log_warning_unit(u->id, "%s activation timed out. Killing.", u->id);
1002 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1004 log_warning_unit(u->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", u->id);
1005 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1009 case SWAP_DEACTIVATING_SIGTERM:
1010 if (s->kill_context.send_sigkill) {
1011 log_warning_unit(u->id, "%s deactivation timed out. Killing.", u->id);
1012 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1014 log_warning_unit(u->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id);
1015 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1019 case SWAP_ACTIVATING_SIGKILL:
1020 case SWAP_DEACTIVATING_SIGKILL:
1021 log_warning_unit(u->id, "%s swap process still around after SIGKILL. Ignoring.", u->id);
1022 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1026 assert_not_reached("Timeout at wrong time.");
1030 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1036 rewind(m->proc_swaps);
1038 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1041 _cleanup_free_ char *dev = NULL, *d = NULL;
1044 k = fscanf(m->proc_swaps,
1045 "%ms " /* device/file */
1046 "%*s " /* type of swap */
1047 "%*s " /* swap size */
1049 "%i\n", /* priority */
1055 log_warning("Failed to parse /proc/swaps:%u", i);
1063 k = swap_process_new_swap(m, d, prio, set_flags);
1071 int swap_dispatch_reload(Manager *m) {
1072 /* This function should go as soon as the kernel properly notifies us */
1074 if (_likely_(!m->request_reload))
1077 m->request_reload = false;
1079 return swap_fd_event(m, EPOLLPRI);
1082 int swap_fd_event(Manager *m, int events) {
1087 assert(events & EPOLLPRI);
1089 r = swap_load_proc_swaps(m, true);
1091 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1093 /* Reset flags, just in case, for late calls */
1094 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1095 Swap *swap = SWAP(u);
1097 swap->is_active = swap->just_activated = false;
1103 manager_dispatch_load_queue(m);
1105 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1106 Swap *swap = SWAP(u);
1108 if (!swap->is_active) {
1109 /* This has just been deactivated */
1111 swap->from_proc_swaps = false;
1112 swap_unset_proc_swaps(swap);
1114 switch (swap->state) {
1117 swap_enter_dead(swap, SWAP_SUCCESS);
1121 swap_set_state(swap, swap->state);
1125 } else if (swap->just_activated) {
1127 /* New swap entry */
1129 switch (swap->state) {
1133 swap_enter_active(swap, SWAP_SUCCESS);
1137 /* Nothing really changed, but let's
1138 * issue an notification call
1139 * nonetheless, in case somebody is
1140 * waiting for this. */
1141 swap_set_state(swap, swap->state);
1146 /* Reset the flags for later calls */
1147 swap->is_active = swap->just_activated = false;
1153 static Unit *swap_following(Unit *u) {
1155 Swap *other, *first = NULL;
1159 if (streq_ptr(s->what, s->parameters_proc_swaps.what))
1162 /* Make everybody follow the unit that's named after the swap
1163 * device in the kernel */
1165 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1166 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1169 LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
1170 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1179 static int swap_following_set(Unit *u, Set **_set) {
1188 if (LIST_JUST_US(same_proc_swaps, s)) {
1193 if (!(set = set_new(NULL, NULL)))
1196 LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1197 if ((r = set_put(set, other)) < 0)
1200 LIST_FOREACH_BEFORE(same_proc_swaps, other, s)
1201 if ((r = set_put(set, other)) < 0)
1212 static void swap_shutdown(Manager *m) {
1215 if (m->proc_swaps) {
1216 fclose(m->proc_swaps);
1217 m->proc_swaps = NULL;
1220 hashmap_free(m->swaps_by_proc_swaps);
1221 m->swaps_by_proc_swaps = NULL;
1224 static int swap_enumerate(Manager *m) {
1228 if (!m->proc_swaps) {
1229 struct epoll_event ev = {
1231 .data.ptr = &m->swap_watch,
1234 m->proc_swaps = fopen("/proc/swaps", "re");
1236 return (errno == ENOENT) ? 0 : -errno;
1238 m->swap_watch.type = WATCH_SWAP;
1239 m->swap_watch.fd = fileno(m->proc_swaps);
1241 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
1245 r = swap_load_proc_swaps(m, false);
1252 static void swap_reset_failed(Unit *u) {
1257 if (s->state == SWAP_FAILED)
1258 swap_set_state(s, SWAP_DEAD);
1260 s->result = SWAP_SUCCESS;
1263 static int swap_kill(Unit *u, KillWho who, int signo, DBusError *error) {
1264 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1267 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1268 [SWAP_DEAD] = "dead",
1269 [SWAP_ACTIVATING] = "activating",
1270 [SWAP_ACTIVE] = "active",
1271 [SWAP_DEACTIVATING] = "deactivating",
1272 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1273 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1274 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1275 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1276 [SWAP_FAILED] = "failed"
1279 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1281 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1282 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1283 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1286 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1288 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1289 [SWAP_SUCCESS] = "success",
1290 [SWAP_FAILURE_RESOURCES] = "resources",
1291 [SWAP_FAILURE_TIMEOUT] = "timeout",
1292 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1293 [SWAP_FAILURE_SIGNAL] = "signal",
1294 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1297 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1299 const UnitVTable swap_vtable = {
1300 .object_size = sizeof(Swap),
1307 .private_section = "Swap",
1308 .exec_context_offset = offsetof(Swap, exec_context),
1309 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1312 .no_instances = true,
1318 .coldplug = swap_coldplug,
1322 .start = swap_start,
1327 .serialize = swap_serialize,
1328 .deserialize_item = swap_deserialize_item,
1330 .active_state = swap_active_state,
1331 .sub_state_to_string = swap_sub_state_to_string,
1333 .check_gc = swap_check_gc,
1335 .sigchld_event = swap_sigchld_event,
1336 .timer_event = swap_timer_event,
1338 .reset_failed = swap_reset_failed,
1340 .bus_interface = "org.freedesktop.systemd1.Swap",
1341 .bus_message_handler = bus_swap_message_handler,
1342 .bus_invalidating_properties = bus_swap_invalidating_properties,
1343 .bus_set_property = bus_swap_set_property,
1344 .bus_commit_properties = bus_swap_commit_properties,
1346 .following = swap_following,
1347 .following_set = swap_following_set,
1349 .enumerate = swap_enumerate,
1350 .shutdown = swap_shutdown,
1352 .status_message_formats = {
1353 .starting_stopping = {
1354 [0] = "Activating swap %s...",
1355 [1] = "Deactivating swap %s...",
1357 .finished_start_job = {
1358 [JOB_DONE] = "Activated swap %s.",
1359 [JOB_FAILED] = "Failed to activate swap %s.",
1360 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1361 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1363 .finished_stop_job = {
1364 [JOB_DONE] = "Deactivated swap %s.",
1365 [JOB_FAILED] = "Failed deactivating swap %s.",
1366 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",