Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/checkpath/checkpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ static int do_create(inode_t type, const char *path, int dirfd, const char *name
static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode, inode_t type,
bool trunc, bool chowner, bool writable, bool symlinks, bool selinux_on)
{
int flags = O_NDELAY | O_NOCTTY | O_RDONLY | O_CLOEXEC | O_NOFOLLOW | (trunc ? O_TRUNC : 0);
int flags = O_NDELAY | O_NOCTTY | O_RDONLY | O_CLOEXEC | O_NOFOLLOW;
const char *name = basename_c(path);
struct stat st;
int dirfd, fd;
Expand All @@ -229,6 +229,9 @@ static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode, inode_t type,
return -1;
}

if (trunc && type == inode_file)
flags |= O_TRUNC;

dirfd = get_dirfd(path, symlinks);
if ((fd = openat(dirfd, name, flags)) == -1 &&
(fd = do_create(type, path, dirfd, name, flags, mode)) == -1)
Expand Down
120 changes: 74 additions & 46 deletions src/openrc-run/openrc-run.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ static RC_STRINGLIST *restart_services;
static RC_STRINGLIST *need_services;
static RC_STRINGLIST *use_services;
static RC_STRINGLIST *want_services;
static RC_HOOK hook_out;
static int exclusive_fd = -1, master_tty = -1;
static bool in_background, deps, dry_run;
static volatile bool sighup, skip_mark, timedout;
Expand Down Expand Up @@ -234,14 +233,6 @@ cleanup(void)
restore_state();

if (!rc_in_plugin) {
if (hook_out) {
rc_plugin_run(hook_out, applet);
if (hook_out == RC_HOOK_SERVICE_START_DONE)
rc_plugin_run(RC_HOOK_SERVICE_START_OUT, applet);
else if (hook_out == RC_HOOK_SERVICE_STOP_DONE)
rc_plugin_run(RC_HOOK_SERVICE_STOP_OUT, applet);
}

if (restart_services)
start_services(restart_services);
}
Expand Down Expand Up @@ -356,11 +347,15 @@ svc_exec(const char *command)
};

/* Setup our signal pipe */
if (pipe2(signal_pipe, O_CLOEXEC) == -1)
eerrorx("%s: pipe2: %s", applet, applet);
if (pipe2(signal_pipe, O_CLOEXEC) == -1) {
eerror("%s: pipe2: %s", applet, applet);
return 1;
}

if ((errno = posix_spawn_file_actions_init(&tty)))
eerrorx("%s: posix_spawn_file_actions_init: %s", applet, strerror(errno));
if ((errno = posix_spawn_file_actions_init(&tty))) {
eerror("%s: posix_spawn_file_actions_init: %s", applet, strerror(errno));
return 1;
}

