fixup! conmon: Don't leave zombies and fix cgroup race

Signed-off-by: Alexander Larsson <alexl@redhat.com>
This commit is contained in:
Alexander Larsson 2017-06-20 12:18:07 +02:00
parent af4fbcd942
commit 72686c78b4
2 changed files with 31 additions and 62 deletions

View file

@ -675,8 +675,10 @@ static gboolean terminal_accept_cb(int fd, G_GNUC_UNUSED GIOCondition condition,
ninfo("about to accept from csfd: %d", fd); ninfo("about to accept from csfd: %d", fd);
connfd = accept4(fd, NULL, NULL, SOCK_CLOEXEC); connfd = accept4(fd, NULL, NULL, SOCK_CLOEXEC);
if (connfd < 0) if (connfd < 0) {
pexit("Failed to accept console-socket connection"); nwarn("Failed to accept console-socket connection");
return G_SOURCE_CONTINUE;
}
/* Not accepting anything else. */ /* Not accepting anything else. */
close(fd); close(fd);
@ -693,7 +695,6 @@ static gboolean terminal_accept_cb(int fd, G_GNUC_UNUSED GIOCondition condition,
* stdout. stderr is ignored. */ * stdout. stderr is ignored. */
masterfd_stdin = console.fd; masterfd_stdin = console.fd;
masterfd_stdout = console.fd; masterfd_stdout = console.fd;
masterfd_stderr = -1;
/* Clean up everything */ /* Clean up everything */
close(connfd); close(connfd);
@ -738,6 +739,7 @@ int main(int argc, char *argv[])
GPtrArray *runtime_argv = NULL; GPtrArray *runtime_argv = NULL;
_cleanup_close_ int dev_null_r = -1; _cleanup_close_ int dev_null_r = -1;
_cleanup_close_ int dev_null_w = -1; _cleanup_close_ int dev_null_w = -1;
int fds[2];
_cleanup_free_ char *memory_cgroup_path = NULL; _cleanup_free_ char *memory_cgroup_path = NULL;
int wb; int wb;
@ -886,7 +888,6 @@ int main(int argc, char *argv[])
if (listen(csfd, 128) < 0) if (listen(csfd, 128) < 0)
pexit("Failed to listen on console-socket"); pexit("Failed to listen on console-socket");
} else { } else {
int fds[2];
/* /*
* Create a "fake" master fd so that we can use the same epoll code in * Create a "fake" master fd so that we can use the same epoll code in
@ -911,14 +912,16 @@ int main(int argc, char *argv[])
masterfd_stdout = fds[0]; masterfd_stdout = fds[0];
slavefd_stdout = fds[1]; slavefd_stdout = fds[1];
if (pipe2(fds, O_CLOEXEC) < 0)
pexit("Failed to create !terminal stderr pipe");
masterfd_stderr = fds[0];
slavefd_stderr = fds[1];
} }
/* We always create a stderr pipe, because that way we can capture
runc stderr messages before the tty is created */
if (pipe2(fds, O_CLOEXEC) < 0)
pexit("Failed to create stderr pipe");
masterfd_stderr = fds[0];
slavefd_stderr = fds[1];
runtime_argv = g_ptr_array_new(); runtime_argv = g_ptr_array_new();
g_ptr_array_add(runtime_argv, runtime_path); g_ptr_array_add(runtime_argv, runtime_path);
@ -1012,32 +1015,21 @@ int main(int argc, char *argv[])
if (!WIFEXITED(runtime_status) || WEXITSTATUS(runtime_status) != 0) { if (!WIFEXITED(runtime_status) || WEXITSTATUS(runtime_status) != 0) {
if (sync_pipe_fd > 0 && !exec) { if (sync_pipe_fd > 0 && !exec) {
if (terminal) { /*
/* * Read from container stderr for any error and send it to parent
* For this case, the stderr is captured in the parent when terminal is passed down. * We send -1 as pid to signal to parent that create container has failed.
* We send -1 as pid to signal to parent that create container has failed. */
*/ num_read = read(masterfd_stderr, buf, BUF_SIZE);
len = snprintf(buf, BUF_SIZE, "{\"pid\": %d}\n", -1); if (num_read > 0) {
_cleanup_free_ char *escaped_message = NULL;
ssize_t len;
buf[num_read] = '\0';
escaped_message = escape_json_string(buf);
len = snprintf(buf, BUF_SIZE, "{\"pid\": %d, \"message\": \"%s\"}\n", -1, escaped_message);
if (len < 0 || write_all(sync_pipe_fd, buf, len) != len) { if (len < 0 || write_all(sync_pipe_fd, buf, len) != len) {
pexit("unable to send container pid to parent"); ninfo("Unable to send container stderr message to parent");
}
} else {
/*
* Read from container stderr for any error and send it to parent
* We send -1 as pid to signal to parent that create container has failed.
*/
num_read = read(masterfd_stderr, buf, BUF_SIZE);
if (num_read > 0) {
_cleanup_free_ char *escaped_message = NULL;
ssize_t len;
buf[num_read] = '\0';
escaped_message = escape_json_string(buf);
len = snprintf(buf, BUF_SIZE, "{\"pid\": %d, \"message\": \"%s\"}\n", -1, escaped_message);
if (len < 0 || write_all(sync_pipe_fd, buf, len) != len) {
ninfo("Unable to send container stderr message to parent");
}
} }
} }
} }
@ -1045,7 +1037,7 @@ int main(int argc, char *argv[])
} }
if (terminal && masterfd_stdout == -1) if (terminal && masterfd_stdout == -1)
pexit("Runtime did not set up terminal"); nexit("Runtime did not set up terminal");
/* Read the pid so we can wait for the process to exit */ /* Read the pid so we can wait for the process to exit */
g_file_get_contents(pid_file, &contents, NULL, &err); g_file_get_contents(pid_file, &contents, NULL, &err);

View file

@ -200,21 +200,10 @@ func (r *Runtime) CreateContainer(c *Container, cgroupParent string) error {
return fmt.Errorf("error reading container (probably exited) json message: %v", ss.err) return fmt.Errorf("error reading container (probably exited) json message: %v", ss.err)
} }
logrus.Debugf("Received container pid: %d", ss.si.Pid) logrus.Debugf("Received container pid: %d", ss.si.Pid)
errorMessage := ""
if c.terminal {
errorMessage = stderrBuf.String()
fmt.Fprintf(os.Stderr, errorMessage)
errorMessage = sanitizeConmonErrorMessage(errorMessage)
} else {
if ss.si.Message != "" {
errorMessage = ss.si.Message
}
}
if ss.si.Pid == -1 { if ss.si.Pid == -1 {
if errorMessage != "" { if ss.si.Message != "" {
logrus.Debugf("Container creation error: %s", errorMessage) logrus.Debugf("Container creation error: %s", ss.si.Message)
return fmt.Errorf("container create failed: %s", errorMessage) return fmt.Errorf("container create failed: %s", ss.si.Message)
} }
logrus.Debugf("Container creation failed") logrus.Debugf("Container creation failed")
return fmt.Errorf("container create failed") return fmt.Errorf("container create failed")
@ -225,18 +214,6 @@ func (r *Runtime) CreateContainer(c *Container, cgroupParent string) error {
return nil return nil
} }
// sanitizeConmonErrorMessage removes conmon debug messages from error string
func sanitizeConmonErrorMessage(errString string) string {
var sanitizedLines []string
lines := strings.Split(errString, "\n")
for _, line := range lines {
if !strings.HasPrefix(line, "[conmon") {
sanitizedLines = append(sanitizedLines, line)
}
}
return strings.Join(sanitizedLines, "\n")
}
func createUnitName(prefix string, name string) string { func createUnitName(prefix string, name string) string {
return fmt.Sprintf("%s-%s.scope", prefix, name) return fmt.Sprintf("%s-%s.scope", prefix, name)
} }