1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2015 Lennart Poettering
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.
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.
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/>.
24 #include "bus-error.h"
26 #include "nspawn-register.h"
27 #include "stat-util.h"
32 const char *machine_name
,
34 const char *directory
,
43 const char *service
) {
45 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
46 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*bus
= NULL
;
49 r
= sd_bus_default_system(&bus
);
51 return log_error_errno(r
, "Failed to open system bus: %m");
54 r
= sd_bus_call_method(
56 "org.freedesktop.machine1",
57 "/org/freedesktop/machine1",
58 "org.freedesktop.machine1.Manager",
59 "RegisterMachineWithNetwork",
64 SD_BUS_MESSAGE_APPEND_ID128(uuid
),
69 local_ifindex
> 0 ? 1 : 0, local_ifindex
);
71 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
75 r
= sd_bus_message_new_method_call(
78 "org.freedesktop.machine1",
79 "/org/freedesktop/machine1",
80 "org.freedesktop.machine1.Manager",
81 "CreateMachineWithNetwork");
83 return bus_log_create_error(r
);
85 r
= sd_bus_message_append(
89 SD_BUS_MESSAGE_APPEND_ID128(uuid
),
94 local_ifindex
> 0 ? 1 : 0, local_ifindex
);
96 return bus_log_create_error(r
);
98 r
= sd_bus_message_open_container(m
, 'a', "(sv)");
100 return bus_log_create_error(r
);
102 if (!isempty(slice
)) {
103 r
= sd_bus_message_append(m
, "(sv)", "Slice", "s", slice
);
105 return bus_log_create_error(r
);
108 r
= sd_bus_message_append(m
, "(sv)", "TasksMax", "t", 8192);
110 return bus_log_create_error(r
);
112 r
= sd_bus_message_append(m
, "(sv)", "DevicePolicy", "s", "strict");
114 return bus_log_create_error(r
);
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
130 "/dev/random", "rwm",
131 "/dev/urandom", "rwm",
133 "/dev/net/tun", "rwm",
134 /* Allow the container
135 * access to ptys. However,
137 * container to ever create
138 * these device nodes. */
139 "/dev/pts/ptmx", "rw",
142 return bus_log_create_error(r
);
144 for (j
= 0; j
< n_mounts
; j
++) {
145 CustomMount
*cm
= mounts
+ j
;
147 if (cm
->type
!= CUSTOM_MOUNT_BIND
)
150 r
= is_device_node(cm
->source
);
152 return log_error_errno(r
, "Failed to stat %s: %m", cm
->source
);
155 r
= sd_bus_message_append(m
, "(sv)", "DeviceAllow", "a(ss)", 1,
156 cm
->source
, cm
->read_only
? "r" : "rw");
158 return log_error_errno(r
, "Failed to append message arguments: %m");
162 if (kill_signal
!= 0) {
163 r
= sd_bus_message_append(m
, "(sv)", "KillSignal", "i", kill_signal
);
165 return bus_log_create_error(r
);
167 r
= sd_bus_message_append(m
, "(sv)", "KillMode", "s", "mixed");
169 return bus_log_create_error(r
);
172 STRV_FOREACH(i
, properties
) {
173 r
= sd_bus_message_open_container(m
, 'r', "sv");
175 return bus_log_create_error(r
);
177 r
= bus_append_unit_property_assignment(m
, *i
);
181 r
= sd_bus_message_close_container(m
);
183 return bus_log_create_error(r
);
186 r
= sd_bus_message_close_container(m
);
188 return bus_log_create_error(r
);
190 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
194 log_error("Failed to register machine: %s", bus_error_message(&error
, r
));
201 int terminate_machine(pid_t pid
) {
202 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
203 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
204 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*bus
= NULL
;
208 r
= sd_bus_default_system(&bus
);
210 return log_error_errno(r
, "Failed to open system bus: %m");
212 r
= sd_bus_call_method(
214 "org.freedesktop.machine1",
215 "/org/freedesktop/machine1",
216 "org.freedesktop.machine1.Manager",
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
));
230 r
= sd_bus_message_read(reply
, "o", &path
);
232 return bus_log_parse_error(r
);
234 r
= sd_bus_call_method(
236 "org.freedesktop.machine1",
238 "org.freedesktop.machine1.Machine",
244 log_debug("Failed to terminate machine: %s", bus_error_message(&error
, r
));