commit
f156f73c2a
|
@ -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. */
|
||||
|
@ -500,7 +501,7 @@ void nsexec(void)
|
|||
* process.
|
||||
*/
|
||||
case JUMP_PARENT: {
|
||||
int len;
|
||||
int len, ready = 0;
|
||||
pid_t child;
|
||||
char buf[JSON_MAX];
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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) {
|
||||
|
@ -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];
|
||||
|
@ -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]);
|
||||
|
|
Loading…
Reference in New Issue