Hello community, here is the log from the commit of package conmon for openSUSE:Factory checked in at 2020-01-13 22:15:32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/conmon (Old) and /work/SRC/openSUSE:Factory/.conmon.new.6675 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "conmon" Mon Jan 13 22:15:32 2020 rev:6 rq:761593 version:2.0.9 Changes: -------- --- /work/SRC/openSUSE:Factory/conmon/conmon.changes 2019-11-18 20:05:34.393738046 +0100 +++ /work/SRC/openSUSE:Factory/.conmon.new.6675/conmon.changes 2020-01-13 22:16:09.134368722 +0100 @@ -1,0 +2,39 @@ +Tue Jan 7 12:20:08 UTC 2020 - Sascha Grunert <sgrun...@suse.com> + +- Add TimedOutMessage to config to share with go code +- Fix format string to limit the size of the string to 10 + characters + +------------------------------------------------------------------- +Mon Dec 16 08:41:54 UTC 2019 - Sascha Grunert <sgrun...@suse.com> + +- Persist oom files on cgroup v2 +- Revert the check for the OOM counter on cgroups v1 before + writing OOM file + +------------------------------------------------------------------- +Fri Dec 13 08:23:04 UTC 2019 - Sascha Grunert <sgrun...@suse.com> + +- Add --persist-dir flag to allow important container files to be + written to a persistent directory +- Check OOM counter on cgroups v1 before writing OOM file +- Use splice(2) to copy from stdin + +------------------------------------------------------------------- +Thu Dec 12 11:37:19 UTC 2019 - Sascha Grunert <sgrun...@suse.com> + +- Kill the process group on timeout + +------------------------------------------------------------------- +Wed Dec 11 07:39:29 UTC 2019 - Sascha Grunert <sgrun...@suse.com> + +- Add --persist-dir to allow callers to specify a directory that + conmon should mirror certain important files that should persist + reboots (right now, just the container exit file) + +------------------------------------------------------------------- +Mon Dec 9 17:34:49 UTC 2019 - Sascha Grunert <sgrun...@suse.com> + +- Fix tight loop on OOM + +------------------------------------------------------------------- Old: ---- conmon-2.0.3.tar.xz New: ---- conmon-2.0.9.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ conmon.spec ++++++ --- /var/tmp/diff_new_pack.fbCaVe/_old 2020-01-13 22:16:10.662369430 +0100 +++ /var/tmp/diff_new_pack.fbCaVe/_new 2020-01-13 22:16:10.674369436 +0100 @@ -1,7 +1,7 @@ # # spec file for package conmon # -# Copyright (c) 2019 SUSE LLC. +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: conmon -Version: 2.0.3 +Version: 2.0.9 Release: 0 Summary: An OCI container runtime monitor License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.fbCaVe/_old 2020-01-13 22:16:10.734369464 +0100 +++ /var/tmp/diff_new_pack.fbCaVe/_new 2020-01-13 22:16:10.734369464 +0100 @@ -2,8 +2,8 @@ <service name="tar_scm" mode="disabled"> <param name="url">https://github.com/containers/conmon</param> <param name="scm">git</param> -<param name="versionformat">2.0.3</param> -<param name="revision">v2.0.3</param> +<param name="versionformat">2.0.9</param> +<param name="revision">v2.0.9</param> </service> <service name="recompress" mode="disabled"> <param name="file">conmon-*.tar</param> ++++++ conmon-2.0.3.tar.xz -> conmon-2.0.9.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.3/VERSION new/conmon-2.0.9/VERSION --- old/conmon-2.0.3/VERSION 2019-11-11 16:16:23.000000000 +0100 +++ new/conmon-2.0.9/VERSION 2020-01-06 18:51:59.000000000 +0100 @@ -1 +1 @@ -2.0.3 +2.0.9 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.3/cmd/conmon-config/conmon-config.go new/conmon-2.0.9/cmd/conmon-config/conmon-config.go --- old/conmon-2.0.3/cmd/conmon-config/conmon-config.go 2019-11-11 16:16:23.000000000 +0100 +++ new/conmon-2.0.9/cmd/conmon-config/conmon-config.go 2020-01-06 18:51:59.000000000 +0100 @@ -18,18 +18,20 @@ #define DEFAULT_SOCKET_PATH "%s" #define WIN_RESIZE_EVENT %d #define REOPEN_LOGS_EVENT %d +#define TIMED_OUT_MESSAGE "%s" #endif // CONFIG_H ` if err := ioutil.WriteFile("config.h", []byte(fmt.Sprintf( - output, - config.BufSize, - config.BufSize, - config.ConnSockBufSize, - config.ContainerAttachSocketDir, - config.WinResizeEvent, - config.ReopenLogsEvent)), + output, + config.BufSize, + config.BufSize, + config.ConnSockBufSize, + config.ContainerAttachSocketDir, + config.WinResizeEvent, + config.ReopenLogsEvent, + config.TimedOutMessage)), 0644); err != nil { - fmt.Errorf(err.Error()) + fmt.Errorf(err.Error()) } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.3/runner/config/config.go new/conmon-2.0.9/runner/config/config.go --- old/conmon-2.0.3/runner/config/config.go 2019-11-11 16:16:23.000000000 +0100 +++ new/conmon-2.0.9/runner/config/config.go 2020-01-06 18:51:59.000000000 +0100 @@ -13,4 +13,7 @@ // ReopenLogsEvent is the event code the caller program will // send along the ctrl fd to signal conmon to reopen the log files ReopenLogsEvent = 2 + // TimedOutMessage is the message sent back to the caller by conmon + // when a container times out + TimedOutMessage = "command timed out" ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.3/src/config.h new/conmon-2.0.9/src/config.h --- old/conmon-2.0.3/src/config.h 2019-11-11 16:16:23.000000000 +0100 +++ new/conmon-2.0.9/src/config.h 2020-01-06 18:51:59.000000000 +0100 @@ -8,5 +8,6 @@ #define DEFAULT_SOCKET_PATH "/var/run/crio" #define WIN_RESIZE_EVENT 1 #define REOPEN_LOGS_EVENT 2 +#define TIMED_OUT_MESSAGE "command timed out" #endif // CONFIG_H diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.3/src/conmon.c new/conmon-2.0.9/src/conmon.c --- old/conmon-2.0.3/src/conmon.c 2019-11-11 16:16:23.000000000 +0100 +++ new/conmon-2.0.9/src/conmon.c 2020-01-06 18:51:59.000000000 +0100 @@ -57,6 +57,7 @@ static char *opt_name = NULL; static char *opt_runtime_path = NULL; static char *opt_bundle_path = NULL; +static char *opt_persist_path = NULL; static char *opt_container_pid_file = NULL; static char *opt_conmon_pid_file = NULL; static gboolean opt_systemd_cgroup = FALSE; @@ -99,6 +100,7 @@ {"no-pivot", 0, 0, G_OPTION_ARG_NONE, &opt_no_pivot, "Do not use pivot_root", NULL}, {"replace-listen-pid", 0, 0, G_OPTION_ARG_NONE, &opt_replace_listen_pid, "Replace listen pid if set for oci-runtime pid", NULL}, {"bundle", 'b', 0, G_OPTION_ARG_STRING, &opt_bundle_path, "Bundle path", NULL}, + {"persist-dir", '0', 0, G_OPTION_ARG_STRING, &opt_persist_path, "Persistent directory for a container that can be used for storing container data", NULL}, {"pidfile", 0, 0, G_OPTION_ARG_STRING, &opt_container_pid_file, "PID file (DEPRECATED)", NULL}, {"container-pidfile", 'p', 0, G_OPTION_ARG_STRING, &opt_container_pid_file, "Container PID file", NULL}, {"conmon-pidfile", 'P', 0, G_OPTION_ARG_STRING, &opt_conmon_pid_file, "Conmon daemon PID file", NULL}, @@ -508,6 +510,28 @@ return G_SOURCE_REMOVE; } +/* write the appropriate files to tell the caller there was an oom event + * this can be used for v1 and v2 OOMS + * returns 0 on success, negative value on failure + */ +static int write_oom_files() { + _cleanup_close_ int oom_fd = -1; + ninfo("OOM received"); + if (opt_persist_path) { + _cleanup_close_ int ctr_oom_fd = -1; + _cleanup_free_ char *ctr_oom_file_path = g_build_filename(opt_persist_path, "oom", NULL); + ctr_oom_fd = open(ctr_oom_file_path, O_CREAT, 0666); + if (ctr_oom_fd < 0) { + nwarn("Failed to write oom file"); + } + } + oom_fd = open("oom", O_CREAT, 0666); + if (oom_fd < 0) { + nwarn("Failed to write oom file"); + } + return oom_fd >= 0 ? 0 : -1; +} + static gboolean oom_cb_cgroup_v1(int fd, GIOCondition condition, G_GNUC_UNUSED gpointer user_data) { uint64_t oom_event; @@ -521,14 +545,10 @@ } if (num_read > 0) { - _cleanup_close_ int oom_fd = -1; if (num_read != sizeof(uint64_t)) nwarn("Failed to read full oom event from eventfd"); - ninfo("OOM received"); - oom_fd = open("oom", O_CREAT, 0666); - if (oom_fd < 0) { - nwarn("Failed to write oom file"); - } + write_oom_files(); + return G_SOURCE_CONTINUE; } } @@ -571,13 +591,7 @@ } if (counter != last_counter) { - _cleanup_close_ int oom_fd = -1; - - ninfo("OOM received"); - oom_fd = open("oom", O_CREAT, 0666); - if (oom_fd < 0) { - nwarn("Failed to write oom file"); - } else { + if (write_oom_files() == 0) { last_counter = counter; } } @@ -588,11 +602,12 @@ static gboolean oom_cb_cgroup_v2(int fd, GIOCondition condition, G_GNUC_UNUSED gpointer user_data) { - struct inotify_event events[10]; + size_t events_size = sizeof(struct inotify_event) + NAME_MAX + 1; + char events[events_size]; gboolean ret = G_SOURCE_REMOVE; /* Drop the inotify events. */ - if (read(fd, &events, sizeof(events) < 0)) { + if (read(fd, &events, events_size) < 0) { pwarn("failed to read events"); } @@ -611,20 +626,33 @@ static gboolean conn_sock_cb(int fd, GIOCondition condition, gpointer user_data) { - char buf[CONN_SOCK_BUF_SIZE]; - ssize_t num_read = 0; struct conn_sock_s *sock = (struct conn_sock_s *)user_data; + ssize_t num_read = 0; if ((condition & G_IO_IN) != 0) { - num_read = read(fd, buf, CONN_SOCK_BUF_SIZE); - if (num_read < 0) + num_read = splice(fd, NULL, masterfd_stdin, NULL, 1 << 20, 0); + if (num_read > 0) return G_SOURCE_CONTINUE; - if (num_read > 0 && masterfd_stdin >= 0) { - if (write_all(masterfd_stdin, buf, num_read) < 0) { + if (num_read < 0) { + if (errno != ESPIPE && errno != EINVAL) { nwarn("Failed to write to container stdin"); + } else { + /* Fallback to read-write. This may lock if the consumer + doesn't read all the data. */ + char buf[CONN_SOCK_BUF_SIZE]; + + num_read = read(fd, buf, CONN_SOCK_BUF_SIZE); + if (num_read < 0) + return G_SOURCE_CONTINUE; + + if (num_read > 0 && masterfd_stdin >= 0) { + if (write_all(masterfd_stdin, buf, num_read) < 0) { + nwarn("Failed to write to container stdin"); + } + return G_SOURCE_CONTINUE; + } } - return G_SOURCE_CONTINUE; } } @@ -1328,8 +1356,7 @@ if (opt_conmon_pid_file) { char content[12]; sprintf(content, "%i", main_pid); - g_file_set_contents(opt_conmon_pid_file, content, strlen(content), &err); - if (err) { + if (!g_file_set_contents(opt_conmon_pid_file, content, strlen(content), &err)) { nexitf("Failed to write conmon pidfile: %s", err->message); } } @@ -1480,6 +1507,20 @@ add_argv(runtime_argv, opt_cid, NULL); end_argv(runtime_argv); + /* Setup endpoint for attach */ + _cleanup_free_ char *attach_symlink_dir_path = NULL; + if (opt_bundle_path != NULL) { + attach_symlink_dir_path = setup_attach_socket(); + dummyfd = setup_terminal_control_fifo(); + setup_console_fifo(); + + if (opt_attach) { + ndebug("sending attach message to parent"); + write_sync_fd(attach_pipe_fd, 0, NULL); + ndebug("sent attach message to parent"); + } + } + sigset_t mask, oldmask; if ((sigemptyset(&mask) < 0) || (sigaddset(&mask, SIGTERM) < 0) || (sigaddset(&mask, SIGQUIT) < 0) || (sigaddset(&mask, SIGINT) < 0) || sigprocmask(SIG_BLOCK, &mask, &oldmask) < 0) @@ -1524,7 +1565,7 @@ errno = 0; int lpid = strtol(listenpid, NULL, 10); if (errno != 0 || lpid <= 0) - pexitf("Invalid LISTEN_PID %10s", listenpid); + pexitf("Invalid LISTEN_PID %.10s", listenpid); if (opt_replace_listen_pid || lpid == getppid()) { gchar *pidstr = g_strdup_printf("%d", getpid()); if (!pidstr) @@ -1588,20 +1629,6 @@ if (slavefd_stderr > -1) close(slavefd_stderr); - /* Setup endpoint for attach */ - _cleanup_free_ char *attach_symlink_dir_path = NULL; - if (opt_bundle_path != NULL) { - attach_symlink_dir_path = setup_attach_socket(); - dummyfd = setup_terminal_control_fifo(); - setup_console_fifo(); - - if (opt_attach) { - ndebug("sending attach message to parent"); - write_sync_fd(attach_pipe_fd, 0, NULL); - ndebug("sent attach message to parent"); - } - } - if (csname != NULL) { g_unix_fd_add(console_socket_fd, G_IO_IN, terminal_accept_cb, csname); /* Process any SIGCHLD we may have missed before the signal handler was in place. */ @@ -1648,8 +1675,7 @@ nexit("Runtime did not set up terminal"); /* Read the pid so we can wait for the process to exit */ - g_file_get_contents(opt_container_pid_file, &contents, NULL, &err); - if (err) { + if (!g_file_get_contents(opt_container_pid_file, &contents, NULL, &err)) { nwarnf("Failed to read pidfile: %s", err->message); g_error_free(err); exit(1); @@ -1718,9 +1744,13 @@ const char *exit_message = NULL; if (timed_out) { - if (container_pid > 0) + pid_t process_group = getpgid(container_pid); + + if (process_group > 0) + kill(-process_group, SIGKILL); + else kill(container_pid, SIGKILL); - exit_message = "command timed out"; + exit_message = TIMED_OUT_MESSAGE; } else { exit_status = get_exit_status(container_status); } @@ -1749,8 +1779,20 @@ closedir(fdsdir); } + _cleanup_free_ char *status_str = g_strdup_printf("%d", exit_status); + + /* Write the exit file to container persistent directory if it is specified */ + if (opt_persist_path) { + _cleanup_free_ char *ctr_exit_file_path = g_build_filename(opt_persist_path, "exit", NULL); + if (!g_file_set_contents(ctr_exit_file_path, status_str, -1, &err)) + nexitf("Failed to write %s to container exit file: %s", status_str, err->message); + } + + /* + * Writing to this directory helps if a daemon process wants to monitor all container exits + * using inotify. + */ if (opt_exit_dir) { - _cleanup_free_ char *status_str = g_strdup_printf("%d", exit_status); _cleanup_free_ char *exit_file_path = g_build_filename(opt_exit_dir, opt_cid, NULL); if (!g_file_set_contents(exit_file_path, status_str, -1, &err)) nexitf("Failed to write %s to exit file: %s", status_str, err->message);