Pass back the pid of runc:[1:CHILD] so we can wait on it
This allows the libcontainer to automatically clean up runc:[1:CHILD] processes created as part of nsenter. Signed-off-by: Alex Fang <littlelightlittlefire@gmail.com>
This commit is contained in:
parent
45bde006ca
commit
e92add2151
|
@ -31,7 +31,8 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type pid struct {
|
type pid struct {
|
||||||
Pid int `json:"pid"`
|
Pid int `json:"pid"`
|
||||||
|
PidFirstChild int `json:"pid_first"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// network is an internal struct used to setup container networks.
|
// network is an internal struct used to setup container networks.
|
||||||
|
|
|
@ -542,7 +542,7 @@ void nsexec(void)
|
||||||
*/
|
*/
|
||||||
case JUMP_PARENT: {
|
case JUMP_PARENT: {
|
||||||
int len;
|
int len;
|
||||||
pid_t child;
|
pid_t child, first_child = -1;
|
||||||
char buf[JSON_MAX];
|
char buf[JSON_MAX];
|
||||||
bool ready = false;
|
bool ready = false;
|
||||||
|
|
||||||
|
@ -606,18 +606,18 @@ void nsexec(void)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SYNC_RECVPID_PLS: {
|
case SYNC_RECVPID_PLS: {
|
||||||
pid_t old = child;
|
first_child = child;
|
||||||
|
|
||||||
/* Get the init_func pid. */
|
/* Get the init_func pid. */
|
||||||
if (read(syncfd, &child, sizeof(child)) != sizeof(child)) {
|
if (read(syncfd, &child, sizeof(child)) != sizeof(child)) {
|
||||||
kill(old, SIGKILL);
|
kill(first_child, SIGKILL);
|
||||||
bail("failed to sync with child: read(childpid)");
|
bail("failed to sync with child: read(childpid)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send ACK. */
|
/* Send ACK. */
|
||||||
s = SYNC_RECVPID_ACK;
|
s = SYNC_RECVPID_ACK;
|
||||||
if (write(syncfd, &s, sizeof(s)) != sizeof(s)) {
|
if (write(syncfd, &s, sizeof(s)) != sizeof(s)) {
|
||||||
kill(old, SIGKILL);
|
kill(first_child, SIGKILL);
|
||||||
kill(child, SIGKILL);
|
kill(child, SIGKILL);
|
||||||
bail("failed to sync with child: write(SYNC_RECVPID_ACK)");
|
bail("failed to sync with child: write(SYNC_RECVPID_ACK)");
|
||||||
}
|
}
|
||||||
|
@ -665,8 +665,13 @@ void nsexec(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send the init_func pid back to our parent. */
|
/*
|
||||||
len = snprintf(buf, JSON_MAX, "{\"pid\": %d}\n", child);
|
* Send the init_func pid and the pid of the first child back to our parent.
|
||||||
|
*
|
||||||
|
* We need to send both back because we can't reap the first child we created (CLONE_PARENT).
|
||||||
|
* It becomes the responsibility of our parent to reap the first child.
|
||||||
|
*/
|
||||||
|
len = snprintf(buf, JSON_MAX, "{\"pid\": %d, \"pid_first\": %d}\n", child, first_child);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
kill(child, SIGKILL);
|
kill(child, SIGKILL);
|
||||||
bail("unable to generate JSON for child pid");
|
bail("unable to generate JSON for child pid");
|
||||||
|
|
|
@ -141,6 +141,16 @@ func (p *setnsProcess) execSetns() error {
|
||||||
p.cmd.Wait()
|
p.cmd.Wait()
|
||||||
return newSystemErrorWithCause(err, "reading pid from init pipe")
|
return newSystemErrorWithCause(err, "reading pid from init pipe")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clean up the zombie parent process
|
||||||
|
firstChildProcess, err := os.FindProcess(pid.PidFirstChild)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore the error in case the child has already been reaped for any reason
|
||||||
|
_, _ = firstChildProcess.Wait()
|
||||||
|
|
||||||
process, err := os.FindProcess(pid.Pid)
|
process, err := os.FindProcess(pid.Pid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -224,6 +234,16 @@ func (p *initProcess) execSetns() error {
|
||||||
p.cmd.Wait()
|
p.cmd.Wait()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clean up the zombie parent process
|
||||||
|
firstChildProcess, err := os.FindProcess(pid.PidFirstChild)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore the error in case the child has already been reaped for any reason
|
||||||
|
_, _ = firstChildProcess.Wait()
|
||||||
|
|
||||||
process, err := os.FindProcess(pid.Pid)
|
process, err := os.FindProcess(pid.Pid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Reference in New Issue