mirror of
https://github.com/clearlinux/hyperstart.git
synced 2026-09-03 20:21:47 +00:00
Merge pull request #13 from gao-feng/stderr
add support of separate stderr output of container
This commit is contained in:
@@ -220,6 +220,7 @@ void hyper_event_hup(struct hyper_event *de, int efd)
|
||||
if (epoll_ctl(efd, EPOLL_CTL_DEL, de->fd, NULL) < 0)
|
||||
perror("epoll_ctl del epoll event failed");
|
||||
close(de->fd);
|
||||
de->fd = -1;
|
||||
hyper_reset_event(de);
|
||||
}
|
||||
|
||||
|
||||
+68
-10
@@ -36,18 +36,25 @@ static void pts_hup(struct hyper_event *de, int efd)
|
||||
hyper_set_be32(buf->data + buf->get + 8, 12);
|
||||
buf->get += 12;
|
||||
|
||||
if (buf->get + 12 > buf->size) {
|
||||
fprintf(stdout, "%s: tty buf full (for stderr)\n", __func__);
|
||||
} else {
|
||||
/* no in event, no more data, send eof in stderr */
|
||||
hyper_set_be64(buf->data + buf->get, exec->errseq);
|
||||
hyper_set_be32(buf->data + buf->get + 8, 12);
|
||||
buf->get += 12;
|
||||
}
|
||||
|
||||
hyper_modify_event(ctl.efd, &ctl.tty, EPOLLIN | EPOLLOUT);
|
||||
|
||||
hyper_release_exec(exec, pod);
|
||||
}
|
||||
|
||||
static int pts_loop(struct hyper_event *de)
|
||||
static int pts_loop(struct hyper_event *de, uint64_t seq)
|
||||
{
|
||||
int size = -1;
|
||||
struct hyper_buf *buf = &ctl.tty.wbuf;
|
||||
struct hyper_exec *exec = container_of(de, struct hyper_exec, e);
|
||||
|
||||
fprintf(stdout, "%s\n", __func__);
|
||||
while ((buf->get + 12 < buf->size) && size) {
|
||||
size = read(de->fd, buf->data + buf->get + 12, buf->size - buf->get - 12);
|
||||
fprintf(stdout, "%s: read %d data\n", __func__, size);
|
||||
@@ -63,11 +70,9 @@ static int pts_loop(struct hyper_event *de)
|
||||
break;
|
||||
}
|
||||
|
||||
hyper_set_be64(buf->data + buf->get, exec->seq);
|
||||
hyper_set_be64(buf->data + buf->get, seq);
|
||||
hyper_set_be32(buf->data + buf->get + 8, size + 12);
|
||||
buf->get += size + 12;
|
||||
|
||||
dprintf("%s: seq %" PRIu64" len %" PRIu32"\n", __func__, exec->seq, size);
|
||||
}
|
||||
|
||||
if (hyper_modify_event(ctl.efd, &ctl.tty, EPOLLIN | EPOLLOUT) < 0) {
|
||||
@@ -78,14 +83,37 @@ static int pts_loop(struct hyper_event *de)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stdout_loop(struct hyper_event *de)
|
||||
{
|
||||
struct hyper_exec *exec = container_of(de, struct hyper_exec, e);
|
||||
fprintf(stdout, "%s, seq %" PRIu64"\n", __func__, exec->seq);
|
||||
|
||||
return pts_loop(de, exec->seq);
|
||||
}
|
||||
|
||||
struct hyper_event_ops pts_ops = {
|
||||
.read = pts_loop,
|
||||
.read = stdout_loop,
|
||||
.hup = pts_hup,
|
||||
.write = hyper_event_write,
|
||||
.wbuf_size = 512,
|
||||
/* don't need read buff, the pts data will store in tty buffer */
|
||||
};
|
||||
|
||||
static int stderr_loop(struct hyper_event *de)
|
||||
{
|
||||
struct hyper_exec *exec = container_of(de, struct hyper_exec, errev);
|
||||
fprintf(stdout, "%s, seq %" PRIu64"\n", __func__, exec->errseq);
|
||||
|
||||
return pts_loop(de, exec->errseq);
|
||||
}
|
||||
|
||||
struct hyper_event_ops err_ops = {
|
||||
/* don't need to deal with hup, the hup will be dealed by pts*/
|
||||
.read = stderr_loop,
|
||||
/* don't need read buff, the stderr data will store in tty buffer */
|
||||
/* don't need write buff, the stderr data is one way */
|
||||
};
|
||||
|
||||
int hyper_setup_exec_tty(struct hyper_exec *e)
|
||||
{
|
||||
int unlock = 0;
|
||||
@@ -94,6 +122,16 @@ int hyper_setup_exec_tty(struct hyper_exec *e)
|
||||
if (e->seq == 0)
|
||||
return 0;
|
||||
|
||||
if (e->errseq > 0) {
|
||||
int errpipe[2];
|
||||
if (pipe2(errpipe, O_NONBLOCK|O_CLOEXEC) < 0) {
|
||||
fprintf(stderr, "creating stderr pipe failed\n");
|
||||
return -1;
|
||||
}
|
||||
e->errev.fd = errpipe[0];
|
||||
e->errfd = errpipe[1];
|
||||
}
|
||||
|
||||
if (e->id) {
|
||||
if (sprintf(path, "/tmp/hyper/%s/devpts/", e->id) < 0) {
|
||||
fprintf(stderr, "get ptmx path failed\n");
|
||||
@@ -179,9 +217,16 @@ int hyper_dup_exec_tty(int to, struct hyper_exec *e)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dup2(fd, STDERR_FILENO) < 0) {
|
||||
perror("dup tty device to stderr failed");
|
||||
goto out;
|
||||
if (e->errseq > 0) {
|
||||
if (dup2(e->errfd, STDERR_FILENO) < 0) {
|
||||
perror("dup err pipe to stderr failed");
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (dup2(fd, STDERR_FILENO) < 0) {
|
||||
perror("dup tty device to stderr failed");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
@@ -205,6 +250,15 @@ int hyper_watch_exec_pty(struct hyper_exec *exec, struct hyper_pod *pod)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (exec->errseq == 0)
|
||||
return 0;
|
||||
|
||||
if (hyper_init_event(&exec->errev, &err_ops, NULL) < 0 ||
|
||||
hyper_add_event(ctl.efd, &exec->errev, EPOLLIN) < 0) {
|
||||
fprintf(stderr, "add container stderr event failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -447,8 +501,12 @@ int hyper_release_exec(struct hyper_exec *exec,
|
||||
/* exec has no pty or the pty user already exited */
|
||||
fprintf(stdout, "last user of exec exit, release\n");
|
||||
close(exec->e.fd);
|
||||
close(exec->errev.fd);
|
||||
close(exec->ptyfd);
|
||||
close(exec->errfd);
|
||||
|
||||
hyper_reset_event(&exec->e);
|
||||
hyper_reset_event(&exec->errev);
|
||||
|
||||
list_del_init(&exec->list);
|
||||
|
||||
|
||||
@@ -7,14 +7,17 @@
|
||||
struct hyper_exec {
|
||||
struct list_head list;
|
||||
struct hyper_event e;
|
||||
struct hyper_event errev;
|
||||
char *id;
|
||||
char **argv;
|
||||
int argc;
|
||||
uint64_t seq;
|
||||
uint64_t errseq;
|
||||
int pid;
|
||||
int ptyno;
|
||||
int init;
|
||||
int ptyfd;
|
||||
int errfd;
|
||||
uint8_t code;
|
||||
uint8_t exit;
|
||||
};
|
||||
|
||||
@@ -228,6 +228,10 @@ static int hyper_parse_container(struct hyper_pod *pod, struct hyper_container *
|
||||
i++;
|
||||
c->exec.seq = json_token_ll(json, &toks[i]);
|
||||
fprintf(stdout, "container seq %" PRIu64 "\n", c->exec.seq);
|
||||
} else if (json_token_streq(json, t, "stderr") && t->size == 1) {
|
||||
i++;
|
||||
c->exec.errseq = json_token_ll(json, &toks[i]);
|
||||
fprintf(stdout, "container stderr seq %" PRIu64 "\n", c->exec.errseq);
|
||||
} else if (json_token_streq(json, t, "workdir") && t->size == 1) {
|
||||
i++;
|
||||
c->workdir = strdup(json_token_str(json, &toks[i]));
|
||||
|
||||
Reference in New Issue
Block a user