On Wed, Jan 26, 2022 at 8:56 AM Ben Pfaff <b...@ovn.org> wrote: > > Until now, the monitor process held its log file open while it waited for > the child to exit, and then it reopened it after the child exited. Holding > the log file open this way prevented log rotation from freeing disk space. > This commit avoids the problem by closing the log file before waiting, then > reopening it afterward. > > Signed-off-by: Ben Pfaff <b...@ovn.org> > Reported-by: Antonin Bas <a...@vmware.com> > VMware-BZ: #2743409 > ---
Hi Ben, Thanks, ASAN reports a memory leak, 2022-01-27T02:17:41.3146557Z 1788: ovsdb-server/add-db with --monitor FAILED (ovs-macros.at:217) 2022-01-27T02:17:41.3467168Z 1789: ovsdb-server/add-db and remove-db with --monitor FAILED (ovs-macros.at:217) ==29645==ERROR: LeakSanitizer: detected memory leaks Direct leak of 99 byte(s) in 1 object(s) allocated from: #0 0x49633d in malloc (/home/runner/work/ovs/ovs/openvswitch-2.17.90/_build/sub/ovsdb/ovsdb-server+0x49633d) #1 0x56df34 in xmalloc__ /home/runner/work/ovs/ovs/openvswitch-2.17.90/_build/sub/../../lib/util.c:137:15 #2 0x56e098 in xmemdup0 /home/runner/work/ovs/ovs/openvswitch-2.17.90/_build/sub/../../lib/util.c:193:15 #3 0x576800 in vlog_get_log_file /home/runner/work/ovs/ovs/openvswitch-2.17.90/_build/sub/../../lib/vlog.c:352:16 #4 0x57a80e in monitor_daemon /home/runner/work/ovs/ovs/openvswitch-2.17.90/_build/sub/../../lib/daemon-unix.c:363:30 #5 0x57a05a in daemonize_start /home/runner/work/ovs/ovs/openvswitch-2.17.90/_build/sub/../../lib/daemon-unix.c:481:13 #6 0x4c5e66 in main /home/runner/work/ovs/ovs/openvswitch-2.17.90/_build/sub/../../ovsdb/ovsdb-server.c:356:5 #7 0x7f0effa20bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6) SUMMARY: AddressSanitizer: 99 byte(s) leaked in 1 allocation(s). I think we should "free(log_file)" after vlog_set_log_file(log_file)? William > include/openvswitch/vlog.h | 2 + > lib/daemon-unix.c | 4 +- > lib/vlog.c | 93 ++++++++++++++++++++++++++------------ > 3 files changed, 70 insertions(+), 29 deletions(-) > > diff --git a/include/openvswitch/vlog.h b/include/openvswitch/vlog.h > index 886fce5e0..e53ce6d81 100644 > --- a/include/openvswitch/vlog.h > +++ b/include/openvswitch/vlog.h > @@ -131,7 +131,9 @@ void vlog_set_verbosity(const char *arg); > > /* Configuring log destinations. */ > void vlog_set_pattern(enum vlog_destination, const char *pattern); > +char *vlog_get_log_file(void); > int vlog_set_log_file(const char *file_name); > +void vlog_close_log_file(void); > int vlog_reopen_log_file(void); > #ifndef _WIN32 > void vlog_change_owner_unix(uid_t, gid_t); > diff --git a/lib/daemon-unix.c b/lib/daemon-unix.c > index 34d45b82a..10806bf81 100644 > --- a/lib/daemon-unix.c > +++ b/lib/daemon-unix.c > @@ -360,12 +360,14 @@ monitor_daemon(pid_t daemon_pid) > (unsigned long int) daemon_pid, status_msg); > > if (child_ready) { > + char *log_file = vlog_get_log_file(); > + vlog_close_log_file(); > int error; > do { > retval = waitpid(daemon_pid, &status, 0); > error = retval == -1 ? errno : 0; > } while (error == EINTR); > - vlog_reopen_log_file(); > + vlog_set_log_file(log_file); > if (error) { > VLOG_FATAL("waitpid failed (%s)", ovs_strerror(error)); > } > diff --git a/lib/vlog.c b/lib/vlog.c > index 533f93755..0a615bb66 100644 > --- a/lib/vlog.c > +++ b/lib/vlog.c > @@ -343,13 +343,25 @@ vlog_set_pattern(enum vlog_destination destination, > const char *pattern) > } > } > > -/* Sets the name of the log file used by VLF_FILE to 'file_name', or to the > - * default file name if 'file_name' is null. Returns 0 if successful, > - * otherwise a positive errno value. */ > -int > -vlog_set_log_file(const char *file_name) > +/* Returns a copy of the name of the log file used by VLF_FILE, or NULL if > none > + * is configured. The caller must eventually free the returned string. */ > +char * > +vlog_get_log_file(void) > +{ > + ovs_mutex_lock(&log_file_mutex); > + char *fn = nullable_xstrdup(log_file_name); > + ovs_mutex_unlock(&log_file_mutex); > + > + return fn; > +} > + > +/* Sets the name of the log file used by VLF_FILE to 'new_log_file_name', or > + * closes the current log file if 'new_log_file_name' is NULL. Takes > ownership > + * of 'new_log_file_name'. Returns 0 if successful, otherwise a positive > errno > + * value. */ > +static int > +vlog_set_log_file__(char *new_log_file_name) > { > - char *new_log_file_name; > struct vlog_module *mp; > struct stat old_stat; > struct stat new_stat; > @@ -358,25 +370,29 @@ vlog_set_log_file(const char *file_name) > bool log_close; > > /* Open new log file. */ > - new_log_file_name = (file_name > - ? xstrdup(file_name) > - : xasprintf("%s/%s.log", ovs_logdir(), > program_name)); > - new_log_fd = open(new_log_file_name, O_WRONLY | O_CREAT | O_APPEND, > 0660); > - if (new_log_fd < 0) { > - VLOG_WARN("failed to open %s for logging: %s", > - new_log_file_name, ovs_strerror(errno)); > - free(new_log_file_name); > - return errno; > + if (new_log_file_name) { > + new_log_fd = open(new_log_file_name, O_WRONLY | O_CREAT | O_APPEND, > + 0660); > + if (new_log_fd < 0) { > + VLOG_WARN("failed to open %s for logging: %s", > + new_log_file_name, ovs_strerror(errno)); > + free(new_log_file_name); > + return errno; > + } > + } else { > + new_log_fd = -1; > } > > /* If the new log file is the same one we already have open, bail out. */ > ovs_mutex_lock(&log_file_mutex); > - same_file = (log_fd >= 0 > - && new_log_fd >= 0 > - && !fstat(log_fd, &old_stat) > - && !fstat(new_log_fd, &new_stat) > - && old_stat.st_dev == new_stat.st_dev > - && old_stat.st_ino == new_stat.st_ino); > + same_file = ((log_fd < 0 > + && new_log_fd < 0) || > + (log_fd >= 0 > + && new_log_fd >= 0 > + && !fstat(log_fd, &old_stat) > + && !fstat(new_log_fd, &new_stat) > + && old_stat.st_dev == new_stat.st_dev > + && old_stat.st_ino == new_stat.st_ino)); > ovs_mutex_unlock(&log_file_mutex); > if (same_file) { > close(new_log_fd); > @@ -392,19 +408,18 @@ vlog_set_log_file(const char *file_name) > VLOG_INFO("closing log file"); > } > > - /* Close old log file, if any, and install new one. */ > + /* Close old log file, if any. */ > ovs_mutex_lock(&log_file_mutex); > if (log_fd >= 0) { > close(log_fd); > - async_append_destroy(log_writer); > } > - > + async_append_destroy(log_writer); > free(log_file_name); > - log_file_name = xstrdup(new_log_file_name); > + > + /* Install new log file. */ > + log_file_name = nullable_xstrdup(new_log_file_name); > log_fd = new_log_fd; > - if (log_async) { > - log_writer = async_append_create(new_log_fd); > - } > + log_writer = log_async ? async_append_create(new_log_fd) : NULL; > > LIST_FOR_EACH (mp, list, &vlog_modules) { > update_min_level(mp); > @@ -418,6 +433,28 @@ vlog_set_log_file(const char *file_name) > return 0; > } > > +/* Closes the log file, if any. > + * > + * If the real goal is open a new log file, use vlog_set_log_file() to > directly > + * do that: there is no need to close the old file first. */ > +void > +vlog_close_log_file(void) > +{ > + vlog_set_log_file__(NULL); > +} > + > +/* Sets the name of the log file used by VLF_FILE to 'file_name', or to the > + * default file name if 'file_name' is null. Returns 0 if successful, > + * otherwise a positive errno value. */ > +int > +vlog_set_log_file(const char *file_name) > +{ > + return vlog_set_log_file__( > + file_name > + ? xstrdup(file_name) > + : xasprintf("%s/%s.log", ovs_logdir(), program_name)); > +} > + > /* Closes and then attempts to re-open the current log file. (This is useful > * just after log rotation, to ensure that the new log file starts being > used.) > * Returns 0 if successful, otherwise a positive errno value. */ > -- > 2.33.1 > > _______________________________________________ > dev mailing list > d...@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev