From cfdf7bf73d4029fe29a7d4d3758e051aac4d108f Mon Sep 17 00:00:00 2001 From: NRK Date: Wed, 11 Feb 2026 06:27:25 +0000 Subject: [PATCH 1/2] fix error message when running as non-root currently trying to stop a service as non-root prints: * ERROR: ${service} stopped by something else but this is plain wrong, the service isn't stopped and the real reason for failure is due to permission problem. same issue with starting a service. --- src/openrc-run/openrc-run.c | 12 ++++++++++-- src/shared/misc.c | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/openrc-run/openrc-run.c b/src/openrc-run/openrc-run.c index f8c163941..fd6cd494d 100644 --- a/src/openrc-run/openrc-run.c +++ b/src/openrc-run/openrc-run.c @@ -557,7 +557,9 @@ svc_start_check(void) if (exclusive_fd == -1) exclusive_fd = svc_lock(applet, !deps); if (exclusive_fd == -1) { - if (state & RC_SERVICE_STOPPING) + if (errno != EWOULDBLOCK) + eerrorx("%s: failed to acquire lock: %s", applet, strerror(errno)); + else if (state & RC_SERVICE_STOPPING) ewarnx("WARNING: %s is stopping", applet); else ewarnx("WARNING: %s is already starting", applet); @@ -631,6 +633,10 @@ svc_start_deps(void) printf(" %s", svc->value); continue; } + /* FIXME(NRK): service_start() can return -1 on + * failure and feeding that to rc_waitpid seems + * very suspicious. needs investigation. + */ pid = service_start(svc->value); if (!rc_conf_yesno("rc_parallel")) rc_waitpid(pid); @@ -792,7 +798,9 @@ svc_stop_check(RC_SERVICE *state) if (exclusive_fd == -1) exclusive_fd = svc_lock(applet, !deps); if (exclusive_fd == -1) { - if (*state & RC_SERVICE_STOPPING) + if (errno != EWOULDBLOCK) + eerrorx("%s: failed to acquire lock: %s", applet, strerror(errno)); + else if (*state & RC_SERVICE_STOPPING) ewarnx("WARNING: %s is already stopping", applet); eerrorx("ERROR: %s stopped by something else", applet); } diff --git a/src/shared/misc.c b/src/shared/misc.c index 50e436105..7d6bb0947 100644 --- a/src/shared/misc.c +++ b/src/shared/misc.c @@ -289,6 +289,7 @@ svc_lock(const char *applet, bool ignore_lock_failure) if (fd == -1) return -1; if (flock(fd, LOCK_EX | LOCK_NB) == -1) { + int saved_errno = errno; if (ignore_lock_failure) { /* Two services with a need b, and b's start() * calling restart --no-deps on a would cause @@ -299,6 +300,7 @@ svc_lock(const char *applet, bool ignore_lock_failure) } eerror("Call to flock failed: %s", strerror(errno)); close(fd); + errno = saved_errno; return -1; } return fd; From 8c351b3c4a38185a1dd2fb49c79d6d2d63e7ecf9 Mon Sep 17 00:00:00 2001 From: NRK Date: Thu, 12 Feb 2026 20:46:48 +0000 Subject: [PATCH 2/2] openrc-run: check state before locking otherwise running as non-root will print permission error, misleading the user to retry with root only to then tell them the service is already stopped - which we could've known without needing root perm. --- src/openrc-run/openrc-run.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/openrc-run/openrc-run.c b/src/openrc-run/openrc-run.c index fd6cd494d..0664fc055 100644 --- a/src/openrc-run/openrc-run.c +++ b/src/openrc-run/openrc-run.c @@ -554,6 +554,13 @@ svc_start_check(void) ewarnx("WARNING: %s will be started in the next runlevel", applet); } + if (state & RC_SERVICE_STARTED) { + ewarn("WARNING: %s has already been started", applet); + exit(EXIT_SUCCESS); + } else if (state & RC_SERVICE_INACTIVE && !in_background) { + ewarnx("WARNING: %s has already started, but is inactive", applet); + } + if (exclusive_fd == -1) exclusive_fd = svc_lock(applet, !deps); if (exclusive_fd == -1) { @@ -566,13 +573,6 @@ svc_start_check(void) } fcntl(exclusive_fd, F_SETFD, fcntl(exclusive_fd, F_GETFD, 0) | FD_CLOEXEC); - if (state & RC_SERVICE_STARTED) { - ewarn("WARNING: %s has already been started", applet); - exit(EXIT_SUCCESS); - } else if (state & RC_SERVICE_INACTIVE && !in_background) { - ewarnx("WARNING: %s has already started, but is inactive", applet); - } - rc_service_mark(applet, RC_SERVICE_STARTING); hook_out = RC_HOOK_SERVICE_START_OUT; rc_plugin_run(RC_HOOK_SERVICE_START_IN, applet); @@ -795,6 +795,11 @@ svc_stop_check(RC_SERVICE *state) if (in_background && !(*state & (RC_SERVICE_STARTED | RC_SERVICE_INACTIVE))) exit(EXIT_FAILURE); + if (*state & RC_SERVICE_STOPPED) { + ewarn("WARNING: %s is already stopped", applet); + return 1; + } + if (exclusive_fd == -1) exclusive_fd = svc_lock(applet, !deps); if (exclusive_fd == -1) { @@ -806,11 +811,6 @@ svc_stop_check(RC_SERVICE *state) } fcntl(exclusive_fd, F_SETFD, fcntl(exclusive_fd, F_GETFD, 0) | FD_CLOEXEC); - if (*state & RC_SERVICE_STOPPED) { - ewarn("WARNING: %s is already stopped", applet); - return 1; - } - rc_service_mark(applet, RC_SERVICE_STOPPING); hook_out = RC_HOOK_SERVICE_STOP_OUT; rc_plugin_run(RC_HOOK_SERVICE_STOP_IN, applet);