]> git.ipfire.org Git - people/ms/systemd.git/blame - snapshot.c
cgroup: if we are already in our own cgroup, then reuse it
[people/ms/systemd.git] / snapshot.c
CommitLineData
5cb5a6ff
LP
1/*-*- Mode: C; c-basic-offset: 8 -*-*/
2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
41447faf
LP
22#include <errno.h>
23
87f0e418 24#include "unit.h"
5cb5a6ff 25#include "snapshot.h"
41447faf
LP
26#include "unit-name.h"
27#include "dbus-snapshot.h"
28
29static const UnitActiveState state_translation_table[_SNAPSHOT_STATE_MAX] = {
30 [SNAPSHOT_DEAD] = UNIT_INACTIVE,
31 [SNAPSHOT_ACTIVE] = UNIT_ACTIVE
32};
33
34static const char* const state_string_table[_SNAPSHOT_STATE_MAX] = {
35 [SNAPSHOT_DEAD] = "dead",
36 [SNAPSHOT_ACTIVE] = "active"
37};
38
39static int snapshot_load(Unit *u) {
40 Iterator i;
41 Unit *other;
42 int r;
43
44 assert(u);
45
46 HASHMAP_FOREACH(other, u->meta.manager->units, i) {
5cb5a6ff 47
41447faf
LP
48 if (UNIT_VTABLE(other)->no_snapshots)
49 continue;
50
51 if ((r = unit_add_dependency(u, UNIT_REQUIRES, other)) < 0)
52 return r;
53
54 if ((r = unit_add_dependency(u, UNIT_AFTER, other)) < 0)
55 return r;
56 }
57
58 u->meta.load_state = UNIT_LOADED;
59
60 return 0;
61}
62
63static void snapshot_dump(Unit *u, FILE *f, const char *prefix) {
87f0e418 64 Snapshot *s = SNAPSHOT(u);
5cb5a6ff
LP
65
66 assert(s);
41447faf 67 assert(f);
5cb5a6ff 68
41447faf
LP
69 fprintf(f,
70 "%sSnapshot State: %s\n"
71 "%sClean Up: %s\n",
72 prefix, state_string_table[s->state],
73 prefix, yes_no(s->cleanup));
74}
75
76static void snapshot_set_state(Snapshot *s, SnapshotState state) {
77 SnapshotState old_state;
78 assert(s);
79
80 old_state = s->state;
81 s->state = state;
82
83 if (state != old_state)
84 log_debug("%s changed %s → %s", UNIT(s)->meta.id, state_string_table[old_state], state_string_table[state]);
85
86 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state]);
87}
88
89static int snapshot_start(Unit *u) {
90 Snapshot *s = SNAPSHOT(u);
91
92 assert(s);
93 assert(s->state == SNAPSHOT_DEAD);
94
95 snapshot_set_state(s, SNAPSHOT_ACTIVE);
96
97 if (s->cleanup)
98 unit_add_to_cleanup_queue(u);
99
100 return 0;
101}
102
103static int snapshot_stop(Unit *u) {
104 Snapshot *s = SNAPSHOT(u);
105
106 assert(s);
107 assert(s->state == SNAPSHOT_ACTIVE);
108
109 snapshot_set_state(s, SNAPSHOT_DEAD);
110 return 0;
5cb5a6ff
LP
111}
112
87f0e418 113static UnitActiveState snapshot_active_state(Unit *u) {
41447faf
LP
114 assert(u);
115
116 return state_translation_table[SNAPSHOT(u)->state];
117}
118
119static const char *snapshot_sub_state_to_string(Unit *u) {
120 assert(u);
121
122 return state_string_table[SNAPSHOT(u)->state];
123}
124
125int snapshot_create(Manager *m, const char *name, bool cleanup, Snapshot **_s) {
126 Unit *u;
127 char *n = NULL;
128 int r;
129
130 assert(m);
131 assert(_s);
132
133 if (name) {
134 if (!unit_name_is_valid(name))
135 return -EINVAL;
136
137 if (unit_name_to_type(name) != UNIT_SNAPSHOT)
138 return -EINVAL;
139
140 if (manager_get_unit(m, name))
141 return -EEXIST;
142
143 } else {
144
145 for (;;) {
146 if (asprintf(&n, "snapshot-%u.snapshot", ++ m->n_snapshots) < 0)
147 return -ENOMEM;
148
149 if (!manager_get_unit(m, n))
150 break;
151
152 free(n);
153 }
154
155 name = n;
156 }
157
158 r = manager_load_unit(m, name, NULL, &u);
159 free(n);
160
161 if (r < 0)
162 return r;
163
164 SNAPSHOT(u)->cleanup = cleanup;
165 *_s = SNAPSHOT(u);
166
167 return 0;
168}
169
170void snapshot_remove(Snapshot *s) {
171 assert(s);
172
173 unit_add_to_cleanup_queue(UNIT(s));
034c6ed7
LP
174}
175
87f0e418 176const UnitVTable snapshot_vtable = {
5cb5a6ff
LP
177 .suffix = ".snapshot",
178
41447faf
LP
179 .no_alias = true,
180 .no_instances = true,
181 .no_snapshots = true,
182
183 .load = snapshot_load,
184
185 .dump = snapshot_dump,
186
187 .start = snapshot_start,
188 .stop = snapshot_stop,
189
190 .active_state = snapshot_active_state,
191 .sub_state_to_string = snapshot_sub_state_to_string,
5cb5a6ff 192
41447faf 193 .bus_message_handler = bus_snapshot_message_handler
5cb5a6ff 194};