diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml
index 90d0d66414..c4e1d1f94a 100644
--- a/man/org.freedesktop.systemd1.xml
+++ b/man/org.freedesktop.systemd1.xml
@@ -121,6 +121,12 @@ node /org/freedesktop/systemd1 {
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,
@@ -774,6 +780,8 @@ node /org/freedesktop/systemd1 {
+
+
@@ -1166,6 +1174,9 @@ node /org/freedesktop/systemd1 {
BindMountUnit() can be used to bind mount new files or directories into
a running service mount namespace.
+ MountImageUnit() can be used to mount new images into a running service
+ mount namespace.
+
KillUnit() may be used to kill (i.e. send a signal to) all processes of a
unit. It takes the unit name, an enum who and a UNIX
signal number to send. The who enum is one of
@@ -2207,6 +2218,11 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
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);
@@ -3268,6 +3284,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
+
+
@@ -3829,12 +3847,12 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
Methods
- BindMount() implements the same operation as the respective method on the
- Manager 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 GetUnit() call to get the unit object
- for a specific unit name. Calling the methods on the Manager object is hence a round trip
- optimization.
+ BindMount() and MountImage() implement the same operations
+ as the respective methods on the Manager 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 GetUnit() call
+ to get the unit object for a specific unit name. Calling the methods on the Manager object is hence a round
+ trip optimization.
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 4b88f0d9f0..eeb74353da 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -731,6 +731,11 @@ static int method_bind_mount_unit(sd_bus_message *message, void *userdata, sd_bu
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);
@@ -2776,6 +2781,17 @@ const sd_bus_vtable bus_manager_vtable[] = {
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),
diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c
index 6df93e44a4..f7cdb51eba 100644
--- a/src/core/dbus-service.c
+++ b/src/core/dbus-service.c
@@ -95,9 +95,10 @@ static int property_get_exit_status_set(
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;
@@ -120,16 +121,22 @@ int bus_service_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
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);
@@ -158,16 +165,30 @@ int bus_service_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
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),
@@ -233,6 +254,17 @@ const sd_bus_vtable bus_service_vtable[] = {
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),
diff --git a/src/core/dbus-service.h b/src/core/dbus-service.h
index 5b7b7b757b..9a05465802 100644
--- a/src/core/dbus-service.h
+++ b/src/core/dbus-service.h
@@ -10,4 +10,5 @@ extern const sd_bus_vtable bus_service_vtable[];
int bus_service_set_property(Unit *u, const char *name, sd_bus_message *i, UnitWriteFlags flags, sd_bus_error *error);
int bus_service_method_bind_mount(sd_bus_message *message, void *userdata, sd_bus_error *error);
+int bus_service_method_mount_image(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_service_commit_properties(Unit *u);
diff --git a/src/core/org.freedesktop.systemd1.conf b/src/core/org.freedesktop.systemd1.conf
index 0cea4d2b02..f405b27658 100644
--- a/src/core/org.freedesktop.systemd1.conf
+++ b/src/core/org.freedesktop.systemd1.conf
@@ -226,6 +226,10 @@
send_interface="org.freedesktop.systemd1.Manager"
send_member="BindMountUnit"/>
+
+
@@ -400,6 +404,10 @@
send_interface="org.freedesktop.systemd1.Service"
send_member="BindMount"/>
+
+