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
3 changes: 3 additions & 0 deletions man/openrc-run.8
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ If using
then using
.Pa retry
is preferred.
.It Ar stopgroup
Signal the whole process group when stopping the daemon.
.It Ar respawn_delay
Respawn delay
.Xr supervise-daemon 8
Expand Down Expand Up @@ -296,6 +298,7 @@ retry:stop:start:
s6_log_arguments:::start
secbits:start:start:
stopsig:stop:start:stop
stopgroup:stop:start:
supervise_daemon_args::start:
timeout_down:::stop
timeout_kill:::stop
Expand Down
1 change: 1 addition & 0 deletions sh/start-stop-daemon.sh
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ ssd_stop()
${procname:+--name} $procname \
${pidfile:+--pidfile} $chroot$pidfile \
${stopsig:+--signal} $stopsig \
${stopgroup+--stop-group} \
${_progress}

eend $? "Failed to stop ${name:-$RC_SVCNAME}"
Expand Down
1 change: 1 addition & 0 deletions sh/supervise-daemon.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ supervise_start()
${command_user+--user} $command_user \
${umask+--umask} $umask \
${notify+--notify} $notify \
${stopgroup+--stop-group} \
${supervise_daemon_args-${start_stop_daemon_args}} \
$command \
-- $command_args $command_args_foreground
Expand Down
43 changes: 28 additions & 15 deletions src/shared/schedules.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,13 +245,17 @@ void parse_schedule(const char *applet, const char *string, int timeout)

