swap.c revision b56a422a919ec5a12f8fa7f9dfc63f7d88c6a077
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen/***
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen This file is part of systemd.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Copyright 2010 Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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
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
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 Andersen***/
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <errno.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <limits.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <unistd.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <fcntl.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <sys/epoll.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <sys/stat.h>
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include <sys/swap.h>
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include <libudev.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
8fcde01280adcbd07e8205b91ac52b06305b6208Lennart Poettering#include "unit.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "swap.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "load-fragment.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "load-dropin.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "unit-name.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "dbus-swap.h"
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering#include "special.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "bus-errors.h"
8fcde01280adcbd07e8205b91ac52b06305b6208Lennart Poettering#include "exit-status.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "def.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "path-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "virt.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [SWAP_DEAD] = UNIT_INACTIVE,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [SWAP_ACTIVATING] = UNIT_ACTIVATING,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [SWAP_ACTIVE] = UNIT_ACTIVE,
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,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [SWAP_FAILED] = UNIT_FAILED
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen};
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poetteringstatic void swap_unset_proc_swaps(Swap *s) {
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering Swap *first;
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering Hashmap *swaps;
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!s->parameters_proc_swaps.what)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (first)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen hashmap_remove_and_replace(swaps,
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek s->parameters_proc_swaps.what,
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek first->parameters_proc_swaps.what,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen first);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen hashmap_remove(swaps, s->parameters_proc_swaps.what);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen free(s->parameters_proc_swaps.what);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->parameters_proc_swaps.what = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void swap_init(Unit *u) {
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen Swap *s = SWAP(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(UNIT(s)->load_state == UNIT_STUB);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->timeout_usec = DEFAULT_TIMEOUT_USEC;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
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
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek s->timer_watch.type = WATCH_INVALID;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek UNIT(s)->ignore_on_isolate = true;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek}
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmekstatic void swap_unwatch_control_pid(Swap *s) {
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek assert(s);
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek if (s->control_pid <= 0)
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek return;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek unit_unwatch_pid(UNIT(s), s->control_pid);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_pid = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void swap_done(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Swap *s = SWAP(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_unset_proc_swaps(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen free(s->what);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->what = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen free(s->parameters_fragment.what);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->parameters_fragment.what = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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 s->control_command = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen cgroup_context_done(&s->cgroup_context);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_unwatch_control_pid(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_unwatch_timer(u, &s->timer_watch);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint swap_add_one_mount_link(Swap *s, Mount *m) {
b7e7184634d573fb73143210962acce205f37f61Michael Biebl int r;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl assert(s);
b7e7184634d573fb73143210962acce205f37f61Michael Biebl assert(m);
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl if (UNIT(s)->load_state != UNIT_LOADED ||
b7e7184634d573fb73143210962acce205f37f61Michael Biebl UNIT(m)->load_state != UNIT_LOADED)
b7e7184634d573fb73143210962acce205f37f61Michael Biebl return 0;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl if (is_device_path(s->what))
b7e7184634d573fb73143210962acce205f37f61Michael Biebl return 0;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl if (!path_startswith(s->what, m->where))
b7e7184634d573fb73143210962acce205f37f61Michael Biebl return 0;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
b7e7184634d573fb73143210962acce205f37f61Michael Biebl if (r < 0)
b7e7184634d573fb73143210962acce205f37f61Michael Biebl return r;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl return 0;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_add_mount_links(Swap *s) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Unit *other;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek int r;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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 Andersen return r;
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_add_device_links(Swap *s) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen SwapParameters *p;
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt assert(s);
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt
4e5589836c9e143796c3f3d81e67ab7a9209e2b0Martin Pitt if (!s->what)
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt return 0;
9993ef2e9817b35b1d467707bef12b2a140b62dcLennart Poettering
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt if (s->from_fragment)
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt p = &s->parameters_fragment;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return 0;
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (is_device_path(s->what))
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);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
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 Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_add_default_dependencies(Swap *s) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen assert(s);
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (detect_container(NULL) > 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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 Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_verify(Swap *s) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool b;
d171ed1c50ba64928b7fb30ee2ae729fdfe0826bThomas Hindoe Paaboel Andersen _cleanup_free_ char *e = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (UNIT(s)->load_state != UNIT_LOADED)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen e = unit_name_from_path(s->what, ".swap");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (e == NULL)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return log_oom();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen b = unit_has_name(UNIT(s), e);
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen if (!b) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error_unit(UNIT(s)->id,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s: Value of \"What\" and unit name do not match, not loading.",
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering UNIT(s)->id);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EINVAL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error_unit(UNIT(s)->id,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(s)->id);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EINVAL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_load(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann Swap *s = SWAP(u);
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
264581a2f1599a27de577549dc75fccefef6a579Felipe Sateler assert(u->load_state == UNIT_STUB);
264581a2f1599a27de577549dc75fccefef6a579Felipe Sateler
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann /* Load a .swap file */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_load_fragment_and_dropin_optional(u);
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann if (r < 0)
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann return r;
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (u->load_state == UNIT_LOADED) {
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann r = unit_add_exec_dependencies(u, &s->exec_context);
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann if (r < 0)
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann return r;
0b2ec8a3bfdd6118b3b4958d236ee203ad420f28David Herrmann
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (UNIT(s)->fragment_path)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->from_fragment = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!s->what) {
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 else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->what = unit_name_to_path(u->id);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!s->what)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -ENOMEM;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen path_kill_slashes(s->what);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!UNIT(s)->description)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if ((r = unit_set_description(u, s->what)) < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering r = swap_add_device_links(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = swap_add_mount_links(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_add_default_slice(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (UNIT(s)->default_dependencies) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = swap_add_default_dependencies(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_exec_context_defaults(u, &s->exec_context);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return swap_verify(s);
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt}
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering
40780877c19ef408da8ab21f4156cfc153f94b5cMartin Pittstatic int swap_add_one(
3315f085178f46155fda345d9526c09083b45946Lennart Poettering Manager *m,
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering const char *what,
3315f085178f46155fda345d9526c09083b45946Lennart Poettering const char *what_proc_swaps,
3315f085178f46155fda345d9526c09083b45946Lennart Poettering int priority,
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt bool noauto,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool nofail,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool set_flags) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Unit *u = NULL;
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering _cleanup_free_ char *e = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char *wp = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool delete = false;
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering int r;
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering SwapParameters *p;
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering Swap *first;
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering
3315f085178f46155fda345d9526c09083b45946Lennart Poettering assert(m);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(what);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(what_proc_swaps);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen e = unit_name_from_path(what, ".swap");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!e)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return log_oom();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen u = manager_get_unit(m, e);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (u &&
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen SWAP(u)->from_proc_swaps &&
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EEXIST;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (!u) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek delete = true;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek u = unit_new(m, sizeof(Swap));
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (!u)
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return log_oom();
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler r = unit_add_name(u, e);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (r < 0)
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek goto fail;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew Jędrzejewski-Szmek SWAP(u)->what = strdup(what);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (!SWAP(u)->what) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek r = log_oom();
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek goto fail;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek unit_add_to_load_queue(u);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek } else
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler delete = false;
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek p = &SWAP(u)->parameters_proc_swaps;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew Jędrzejewski-Szmek if (!p->what) {
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering wp = strdup(what_proc_swaps);
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler if (!wp) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek r = log_oom();
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek goto fail;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (!m->swaps_by_proc_swaps) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (!m->swaps_by_proc_swaps) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek r = log_oom();
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek goto fail;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek free(p->what);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek p->what = wp;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
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
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler r = hashmap_replace(m->swaps_by_proc_swaps, wp, first);
2c09a745eba5f463e12b498a2f62a5036253c55cFelipe Sateler if (r < 0)
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek goto fail;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (set_flags) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek SWAP(u)->is_active = true;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek }
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek SWAP(u)->from_proc_swaps = true;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek p->priority = priority;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek p->noauto = noauto;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek p->nofail = nofail;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek unit_add_to_dbus_queue(u);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return 0;
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmekfail:
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering free(wp);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (delete && u)
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek unit_free(u);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return r;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek}
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmekstatic int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek struct stat st;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek int r = 0, k;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek assert(m);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew Jędrzejewski-Szmek if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek struct udev_device *d;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek const char *dn;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek struct udev_list_entry *item = NULL, *first = NULL;
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew Jędrzejewski-Szmek
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 */
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (!d)
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek return log_oom();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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
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 const char *p;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (path_startswith(p, "/dev/block/"))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen continue;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (stat(p, &st) >= 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if ((!S_ISBLK(st.st_mode)) ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen st.st_rdev != udev_device_get_devnum(d))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen continue;
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt k = swap_add_one(m, p, device, prio, false, false, set_flags);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (k < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = k;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen udev_device_unref(d);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering k = swap_add_one(m, device, device, prio, false, false, set_flags);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (k < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = k;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void swap_set_state(Swap *s, SwapState state) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen SwapState old_state;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen old_state = s->state;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->state = state;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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 swap_unwatch_control_pid(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_command = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (state != old_state)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug_unit(UNIT(s)->id,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s changed %s -> %s",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(s)->id,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_state_to_string(old_state),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_state_to_string(state));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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 Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_coldplug(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Swap *s = SWAP(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen SwapState new_state = SWAP_DEAD;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s->state == SWAP_DEAD);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (s->deserialized_state != s->state)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen new_state = s->deserialized_state;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (s->from_proc_swaps)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen new_state = SWAP_ACTIVE;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (new_state != s->state) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (s->control_pid <= 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EBADMSG;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_watch_pid(UNIT(s), s->control_pid);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering swap_set_state(s, new_state);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void swap_dump(Unit *u, FILE *f, const char *prefix) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Swap *s = SWAP(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen SwapParameters *p;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(f);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (s->from_proc_swaps)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p = &s->parameters_proc_swaps;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (s->from_fragment)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p = &s->parameters_fragment;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen fprintf(f,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sSwap State: %s\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sResult: %s\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sWhat: %s\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sFrom /proc/swaps: %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, s->what,
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
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (p)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen fprintf(f,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sPriority: %i\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sNoAuto: %s\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sNoFail: %s\n",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen prefix, p->priority,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen prefix, yes_no(p->noauto),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen prefix, yes_no(p->nofail));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (s->control_pid > 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen fprintf(f,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sControl PID: %lu\n",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen prefix, (unsigned long) s->control_pid);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek exec_context_dump(&s->exec_context, f, prefix);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek kill_context_dump(&s->kill_context, f, prefix);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen pid_t pid;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(c);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek assert(_pid);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek unit_realize_cgroup(UNIT(s));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = exec_spawn(c,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen NULL,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen &s->exec_context,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen NULL, 0,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(s)->manager->environment,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen true,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen true,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen true,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(s)->manager->confirm_spawn,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(s)->cgroup_mask,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(s)->cgroup_path,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(s)->id,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen NULL,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen &pid);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_watch_pid(UNIT(s), pid);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* FIXME: we need to do something here */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen *_pid = pid;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenfail:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_unwatch_timer(UNIT(s), &s->timer_watch);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void swap_enter_dead(Swap *s, SwapResult f) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (f != SWAP_SUCCESS)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->result = f;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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 Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void swap_enter_active(Swap *s, SwapResult f) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (f != SWAP_SUCCESS)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->result = f;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_set_state(s, SWAP_ACTIVE);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (f != SWAP_SUCCESS)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->result = f;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_kill_context(
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(s),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen &s->kill_context,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen -1,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_pid,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen false);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r > 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_set_state(s, state);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_enter_dead(s, SWAP_SUCCESS);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenfail:
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
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void swap_enter_activating(Swap *s) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r, priority;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (s->from_fragment)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen priority = s->parameters_fragment.priority;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen priority = -1;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (priority >= 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char p[LINE_MAX];
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen snprintf(p, sizeof(p), "%i", priority);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char_array_0(p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = exec_command_set(
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_command,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "/sbin/swapon",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "-p",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen p,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->what,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen NULL);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = exec_command_set(
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_command,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "/sbin/swapon",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->what,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen NULL);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_unwatch_control_pid(s);
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = swap_spawn(s, s->control_command, &s->control_pid);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_set_state(s, SWAP_ACTIVATING);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenfail:
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt log_warning_unit(UNIT(s)->id,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s failed to run 'swapon' task: %s",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(s)->id, strerror(-r));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmekstatic void swap_enter_deactivating(Swap *s) {
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering s->control_command_id = SWAP_EXEC_DEACTIVATE;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
7b729f8686a83b24f3d9a891cde1c35a6aa37cf9Lukas Nykryn
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering r = exec_command_set(s->control_command,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "/sbin/swapoff",
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering s->what,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen NULL);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering swap_unwatch_control_pid(s);
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering r = swap_spawn(s, s->control_command, &s->control_pid);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_set_state(s, SWAP_DEACTIVATING);
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering return;
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poetteringfail:
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering log_warning_unit(UNIT(s)->id,
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering "%s failed to run 'swapoff' task: %s",
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering UNIT(s)->id, strerror(-r));
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek swap_enter_active(s, SWAP_FAILURE_RESOURCES);
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt}
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pittstatic int swap_start(Unit *u) {
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt Swap *s = SWAP(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* We cannot fulfill this request right now, try again later
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * please! */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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 ||
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering s->state == SWAP_ACTIVATING_SIGTERM ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->state == SWAP_ACTIVATING_SIGKILL)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EAGAIN;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering if (s->state == SWAP_ACTIVATING)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (detect_container(NULL) > 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EPERM;
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->result = SWAP_SUCCESS;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_enter_activating(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
7a03974a6f4510dcb1850515a80c2063c767a80fThomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_stop(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Swap *s = SWAP(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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 return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s->state == SWAP_ACTIVATING ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->state == SWAP_ACTIVE);
ed0d40229bc536c424fad481e56afcaa1d0e38dbLennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (detect_container(NULL) > 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EPERM;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_enter_deactivating(s);
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Swap *s = SWAP(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
7a03974a6f4510dcb1850515a80c2063c767a80fThomas Hindoe Paaboel Andersen assert(s);
7a03974a6f4510dcb1850515a80c2063c767a80fThomas Hindoe Paaboel Andersen assert(f);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(fds);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (s->control_pid > 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen exec_context_serialize(&s->exec_context, UNIT(s), f);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Swap *s = SWAP(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(fds);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (streq(key, "state")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen SwapState state;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen state = swap_state_from_string(value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (state < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug_unit(u->id, "Failed to parse state value %s", value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->deserialized_state = state;
8c84621c25c563c7428f3d355136fc542389aab8Thomas Hindoe Paaboel Andersen } else if (streq(key, "result")) {
8c84621c25c563c7428f3d355136fc542389aab8Thomas Hindoe Paaboel Andersen SwapResult f;
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt f = swap_result_from_string(value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (f < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug_unit(u->id, "Failed to parse result value %s", value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (f != SWAP_SUCCESS)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->result = f;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(key, "control-pid")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen pid_t pid;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
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
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt s->control_pid = pid;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(key, "control-command")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen SwapExecCommand id;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen id = swap_exec_command_from_string(value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (id < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_command_id = id;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_command = s->exec_command + id;
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(key, "tmp-dir")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char *t;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t = strdup(value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!t)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return log_oom();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->exec_context.tmp_dir = t;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(key, "var-tmp-dir")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char *t;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t = strdup(value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!t)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return log_oom();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->exec_context.var_tmp_dir = t;
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen } else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug_unit(u->id, "Unknown serialization key '%s'", key);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen_pure_ static UnitActiveState swap_active_state(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return state_translation_table[SWAP(u)->state];
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen_pure_ static const char *swap_sub_state_to_string(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return swap_state_to_string(SWAP(u)->state);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen_pure_ static bool swap_check_gc(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Swap *s = SWAP(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return s->from_proc_swaps;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
f8bc41822ba19905707a97f9d87262f2c2b6e5faZbigniew Jędrzejewski-Szmekstatic void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
5921fc3cc36df4baa5e16060e7675ace9eda2befThomas Hindoe Paaboel Andersen Swap *s = SWAP(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen SwapResult f;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(pid >= 0);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (pid != s->control_pid)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_pid = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (is_clean_exit(code, status, NULL))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen f = SWAP_SUCCESS;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (code == CLD_EXITED)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen f = SWAP_FAILURE_EXIT_CODE;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (code == CLD_KILLED)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen f = SWAP_FAILURE_SIGNAL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (code == CLD_DUMPED)
b2c23da8cea1987a1a329f5a964d3299b7ca7890Lennart Poettering f = SWAP_FAILURE_CORE_DUMP;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert_not_reached("Unknown code");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (f != SWAP_SUCCESS)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->result = f;
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (s->control_command) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_command = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen u->id,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s swap process exited, code=%s status=%i",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen u->id, sigchld_code_to_string(code), status);
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen switch (s->state) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case SWAP_ACTIVATING:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case SWAP_ACTIVATING_SIGTERM:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case SWAP_ACTIVATING_SIGKILL:
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering if (f == SWAP_SUCCESS)
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering swap_enter_active(s, f);
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering else
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering swap_enter_dead(s, f);
b3fae863ef548add2d01c3956ce7720f4eeeca7eLennart Poettering break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case SWAP_DEACTIVATING:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case SWAP_DEACTIVATING_SIGKILL:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case SWAP_DEACTIVATING_SIGTERM:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (f == SWAP_SUCCESS)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_enter_dead(s, f);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen swap_enter_dead(s, f);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen default:
assert_not_reached("Uh, control process died at wrong time.");
}
/* Notify clients about changed exit status */
unit_add_to_dbus_queue(u);
/* Request a reload of /proc/swaps, so that following units
* can follow our state change */
u->manager->request_reload = true;
}
static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
Swap *s = SWAP(u);
assert(s);
assert(elapsed == 1);
assert(w == &s->timer_watch);
switch (s->state) {
case SWAP_ACTIVATING:
log_warning_unit(u->id, "%s activation timed out. Stopping.", u->id);
swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
break;
case SWAP_DEACTIVATING:
log_warning_unit(u->id, "%s deactivation timed out. Stopping.", u->id);
swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
break;
case SWAP_ACTIVATING_SIGTERM:
if (s->kill_context.send_sigkill) {
log_warning_unit(u->id, "%s activation timed out. Killing.", u->id);
swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
} else {
log_warning_unit(u->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", u->id);
swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
}
break;
case SWAP_DEACTIVATING_SIGTERM:
if (s->kill_context.send_sigkill) {
log_warning_unit(u->id, "%s deactivation timed out. Killing.", u->id);
swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
} else {
log_warning_unit(u->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id);
swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
}
break;
case SWAP_ACTIVATING_SIGKILL:
case SWAP_DEACTIVATING_SIGKILL:
log_warning_unit(u->id, "%s swap process still around after SIGKILL. Ignoring.", u->id);
swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
break;
default:
assert_not_reached("Timeout at wrong time.");
}
}
static int swap_load_proc_swaps(Manager *m, bool set_flags) {
unsigned i;
int r = 0;
assert(m);
rewind(m->proc_swaps);
(void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
for (i = 1;; i++) {
char *dev = NULL, *d;
int prio = 0, k;
k = fscanf(m->proc_swaps,
"%ms " /* device/file */
"%*s " /* type of swap */
"%*s " /* swap size */
"%*s " /* used */
"%i\n", /* priority */
&dev, &prio);
if (k != 2) {
if (k == EOF)
break;
log_warning("Failed to parse /proc/swaps:%u", i);
free(dev);
continue;
}
d = cunescape(dev);
free(dev);
if (!d)
return -ENOMEM;
k = swap_process_new_swap(m, d, prio, set_flags);
free(d);
if (k < 0)
r = k;
}
return r;
}
int swap_dispatch_reload(Manager *m) {
/* This function should go as soon as the kernel properly notifies us */
if (_likely_(!m->request_reload))
return 0;
m->request_reload = false;
return swap_fd_event(m, EPOLLPRI);
}
int swap_fd_event(Manager *m, int events) {
Unit *u;
int r;
assert(m);
assert(events & EPOLLPRI);
r = swap_load_proc_swaps(m, true);
if (r < 0) {
log_error("Failed to reread /proc/swaps: %s", strerror(-r));
/* Reset flags, just in case, for late calls */
LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
Swap *swap = SWAP(u);
swap->is_active = swap->just_activated = false;
}
return 0;
}
manager_dispatch_load_queue(m);
LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
Swap *swap = SWAP(u);
if (!swap->is_active) {
/* This has just been deactivated */
swap->from_proc_swaps = false;
swap_unset_proc_swaps(swap);
switch (swap->state) {
case SWAP_ACTIVE:
swap_enter_dead(swap, SWAP_SUCCESS);
break;
default:
swap_set_state(swap, swap->state);
break;
}
} else if (swap->just_activated) {
/* New swap entry */
switch (swap->state) {
case SWAP_DEAD:
case SWAP_FAILED:
swap_enter_active(swap, SWAP_SUCCESS);
break;
default:
/* Nothing really changed, but let's
* issue an notification call
* nonetheless, in case somebody is
* waiting for this. */
swap_set_state(swap, swap->state);
break;
}
}
/* Reset the flags for later calls */
swap->is_active = swap->just_activated = false;
}
return 1;
}
static Unit *swap_following(Unit *u) {
Swap *s = SWAP(u);
Swap *other, *first = NULL;
assert(s);
if (streq_ptr(s->what, s->parameters_proc_swaps.what))
return NULL;
/* Make everybody follow the unit that's named after the swap
* device in the kernel */
LIST_FOREACH_AFTER(same_proc_swaps, other, s)
if (streq_ptr(other->what, other->parameters_proc_swaps.what))
return UNIT(other);
LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
if (streq_ptr(other->what, other->parameters_proc_swaps.what))
return UNIT(other);
first = other;
}
return UNIT(first);
}
static int swap_following_set(Unit *u, Set **_set) {
Swap *s = SWAP(u);
Swap *other;
Set *set;
int r;
assert(s);
assert(_set);
if (LIST_JUST_US(same_proc_swaps, s)) {
*_set = NULL;
return 0;
}
if (!(set = set_new(NULL, NULL)))
return -ENOMEM;
LIST_FOREACH_AFTER(same_proc_swaps, other, s)
if ((r = set_put(set, other)) < 0)
goto fail;
LIST_FOREACH_BEFORE(same_proc_swaps, other, s)
if ((r = set_put(set, other)) < 0)
goto fail;
*_set = set;
return 1;
fail:
set_free(set);
return r;
}
static void swap_shutdown(Manager *m) {
assert(m);
if (m->proc_swaps) {
fclose(m->proc_swaps);
m->proc_swaps = NULL;
}
hashmap_free(m->swaps_by_proc_swaps);
m->swaps_by_proc_swaps = NULL;
}
static int swap_enumerate(Manager *m) {
int r;
assert(m);
if (!m->proc_swaps) {
struct epoll_event ev = {
.events = EPOLLPRI,
.data.ptr = &m->swap_watch,
};
m->proc_swaps = fopen("/proc/swaps", "re");
if (!m->proc_swaps)
return (errno == ENOENT) ? 0 : -errno;
m->swap_watch.type = WATCH_SWAP;
m->swap_watch.fd = fileno(m->proc_swaps);
if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
return -errno;
}
r = swap_load_proc_swaps(m, false);
if (r < 0)
swap_shutdown(m);
return r;
}
static void swap_reset_failed(Unit *u) {
Swap *s = SWAP(u);
assert(s);
if (s->state == SWAP_FAILED)
swap_set_state(s, SWAP_DEAD);
s->result = SWAP_SUCCESS;
}
static int swap_kill(Unit *u, KillWho who, int signo, DBusError *error) {
return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
}
static const char* const swap_state_table[_SWAP_STATE_MAX] = {
[SWAP_DEAD] = "dead",
[SWAP_ACTIVATING] = "activating",
[SWAP_ACTIVE] = "active",
[SWAP_DEACTIVATING] = "deactivating",
[SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
[SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
[SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
[SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
[SWAP_FAILED] = "failed"
};
DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
[SWAP_EXEC_ACTIVATE] = "ExecActivate",
[SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
};
DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
[SWAP_SUCCESS] = "success",
[SWAP_FAILURE_RESOURCES] = "resources",
[SWAP_FAILURE_TIMEOUT] = "timeout",
[SWAP_FAILURE_EXIT_CODE] = "exit-code",
[SWAP_FAILURE_SIGNAL] = "signal",
[SWAP_FAILURE_CORE_DUMP] = "core-dump"
};
DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
const UnitVTable swap_vtable = {
.object_size = sizeof(Swap),
.sections =
"Unit\0"
"Swap\0"
"Install\0",
.private_section = "Swap",
.exec_context_offset = offsetof(Swap, exec_context),
.cgroup_context_offset = offsetof(Swap, cgroup_context),
.no_alias = true,
.no_instances = true,
.init = swap_init,
.load = swap_load,
.done = swap_done,
.coldplug = swap_coldplug,
.dump = swap_dump,
.start = swap_start,
.stop = swap_stop,
.kill = swap_kill,
.serialize = swap_serialize,
.deserialize_item = swap_deserialize_item,
.active_state = swap_active_state,
.sub_state_to_string = swap_sub_state_to_string,
.check_gc = swap_check_gc,
.sigchld_event = swap_sigchld_event,
.timer_event = swap_timer_event,
.reset_failed = swap_reset_failed,
.bus_interface = "org.freedesktop.systemd1.Swap",
.bus_message_handler = bus_swap_message_handler,
.bus_invalidating_properties = bus_swap_invalidating_properties,
.bus_set_property = bus_swap_set_property,
.bus_commit_properties = bus_swap_commit_properties,
.following = swap_following,
.following_set = swap_following_set,
.enumerate = swap_enumerate,
.shutdown = swap_shutdown,
.status_message_formats = {
.starting_stopping = {
[0] = "Activating swap %s...",
[1] = "Deactivating swap %s...",
},
.finished_start_job = {
[JOB_DONE] = "Activated swap %s.",
[JOB_FAILED] = "Failed to activate swap %s.",
[JOB_DEPENDENCY] = "Dependency failed for %s.",
[JOB_TIMEOUT] = "Timed out activating swap %s.",
},
.finished_stop_job = {
[JOB_DONE] = "Deactivated swap %s.",
[JOB_FAILED] = "Failed deactivating swap %s.",
[JOB_TIMEOUT] = "Timed out deactivating swap %s.",
},
},
};