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/>.
24 #include <sys/epoll.h>
30 #include "unit-name.h"
31 #include "dbus-swap.h"
33 #include "exit-status.h"
34 #include "path-util.h"
36 #include "udev-util.h"
37 #include "fstab-util.h"
39 static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
40 [SWAP_DEAD] = UNIT_INACTIVE,
41 [SWAP_ACTIVATING] = UNIT_ACTIVATING,
42 [SWAP_ACTIVATING_DONE] = UNIT_ACTIVE,
43 [SWAP_ACTIVE] = UNIT_ACTIVE,
44 [SWAP_DEACTIVATING] = UNIT_DEACTIVATING,
45 [SWAP_ACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
46 [SWAP_ACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
47 [SWAP_DEACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
48 [SWAP_DEACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
49 [SWAP_FAILED] = UNIT_FAILED
52 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
53 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
55 static void swap_unset_proc_swaps(Swap *s) {
58 if (!s->from_proc_swaps)
61 free(s->parameters_proc_swaps.what);
62 s->parameters_proc_swaps.what = NULL;
64 s->from_proc_swaps = false;
67 static int swap_set_devnode(Swap *s, const char *devnode) {
74 r = hashmap_ensure_allocated(&UNIT(s)->manager->swaps_by_devnode, &string_hash_ops);
78 swaps = UNIT(s)->manager->swaps_by_devnode;
81 first = hashmap_get(swaps, s->devnode);
83 LIST_REMOVE(same_devnode, first, s);
85 hashmap_replace(swaps, first->devnode, first);
87 hashmap_remove(swaps, s->devnode);
94 s->devnode = strdup(devnode);
98 first = hashmap_get(swaps, s->devnode);
99 LIST_PREPEND(same_devnode, first, s);
101 return hashmap_replace(swaps, first->devnode, first);
107 static void swap_init(Unit *u) {
111 assert(UNIT(s)->load_state == UNIT_STUB);
113 s->timeout_usec = u->manager->default_timeout_start_usec;
115 s->exec_context.std_output = u->manager->default_std_output;
116 s->exec_context.std_error = u->manager->default_std_error;
118 s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
120 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
122 u->ignore_on_isolate = true;
125 static void swap_unwatch_control_pid(Swap *s) {
128 if (s->control_pid <= 0)
131 unit_unwatch_pid(UNIT(s), s->control_pid);
135 static void swap_done(Unit *u) {
140 swap_unset_proc_swaps(s);
141 swap_set_devnode(s, NULL);
146 free(s->parameters_fragment.what);
147 s->parameters_fragment.what = NULL;
149 free(s->parameters_fragment.options);
150 s->parameters_fragment.options = NULL;
152 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
153 exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
154 s->control_command = NULL;
156 swap_unwatch_control_pid(s);
158 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
161 static int swap_arm_timer(Swap *s) {
166 if (s->timeout_usec <= 0) {
167 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
171 if (s->timer_event_source) {
172 r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec);
176 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
179 return sd_event_add_time(
180 UNIT(s)->manager->event,
181 &s->timer_event_source,
183 now(CLOCK_MONOTONIC) + s->timeout_usec, 0,
184 swap_dispatch_timer, s);
187 static int swap_add_device_links(Swap *s) {
193 if (!s->from_fragment)
196 if (is_device_path(s->what))
197 return unit_add_node_link(UNIT(s), s->what, UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
199 /* File based swap devices need to be ordered after
200 * systemd-remount-fs.service, since they might need a
201 * writable file system. */
202 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
205 static int swap_add_default_dependencies(Swap *s) {
208 if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
211 if (detect_container(NULL) > 0)
214 return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
217 static int swap_verify(Swap *s) {
219 _cleanup_free_ char *e = NULL;
221 if (UNIT(s)->load_state != UNIT_LOADED)
224 e = unit_name_from_path(s->what, ".swap");
228 b = unit_has_name(UNIT(s), e);
230 log_unit_error(UNIT(s)->id, "%s: Value of \"What\" and unit name do not match, not loading.", UNIT(s)->id);
234 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
235 log_unit_error(UNIT(s)->id, "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.", UNIT(s)->id);
242 static int swap_load_devnode(Swap *s) {
243 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
249 if (stat(s->what, &st) < 0 || !S_ISBLK(st.st_mode))
252 d = udev_device_new_from_devnum(UNIT(s)->manager->udev, 'b', st.st_rdev);
256 p = udev_device_get_devnode(d);
260 return swap_set_devnode(s, p);
263 static int swap_load(Unit *u) {
268 assert(u->load_state == UNIT_STUB);
270 /* Load a .swap file */
271 r = unit_load_fragment_and_dropin_optional(u);
275 if (u->load_state == UNIT_LOADED) {
277 if (UNIT(s)->fragment_path)
278 s->from_fragment = true;
281 if (s->parameters_fragment.what)
282 s->what = strdup(s->parameters_fragment.what);
283 else if (s->parameters_proc_swaps.what)
284 s->what = strdup(s->parameters_proc_swaps.what);
286 s->what = unit_name_to_path(u->id);
292 path_kill_slashes(s->what);
294 if (!UNIT(s)->description) {
295 r = unit_set_description(u, s->what);
300 r = unit_require_mounts_for(UNIT(s), s->what);
304 r = swap_add_device_links(s);
308 r = swap_load_devnode(s);
312 r = unit_patch_contexts(u);
316 r = unit_add_exec_dependencies(u, &s->exec_context);
320 r = unit_add_default_slice(u, &s->cgroup_context);
324 if (UNIT(s)->default_dependencies) {
325 r = swap_add_default_dependencies(s);
331 return swap_verify(s);
334 static int swap_add_one(
337 const char *what_proc_swaps,
341 _cleanup_free_ char *e = NULL;
349 assert(what_proc_swaps);
351 e = unit_name_from_path(what, ".swap");
355 u = manager_get_unit(m, e);
358 SWAP(u)->from_proc_swaps &&
359 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
365 u = unit_new(m, sizeof(Swap));
369 r = unit_add_name(u, e);
373 SWAP(u)->what = strdup(what);
374 if (!SWAP(u)->what) {
379 unit_add_to_load_queue(u);
383 p = &SWAP(u)->parameters_proc_swaps;
386 p->what = strdup(what_proc_swaps);
394 SWAP(u)->is_active = true;
395 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
398 SWAP(u)->from_proc_swaps = true;
400 p->priority = priority;
402 unit_add_to_dbus_queue(u);
407 log_unit_warning_errno(e, r, "Failed to load swap unit: %m");
415 static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
416 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
417 struct udev_list_entry *item = NULL, *first = NULL;
424 r = swap_add_one(m, device, device, prio, set_flags);
428 /* If this is a block device, then let's add duplicates for
429 * all other names of this block device */
430 if (stat(device, &st) < 0 || !S_ISBLK(st.st_mode))
433 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
437 /* Add the main device node */
438 dn = udev_device_get_devnode(d);
439 if (dn && !streq(dn, device))
440 swap_add_one(m, dn, device, prio, set_flags);
442 /* Add additional units for all symlinks */
443 first = udev_device_get_devlinks_list_entry(d);
444 udev_list_entry_foreach(item, first) {
447 /* Don't bother with the /dev/block links */
448 p = udev_list_entry_get_name(item);
450 if (streq(p, device))
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 swap_add_one(m, p, device, prio, set_flags);
467 static void swap_set_state(Swap *s, SwapState state) {
473 old_state = s->state;
476 if (state != SWAP_ACTIVATING &&
477 state != SWAP_ACTIVATING_SIGTERM &&
478 state != SWAP_ACTIVATING_SIGKILL &&
479 state != SWAP_ACTIVATING_DONE &&
480 state != SWAP_DEACTIVATING &&
481 state != SWAP_DEACTIVATING_SIGTERM &&
482 state != SWAP_DEACTIVATING_SIGKILL) {
483 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
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_unit_debug(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], state_translation_table[state], true);
498 /* If there other units for the same device node have a job
499 queued it might be worth checking again if it is runnable
500 now. This is necessary, since swap_start() refuses
501 operation with EAGAIN if there's already another job for
502 the same device node queued. */
503 LIST_FOREACH_OTHERS(same_devnode, other, s)
504 if (UNIT(other)->job)
505 job_add_to_run_queue(UNIT(other)->job);
508 static int swap_coldplug(Unit *u) {
510 SwapState new_state = SWAP_DEAD;
514 assert(s->state == SWAP_DEAD);
516 if (s->deserialized_state != s->state)
517 new_state = s->deserialized_state;
518 else if (s->from_proc_swaps)
519 new_state = SWAP_ACTIVE;
521 if (new_state == s->state)
524 if (new_state == SWAP_ACTIVATING ||
525 new_state == SWAP_ACTIVATING_SIGTERM ||
526 new_state == SWAP_ACTIVATING_SIGKILL ||
527 new_state == SWAP_ACTIVATING_DONE ||
528 new_state == SWAP_DEACTIVATING ||
529 new_state == SWAP_DEACTIVATING_SIGTERM ||
530 new_state == SWAP_DEACTIVATING_SIGKILL) {
532 if (s->control_pid <= 0)
535 r = unit_watch_pid(UNIT(s), s->control_pid);
539 r = swap_arm_timer(s);
544 swap_set_state(s, new_state);
548 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
555 if (s->from_proc_swaps)
556 p = &s->parameters_proc_swaps;
557 else if (s->from_fragment)
558 p = &s->parameters_fragment;
566 "%sFrom /proc/swaps: %s\n"
567 "%sFrom fragment: %s\n",
568 prefix, swap_state_to_string(s->state),
569 prefix, swap_result_to_string(s->result),
571 prefix, yes_no(s->from_proc_swaps),
572 prefix, yes_no(s->from_fragment));
575 fprintf(f, "%sDevice Node: %s\n", prefix, s->devnode);
582 prefix, strempty(p->options));
584 if (s->control_pid > 0)
586 "%sControl PID: "PID_FMT"\n",
587 prefix, s->control_pid);
589 exec_context_dump(&s->exec_context, f, prefix);
590 kill_context_dump(&s->kill_context, f, prefix);
593 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
596 ExecParameters exec_params = {
597 .apply_permissions = true,
598 .apply_chroot = true,
599 .apply_tty_stdin = true,
606 unit_realize_cgroup(UNIT(s));
608 r = unit_setup_exec_runtime(UNIT(s));
612 r = swap_arm_timer(s);
616 exec_params.environment = UNIT(s)->manager->environment;
617 exec_params.confirm_spawn = UNIT(s)->manager->confirm_spawn;
618 exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
619 exec_params.cgroup_path = UNIT(s)->cgroup_path;
620 exec_params.cgroup_delegate = s->cgroup_context.delegate;
621 exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
622 exec_params.unit_id = UNIT(s)->id;
632 r = unit_watch_pid(UNIT(s), pid);
634 /* FIXME: we need to do something here */
642 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
646 static void swap_enter_dead(Swap *s, SwapResult f) {
649 if (f != SWAP_SUCCESS)
652 exec_runtime_destroy(s->exec_runtime);
653 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
655 exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
657 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
660 static void swap_enter_active(Swap *s, SwapResult f) {
663 if (f != SWAP_SUCCESS)
666 swap_set_state(s, SWAP_ACTIVE);
669 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
674 if (f != SWAP_SUCCESS)
677 r = unit_kill_context(
680 (state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM) ?
681 KILL_KILL : KILL_TERMINATE,
689 r = swap_arm_timer(s);
693 swap_set_state(s, state);
694 } else if (state == SWAP_ACTIVATING_SIGTERM)
695 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_SUCCESS);
696 else if (state == SWAP_DEACTIVATING_SIGTERM)
697 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_SUCCESS);
699 swap_enter_dead(s, SWAP_SUCCESS);
704 log_unit_warning_errno(UNIT(s)->id, r, "%s failed to kill processes: %m", UNIT(s)->id);
705 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
708 static void swap_enter_activating(Swap *s) {
709 _cleanup_free_ char *discard = NULL;
710 int r, priority = -1;
714 s->control_command_id = SWAP_EXEC_ACTIVATE;
715 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
717 if (s->from_fragment) {
718 fstab_filter_options(s->parameters_fragment.options, "discard\0",
719 NULL, &discard, NULL);
721 priority = s->parameters_fragment.priority;
723 fstab_find_pri(s->parameters_fragment.options, &priority);
726 r = exec_command_set(s->control_command, "/sbin/swapon", NULL);
731 char p[DECIMAL_STR_MAX(int)];
733 sprintf(p, "%i", priority);
734 r = exec_command_append(s->control_command, "-p", p, NULL);
739 if (discard && !streq(discard, "none")) {
740 const char *discard_arg;
742 if (streq(discard, "all"))
743 discard_arg = "--discard";
745 discard_arg = strjoina("--discard=", discard);
747 r = exec_command_append(s->control_command, discard_arg, NULL);
752 r = exec_command_append(s->control_command, s->what, NULL);
756 swap_unwatch_control_pid(s);
758 r = swap_spawn(s, s->control_command, &s->control_pid);
762 swap_set_state(s, SWAP_ACTIVATING);
767 log_unit_warning_errno(UNIT(s)->id, r, "%s failed to run 'swapon' task: %m", UNIT(s)->id);
768 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
771 static void swap_enter_deactivating(Swap *s) {
776 s->control_command_id = SWAP_EXEC_DEACTIVATE;
777 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
779 r = exec_command_set(s->control_command,
786 swap_unwatch_control_pid(s);
788 r = swap_spawn(s, s->control_command, &s->control_pid);
792 swap_set_state(s, SWAP_DEACTIVATING);
797 log_unit_warning_errno(UNIT(s)->id, r, "%s failed to run 'swapoff' task: %m", UNIT(s)->id);
798 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
801 static int swap_start(Unit *u) {
802 Swap *s = SWAP(u), *other;
806 /* We cannot fulfill this request right now, try again later
809 if (s->state == SWAP_DEACTIVATING ||
810 s->state == SWAP_DEACTIVATING_SIGTERM ||
811 s->state == SWAP_DEACTIVATING_SIGKILL ||
812 s->state == SWAP_ACTIVATING_SIGTERM ||
813 s->state == SWAP_ACTIVATING_SIGKILL)
816 if (s->state == SWAP_ACTIVATING)
819 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
821 if (detect_container(NULL) > 0)
824 /* If there's a job for another swap unit for the same node
825 * running, then let's not dispatch this one for now, and wait
826 * until that other job has finished. */
827 LIST_FOREACH_OTHERS(same_devnode, other, s)
828 if (UNIT(other)->job && UNIT(other)->job->state == JOB_RUNNING)
831 s->result = SWAP_SUCCESS;
832 swap_enter_activating(s);
836 static int swap_stop(Unit *u) {
841 if (s->state == SWAP_DEACTIVATING ||
842 s->state == SWAP_DEACTIVATING_SIGTERM ||
843 s->state == SWAP_DEACTIVATING_SIGKILL ||
844 s->state == SWAP_ACTIVATING_SIGTERM ||
845 s->state == SWAP_ACTIVATING_SIGKILL)
848 assert(s->state == SWAP_ACTIVATING ||
849 s->state == SWAP_ACTIVATING_DONE ||
850 s->state == SWAP_ACTIVE);
852 if (detect_container(NULL) > 0)
855 swap_enter_deactivating(s);
859 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
866 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
867 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
869 if (s->control_pid > 0)
870 unit_serialize_item_format(u, f, "control-pid", PID_FMT, s->control_pid);
872 if (s->control_command_id >= 0)
873 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
878 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
884 if (streq(key, "state")) {
887 state = swap_state_from_string(value);
889 log_unit_debug(u->id, "Failed to parse state value %s", value);
891 s->deserialized_state = state;
892 } else if (streq(key, "result")) {
895 f = swap_result_from_string(value);
897 log_unit_debug(u->id, "Failed to parse result value %s", value);
898 else if (f != SWAP_SUCCESS)
900 } else if (streq(key, "control-pid")) {
903 if (parse_pid(value, &pid) < 0)
904 log_unit_debug(u->id, "Failed to parse control-pid value %s", value);
906 s->control_pid = pid;
908 } else if (streq(key, "control-command")) {
911 id = swap_exec_command_from_string(value);
913 log_unit_debug(u->id, "Failed to parse exec-command value %s", value);
915 s->control_command_id = id;
916 s->control_command = s->exec_command + id;
919 log_unit_debug(u->id, "Unknown serialization key '%s'", key);
924 _pure_ static UnitActiveState swap_active_state(Unit *u) {
927 return state_translation_table[SWAP(u)->state];
930 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
933 return swap_state_to_string(SWAP(u)->state);
936 _pure_ static bool swap_check_gc(Unit *u) {
941 return s->from_proc_swaps;
944 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
951 if (pid != s->control_pid)
956 if (is_clean_exit(code, status, NULL))
958 else if (code == CLD_EXITED)
959 f = SWAP_FAILURE_EXIT_CODE;
960 else if (code == CLD_KILLED)
961 f = SWAP_FAILURE_SIGNAL;
962 else if (code == CLD_DUMPED)
963 f = SWAP_FAILURE_CORE_DUMP;
965 assert_not_reached("Unknown code");
967 if (f != SWAP_SUCCESS)
970 if (s->control_command) {
971 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
973 s->control_command = NULL;
974 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
978 f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
979 "%s swap process exited, code=%s status=%i",
980 u->id, sigchld_code_to_string(code), status);
984 case SWAP_ACTIVATING:
985 case SWAP_ACTIVATING_DONE:
986 case SWAP_ACTIVATING_SIGTERM:
987 case SWAP_ACTIVATING_SIGKILL:
989 if (f == SWAP_SUCCESS)
990 swap_enter_active(s, f);
992 swap_enter_dead(s, f);
995 case SWAP_DEACTIVATING:
996 case SWAP_DEACTIVATING_SIGKILL:
997 case SWAP_DEACTIVATING_SIGTERM:
999 swap_enter_dead(s, f);
1003 assert_not_reached("Uh, control process died at wrong time.");
1006 /* Notify clients about changed exit status */
1007 unit_add_to_dbus_queue(u);
1010 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1011 Swap *s = SWAP(userdata);
1014 assert(s->timer_event_source == source);
1018 case SWAP_ACTIVATING:
1019 case SWAP_ACTIVATING_DONE:
1020 log_unit_warning(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
1021 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1024 case SWAP_DEACTIVATING:
1025 log_unit_warning(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
1026 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1029 case SWAP_ACTIVATING_SIGTERM:
1030 if (s->kill_context.send_sigkill) {
1031 log_unit_warning(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
1032 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1034 log_unit_warning(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1035 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1039 case SWAP_DEACTIVATING_SIGTERM:
1040 if (s->kill_context.send_sigkill) {
1041 log_unit_warning(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
1042 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1044 log_unit_warning(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1045 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1049 case SWAP_ACTIVATING_SIGKILL:
1050 case SWAP_DEACTIVATING_SIGKILL:
1051 log_unit_warning(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
1052 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1056 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 _cleanup_free_ char *dev = NULL, *d = NULL;
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);
1095 k = swap_process_new_swap(m, d, prio, set_flags);
1103 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1104 Manager *m = userdata;
1109 assert(revents & EPOLLPRI);
1111 r = swap_load_proc_swaps(m, true);
1113 log_error_errno(r, "Failed to reread /proc/swaps: %m");
1115 /* Reset flags, just in case, for late calls */
1116 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1117 Swap *swap = SWAP(u);
1119 swap->is_active = swap->just_activated = false;
1125 manager_dispatch_load_queue(m);
1127 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1128 Swap *swap = SWAP(u);
1130 if (!swap->is_active) {
1131 /* This has just been deactivated */
1133 swap_unset_proc_swaps(swap);
1135 switch (swap->state) {
1138 swap_enter_dead(swap, SWAP_SUCCESS);
1143 swap_set_state(swap, swap->state);
1147 } else if (swap->just_activated) {
1149 /* New swap entry */
1151 switch (swap->state) {
1155 swap_enter_active(swap, SWAP_SUCCESS);
1158 case SWAP_ACTIVATING:
1159 swap_set_state(swap, SWAP_ACTIVATING_DONE);
1163 /* Nothing really changed, but let's
1164 * issue an notification call
1165 * nonetheless, in case somebody is
1166 * waiting for this. */
1167 swap_set_state(swap, swap->state);
1172 /* Reset the flags for later calls */
1173 swap->is_active = swap->just_activated = false;
1179 static Unit *swap_following(Unit *u) {
1181 Swap *other, *first = NULL;
1185 /* If the user configured the swap through /etc/fstab or
1186 * a device unit, follow that. */
1188 if (s->from_fragment)
1191 LIST_FOREACH_OTHERS(same_devnode, other, s)
1192 if (other->from_fragment)
1195 /* Otherwise make everybody follow the unit that's named after
1196 * the swap device in the kernel */
1198 if (streq_ptr(s->what, s->devnode))
1201 LIST_FOREACH_AFTER(same_devnode, other, s)
1202 if (streq_ptr(other->what, other->devnode))
1205 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1206 if (streq_ptr(other->what, other->devnode))
1212 /* Fall back to the first on the list */
1216 static int swap_following_set(Unit *u, Set **_set) {
1217 Swap *s = SWAP(u), *other;
1224 if (LIST_JUST_US(same_devnode, s)) {
1229 set = set_new(NULL);
1233 LIST_FOREACH_OTHERS(same_devnode, other, s) {
1234 r = set_put(set, other);
1247 static void swap_shutdown(Manager *m) {
1250 m->swap_event_source = sd_event_source_unref(m->swap_event_source);
1252 if (m->proc_swaps) {
1253 fclose(m->proc_swaps);
1254 m->proc_swaps = NULL;
1257 hashmap_free(m->swaps_by_devnode);
1258 m->swaps_by_devnode = NULL;
1261 static int swap_enumerate(Manager *m) {
1266 if (!m->proc_swaps) {
1267 m->proc_swaps = fopen("/proc/swaps", "re");
1269 return errno == ENOENT ? 0 : -errno;
1271 r = sd_event_add_io(m->event, &m->swap_event_source, fileno(m->proc_swaps), EPOLLPRI, swap_dispatch_io, m);
1275 /* Dispatch this before we dispatch SIGCHLD, so that
1276 * we always get the events from /proc/swaps before
1277 * the SIGCHLD of /sbin/swapon. */
1278 r = sd_event_source_set_priority(m->swap_event_source, -10);
1283 r = swap_load_proc_swaps(m, false);
1294 int swap_process_new_device(Manager *m, struct udev_device *dev) {
1295 struct udev_list_entry *item = NULL, *first = NULL;
1296 _cleanup_free_ char *e = NULL;
1304 dn = udev_device_get_devnode(dev);
1308 e = unit_name_from_path(dn, ".swap");
1312 s = hashmap_get(m->units, e);
1314 r = swap_set_devnode(s, dn);
1316 first = udev_device_get_devlinks_list_entry(dev);
1317 udev_list_entry_foreach(item, first) {
1318 _cleanup_free_ char *n = NULL;
1320 n = unit_name_from_path(udev_list_entry_get_name(item), ".swap");
1324 s = hashmap_get(m->units, n);
1328 q = swap_set_devnode(s, dn);
1337 int swap_process_removed_device(Manager *m, struct udev_device *dev) {
1342 dn = udev_device_get_devnode(dev);
1346 while ((s = hashmap_get(m->swaps_by_devnode, dn))) {
1349 q = swap_set_devnode(s, NULL);
1357 static void swap_reset_failed(Unit *u) {
1362 if (s->state == SWAP_FAILED)
1363 swap_set_state(s, SWAP_DEAD);
1365 s->result = SWAP_SUCCESS;
1368 static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1369 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1372 static int swap_get_timeout(Unit *u, uint64_t *timeout) {
1376 if (!s->timer_event_source)
1379 r = sd_event_source_get_time(s->timer_event_source, timeout);
1386 static bool swap_supported(Manager *m) {
1387 static int supported = -1;
1389 /* If swap support is not available in the kernel, or we are
1390 * running in a container we don't support swap units, and any
1391 * attempts to starting one should fail immediately. */
1395 access("/proc/swaps", F_OK) >= 0 &&
1396 detect_container(NULL) <= 0;
1401 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1402 [SWAP_DEAD] = "dead",
1403 [SWAP_ACTIVATING] = "activating",
1404 [SWAP_ACTIVATING_DONE] = "activating-done",
1405 [SWAP_ACTIVE] = "active",
1406 [SWAP_DEACTIVATING] = "deactivating",
1407 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1408 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1409 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1410 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1411 [SWAP_FAILED] = "failed"
1414 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1416 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1417 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1418 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1421 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1423 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1424 [SWAP_SUCCESS] = "success",
1425 [SWAP_FAILURE_RESOURCES] = "resources",
1426 [SWAP_FAILURE_TIMEOUT] = "timeout",
1427 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1428 [SWAP_FAILURE_SIGNAL] = "signal",
1429 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1432 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1434 const UnitVTable swap_vtable = {
1435 .object_size = sizeof(Swap),
1436 .exec_context_offset = offsetof(Swap, exec_context),
1437 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1438 .kill_context_offset = offsetof(Swap, kill_context),
1439 .exec_runtime_offset = offsetof(Swap, exec_runtime),
1445 .private_section = "Swap",
1448 .no_instances = true,
1454 .coldplug = swap_coldplug,
1458 .start = swap_start,
1463 .get_timeout = swap_get_timeout,
1465 .serialize = swap_serialize,
1466 .deserialize_item = swap_deserialize_item,
1468 .active_state = swap_active_state,
1469 .sub_state_to_string = swap_sub_state_to_string,
1471 .check_gc = swap_check_gc,
1473 .sigchld_event = swap_sigchld_event,
1475 .reset_failed = swap_reset_failed,
1477 .bus_interface = "org.freedesktop.systemd1.Swap",
1478 .bus_vtable = bus_swap_vtable,
1479 .bus_set_property = bus_swap_set_property,
1480 .bus_commit_properties = bus_swap_commit_properties,
1482 .following = swap_following,
1483 .following_set = swap_following_set,
1485 .enumerate = swap_enumerate,
1486 .shutdown = swap_shutdown,
1487 .supported = swap_supported,
1489 .status_message_formats = {
1490 .starting_stopping = {
1491 [0] = "Activating swap %s...",
1492 [1] = "Deactivating swap %s...",
1494 .finished_start_job = {
1495 [JOB_DONE] = "Activated swap %s.",
1496 [JOB_FAILED] = "Failed to activate swap %s.",
1497 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1498 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1500 .finished_stop_job = {
1501 [JOB_DONE] = "Deactivated swap %s.",
1502 [JOB_FAILED] = "Failed deactivating swap %s.",
1503 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",