[#97] Tear down exec commands properly

This commit is contained in:
Radon Rosborough 2021-08-20 20:55:41 -07:00
parent b6a45414e4
commit 2a65f7772d
2 changed files with 53 additions and 13 deletions

View File

@ -36,12 +36,20 @@ while read -t2 -r cmdline; do
stdout="/var/cache/riju/share/cmd-${uuid}-stdout" stdout="/var/cache/riju/share/cmd-${uuid}-stdout"
stderr="/var/cache/riju/share/cmd-${uuid}-stderr" stderr="/var/cache/riju/share/cmd-${uuid}-stderr"
status="/var/cache/riju/share/cmd-${uuid}-status" status="/var/cache/riju/share/cmd-${uuid}-status"
mkfifo "${stdin}" "${stdout}" "${stderr}" "${status}" live="/var/cache/riju/share/cmd-${uuid}-live"
mkfifo "${stdin}" "${stdout}" "${stderr}" "${status}" "${live}"
( (
set +e set +e
runuser -u riju -- bash -c "exec ${maybe_pty:-} \"\$@\"" -- "${args[@]}" < "${stdin}" > "${stdout}" 2> "${stderr}" (
echo "$?" > "${status}" runuser -u riju -- bash -c "exec ${maybe_pty:-} \"\$@\"" -- "${args[@]}" < "${stdin}" > "${stdout}" 2> "${stderr}"
echo "$?"
) > "${status}"
) & ) &
bg=$!
while kill -0 "$bg" 2>/dev/null; do
sleep 1
echo "ping" 2>/dev/null || break
done > "${live}" &
fi fi
;; ;;
*) *)

View File

@ -119,12 +119,19 @@ char *parseImageHash(char *imageHash)
char *timeout_msg; char *timeout_msg;
void wait_alarm(int signum) void sigalrm_die(int signum)
{ {
(void)signum; (void)signum;
die(timeout_msg); die(timeout_msg);
} }
void sigalrm_kill_parent(int signum)
{
(void)signum;
kill(getppid(), SIGTERM);
exit(EXIT_FAILURE);
}
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)
@ -252,7 +259,7 @@ void session(char *uuid, char *lang, char *imageHash)
ts_10ms.tv_sec = 0; ts_10ms.tv_sec = 0;
ts_10ms.tv_nsec = 1000 * 1000 * 10; ts_10ms.tv_nsec = 1000 * 1000 * 10;
timeout_msg = "container did not come up within 10 seconds"; timeout_msg = "container did not come up within 10 seconds";
if (signal(SIGALRM, wait_alarm) == SIG_ERR) if (signal(SIGALRM, sigalrm_die) == SIG_ERR)
die("signal failed"); die("signal failed");
alarm(10); alarm(10);
int fd; int fd;
@ -287,7 +294,7 @@ 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, *stdinFIFO, *stdoutFIFO, *stderrFIFO, *statusFIFO, char *share, *ctlFIFO, *stdinFIFO, *stdoutFIFO, *stderrFIFO, *statusFIFO,
*ctlCmd, *dataFIFO; *liveFIFO, *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)
@ -301,6 +308,8 @@ void exec(char *uuid, int argc, char **cmdline, bool pty)
die("asprintf failed"); die("asprintf failed");
if (asprintf(&statusFIFO, "%s/cmd-%s-status", share, procUUID) < 0) if (asprintf(&statusFIFO, "%s/cmd-%s-status", share, procUUID) < 0)
die("asprintf failed"); die("asprintf failed");
if (asprintf(&liveFIFO, "%s/cmd-%s-live", 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");
@ -352,15 +361,24 @@ void exec(char *uuid, int argc, char **cmdline, bool pty)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
dataFIFO = stderrFIFO; dataFIFO = stderrFIFO;
} else { } else {
dataFIFO = statusFIFO; pid = fork();
if (pid < 0)
die("fork failed");
else if (pid == 0) {
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
die("prctl failed");
if (getppid() != orig_ppid)
exit(EXIT_FAILURE);
dataFIFO = liveFIFO;
} else {
dataFIFO = statusFIFO;
}
} }
} }
} }
if (dataFIFO != statusFIFO) { if (signal(SIGALRM, sigalrm_die) == SIG_ERR)
if (signal(SIGALRM, wait_alarm) == SIG_ERR) die("signal failed");
die("signal failed"); alarm(1);
alarm(1);
}
while (1) { while (1) {
int mode = dataFIFO == stdinFIFO ? O_WRONLY : O_RDONLY; int mode = dataFIFO == stdinFIFO ? O_WRONLY : O_RDONLY;
fd = open(dataFIFO, mode); fd = open(dataFIFO, mode);
@ -403,7 +421,7 @@ void exec(char *uuid, int argc, char **cmdline, bool pty)
} }
if (len < 0) if (len < 0)
die("read failed"); die("read failed");
} else { } else if (dataFIFO == statusFIFO) {
if (close(STDIN_FILENO) < 0) if (close(STDIN_FILENO) < 0)
die("close failed"); die("close failed");
if (close(STDOUT_FILENO) < 0) if (close(STDOUT_FILENO) < 0)
@ -422,6 +440,20 @@ void exec(char *uuid, int argc, char **cmdline, bool pty)
if (*endptr != '\n') if (*endptr != '\n')
die("strtol failed"); die("strtol failed");
exit(status); exit(status);
} else if (dataFIFO == liveFIFO) {
char line[1024];
int len;
timeout_msg = "container died";
if (signal(SIGALRM, sigalrm_kill_parent) < 0)
die("signal failed");
if (alarm(2) < 0)
die("alarm failed");
while ((len = read(fd, line, 1024)) > 0) {
if (alarm(2) < 0)
die("alarm failed");
}
if (len < 0)
die("read failed");
} }
} }