Report exit status from sentinel via FIFO
This commit is contained in:
parent
50ade82e81
commit
f8faba0c8f
|
@ -30,8 +30,13 @@ while read -t2 -r cmdline; do
|
||||||
args=("${cmd[@]:2}")
|
args=("${cmd[@]:2}")
|
||||||
input="/var/cache/riju/share/cmd-${uuid}-input"
|
input="/var/cache/riju/share/cmd-${uuid}-input"
|
||||||
output="/var/cache/riju/share/cmd-${uuid}-output"
|
output="/var/cache/riju/share/cmd-${uuid}-output"
|
||||||
mkfifo "${input}" "${output}"
|
status="/var/cache/riju/share/cmd-${uuid}-status"
|
||||||
${maybe_pty:-} runuser -u riju -- bash -c 'exec "$@"' sentinel "${args[@]}" < "${input}" &> "${output}" &
|
mkfifo "${input}" "${output}" "${status}"
|
||||||
|
(
|
||||||
|
set +e
|
||||||
|
${maybe_pty:-} runuser -u riju -- bash -c 'exec "$@"' sentinel "${args[@]}" < "${input}" &> "${output}"
|
||||||
|
echo "$?" > "${status}"
|
||||||
|
) &
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
|
|
@ -122,6 +122,16 @@ void wait_alarm(int signum)
|
||||||
die(timeout_msg);
|
die(timeout_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wait_alarm_group(int signum)
|
||||||
|
{
|
||||||
|
(void)signum;
|
||||||
|
if (signal(SIGTERM, SIG_IGN) == SIG_ERR)
|
||||||
|
die("signal failed");
|
||||||
|
if (kill(0, SIGTERM) < 0)
|
||||||
|
die("kill failed");
|
||||||
|
die(timeout_msg);
|
||||||
|
}
|
||||||
|
|
||||||
void session(char *uuid, char *lang, char *imageHash)
|
void session(char *uuid, char *lang, char *imageHash)
|
||||||
{
|
{
|
||||||
if (setvbuf(stdout, NULL, _IONBF, 0) != 0)
|
if (setvbuf(stdout, NULL, _IONBF, 0) != 0)
|
||||||
|
@ -278,7 +288,8 @@ void exec(char *uuid, int argc, char **cmdline, bool pty)
|
||||||
{
|
{
|
||||||
if (setvbuf(stdout, NULL, _IONBF, 0) != 0)
|
if (setvbuf(stdout, NULL, _IONBF, 0) != 0)
|
||||||
die("setvbuf failed");
|
die("setvbuf failed");
|
||||||
char *share, *ctlFIFO, *inputFIFO, *outputFIFO, *ctlCmd, *dataFIFO;
|
char *share, *ctlFIFO, *inputFIFO, *outputFIFO, *statusFIFO, *ctlCmd,
|
||||||
|
*dataFIFO;
|
||||||
if (asprintf(&share, "/var/cache/riju/shares/%s", uuid) < 0)
|
if (asprintf(&share, "/var/cache/riju/shares/%s", uuid) < 0)
|
||||||
die("asprintf failed");
|
die("asprintf failed");
|
||||||
if (asprintf(&ctlFIFO, "%s/control", share) < 0)
|
if (asprintf(&ctlFIFO, "%s/control", share) < 0)
|
||||||
|
@ -288,6 +299,8 @@ void exec(char *uuid, int argc, char **cmdline, bool pty)
|
||||||
die("asprintf failed");
|
die("asprintf failed");
|
||||||
if (asprintf(&outputFIFO, "%s/cmd-%s-output", share, procUUID) < 0)
|
if (asprintf(&outputFIFO, "%s/cmd-%s-output", share, procUUID) < 0)
|
||||||
die("asprintf failed");
|
die("asprintf failed");
|
||||||
|
if (asprintf(&statusFIFO, "%s/cmd-%s-status", share, procUUID) < 0)
|
||||||
|
die("asprintf failed");
|
||||||
int fd = open(ctlFIFO, O_WRONLY);
|
int fd = open(ctlFIFO, O_WRONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
die("open failed");
|
die("open failed");
|
||||||
|
@ -304,25 +317,33 @@ void exec(char *uuid, int argc, char **cmdline, bool pty)
|
||||||
if (len_written < 0)
|
if (len_written < 0)
|
||||||
die("write failed");
|
die("write failed");
|
||||||
close(fd);
|
close(fd);
|
||||||
|
if (setpgrp() < 0)
|
||||||
|
die("setpgrp failed");
|
||||||
|
timeout_msg = "sentinel did not set up FIFOs within 1 second";
|
||||||
struct timespec ts_10ms;
|
struct timespec ts_10ms;
|
||||||
ts_10ms.tv_sec = 0;
|
ts_10ms.tv_sec = 0;
|
||||||
ts_10ms.tv_nsec = 1000 * 1000 * 10;
|
ts_10ms.tv_nsec = 1000 * 1000 * 10;
|
||||||
int mode;
|
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid < 0)
|
if (pid < 0)
|
||||||
die("fork failed");
|
die("fork failed");
|
||||||
else if (pid == 0) {
|
else if (pid == 0) {
|
||||||
dataFIFO = inputFIFO;
|
dataFIFO = inputFIFO;
|
||||||
timeout_msg = "sentinel did not set up input FIFO within 1 second";
|
|
||||||
mode = O_WRONLY;
|
|
||||||
} else {
|
} else {
|
||||||
|
pid = fork();
|
||||||
|
if (pid < 0)
|
||||||
|
die("fork failed");
|
||||||
|
else if (pid == 0) {
|
||||||
dataFIFO = outputFIFO;
|
dataFIFO = outputFIFO;
|
||||||
timeout_msg = "sentinel did not set up output FIFO within 1 second";
|
} else {
|
||||||
mode = O_RDONLY;
|
dataFIFO = statusFIFO;
|
||||||
}
|
}
|
||||||
signal(SIGALRM, wait_alarm);
|
}
|
||||||
|
if (dataFIFO != statusFIFO) {
|
||||||
|
signal(SIGALRM, wait_alarm_group);
|
||||||
alarm(1);
|
alarm(1);
|
||||||
|
}
|
||||||
while (1) {
|
while (1) {
|
||||||
|
int mode = dataFIFO == inputFIFO ? O_WRONLY : O_RDONLY;
|
||||||
fd = open(dataFIFO, mode);
|
fd = open(dataFIFO, mode);
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
break;
|
break;
|
||||||
|
@ -334,7 +355,7 @@ void exec(char *uuid, int argc, char **cmdline, bool pty)
|
||||||
}
|
}
|
||||||
signal(SIGALRM, SIG_IGN);
|
signal(SIGALRM, SIG_IGN);
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
if (pid == 0) {
|
if (dataFIFO == inputFIFO) {
|
||||||
while ((len = read(STDIN_FILENO, buf, 1024)) > 0) {
|
while ((len = read(STDIN_FILENO, buf, 1024)) > 0) {
|
||||||
char *ptr = buf;
|
char *ptr = buf;
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
|
@ -345,7 +366,9 @@ void exec(char *uuid, int argc, char **cmdline, bool pty)
|
||||||
ptr += len_written;
|
ptr += len_written;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
if (len < 0)
|
||||||
|
die("read failed");
|
||||||
|
} else if (dataFIFO == outputFIFO) {
|
||||||
while ((len = read(fd, buf, 1024)) > 0) {
|
while ((len = read(fd, buf, 1024)) > 0) {
|
||||||
fwrite(buf, 1, len, stdout);
|
fwrite(buf, 1, len, stdout);
|
||||||
if (ferror(stdout))
|
if (ferror(stdout))
|
||||||
|
@ -353,9 +376,28 @@ void exec(char *uuid, int argc, char **cmdline, bool pty)
|
||||||
if (feof(stdout))
|
if (feof(stdout))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (len < 0)
|
||||||
|
die("read failed");
|
||||||
|
} else {
|
||||||
|
char line[1024];
|
||||||
|
char *ptr = line;
|
||||||
|
int len;
|
||||||
|
while ((len = read(fd, ptr, 1023 - (ptr - line))) > 0) {
|
||||||
|
ptr += len;
|
||||||
}
|
}
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
die("read failed");
|
die("read failed");
|
||||||
|
*ptr = '\0';
|
||||||
|
char *endptr;
|
||||||
|
long status = strtol(line, &endptr, 10);
|
||||||
|
if (*endptr != '\n')
|
||||||
|
die("strtol failed");
|
||||||
|
if (signal(SIGTERM, SIG_IGN) == SIG_ERR)
|
||||||
|
die("signal failed");
|
||||||
|
if (kill(0, SIGTERM) < 0)
|
||||||
|
die("kill failed");
|
||||||
|
exit(status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
|
|
Loading…
Reference in New Issue