Skip to content

Commit a6d66bf

Browse files
committed
supervise-daemon: add s6-style readiness notification.
1 parent da04d1c commit a6d66bf

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

sh/supervise-daemon.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ supervise_start()
4343
${no_new_privs:+--no-new-privs} \
4444
${command_user+--user} $command_user \
4545
${umask+--umask} $umask \
46+
${ready+--ready} $ready \
4647
${supervise_daemon_args-${start_stop_daemon_args}} \
4748
$command \
4849
-- $command_args $command_args_foreground

src/supervise-daemon/supervise-daemon.c

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ enum {
8282
LONGOPT_SECBITS,
8383
LONGOPT_STDERR_LOGGER,
8484
LONGOPT_STDOUT_LOGGER,
85+
LONGOPT_READY,
8586
};
8687

8788
const char *applet = NULL;
@@ -115,6 +116,7 @@ const struct option longopts[] = {
115116
{ "stderr", 1, NULL, '2'},
116117
{ "stdout-logger",1, NULL, LONGOPT_STDOUT_LOGGER},
117118
{ "stderr-logger",1, NULL, LONGOPT_STDERR_LOGGER},
119+
{ "ready", 1, NULL, LONGOPT_READY},
118120
{ "reexec", 0, NULL, '3'},
119121
longopts_COMMON
120122
};
@@ -165,6 +167,8 @@ static int devnull_fd = -1;
165167
static int stdin_fd;
166168
static int stdout_fd;
167169
static int stderr_fd;
170+
static int ready_fd = -1;
171+
static int ready_pipe[2];
168172
static char *redirect_stderr = NULL;
169173
static char *redirect_stdout = NULL;
170174
static char *stderr_process = NULL;
@@ -588,6 +592,9 @@ RC_NORETURN static void child_process(char *exec, char **argv)
588592

589593
cloexec_fds_from(3);
590594

595+
if (ready_fd != -1)
596+
dup2(ready_pipe[1], ready_fd);
597+
591598
cmdline = make_cmdline(argv);
592599
syslog(LOG_INFO, "Child command line: %s", cmdline);
593600
free(cmdline);
@@ -786,6 +793,28 @@ RC_NORETURN static void supervisor(char *exec, char **argv)
786793
exit(EXIT_SUCCESS);
787794
}
788795

796+
static void wait_ready(void)
797+
{
798+
if (ready_fd == -1)
799+
exit(EXIT_SUCCESS);
800+
801+
close(ready_pipe[1]);
802+
/* TODO: add timeout failure and stop child supervisor */
803+
for (;;) {
804+
char buf[BUFSIZ];
805+
int bytes = read(ready_pipe[0], buf, BUFSIZ);
806+
if (bytes == -1 && errno != EINTR) {
807+
eerror("%s: read failed '%s'\n", applet, strerror(errno));
808+
exit(EXIT_FAILURE);
809+
}
810+
811+
if (memchr(buf, '\n', bytes))
812+
break;
813+
}
814+
815+
exit(EXIT_SUCCESS);
816+
}
817+
789818
int main(int argc, char **argv)
790819
{
791820
int opt;
@@ -1068,6 +1097,12 @@ int main(int argc, char **argv)
10681097
stderr_process = optarg;
10691098
break;
10701099

1100+
case LONGOPT_READY:
1101+
if (sscanf(optarg, "fd:%d", &ready_fd) != 1)
1102+
eerrorx("%s: invalid ready '%s'.", applet, optarg);
1103+
pipe(ready_pipe);
1104+
break;
1105+
10711106
case_RC_COMMON_GETOPT
10721107
}
10731108

@@ -1205,19 +1240,25 @@ int main(int argc, char **argv)
12051240
if (child_pid == -1)
12061241
eerrorx("%s: fork: %s", applet, strerror(errno));
12071242
if (child_pid != 0)
1208-
/* first parent process, do nothing. */
1209-
exit(EXIT_SUCCESS);
1243+
wait_ready();
1244+
12101245
#ifdef TIOCNOTTY
12111246
tty_fd = open("/dev/tty", O_RDWR);
12121247
#endif
12131248
devnull_fd = open("/dev/null", O_RDWR);
12141249
dup2(devnull_fd, STDIN_FILENO);
12151250
dup2(devnull_fd, STDOUT_FILENO);
12161251
dup2(devnull_fd, STDERR_FILENO);
1252+
1253+
if (ready_fd != -1)
1254+
close(ready_pipe[0]);
1255+
12171256
child_pid = fork();
12181257
if (child_pid == -1)
12191258
eerrorx("%s: fork: %s", applet, strerror(errno));
12201259
else if (child_pid != 0) {
1260+
if (ready_fd != -1)
1261+
close(ready_pipe[1]);
12211262
c = argv;
12221263
x = 0;
12231264
while (c && *c) {

0 commit comments

Comments
 (0)