core: clean up errors for live mounting
* Use SD_BUS_ERROR_NOT_SUPPORTED where appropriate * Use Service object in service_can_live_mount() * Include errno in bus error message
This commit is contained in:
+28
-44
@@ -5167,7 +5167,8 @@ static int service_can_clean(Unit *u, ExecCleanMask *ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int service_live_mount(Unit *u,
|
||||
static int service_live_mount(
|
||||
Unit *u,
|
||||
const char *src,
|
||||
const char *dst,
|
||||
sd_bus_message *message,
|
||||
@@ -5175,9 +5176,8 @@ static int service_live_mount(Unit *u,
|
||||
const MountOptions *options,
|
||||
sd_bus_error *error) {
|
||||
|
||||
_cleanup_(pidref_done) PidRef worker = PIDREF_NULL;
|
||||
Service *s = ASSERT_PTR(SERVICE(u));
|
||||
const char *propagate_directory;
|
||||
_cleanup_(pidref_done) PidRef worker = PIDREF_NULL;
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
@@ -5188,7 +5188,7 @@ static int service_live_mount(Unit *u,
|
||||
assert(!s->mount_request);
|
||||
|
||||
if (s->state != SERVICE_RUNNING || !pidref_is_set(&s->main_pid)) {
|
||||
log_unit_warning(u, "Service is not running, cannot live mount");
|
||||
log_unit_warning(u, "Service is not running, cannot live mount.");
|
||||
return sd_bus_error_setf(
|
||||
error,
|
||||
BUS_ERROR_UNIT_INACTIVE,
|
||||
@@ -5199,7 +5199,7 @@ static int service_live_mount(Unit *u,
|
||||
}
|
||||
|
||||
if (mount_point_is_credentials(u->manager->prefix[EXEC_DIRECTORY_RUNTIME], dst)) {
|
||||
log_unit_warning(u, "Refusing to live mount over credential mount '%s'", dst);
|
||||
log_unit_warning(u, "Refusing to live mount over credential mount '%s'.", dst);
|
||||
return sd_bus_error_setf(
|
||||
error,
|
||||
SD_BUS_ERROR_INVALID_ARGS,
|
||||
@@ -5210,7 +5210,7 @@ static int service_live_mount(Unit *u,
|
||||
}
|
||||
|
||||
if (path_startswith_strv(dst, s->exec_context.inaccessible_paths)) {
|
||||
log_unit_warning(u, "%s is not accessible to this unit, cannot live mount", dst);
|
||||
log_unit_warning(u, "%s is not accessible to this unit, cannot live mount.", dst);
|
||||
return sd_bus_error_setf(
|
||||
error,
|
||||
SD_BUS_ERROR_INVALID_ARGS,
|
||||
@@ -5227,18 +5227,14 @@ static int service_live_mount(Unit *u,
|
||||
|
||||
r = service_arm_timer(s, /* relative= */ true, s->timeout_start_usec);
|
||||
if (r < 0) {
|
||||
log_unit_warning_errno(u, r, "Failed to install timer: %m");
|
||||
sd_bus_error_set_errnof(
|
||||
error,
|
||||
r,
|
||||
"Live mounting '%s' on '%s' for unit '%s' cannot be scheduled: failed to install timer",
|
||||
src,
|
||||
dst,
|
||||
u->id);
|
||||
log_unit_error_errno(u, r, "Failed to install timer: %m");
|
||||
sd_bus_error_set_errnof(error, r,
|
||||
"Live mounting '%s' on '%s' for unit '%s': failed to install timer: %m",
|
||||
src, dst, u->id);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
propagate_directory = strjoina("/run/systemd/propagate/", u->id);
|
||||
const char *propagate_directory = strjoina("/run/systemd/propagate/", u->id);
|
||||
|
||||
/* Given we are running from PID1, avoid doing potentially heavy I/O operations like opening images
|
||||
* directly, and instead fork a worker process. We record the D-Bus message, so that we can reply
|
||||
@@ -5246,19 +5242,12 @@ static int service_live_mount(Unit *u,
|
||||
* resource is available (or the operation failed) once they receive the response. */
|
||||
r = unit_fork_helper_process(u, "(sd-mount-in-ns)", /* into_cgroup= */ false, &worker);
|
||||
if (r < 0) {
|
||||
log_unit_warning_errno(
|
||||
u,
|
||||
r,
|
||||
"Failed to fork process to mount '%s' on '%s' in unit's namespace: %m",
|
||||
src,
|
||||
dst);
|
||||
sd_bus_error_set_errnof(
|
||||
error,
|
||||
r,
|
||||
"Live mounting '%s' on '%s' for unit '%s' cannot be scheduled: failed to fork process",
|
||||
src,
|
||||
dst,
|
||||
u->id);
|
||||
log_unit_error_errno(u, r,
|
||||
"Failed to fork process to mount '%s' on '%s' in unit's namespace: %m",
|
||||
src, dst);
|
||||
sd_bus_error_set_errnof(error, r,
|
||||
"Live mounting '%s' on '%s' for unit '%s': failed to fork off helper process into namespace: %m",
|
||||
src, dst, u->id);
|
||||
goto fail;
|
||||
}
|
||||
if (r == 0) {
|
||||
@@ -5279,26 +5268,21 @@ static int service_live_mount(Unit *u,
|
||||
src, dst,
|
||||
flags);
|
||||
if (r < 0)
|
||||
log_unit_warning_errno(
|
||||
u,
|
||||
r,
|
||||
"Failed to mount '%s' on '%s' in unit's namespace: %m",
|
||||
src,
|
||||
dst);
|
||||
log_unit_error_errno(u, r,
|
||||
"Failed to mount '%s' on '%s' in unit's namespace: %m",
|
||||
src, dst);
|
||||
else
|
||||
log_unit_debug(u, "Mounted '%s' on '%s' in unit's namespace", src, dst);
|
||||
|
||||
_exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
r = unit_watch_pidref(u, &worker, /* exclusive= */ true);
|
||||
if (r < 0) {
|
||||
sd_bus_error_set_errnof(
|
||||
error,
|
||||
r,
|
||||
"Live mounting '%s' on '%s' for unit '%s' failed: failed to watch worker process",
|
||||
src,
|
||||
dst,
|
||||
u->id);
|
||||
log_unit_warning_errno(u, r, "Failed to watch live mount helper process: %m");
|
||||
sd_bus_error_set_errnof(error, r,
|
||||
"Live mounting '%s' on '%s' for unit '%s': failed to watch live mount helper process: %m",
|
||||
src, dst, u->id);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -5313,11 +5297,11 @@ fail:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int service_can_live_mount(const Unit *u, sd_bus_error *error) {
|
||||
assert(u);
|
||||
static int service_can_live_mount(Unit *u, sd_bus_error *error) {
|
||||
Service *s = ASSERT_PTR(SERVICE(u));
|
||||
|
||||
/* Ensure that the unit runs in a private mount namespace */
|
||||
if (!exec_needs_mount_namespace(unit_get_exec_context(u), /* params= */ NULL, unit_get_exec_runtime(u)))
|
||||
if (!exec_needs_mount_namespace(&s->exec_context, /* params= */ NULL, s->exec_runtime))
|
||||
return sd_bus_error_setf(
|
||||
error,
|
||||
SD_BUS_ERROR_INVALID_ARGS,
|
||||
|
||||
+7
-8
@@ -6397,22 +6397,21 @@ Condition *unit_find_failed_condition(Unit *u) {
|
||||
return failed_trigger && !has_succeeded_trigger ? failed_trigger : NULL;
|
||||
}
|
||||
|
||||
int unit_can_live_mount(const Unit *u, sd_bus_error *error) {
|
||||
int unit_can_live_mount(Unit *u, sd_bus_error *error) {
|
||||
assert(u);
|
||||
|
||||
if (!UNIT_VTABLE(u)->live_mount)
|
||||
return sd_bus_error_setf(
|
||||
error,
|
||||
SD_BUS_ERROR_INVALID_ARGS,
|
||||
"Live mounting not supported for unit type '%s' of unit '%s'.",
|
||||
unit_type_to_string(u->type),
|
||||
u->id);
|
||||
SD_BUS_ERROR_NOT_SUPPORTED,
|
||||
"Live mounting not supported by unit type '%s'",
|
||||
unit_type_to_string(u->type));
|
||||
|
||||
if (u->load_state != UNIT_LOADED)
|
||||
return sd_bus_error_setf(
|
||||
error,
|
||||
BUS_ERROR_NO_SUCH_UNIT,
|
||||
"Unit '%s' not loaded, cannot live mount.",
|
||||
"Unit '%s' not loaded, cannot live mount",
|
||||
u->id);
|
||||
|
||||
if (!UNIT_VTABLE(u)->can_live_mount)
|
||||
@@ -6434,7 +6433,7 @@ int unit_live_mount(
|
||||
assert(UNIT_VTABLE(u)->live_mount);
|
||||
|
||||
if (!UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) {
|
||||
log_unit_debug(u, "Unit not active");
|
||||
log_unit_debug(u, "Unit not active, cannot perform live mount.");
|
||||
return sd_bus_error_setf(
|
||||
error,
|
||||
BUS_ERROR_UNIT_INACTIVE,
|
||||
@@ -6445,7 +6444,7 @@ int unit_live_mount(
|
||||
}
|
||||
|
||||
if (unit_active_state(u) == UNIT_REFRESHING) {
|
||||
log_unit_debug(u, "Unit already live mounting");
|
||||
log_unit_debug(u, "Unit already live mounting, refusing further requests.");
|
||||
return sd_bus_error_setf(
|
||||
error,
|
||||
BUS_ERROR_UNIT_BUSY,
|
||||
|
||||
+3
-3
@@ -587,7 +587,7 @@ typedef struct UnitVTable {
|
||||
|
||||
/* Add a bind/image mount into the unit namespace while it is running. */
|
||||
int (*live_mount)(Unit *u, const char *src, const char *dst, sd_bus_message *message, MountInNamespaceFlags flags, const MountOptions *options, sd_bus_error *error);
|
||||
int (*can_live_mount)(const Unit *u, sd_bus_error *error);
|
||||
int (*can_live_mount)(Unit *u, sd_bus_error *error);
|
||||
|
||||
/* Serialize state and file descriptors that should be carried over into the new
|
||||
* instance after reexecution. */
|
||||
@@ -650,7 +650,7 @@ typedef struct UnitVTable {
|
||||
int (*bus_commit_properties)(Unit *u);
|
||||
|
||||
/* Return the unit this unit is following */
|
||||
Unit *(*following)(Unit *u);
|
||||
Unit* (*following)(Unit *u);
|
||||
|
||||
/* Return the set of units that are following each other */
|
||||
int (*following_set)(Unit *u, Set **s);
|
||||
@@ -1047,7 +1047,7 @@ void unit_next_freezer_state(Unit *u, FreezerAction action, FreezerState *ret_ne
|
||||
void unit_set_freezer_state(Unit *u, FreezerState state);
|
||||
void unit_freezer_complete(Unit *u, FreezerState kernel_state);
|
||||
|
||||
int unit_can_live_mount(const Unit *u, sd_bus_error *error);
|
||||
int unit_can_live_mount(Unit *u, sd_bus_error *error);
|
||||
int unit_live_mount(Unit *u, const char *src, const char *dst, sd_bus_message *message, MountInNamespaceFlags flags, const MountOptions *options, sd_bus_error *error);
|
||||
|
||||
Condition *unit_find_failed_condition(Unit *u);
|
||||
|
||||
Reference in New Issue
Block a user