/* return number of processes killed, -1 on error */
int do_stop(const char *applet, const char *exec, const char *const *argv,
pid_t pid, uid_t uid,int sig, bool test, bool quiet)
pid_t pid, uid_t uid, int sig, bool group, bool test, bool quiet)
{
RC_PIDLIST *pids;
RC_PID *pi;
RC_PID *np;
bool killed;
int nkilled = 0;
uid_t target;
char* kind = "PID";
if (group)
kind = "GID";

if (pid > 0)
pids = rc_find_pids(NULL, NULL, 0, pid);
Expand All @@ -263,24 +267,28 @@ int do_stop(const char *applet, const char *exec, const char *const *argv,

LIST_FOREACH_SAFE(pi, pids, entries, np) {
if (test) {
einfo("Would send signal %d to PID %d", sig, pi->pid);
einfo("Would send signal %d to %s %d", sig, kind, pi->pid);
nkilled++;
} else {
if (sig) {
syslog(LOG_DEBUG, "Sending signal %d to PID %d", sig, pi->pid);
syslog(LOG_DEBUG, "Sending signal %d to %s %d", sig, kind, pi->pid);
if (!quiet)
ebeginv("Sending signal %d to PID %d", sig, pi->pid);
ebeginv("Sending signal %d to %s %d", sig, kind, pi->pid);
}
errno = 0;
killed = (kill(pi->pid, sig) == 0 ||
if (group)
target = -pi->pid;
else
target = pi->pid;
killed = (kill(target, sig) == 0 ||
errno == ESRCH ? true : false);
if (!quiet)
eendv(killed ? 0 : 1,
"%s: failed to send signal %d to PID %d: %s",
applet, sig, pi->pid, strerror(errno));
"%s: failed to send signal %d to %s %d: %s",
applet, kind, sig, pi->pid, strerror(errno));
else if (!killed)
syslog(LOG_ERR, "Failed to send signal %d to PID %d: %s",
sig, pi->pid, strerror(errno));
syslog(LOG_ERR, "Failed to send signal %d to %s %d: %s",
sig, kind, pi->pid, strerror(errno));
if (!killed) {
nkilled = -1;
} else {
Expand All @@ -297,7 +305,7 @@ int do_stop(const char *applet, const char *exec, const char *const *argv,

int run_stop_schedule(const char *applet,
const char *exec, const char *const *argv,
pid_t pid, uid_t uid,
pid_t pid, uid_t uid, bool group,
bool test, bool progress, bool quiet)
{
SCHEDULEITEM *item = TAILQ_FIRST(&schedule);
Expand All @@ -317,8 +325,13 @@ int run_stop_schedule(const char *applet,
syslog(LOG_DEBUG, "Will stop %s", exec);
}
if (pid > 0) {
einfov("Will stop PID %d", pid);
syslog(LOG_DEBUG, "Will stop PID %d", pid);
if (!group) {
einfov("Will stop PID %d", pid);
syslog(LOG_DEBUG, "Will stop PID %d", pid);
} else {
einfov("Will stop GID %d", pid);
syslog(LOG_DEBUG, "Will stop GID %d", pid);
}
}
if (uid) {
einfov("Will stop processes owned by UID %d", uid);
Expand All @@ -344,8 +357,8 @@ int run_stop_schedule(const char *applet,

case SC_SIGNAL:
nrunning = 0;
nkilled = do_stop(applet, exec, argv, pid, uid, item->value, test,
quiet);
nkilled = do_stop(applet, exec, argv, pid, uid, item->value, group,
test, quiet);
if (nkilled == 0) {
if (tkilled == 0) {
if (progressed)
Expand Down Expand Up @@ -375,7 +388,7 @@ int run_stop_schedule(const char *applet,
nloops++)
{
if ((nrunning = do_stop(applet, exec, argv,
pid, uid, 0, test, quiet)) == 0)
pid, uid, 0, group, test, quiet)) == 0)
return 0;


Expand Down
4 changes: 2 additions & 2 deletions src/shared/schedules.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ void free_schedulelist(void);
int parse_signal(const char *applet, const char *sig);
void parse_schedule(const char *applet, const char *string, int timeout);
int do_stop(const char *applet, const char *exec, const char *const *argv,
pid_t pid, uid_t uid,int sig, bool test, bool quiet);
pid_t pid, uid_t uid, int sig, bool group, bool test, bool quiet);
int run_stop_schedule(const char *applet,
const char *exec, const char *const *argv,
pid_t pid, uid_t uid,
pid_t pid, uid_t uid, bool group,
bool test, bool progress, bool quiet);

#endif
13 changes: 10 additions & 3 deletions src/start-stop-daemon/start-stop-daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ enum {

const char *applet = NULL;
const char *extraopts = NULL;
const char getoptstring[] = "I:KN:PR:Sa:bc:d:e:g:ik:mn:op:s:tu:r:w:x:0:1:2:3:4:" \
const char getoptstring[] = "I:KN:PR:Sa:bc:d:e:Gg:ik:mn:op:s:tu:r:w:x:0:1:2:3:4:" \
getoptstring_COMMON;
const struct option longopts[] = {
{ "capabilities", 1, NULL, LONGOPT_CAPABILITIES},
Expand All @@ -115,6 +115,7 @@ const struct option longopts[] = {
{ "env", 1, NULL, 'e'},
{ "umask", 1, NULL, 'k'},
{ "group", 1, NULL, 'g'},
{ "stop-group", 0, NULL, 'G'},
{ "interpreted", 0, NULL, 'i'},
{ "make-pidfile", 0, NULL, 'm'},
{ "name", 1, NULL, 'n'},
Expand Down Expand Up @@ -154,6 +155,7 @@ const char * const longopts_help[] = {
"Set an environment string",
"Set the umask for the daemon",
"Change the process group",
"Stop the whole process group",
"Match process name by interpreter",
"Create a pidfile",
"Match process name",
Expand Down Expand Up @@ -343,6 +345,7 @@ int main(int argc, char **argv)
char *exec_file = NULL;
struct passwd *pw;
struct group *gr;
bool stopgroup = false;
char *line = NULL;
FILE *fp;
size_t len;
Expand Down Expand Up @@ -461,6 +464,10 @@ int main(int argc, char **argv)
stop = true;
break;

case 'G': /* --stop-group */
stopgroup = true;
break;

case 'N': /* --nice */
if (sscanf(optarg, "%d", &nicelevel) != 1)
eerrorx("%s: invalid nice level `%s'",
Expand Down Expand Up @@ -813,7 +820,7 @@ int main(int argc, char **argv)
pid = 0;
}
i = run_stop_schedule(applet, exec, (const char *const *)margv,
pid, uid, test, progress, false);
pid, uid, stopgroup, test, progress, false);

if (i < 0)
/* We failed to stop something */
Expand Down Expand Up @@ -1266,7 +1273,7 @@ int main(int argc, char **argv)
} else
pid = 0;
if (do_stop(applet, exec, (const char *const *)margv,
pid, uid, 0, test, false) > 0)
pid, uid, 0, false, test, false) > 0)
alive = true;
}

Expand Down
15 changes: 11 additions & 4 deletions src/supervise-daemon/supervise-daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ enum {

const char *applet = NULL;
const char *extraopts = NULL;
const char getoptstring[] = "A:a:D:d:e:g:I:Kk:m:N:p:R:r:s:Su:0:1:2:3" \
const char getoptstring[] = "A:a:D:d:e:Gg:I:Kk:m:N:p:R:r:s:Su:0:1:2:3" \
getoptstring_COMMON;
const struct option longopts[] = {
{ "healthcheck-timer", 1, NULL, 'a'},
Expand All @@ -99,6 +99,7 @@ const struct option longopts[] = {
{ "chdir", 1, NULL, 'd'},
{ "env", 1, NULL, 'e'},
{ "group", 1, NULL, 'g'},
{ "stop-group", 0, NULL, 'G'},
{ "ionice", 1, NULL, 'I'},
{ "stop", 0, NULL, 'K'},
{ "umask", 1, NULL, 'k'},
Expand Down Expand Up @@ -133,6 +134,7 @@ const char * const longopts_help[] = {
"Change the PWD",
"Set an environment string",
"Change the process group",
"Stop the whole process group",
"Set an ionice class:data when starting",
"Stop daemon",
"Set the umask for the daemon",
Expand Down Expand Up @@ -168,6 +170,7 @@ static int oom_score_adj = INT_MIN;
static char *changeuser, *ch_root, *ch_dir;
static uid_t uid = 0;
static gid_t gid = 0;
static bool stopgroup = false;
static int devnull_fd = -1;
static int stdin_fd;
static int stdout_fd;
Expand Down Expand Up @@ -735,7 +738,7 @@ RC_NORETURN static void supervisor(char *exec, char **argv)
rc_waitpid(health_pid);
syslog(LOG_INFO, "stopping %s, pid %d", exec, child_pid);
nkilled = run_stop_schedule(applet, NULL, NULL, child_pid, 0,
false, false, true);
stopgroup, false, false, true);
if (nkilled < 0)
syslog(LOG_INFO, "Unable to kill %d: %s",
child_pid, strerror(errno));
Expand All @@ -747,7 +750,7 @@ RC_NORETURN static void supervisor(char *exec, char **argv)
alarm(0);
syslog(LOG_INFO, "stopping %s, pid %d", exec, child_pid);
nkilled = run_stop_schedule(applet, NULL, NULL, child_pid, 0,
false, false, true);
stopgroup, false, false, true);
if (nkilled > 0)
syslog(LOG_INFO, "killed %d processes", nkilled);
continue;
Expand Down Expand Up @@ -1018,6 +1021,10 @@ int main(int argc, char **argv)
gid = gr->gr_gid;
break;

case 'G': /* -G */
stopgroup = true;
break;

case 'k':
if (parse_mode(&numask, optarg))
eerrorx("%s: invalid mode `%s'",
Expand Down Expand Up @@ -1225,7 +1232,7 @@ int main(int argc, char **argv)
pid = get_pid(applet, pidfile);
if (pid != -1)
if (do_stop(applet, exec, (const char * const *)argv, pid, uid,
0, false, true) > 0)
0, false, false, true) > 0)
eerrorx("%s: %s is already running", applet, exec);

if (respawn_period > 0 && respawn_delay * respawn_max > respawn_period)
Expand Down
Loading