From: Mike Yuan Date: Wed, 16 Oct 2024 14:30:10 +0000 (+0200) Subject: core: clean up errors for live mounting X-Git-Tag: v257-rc1~147^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F34799%2Fhead;p=thirdparty%2Fsystemd.git 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 --- diff --git a/src/core/service.c b/src/core/service.c index d33abd16823..1ac158f1eab 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -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, diff --git a/src/core/unit.c b/src/core/unit.c index 230a782631a..d0e62c4d884 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -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, diff --git a/src/core/unit.h b/src/core/unit.h index 5ffd82b67eb..01e1adf961e 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -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);