/* Open a pty for our prefixed output
* We do this instead of mapping pipes to stdout, stderr so that
Expand All @@ -382,8 +377,10 @@ svc_exec(const char *command)
fcntl(slave_tty, F_SETFD, flags | FD_CLOEXEC);

if ((errno = posix_spawn_file_actions_adddup2(&tty, slave_tty, STDOUT_FILENO))
|| (errno = posix_spawn_file_actions_adddup2(&tty, slave_tty, STDERR_FILENO)))
eerrorx("%s: posix_spawn_file_actions_adddup2: %s", applet, strerror(errno));
|| (errno = posix_spawn_file_actions_adddup2(&tty, slave_tty, STDERR_FILENO))) {
eerror("%s: posix_spawn_file_actions_adddup2: %s", applet, strerror(errno));
return 1;
}
}

if (faccessat(rc_dirfd(RC_DIR_SVCDIR), "openrc-run.sh", F_OK, 0) == 0) {
Expand All @@ -395,8 +392,10 @@ svc_exec(const char *command)
rc_environ_export(&env, (const char *const *) environ, &envp);

einfov("Executing: %s %s %s", argv[0], service, command);
if ((errno = posix_spawn(&service_pid, argv[0], &tty, NULL, UNCONST(argv), envp ? UNCONST(envp) : environ)))
eerrorx("%s: exec '%s': %s", service, argv[0], strerror(errno));
if ((errno = posix_spawn(&service_pid, argv[0], &tty, NULL, UNCONST(argv), envp ? UNCONST(envp) : environ))) {
eerror("%s: exec '%s': %s", service, argv[0], strerror(errno));
return 1;
}

posix_spawn_file_actions_destroy(&tty);
free(openrc_sh);
Expand Down Expand Up @@ -549,13 +548,15 @@ setup_deptypes(void)
static void
svc_start_check(void)
{
int ret = EXIT_FAILURE;
RC_SERVICE state;

state = rc_service_state(applet);

if (in_background) {
if (!(state & (RC_SERVICE_INACTIVE | RC_SERVICE_STOPPED)))
exit(EXIT_FAILURE);
goto exit;

if (rc_yesno(getenv("IN_HOTPLUG")))
rc_service_mark(applet, RC_SERVICE_HOTPLUGGED);
if (strcmp(runlevel, RC_LEVEL_SYSINIT) == 0)
Expand All @@ -564,26 +565,35 @@ svc_start_check(void)

if (state & RC_SERVICE_STARTED) {
ewarn("WARNING: %s has already been started", applet);
exit(EXIT_SUCCESS);
ret = EXIT_SUCCESS;
goto exit;
} 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) {
if (errno != EWOULDBLOCK)
eerrorx("%s: failed to acquire lock: %s", applet, strerror(errno));
else if (state & RC_SERVICE_STOPPING)
if (errno != EWOULDBLOCK) {
eerror("%s: failed to acquire lock: %s", applet, strerror(errno));
goto exit;
}

if (state & RC_SERVICE_STOPPING)
ewarnx("WARNING: %s is stopping", applet);
else
ewarnx("WARNING: %s is already starting", applet);
}
fcntl(exclusive_fd, F_SETFD, fcntl(exclusive_fd, F_GETFD, 0) | FD_CLOEXEC);

rc_service_mark(applet, RC_SERVICE_STARTING);
hook_out = RC_HOOK_SERVICE_START_OUT;
rc_plugin_run(RC_HOOK_SERVICE_START_IN, applet);

return;

exit:
rc_plugin_run(RC_HOOK_SERVICE_START_OUT, applet);
exit(ret);
}

static void
Expand All @@ -602,8 +612,11 @@ svc_start_deps(void)
if (rc_conf_yesno("rc_depend_strict") || errno == ENOENT)
depoptions |= RC_DEP_STRICT;

if (!deptree && ((deptree = _rc_deptree_load(0, NULL)) == NULL))
eerrorx("failed to load deptree");
if (!deptree && ((deptree = _rc_deptree_load(0, NULL)) == NULL)) {
eerror("failed to load deptree");
goto exit;
}

if (!deptypes_b)
setup_deptypes();

Expand All @@ -620,7 +633,7 @@ svc_start_deps(void)
fprintf(stderr, "%s", svc->value);
}
fprintf(stderr, "\n");
exit(EXIT_FAILURE);
goto exit;
}
rc_stringlist_free(services);
services = NULL;
Expand Down Expand Up @@ -684,10 +697,12 @@ svc_start_deps(void)
continue;
}
if (rc_stringlist_find(need_services, svc->value)) {
if (state & (RC_SERVICE_INACTIVE | RC_SERVICE_WASINACTIVE))
if (state & (RC_SERVICE_INACTIVE | RC_SERVICE_WASINACTIVE)) {
rc_stringlist_add(tmplist, svc->value);
else if (!TAILQ_FIRST(tmplist))
eerrorx("ERROR: cannot start %s as %s would not start", applet, svc->value);
} else if (!TAILQ_FIRST(tmplist)) {
eerror("ERROR: cannot start %s as %s would not start", applet, svc->value);
goto exit;
}
}
}

Expand Down Expand Up @@ -723,6 +738,12 @@ svc_start_deps(void)
tmplist = NULL;
rc_stringlist_free(services);
services = NULL;

return;

exit:
rc_plugin_run(RC_HOOK_SERVICE_START_OUT, applet);
exit(EXIT_FAILURE);
}


Expand Down Expand Up @@ -758,13 +779,17 @@ static void svc_start_real(void)

if (ibsave)
setenv("IN_BACKGROUND", ibsave, 1);
hook_out = RC_HOOK_SERVICE_START_DONE;
rc_plugin_run(RC_HOOK_SERVICE_START_NOW, applet);
skip_mark = false;
started = (svc_exec("start") == 0);
if (ibsave)
unsetenv("IN_BACKGROUND");

if (!started) {
rc_plugin_run(RC_HOOK_SERVICE_START_DONE, applet);
rc_plugin_run(RC_HOOK_SERVICE_START_OUT, applet);
}

if (rc_service_state(applet) & RC_SERVICE_INACTIVE)
ewarnx("WARNING: %s has started, but is inactive", applet);
else if (!started)
Expand All @@ -773,7 +798,6 @@ static void svc_start_real(void)
if (!skip_mark)
rc_service_mark(applet, RC_SERVICE_STARTED);
exclusive_fd = svc_unlock(applet, exclusive_fd);
hook_out = RC_HOOK_SERVICE_START_OUT;
rc_plugin_run(RC_HOOK_SERVICE_START_DONE, applet);

/* Now start any scheduled services */
Expand All @@ -799,7 +823,6 @@ static void svc_start_real(void)
tmplist = NULL;
}

