]>
Commit | Line | Data |
---|---|---|
b7103bc5 LP |
1 | /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ |
2 | ||
3 | /*** | |
4 | This file is part of systemd. | |
5 | ||
6 | Copyright 2015 Lennart Poettering | |
7 | ||
8 | systemd is free software; you can redistribute it and/or modify it | |
9 | under the terms of the GNU Lesser General Public License as published by | |
10 | the Free Software Foundation; either version 2.1 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 | Lesser General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU Lesser General Public License | |
19 | along with systemd; If not, see <http://www.gnu.org/licenses/>. | |
20 | ***/ | |
21 | ||
22 | #include "sd-bus.h" | |
23 | ||
b7103bc5 | 24 | #include "bus-error.h" |
8fcde012 | 25 | #include "bus-util.h" |
b7103bc5 | 26 | #include "nspawn-register.h" |
8fcde012 LP |
27 | #include "stat-util.h" |
28 | #include "strv.h" | |
29 | #include "util.h" | |
b7103bc5 LP |
30 | |
31 | int register_machine( | |
32 | const char *machine_name, | |
33 | pid_t pid, | |
34 | const char *directory, | |
35 | sd_id128_t uuid, | |
36 | int local_ifindex, | |
37 | const char *slice, | |
38 | CustomMount *mounts, | |
39 | unsigned n_mounts, | |
40 | int kill_signal, | |
41 | char **properties, | |
6aadfa4c ILG |
42 | bool keep_unit, |
43 | const char *service) { | |
b7103bc5 LP |
44 | |
45 | _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; | |
46 | _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; | |
47 | int r; | |
48 | ||
49 | r = sd_bus_default_system(&bus); | |
50 | if (r < 0) | |
51 | return log_error_errno(r, "Failed to open system bus: %m"); | |
52 | ||
53 | if (keep_unit) { | |
54 | r = sd_bus_call_method( | |
55 | bus, | |
56 | "org.freedesktop.machine1", | |
57 | "/org/freedesktop/machine1", | |
58 | "org.freedesktop.machine1.Manager", | |
59 | "RegisterMachineWithNetwork", | |
60 | &error, | |
61 | NULL, | |
62 | "sayssusai", | |
63 | machine_name, | |
64 | SD_BUS_MESSAGE_APPEND_ID128(uuid), | |
6aadfa4c | 65 | service, |
b7103bc5 LP |
66 | "container", |
67 | (uint32_t) pid, | |
68 | strempty(directory), | |
69 | local_ifindex > 0 ? 1 : 0, local_ifindex); | |
70 | } else { | |
71 | _cleanup_bus_message_unref_ sd_bus_message *m = NULL; | |
72 | char **i; | |
73 | unsigned j; | |
74 | ||
75 | r = sd_bus_message_new_method_call( | |
76 | bus, | |
77 | &m, | |
78 | "org.freedesktop.machine1", | |
79 | "/org/freedesktop/machine1", | |
80 | "org.freedesktop.machine1.Manager", | |
81 | "CreateMachineWithNetwork"); | |
82 | if (r < 0) | |
83 | return bus_log_create_error(r); | |
84 | ||
85 | r = sd_bus_message_append( | |
86 | m, | |
87 | "sayssusai", | |
88 | machine_name, | |
89 | SD_BUS_MESSAGE_APPEND_ID128(uuid), | |
6aadfa4c | 90 | service, |
b7103bc5 LP |
91 | "container", |
92 | (uint32_t) pid, | |
93 | strempty(directory), | |
94 | local_ifindex > 0 ? 1 : 0, local_ifindex); | |
95 | if (r < 0) | |
96 | return bus_log_create_error(r); | |
97 | ||
98 | r = sd_bus_message_open_container(m, 'a', "(sv)"); | |
99 | if (r < 0) | |
100 | return bus_log_create_error(r); | |
101 | ||
102 | if (!isempty(slice)) { | |
103 | r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice); | |
104 | if (r < 0) | |
105 | return bus_log_create_error(r); | |
106 | } | |
107 | ||
541ec330 LP |
108 | r = sd_bus_message_append(m, "(sv)", "TasksMax", "t", 8192); |
109 | if (r < 0) | |
110 | return bus_log_create_error(r); | |
111 | ||
b7103bc5 LP |
112 | r = sd_bus_message_append(m, "(sv)", "DevicePolicy", "s", "strict"); |
113 | if (r < 0) | |
114 | return bus_log_create_error(r); | |
115 | ||
116 | /* If you make changes here, also make sure to update | |
117 | * systemd-nspawn@.service, to keep the device | |
118 | * policies in sync regardless if we are run with or | |
119 | * without the --keep-unit switch. */ | |
120 | r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 9, | |
121 | /* Allow the container to | |
122 | * access and create the API | |
123 | * device nodes, so that | |
124 | * PrivateDevices= in the | |
125 | * container can work | |
126 | * fine */ | |
127 | "/dev/null", "rwm", | |
128 | "/dev/zero", "rwm", | |
129 | "/dev/full", "rwm", | |
130 | "/dev/random", "rwm", | |
131 | "/dev/urandom", "rwm", | |
132 | "/dev/tty", "rwm", | |
133 | "/dev/net/tun", "rwm", | |
134 | /* Allow the container | |
135 | * access to ptys. However, | |
136 | * do not permit the | |
137 | * container to ever create | |
138 | * these device nodes. */ | |
139 | "/dev/pts/ptmx", "rw", | |
140 | "char-pts", "rw"); | |
141 | if (r < 0) | |
142 | return bus_log_create_error(r); | |
143 | ||
144 | for (j = 0; j < n_mounts; j++) { | |
145 | CustomMount *cm = mounts + j; | |
146 | ||
147 | if (cm->type != CUSTOM_MOUNT_BIND) | |
148 | continue; | |
149 | ||
150 | r = is_device_node(cm->source); | |
151 | if (r < 0) | |
152 | return log_error_errno(r, "Failed to stat %s: %m", cm->source); | |
153 | ||
154 | if (r) { | |
155 | r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 1, | |
156 | cm->source, cm->read_only ? "r" : "rw"); | |
157 | if (r < 0) | |
158 | return log_error_errno(r, "Failed to append message arguments: %m"); | |
159 | } | |
160 | } | |
161 | ||
162 | if (kill_signal != 0) { | |
163 | r = sd_bus_message_append(m, "(sv)", "KillSignal", "i", kill_signal); | |
164 | if (r < 0) | |
165 | return bus_log_create_error(r); | |
166 | ||
167 | r = sd_bus_message_append(m, "(sv)", "KillMode", "s", "mixed"); | |
168 | if (r < 0) | |
169 | return bus_log_create_error(r); | |
170 | } | |
171 | ||
172 | STRV_FOREACH(i, properties) { | |
173 | r = sd_bus_message_open_container(m, 'r', "sv"); | |
174 | if (r < 0) | |
175 | return bus_log_create_error(r); | |
176 | ||
177 | r = bus_append_unit_property_assignment(m, *i); | |
178 | if (r < 0) | |
179 | return r; | |
180 | ||
181 | r = sd_bus_message_close_container(m); | |
182 | if (r < 0) | |
183 | return bus_log_create_error(r); | |
184 | } | |
185 | ||
186 | r = sd_bus_message_close_container(m); | |
187 | if (r < 0) | |
188 | return bus_log_create_error(r); | |
189 | ||
190 | r = sd_bus_call(bus, m, 0, &error, NULL); | |
191 | } | |
192 | ||
193 | if (r < 0) { | |
194 | log_error("Failed to register machine: %s", bus_error_message(&error, r)); | |
195 | return r; | |
196 | } | |
197 | ||
198 | return 0; | |
199 | } | |
200 | ||
201 | int terminate_machine(pid_t pid) { | |
202 | _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; | |
203 | _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; | |
204 | _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; | |
205 | const char *path; | |
206 | int r; | |
207 | ||
208 | r = sd_bus_default_system(&bus); | |
209 | if (r < 0) | |
210 | return log_error_errno(r, "Failed to open system bus: %m"); | |
211 | ||
212 | r = sd_bus_call_method( | |
213 | bus, | |
214 | "org.freedesktop.machine1", | |
215 | "/org/freedesktop/machine1", | |
216 | "org.freedesktop.machine1.Manager", | |
217 | "GetMachineByPID", | |
218 | &error, | |
219 | &reply, | |
220 | "u", | |
221 | (uint32_t) pid); | |
222 | if (r < 0) { | |
223 | /* Note that the machine might already have been | |
224 | * cleaned up automatically, hence don't consider it a | |
225 | * failure if we cannot get the machine object. */ | |
226 | log_debug("Failed to get machine: %s", bus_error_message(&error, r)); | |
227 | return 0; | |
228 | } | |
229 | ||
230 | r = sd_bus_message_read(reply, "o", &path); | |
231 | if (r < 0) | |
232 | return bus_log_parse_error(r); | |
233 | ||
234 | r = sd_bus_call_method( | |
235 | bus, | |
236 | "org.freedesktop.machine1", | |
237 | path, | |
238 | "org.freedesktop.machine1.Machine", | |
239 | "Terminate", | |
240 | &error, | |
241 | NULL, | |
242 | NULL); | |
243 | if (r < 0) { | |
244 | log_debug("Failed to terminate machine: %s", bus_error_message(&error, r)); | |
245 | return 0; | |
246 | } | |
247 | ||
248 | return 0; | |
249 | } |