in s destination,
in b read_only,
in b mkdir);
+ MountImageUnit(in s name,
+ in s source,
+ in s destination,
+ in b read_only,
+ in b mkdir,
+ in a(ss) options);
RefUnit(in s name);
UnrefUnit(in s name);
StartTransientUnit(in s name,
<variablelist class="dbus-method" generated="True" extra-ref="BindMountUnit()"/>
+ <variablelist class="dbus-method" generated="True" extra-ref="MountImageUnit()"/>
+
<variablelist class="dbus-method" generated="True" extra-ref="RefUnit()"/>
<variablelist class="dbus-method" generated="True" extra-ref="UnrefUnit()"/>
<para><function>BindMountUnit()</function> can be used to bind mount new files or directories into
a running service mount namespace.</para>
+ <para><function>MountImageUnit()</function> can be used to mount new images into a running service
+ mount namespace.</para>
+
<para><function>KillUnit()</function> may be used to kill (i.e. send a signal to) all processes of a
unit. It takes the unit <varname>name</varname>, an enum <varname>who</varname> and a UNIX
<varname>signal</varname> number to send. The <varname>who</varname> enum is one of
in s destination,
in b read_only,
in b mkdir);
+ MountImage(in s source,
+ in s destination,
+ in b read_only,
+ in b mkdir,
+ in a(ss) options);
GetProcesses(out a(sus) processes);
AttachProcesses(in s subcgroup,
in au pids);
<variablelist class="dbus-method" generated="True" extra-ref="BindMount()"/>
+ <variablelist class="dbus-method" generated="True" extra-ref="MountImage()"/>
+
<variablelist class="dbus-method" generated="True" extra-ref="GetProcesses()"/>
<variablelist class="dbus-method" generated="True" extra-ref="AttachProcesses()"/>
<refsect2>
<title>Methods</title>
- <para><function>BindMount()</function> implements the same operation as the respective method on the
- <interfacename>Manager</interfacename> object (see above). However, this method operates on the service
- object and hence does not take a unit name parameter. Invoking the methods directly on the Manager
- object has the advantage of not requiring a <function>GetUnit()</function> call to get the unit object
- for a specific unit name. Calling the methods on the Manager object is hence a round trip
- optimization.</para>
+ <para><function>BindMount()</function> and <function>MountImage()</function> implement the same operations
+ as the respective methods on the <interfacename>Manager</interfacename> object (see above). However, these
+ methods operate on the service object and hence do not take a unit name parameter. Invoking the methods
+ directly on the Manager object has the advantage of not requiring a <function>GetUnit()</function> call
+ to get the unit object for a specific unit name. Calling the methods on the Manager object is hence a round
+ trip optimization.</para>
</refsect2>
<refsect2>
return method_generic_unit_operation(message, userdata, error, bus_service_method_bind_mount, GENERIC_UNIT_VALIDATE_LOADED);
}
+static int method_mount_image_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ /* Only add mounts on fully loaded units */
+ return method_generic_unit_operation(message, userdata, error, bus_service_method_mount_image, GENERIC_UNIT_VALIDATE_LOADED);
+}
+
static int method_ref_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
/* Only allow reffing of fully loaded units, and make sure reffing a unit loads it. */
return method_generic_unit_operation(message, userdata, error, bus_unit_method_ref, GENERIC_UNIT_LOAD|GENERIC_UNIT_VALIDATE_LOADED);
NULL,,
method_bind_mount_unit,
SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("MountImageUnit",
+ "sssbba(ss)",
+ SD_BUS_PARAM(name)
+ SD_BUS_PARAM(source)
+ SD_BUS_PARAM(destination)
+ SD_BUS_PARAM(read_only)
+ SD_BUS_PARAM(mkdir)
+ SD_BUS_PARAM(options),
+ NULL,,
+ method_mount_image_unit,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("RefUnit",
"s",
SD_BUS_PARAM(name),
return sd_bus_message_close_container(reply);
}
-int bus_service_method_bind_mount(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- int read_only, make_file_or_directory;
+static int bus_service_method_mount(sd_bus_message *message, void *userdata, sd_bus_error *error, bool is_image) {
+ _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
const char *dest, *src, *propagate_directory;
+ int read_only, make_file_or_directory;
Unit *u = userdata;
ExecContext *c;
pid_t unit_pid;
if (!path_is_absolute(src) || !path_is_normalized(src))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path must be absolute and normalized.");
- if (isempty(dest))
+ if (!is_image && isempty(dest))
dest = src;
else if (!path_is_absolute(dest) || !path_is_normalized(dest))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path must be absolute and normalized.");
+ if (is_image) {
+ r = bus_read_mount_options(message, error, &options, NULL, "");
+ if (r < 0)
+ return r;
+ }
+
r = bus_verify_manage_units_async_full(
u,
- "bind-mount",
+ is_image ? "mount-image" : "bind-mount",
CAP_SYS_ADMIN,
- N_("Authentication is required to bind mount on '$(unit)'."),
+ N_("Authentication is required to mount on '$(unit)'."),
true,
message,
error);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit is not running");
propagate_directory = strjoina("/run/systemd/propagate/", u->id);
- r = bind_mount_in_namespace(unit_pid,
- propagate_directory,
- "/run/systemd/incoming/",
- src, dest, read_only, make_file_or_directory);
+ if (is_image)
+ r = mount_image_in_namespace(unit_pid,
+ propagate_directory,
+ "/run/systemd/incoming/",
+ src, dest, read_only, make_file_or_directory, options);
+ else
+ r = bind_mount_in_namespace(unit_pid,
+ propagate_directory,
+ "/run/systemd/incoming/",
+ src, dest, read_only, make_file_or_directory);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to mount %s on %s in unit's namespace: %m", src, dest);
return sd_bus_reply_method_return(message, NULL);
}
+int bus_service_method_bind_mount(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ return bus_service_method_mount(message, userdata, error, false);
+}
+
+int bus_service_method_mount_image(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ return bus_service_method_mount(message, userdata, error, true);
+}
+
const sd_bus_vtable bus_service_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Service, type), SD_BUS_VTABLE_PROPERTY_CONST),
bus_service_method_bind_mount,
SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("MountImage",
+ "ssbba(ss)",
+ SD_BUS_PARAM(source)
+ SD_BUS_PARAM(destination)
+ SD_BUS_PARAM(read_only)
+ SD_BUS_PARAM(mkdir)
+ SD_BUS_PARAM(options),
+ NULL,,
+ bus_service_method_mount_image,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+
/* The following four are obsolete, and thus marked hidden here. They moved into the Unit interface */
SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Unit, start_ratelimit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Unit, start_ratelimit.burst), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),