hook_out = 0;
rc_plugin_run(RC_HOOK_SERVICE_START_OUT, applet);
}

Expand Down Expand Up @@ -828,10 +851,10 @@ svc_stop_check(RC_SERVICE *state)
*state = rc_service_state(applet);

if (rc_runlevel_stopping() && *state & RC_SERVICE_FAILED)
exit(EXIT_FAILURE);
goto exit;

if (in_background && !(*state & (RC_SERVICE_STARTED) && !(*state & RC_SERVICE_INACTIVE)))
exit(EXIT_FAILURE);
goto exit;

if (*state & RC_SERVICE_STOPPED) {
ewarn("WARNING: %s is already stopped", applet);
Expand All @@ -842,15 +865,16 @@ svc_stop_check(RC_SERVICE *state)
exclusive_fd = svc_lock(applet, !deps);
if (exclusive_fd == -1) {
if (errno != EWOULDBLOCK)
eerrorx("%s: failed to acquire lock: %s", applet, strerror(errno));
eerror("%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);
ewarn("WARNING: %s is already stopping", applet);
else
eerror("ERROR: %s stopped by something else", applet);
goto exit;
}
fcntl(exclusive_fd, F_SETFD, fcntl(exclusive_fd, F_GETFD, 0) | FD_CLOEXEC);

rc_service_mark(applet, RC_SERVICE_STOPPING);
hook_out = RC_HOOK_SERVICE_STOP_OUT;
rc_plugin_run(RC_HOOK_SERVICE_STOP_IN, applet);

if (!rc_runlevel_stopping()) {
Expand All @@ -861,6 +885,10 @@ svc_stop_check(RC_SERVICE *state)
}

return 0;

exit:
rc_plugin_run(RC_HOOK_SERVICE_STOP_OUT, applet);
exit(EXIT_FAILURE);
}

static void
Expand All @@ -877,8 +905,10 @@ svc_stop_deps(RC_SERVICE state)
if (rc_conf_yesno("rc_depend_strict") || errno == ENOENT)
depoptions |= RC_DEP_STRICT;

if (!deptree && ((deptree = _rc_deptree_load(0, NULL)) == NULL))
if (!deptree && ((deptree = _rc_deptree_load(0, NULL)) == NULL)) {
rc_plugin_run(RC_HOOK_SERVICE_STOP_OUT, applet);
eerrorx("failed to load deptree");
}

if (!deptypes_m)
setup_deptypes();
Expand Down Expand Up @@ -924,6 +954,7 @@ svc_stop_deps(RC_SERVICE state)
continue;
rc_service_mark(applet, RC_SERVICE_FAILED);
}
rc_plugin_run(RC_HOOK_SERVICE_STOP_OUT, applet);
eerrorx("ERROR: cannot stop %s as %s is still up", applet, svc->value);
}
rc_stringlist_free(tmplist);
Expand Down Expand Up @@ -969,23 +1000,20 @@ svc_stop_real(void)

if (ibsave)
setenv("IN_BACKGROUND", ibsave, 1);
hook_out = RC_HOOK_SERVICE_STOP_DONE;
rc_plugin_run(RC_HOOK_SERVICE_STOP_NOW, applet);
skip_mark = false;
stopped = (svc_exec("stop") == 0);
if (ibsave)
unsetenv("IN_BACKGROUND");

if (!stopped)
eerrorx("ERROR: %s failed to stop", applet);

if (!skip_mark)
if (stopped && !skip_mark)
rc_service_mark(applet, in_background ? RC_SERVICE_INACTIVE : RC_SERVICE_STOPPED);

hook_out = RC_HOOK_SERVICE_STOP_OUT;
rc_plugin_run(RC_HOOK_SERVICE_STOP_DONE, applet);
hook_out = 0;
rc_plugin_run(RC_HOOK_SERVICE_STOP_OUT, applet);

if (!stopped)
eerrorx("ERROR: %s failed to stop", applet);
}

static int
Expand Down
Loading
Loading