snapshot.c revision 6bedfcbb2970e06a4d3280c8fb62083d252ede73
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek/***
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek This file is part of systemd.
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek Copyright 2010 Lennart Poettering
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
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
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
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-Szmek***/
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek#include <errno.h>
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "bus-common-errors.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "dbus-snapshot.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "parse-util.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "parse-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "snapshot.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "string-util.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "unit-name.h"
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek#include "unit.h"
8eea868708923a092ee85d6146ba4c04b7baea06Zbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmekstatic const UnitActiveState state_translation_table[_SNAPSHOT_STATE_MAX] = {
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek [SNAPSHOT_DEAD] = UNIT_INACTIVE,
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek [SNAPSHOT_ACTIVE] = UNIT_ACTIVE
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek};
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
8eea868708923a092ee85d6146ba4c04b7baea06Zbigniew Jędrzejewski-Szmekstatic void snapshot_init(Unit *u) {
8eea868708923a092ee85d6146ba4c04b7baea06Zbigniew Jędrzejewski-Szmek Snapshot *s = SNAPSHOT(u);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek assert(s);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek assert(UNIT(s)->load_state == UNIT_STUB);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek UNIT(s)->ignore_on_isolate = true;
8eea868708923a092ee85d6146ba4c04b7baea06Zbigniew Jędrzejewski-Szmek UNIT(s)->ignore_on_snapshot = true;
8eea868708923a092ee85d6146ba4c04b7baea06Zbigniew Jędrzejewski-Szmek UNIT(s)->allow_isolate = true;
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek}
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmekstatic void snapshot_set_state(Snapshot *s, SnapshotState state) {
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek SnapshotState old_state;
ae6c3cc009a21df4b51851fb8fe3fde0b7d6d8f0Lennart Poettering assert(s);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek old_state = s->state;
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek s->state = state;
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek if (state != old_state)
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek log_unit_debug(UNIT(s), "Changed %s -> %s", snapshot_state_to_string(old_state), snapshot_state_to_string(state));
8eea868708923a092ee85d6146ba4c04b7baea06Zbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek}
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmekstatic int snapshot_load(Unit *u) {
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek Snapshot *s = SNAPSHOT(u);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek assert(u);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek assert(u->load_state == UNIT_STUB);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
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-Szmek return -ENOENT;
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek u->load_state = UNIT_LOADED;
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek return 0;
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek}
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmekstatic int snapshot_coldplug(Unit *u) {
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek Snapshot *s = SNAPSHOT(u);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
8eea868708923a092ee85d6146ba4c04b7baea06Zbigniew Jędrzejewski-Szmek assert(s);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek assert(s->state == SNAPSHOT_DEAD);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek if (s->deserialized_state != s->state)
45519fd6304aae453d95c6cf11bfc8539c38494cLennart Poettering snapshot_set_state(s, s->deserialized_state);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek return 0;
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek}
8eea868708923a092ee85d6146ba4c04b7baea06Zbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmekstatic void snapshot_dump(Unit *u, FILE *f, const char *prefix) {
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek Snapshot *s = SNAPSHOT(u);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek assert(s);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek assert(f);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek fprintf(f,
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-Szmek prefix, yes_no(s->cleanup));
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek}
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmekstatic int snapshot_start(Unit *u) {
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek Snapshot *s = SNAPSHOT(u);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek assert(s);
8eea868708923a092ee85d6146ba4c04b7baea06Zbigniew Jędrzejewski-Szmek assert(s->state == SNAPSHOT_DEAD);
2968644080fd103062f070e83edd620e0a58c44dZbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek snapshot_set_state(s, SNAPSHOT_ACTIVE);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek if (s->cleanup)
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek unit_add_to_cleanup_queue(u);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek return 1;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek}
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmekstatic int snapshot_stop(Unit *u) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek Snapshot *s = SNAPSHOT(u);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek assert(s);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek assert(s->state == SNAPSHOT_ACTIVE);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek snapshot_set_state(s, SNAPSHOT_DEAD);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek return 1;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek}
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmekstatic int snapshot_serialize(Unit *u, FILE *f, FDSet *fds) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek Snapshot *s = SNAPSHOT(u);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek Unit *other;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek Iterator i;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek assert(s);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek assert(f);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek assert(fds);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
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-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek return 0;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek}
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmekstatic int snapshot_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek Snapshot *s = SNAPSHOT(u);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek int r;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek assert(u);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek assert(key);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek assert(value);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek assert(fds);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek if (streq(key, "state")) {
a34bf9db5da0fdd6bdb14459e203dbe41ee99614Lennart Poettering SnapshotState state;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek state = snapshot_state_from_string(value);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek if (state < 0)
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek log_unit_debug(u, "Failed to parse state value: %s", value);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek else
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek s->deserialized_state = state;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek } else if (streq(key, "cleanup")) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek r = parse_boolean(value);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek if (r < 0)
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek log_unit_debug(u, "Failed to parse cleanup value: %s", value);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek else
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek s->cleanup = r;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering } else if (streq(key, "wants")) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, value, NULL, true);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek if (r < 0)
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek return r;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek } else
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek log_unit_debug(u, "Unknown serialization key: %s", key);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek return 0;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek}
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek_pure_ static UnitActiveState snapshot_active_state(Unit *u) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek assert(u);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek return state_translation_table[SNAPSHOT(u)->state];
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek}
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek_pure_ static const char *snapshot_sub_state_to_string(Unit *u) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek assert(u);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek return snapshot_state_to_string(SNAPSHOT(u)->state);
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering}
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poetteringint snapshot_create(Manager *m, const char *name, bool cleanup, sd_bus_error *e, Snapshot **_s) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek _cleanup_free_ char *n = NULL;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek Unit *other, *u = NULL;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek Iterator i;
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering int r;
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering const char *k;
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek assert(m);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek assert(_s);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek if (name) {
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);
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering
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
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek if (manager_get_unit(m, name))
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek return sd_bus_error_setf(e, BUS_ERROR_UNIT_EXISTS, "Snapshot %s exists already.", name);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek } else {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek for (;;) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek if (asprintf(&n, "snapshot-%u.snapshot", ++ m->n_snapshots) < 0)
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek return -ENOMEM;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek if (!manager_get_unit(m, n)) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek name = n;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek break;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek }
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek n = mfree(n);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek }
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek }
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek r = manager_load_unit_prepare(m, name, NULL, e, &u);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek if (r < 0)
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek goto fail;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek u->transient = true;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek manager_dispatch_load_queue(m);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek assert(u->load_state == UNIT_LOADED);
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek HASHMAP_FOREACH_KEY(other, k, m->units, i) {
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek if (other->ignore_on_snapshot ||
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek other->transient)
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek continue;
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek
1a7f1b385cd9de8a0da934fadc379860f914ef33Zbigniew Jędrzejewski-Szmek if (k != other->id)
continue;
if (UNIT_VTABLE(other)->check_snapshot)
if (!UNIT_VTABLE(other)->check_snapshot(other))
continue;
if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
continue;
r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, other, true);
if (r < 0)
goto fail;
}
SNAPSHOT(u)->cleanup = cleanup;
*_s = SNAPSHOT(u);
log_unit_info(u, "Created snapshot.");
return 0;
fail:
if (u)
unit_add_to_cleanup_queue(u);
return r;
}
void snapshot_remove(Snapshot *s) {
assert(s);
log_unit_info(UNIT(s), "Removing snapshot.");
unit_add_to_cleanup_queue(UNIT(s));
}
const UnitVTable snapshot_vtable = {
.object_size = sizeof(Snapshot),
.no_alias = true,
.no_instances = true,
.no_gc = true,
.init = snapshot_init,
.load = snapshot_load,
.coldplug = snapshot_coldplug,
.dump = snapshot_dump,
.start = snapshot_start,
.stop = snapshot_stop,
.serialize = snapshot_serialize,
.deserialize_item = snapshot_deserialize_item,
.active_state = snapshot_active_state,
.sub_state_to_string = snapshot_sub_state_to_string,
.bus_vtable = bus_snapshot_vtable
};