Skip to content

Commit

Permalink
Merge pull request opencontainers#1154 from hqhq/sync_child
Browse files Browse the repository at this point in the history
Sync with grandchild
  • Loading branch information
dqminh authored Nov 23, 2016
2 parents a6e649f + 16a2e8b commit f156f73
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions libcontainer/nsenter/nsexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ enum sync_t {
SYNC_USERMAP_ACK = 0x41, /* Mapping finished by the parent. */
SYNC_RECVPID_PLS = 0x42, /* Tell parent we're sending the PID. */
SYNC_RECVPID_ACK = 0x43, /* PID was correctly received by parent. */
SYNC_CHILD_READY = 0x44, /* The grandchild is ready to return. */

/* XXX: This doesn't help with segfaults and other such issues. */
SYNC_ERR = 0xFF, /* Fatal error, no turning back. The error code follows. */
Expand Down Expand Up @@ -500,7 +501,7 @@ void nsexec(void)
* process.
*/
case JUMP_PARENT: {
int len;
int len, ready = 0;
pid_t child;
char buf[JSON_MAX];

Expand All @@ -512,8 +513,14 @@ void nsexec(void)
if (child < 0)
bail("unable to fork: child_func");

/* State machine for synchronisation with the children. */
while (true) {
/*
* State machine for synchronisation with the children.
*
* Father only return when both child and grandchild are
* ready, so we can receive all possible error codes
* generated by children.
*/
while (ready < 2) {
enum sync_t s;

/* This doesn't need to be global, we're in the parent. */
Expand Down Expand Up @@ -571,17 +578,22 @@ void nsexec(void)
}
}

/* Leave the loop. */
goto out;
ready++;
break;
case SYNC_RECVPID_ACK:
/* We should _never_ receive acks. */
kill(child, SIGKILL);
bail("failed to sync with child: unexpected SYNC_RECVPID_ACK");
break;
case SYNC_CHILD_READY:
ready++;
break;
default:
bail("unexpected sync value");
break;
}
}

out:
/* Send the init_func pid back to our parent. */
len = snprintf(buf, JSON_MAX, "{\"pid\": %d}\n", child);
if (len < 0) {
Expand Down Expand Up @@ -711,6 +723,7 @@ void nsexec(void)
* start_child() code after forking in the parent.
*/
int consolefd = config.consolefd;
enum sync_t s;

/* We're in a child and thus need to tell the parent if we die. */
syncfd = syncpipe[0];
Expand Down Expand Up @@ -741,6 +754,10 @@ void nsexec(void)
bail("failed to dup stderr");
}

s = SYNC_CHILD_READY;
if (write(syncfd, &s, sizeof(s)) != sizeof(s))
bail("failed to sync with patent: write(SYNC_CHILD_READY)");

/* Close sync pipes. */
close(syncpipe[0]);
close(syncpipe[1]);
Expand Down

0 comments on commit f156f73

Please sign in to comment.