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