snapshot.c revision 6bedfcbb2970e06a4d3280c8fb62083d252ede73
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek This file is part of systemd.
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek Copyright 2010 Lennart Poettering
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek under the terms of the GNU Lesser General Public License as published by
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 2.1 of the License, or
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek (at your option) any later version.
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek systemd is distributed in the hope that it will be useful, but
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek WITHOUT ANY WARRANTY; without even the implied warranty of
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek Lesser General Public License for more details.
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek You should have received a copy of the GNU Lesser General Public License
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek along with systemd; If not, see <http://www.gnu.org/licenses/>.
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmekstatic const UnitActiveState state_translation_table[_SNAPSHOT_STATE_MAX] = {
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek [SNAPSHOT_DEAD] = UNIT_INACTIVE,
8eea868708923a092ee85d6146ba4c04b7baea06Zbigniew Jędrzejewski-Szmekstatic void snapshot_init(Unit *u) {
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek assert(UNIT(s)->load_state == UNIT_STUB);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek UNIT(s)->ignore_on_isolate = true;
8eea868708923a092ee85d6146ba4c04b7baea06Zbigniew Jędrzejewski-Szmek UNIT(s)->ignore_on_snapshot = true;
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmekstatic void snapshot_set_state(Snapshot *s, SnapshotState state) {
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek log_unit_debug(UNIT(s), "Changed %s -> %s", snapshot_state_to_string(old_state), snapshot_state_to_string(state));
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmekstatic int snapshot_load(Unit *u) {
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek assert(u->load_state == UNIT_STUB);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek /* Make sure that only snapshots created via snapshot_create()
8eea868708923a092ee85d6146ba4c04b7baea06Zbigniew Jędrzejewski-Szmek * can be loaded */
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek if (!u->transient && UNIT(s)->manager->n_reloading <= 0)
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmekstatic int snapshot_coldplug(Unit *u) {
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek assert(s->state == SNAPSHOT_DEAD);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek if (s->deserialized_state != s->state)
45519fd6304aae453d95c6cf11bfc8539c38494cLennart Poettering snapshot_set_state(s, s->deserialized_state);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmekstatic void snapshot_dump(Unit *u, FILE *f, const char *prefix) {
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek "%sSnapshot State: %s\n"
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek "%sClean Up: %s\n",
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek prefix, snapshot_state_to_string(s->state),
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmekstatic int snapshot_start(Unit *u) {
8eea868708923a092ee85d6146ba4c04b7baea06Zbigniew Jędrzejewski-Szmek assert(s->state == SNAPSHOT_DEAD);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek snapshot_set_state(s, SNAPSHOT_ACTIVE);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmekstatic int snapshot_stop(Unit *u) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek assert(s->state == SNAPSHOT_ACTIVE);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek snapshot_set_state(s, SNAPSHOT_DEAD);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmekstatic int snapshot_serialize(Unit *u, FILE *f, FDSet *fds) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek unit_serialize_item(u, f, "state", snapshot_state_to_string(s->state));
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek unit_serialize_item(u, f, "cleanup", yes_no(s->cleanup));
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
45519fd6304aae453d95c6cf11bfc8539c38494cLennart Poettering unit_serialize_item(u, f, "wants", other->id);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmekstatic int snapshot_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek state = snapshot_state_from_string(value);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek log_unit_debug(u, "Failed to parse state value: %s", value);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek } else if (streq(key, "cleanup")) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek log_unit_debug(u, "Failed to parse cleanup value: %s", value);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, value, NULL, true);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek log_unit_debug(u, "Unknown serialization key: %s", key);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek_pure_ static UnitActiveState snapshot_active_state(Unit *u) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek return state_translation_table[SNAPSHOT(u)->state];
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek_pure_ static const char *snapshot_sub_state_to_string(Unit *u) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek return snapshot_state_to_string(SNAPSHOT(u)->state);
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poetteringint snapshot_create(Manager *m, const char *name, bool cleanup, sd_bus_error *e, Snapshot **_s) {
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering const char *k;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek if (!unit_name_is_valid(name, UNIT_NAME_PLAIN))
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s is not valid.", name);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek if (!endswith(name, ".snapshot"))
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s lacks snapshot suffix.", name);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek return sd_bus_error_setf(e, BUS_ERROR_UNIT_EXISTS, "Snapshot %s exists already.", name);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek if (asprintf(&n, "snapshot-%u.snapshot", ++ m->n_snapshots) < 0)
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek r = manager_load_unit_prepare(m, name, NULL, e, &u);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek assert(u->load_state == UNIT_LOADED);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek HASHMAP_FOREACH_KEY(other, k, m->units, i) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek if (other->ignore_on_snapshot ||
goto fail;
fail:
assert(s);
.no_alias = true,
.no_instances = true,
.no_gc = true,