swap.c revision b56a422a919ec5a12f8fa7f9dfc63f7d88c6a077
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen This file is part of systemd.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Copyright 2010 Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen systemd is free software; you can redistribute it and/or modify it
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen under the terms of the GNU Lesser General Public License as published by
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen the Free Software Foundation; either version 2.1 of the License, or
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (at your option) any later version.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen systemd is distributed in the hope that it will be useful, but
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen WITHOUT ANY WARRANTY; without even the implied warranty of
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Lesser General Public License for more details.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen You should have received a copy of the GNU Lesser General Public License
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [SWAP_ACTIVATING] = UNIT_ACTIVATING,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [SWAP_DEACTIVATING] = UNIT_DEACTIVATING,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [SWAP_ACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [SWAP_ACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [SWAP_DEACTIVATING_SIGTERM] = UNIT_DEACTIVATING,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [SWAP_DEACTIVATING_SIGKILL] = UNIT_DEACTIVATING,
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poetteringstatic void swap_unset_proc_swaps(Swap *s) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!s->parameters_proc_swaps.what)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Remove this unit from the chain of swaps which share the
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * same kernel swap device. */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swaps = UNIT(s)->manager->swaps_by_proc_swaps;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen first = hashmap_get(swaps, s->parameters_proc_swaps.what);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen LIST_REMOVE(Swap, same_proc_swaps, first, s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen hashmap_remove_and_replace(swaps,
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek first->parameters_proc_swaps.what,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen hashmap_remove(swaps, s->parameters_proc_swaps.what);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen free(s->parameters_proc_swaps.what);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->parameters_proc_swaps.what = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void swap_init(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(UNIT(s)->load_state == UNIT_STUB);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->timeout_usec = DEFAULT_TIMEOUT_USEC;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek exec_context_init(&s->exec_context);
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek s->exec_context.std_output = u->manager->default_std_output;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek s->exec_context.std_error = u->manager->default_std_error;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek kill_context_init(&s->kill_context);
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek cgroup_context_init(&s->cgroup_context);
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek s->timer_watch.type = WATCH_INVALID;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek UNIT(s)->ignore_on_isolate = true;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmekstatic void swap_unwatch_control_pid(Swap *s) {
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek unit_unwatch_pid(UNIT(s), s->control_pid);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void swap_done(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen free(s->parameters_fragment.what);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->parameters_fragment.what = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen exec_context_done(&s->exec_context, manager_is_reloading_or_reexecuting(u->manager));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen cgroup_context_done(&s->cgroup_context);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_unwatch_timer(u, &s->timer_watch);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint swap_add_one_mount_link(Swap *s, Mount *m) {
b7e7184634d573fb73143210962acce205f37f61Michael Biebl r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_add_mount_links(Swap *s) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT])
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if ((r = swap_add_one_mount_link(s, MOUNT(other))) < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_add_device_links(Swap *s) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return unit_add_node_link(UNIT(s), s->what, !p->noauto &&
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
aad0a2c80097926757d4385e5f5492082d47f006Zbigniew Jędrzejewski-Szmek /* File based swap devices need to be ordered after
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * systemd-remount-fs.service, since they might need a
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * writable file system. */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_add_default_dependencies(Swap *s) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (detect_container(NULL) > 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_verify(Swap *s) {
d171ed1c50ba64928b7fb30ee2ae729fdfe0826bThomas Hindoe Paaboel Andersen _cleanup_free_ char *e = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (UNIT(s)->load_state != UNIT_LOADED)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen e = unit_name_from_path(s->what, ".swap");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen b = unit_has_name(UNIT(s), e);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s: Value of \"What\" and unit name do not match, not loading.",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_load(Unit *u) {
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann /* Load a .swap file */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_load_fragment_and_dropin_optional(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (u->load_state == UNIT_LOADED) {
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann r = unit_add_exec_dependencies(u, &s->exec_context);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (s->parameters_fragment.what)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->what = strdup(s->parameters_fragment.what);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (s->parameters_proc_swaps.what)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->what = strdup(s->parameters_proc_swaps.what);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->what = unit_name_to_path(u->id);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if ((r = unit_set_description(u, s->what)) < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_add_default_slice(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (UNIT(s)->default_dependencies) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = swap_add_default_dependencies(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_exec_context_defaults(u, &s->exec_context);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen e = unit_name_from_path(what, ".swap");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek p = &SWAP(u)->parameters_proc_swaps;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek first = hashmap_get(m->swaps_by_proc_swaps, wp);
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u));
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler r = hashmap_replace(m->swaps_by_proc_swaps, wp, first);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek SWAP(u)->from_proc_swaps = true;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmekstatic int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew Jędrzejewski-Szmek if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek struct udev_list_entry *item = NULL, *first = NULL;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek /* So this is a proper swap device. Create swap units
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek * for all names this swap device is known under */
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen dn = udev_device_get_devnode(d);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Skip dn==device, since that case will be handled below */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (dn && !streq(dn, device))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = swap_add_one(m, dn, device, prio, false, false, set_flags);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Add additional units for all symlinks */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen first = udev_device_get_devlinks_list_entry(d);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen udev_list_entry_foreach(item, first) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Don't bother with the /dev/block links */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p = udev_list_entry_get_name(item);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (path_startswith(p, "/dev/block/"))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if ((!S_ISBLK(st.st_mode)) ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen st.st_rdev != udev_device_get_devnum(d))
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt k = swap_add_one(m, p, device, prio, false, false, set_flags);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering k = swap_add_one(m, device, device, prio, false, false, set_flags);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void swap_set_state(Swap *s, SwapState state) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (state != SWAP_ACTIVATING &&
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen state != SWAP_ACTIVATING_SIGTERM &&
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen state != SWAP_ACTIVATING_SIGKILL &&
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen state != SWAP_DEACTIVATING &&
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen state != SWAP_DEACTIVATING_SIGTERM &&
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen state != SWAP_DEACTIVATING_SIGKILL) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_unwatch_timer(UNIT(s), &s->timer_watch);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s changed %s -> %s",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_state_to_string(old_state),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_state_to_string(state));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_notify(UNIT(s), state_translation_table[old_state],
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen state_translation_table[state], true);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_coldplug(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen SwapState new_state = SWAP_DEAD;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s->state == SWAP_DEAD);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (s->deserialized_state != s->state)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen new_state = s->deserialized_state;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (new_state == SWAP_ACTIVATING ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen new_state == SWAP_ACTIVATING_SIGTERM ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen new_state == SWAP_ACTIVATING_SIGKILL ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen new_state == SWAP_DEACTIVATING ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen new_state == SWAP_DEACTIVATING_SIGTERM ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen new_state == SWAP_DEACTIVATING_SIGKILL) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_watch_pid(UNIT(s), s->control_pid);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void swap_dump(Unit *u, FILE *f, const char *prefix) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p = &s->parameters_proc_swaps;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sSwap State: %s\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sFrom fragment: %s\n",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen prefix, swap_state_to_string(s->state),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen prefix, swap_result_to_string(s->result),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen prefix, yes_no(s->from_proc_swaps),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen prefix, yes_no(s->from_fragment));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sPriority: %i\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sNoFail: %s\n",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sControl PID: %lu\n",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen prefix, (unsigned long) s->control_pid);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek exec_context_dump(&s->exec_context, f, prefix);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek kill_context_dump(&s->kill_context, f, prefix);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(s)->manager->environment,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(s)->manager->confirm_spawn,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_watch_pid(UNIT(s), pid);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* FIXME: we need to do something here */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_unwatch_timer(UNIT(s), &s->timer_watch);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void swap_enter_dead(Swap *s, SwapResult f) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen exec_context_tmp_dirs_done(&s->exec_context);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void swap_enter_active(Swap *s, SwapResult f) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_set_state(s, SWAP_ACTIVE);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_enter_dead(s, SWAP_SUCCESS);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_warning_unit(UNIT(s)->id,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void swap_enter_activating(Swap *s) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_command_id = SWAP_EXEC_ACTIVATE;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen priority = s->parameters_fragment.priority;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen snprintf(p, sizeof(p), "%i", priority);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = swap_spawn(s, s->control_command, &s->control_pid);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_set_state(s, SWAP_ACTIVATING);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s failed to run 'swapon' task: %s",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmekstatic void swap_enter_deactivating(Swap *s) {
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering s->control_command_id = SWAP_EXEC_DEACTIVATE;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering r = swap_spawn(s, s->control_command, &s->control_pid);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_set_state(s, SWAP_DEACTIVATING);
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering "%s failed to run 'swapoff' task: %s",
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek swap_enter_active(s, SWAP_FAILURE_RESOURCES);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* We cannot fulfill this request right now, try again later
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (s->state == SWAP_DEACTIVATING ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->state == SWAP_DEACTIVATING_SIGTERM ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->state == SWAP_DEACTIVATING_SIGKILL ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->state == SWAP_ACTIVATING_SIGKILL)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (detect_container(NULL) > 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_stop(Unit *u) {
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek if (s->state == SWAP_DEACTIVATING ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->state == SWAP_DEACTIVATING_SIGTERM ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->state == SWAP_DEACTIVATING_SIGKILL ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->state == SWAP_ACTIVATING_SIGTERM ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->state == SWAP_ACTIVATING_SIGKILL)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s->state == SWAP_ACTIVATING ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (detect_container(NULL) > 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
a34bf9db5da0fdd6bdb14459e203dbe41ee99614Lennart Poettering unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (s->control_command_id >= 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen exec_context_serialize(&s->exec_context, UNIT(s), f);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen state = swap_state_from_string(value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug_unit(u->id, "Failed to parse state value %s", value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->deserialized_state = state;
8c84621c25c563c7428f3d355136fc542389aab8Thomas Hindoe Paaboel Andersen } else if (streq(key, "result")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug_unit(u->id, "Failed to parse result value %s", value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(key, "control-pid")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (parse_pid(value, &pid) < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(key, "control-command")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen id = swap_exec_command_from_string(value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_command = s->exec_command + id;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(key, "tmp-dir")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(key, "var-tmp-dir")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->exec_context.var_tmp_dir = t;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug_unit(u->id, "Unknown serialization key '%s'", key);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen_pure_ static UnitActiveState swap_active_state(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return state_translation_table[SWAP(u)->state];
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen_pure_ static const char *swap_sub_state_to_string(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return swap_state_to_string(SWAP(u)->state);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen_pure_ static bool swap_check_gc(Unit *u) {
f8bc41822ba19905707a97f9d87262f2c2b6e5faZbigniew Jędrzejewski-Szmekstatic void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (is_clean_exit(code, status, NULL))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert_not_reached("Unknown code");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s swap process exited, code=%s status=%i",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen u->id, sigchld_code_to_string(code), status);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case SWAP_ACTIVATING_SIGTERM:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case SWAP_ACTIVATING_SIGKILL:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case SWAP_DEACTIVATING_SIGKILL:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case SWAP_DEACTIVATING_SIGTERM:
assert(s);
switch (s->state) {
case SWAP_ACTIVATING:
case SWAP_DEACTIVATING:
case SWAP_ACTIVATING_SIGTERM:
case SWAP_ACTIVATING_SIGKILL:
assert(m);
int prio = 0, k;
if (k == EOF)
return -ENOMEM;
free(d);
m->request_reload = false;
Unit *u;
assert(m);
r = swap_load_proc_swaps(m, true);
case SWAP_ACTIVE:
case SWAP_DEAD:
case SWAP_FAILED:
assert(s);
return NULL;
assert(s);
return -ENOMEM;
goto fail;
goto fail;
fail:
assert(m);
if (m->proc_swaps) {
assert(m);
if (!m->proc_swaps) {
if (!m->proc_swaps)
return -errno;
r = swap_load_proc_swaps(m, false);
swap_shutdown(m);
assert(s);
.sections =
.no_alias = true,
.no_instances = true,
.starting_stopping = {
.finished_start_job = {
.finished_stop_job = {