X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=lib%2Fvlog.c;h=bbc6eb6f68f303417312224bb60556ad778eae74;hb=d0a46cb4608e632f5028034762f0adde2ce947a0;hp=18d0e3361b52a31311d97570a1058c03cde0a4bb;hpb=de929213d10d25394df586dfffe8e3dd04976155;p=cascardo%2Fovs.git diff --git a/lib/vlog.c b/lib/vlog.c index 18d0e3361..bbc6eb6f6 100644 --- a/lib/vlog.c +++ b/lib/vlog.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2015 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2015, 2016 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,9 +77,6 @@ VLOG_LEVELS * used for LOG_LOCAL0. */ BUILD_ASSERT_DECL(LOG_LOCAL0 == (16 << 3)); -/* The log modules. */ -struct ovs_list vlog_modules = OVS_LIST_INITIALIZER(&vlog_modules); - /* Protects the 'pattern' in all "struct destination"s, so that a race between * changing and reading the pattern does not cause an access to freed * memory. */ @@ -104,13 +101,18 @@ DEFINE_STATIC_PER_THREAD_DATA(unsigned int, msg_num, 0); * * All of the following is protected by 'log_file_mutex', which nests inside * pattern_rwlock. */ -static struct ovs_mutex log_file_mutex = OVS_MUTEX_INITIALIZER; -static char *log_file_name = NULL OVS_GUARDED_BY(log_file_mutex); +static struct ovs_mutex log_file_mutex OVS_ACQ_AFTER(pattern_rwlock) + = OVS_MUTEX_INITIALIZER; +static char *log_file_name OVS_GUARDED_BY(log_file_mutex) = NULL; static int log_fd OVS_GUARDED_BY(log_file_mutex) = -1; static struct async_append *log_writer OVS_GUARDED_BY(log_file_mutex); static bool log_async OVS_GUARDED_BY(log_file_mutex); static struct syslogger *syslogger = NULL; +/* The log modules. */ +static struct ovs_list vlog_modules OVS_GUARDED_BY(log_file_mutex) + = OVS_LIST_INITIALIZER(&vlog_modules); + /* Syslog export configuration. */ static int syslog_fd OVS_GUARDED_BY(pattern_rwlock) = -1; @@ -209,9 +211,12 @@ vlog_get_destination_val(const char *name) return i; } -void vlog_insert_module(struct ovs_list *vlog) +void +vlog_insert_module(struct ovs_list *vlog) { + ovs_mutex_lock(&log_file_mutex); list_insert(&vlog_modules, vlog); + ovs_mutex_unlock(&log_file_mutex); } /* Returns the name for logging module 'module'. */ @@ -228,11 +233,14 @@ vlog_module_from_name(const char *name) { struct vlog_module *mp; + ovs_mutex_lock(&log_file_mutex); LIST_FOR_EACH (mp, list, &vlog_modules) { if (!strcasecmp(name, mp->name)) { + ovs_mutex_unlock(&log_file_mutex); return mp; } } + ovs_mutex_unlock(&log_file_mutex); return NULL; } @@ -438,17 +446,23 @@ vlog_reopen_log_file(void) void vlog_change_owner_unix(uid_t user, gid_t group) { - if (!log_file_name) { - return; - } + struct ds err = DS_EMPTY_INITIALIZER; + int error; ovs_mutex_lock(&log_file_mutex); - int error = chown(log_file_name, user, group); + error = log_file_name ? chown(log_file_name, user, group) : 0; + if (error) { + /* Build the error message. We can not call VLOG_FATAL directly + * here because VLOG_FATAL() will try again to to acquire + * 'log_file_mutex' lock, causing deadlock. + */ + ds_put_format(&err, "Failed to change %s ownership: %s.", + log_file_name, ovs_strerror(errno)); + } ovs_mutex_unlock(&log_file_mutex); if (error) { - VLOG_FATAL("Failed to change %s ownership: %s.", - log_file_name, ovs_strerror(errno)); + VLOG_FATAL("%s", ds_steal_cstr(&err)); } } #endif @@ -670,14 +684,38 @@ vlog_unixctl_reopen(struct unixctl_conn *conn, int argc OVS_UNUSED, } } +static void +vlog_unixctl_close(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) +{ + ovs_mutex_lock(&log_file_mutex); + if (log_fd >= 0) { + close(log_fd); + log_fd = -1; + + async_append_destroy(log_writer); + log_writer = NULL; + + struct vlog_module *mp; + LIST_FOR_EACH (mp, list, &vlog_modules) { + update_min_level(mp); + } + } + ovs_mutex_unlock(&log_file_mutex); + + unixctl_command_reply(conn, NULL); +} + static void set_all_rate_limits(bool enable) { struct vlog_module *mp; + ovs_mutex_lock(&log_file_mutex); LIST_FOR_EACH (mp, list, &vlog_modules) { mp->honor_rate_limits = enable; } + ovs_mutex_unlock(&log_file_mutex); } static void @@ -764,6 +802,8 @@ vlog_init(void) 0, INT_MAX, vlog_disable_rate_limit, NULL); unixctl_command_register("vlog/reopen", "", 0, 0, vlog_unixctl_reopen, NULL); + unixctl_command_register("vlog/close", "", 0, 0, + vlog_unixctl_close, NULL); ovs_rwlock_rdlock(&pattern_rwlock); print_syslog_target_deprecation = syslog_fd >= 0; @@ -805,6 +845,7 @@ vlog_get_levels(void) ds_put_format(&s, " console syslog file\n"); ds_put_format(&s, " ------- ------ ------\n"); + ovs_mutex_lock(&log_file_mutex); LIST_FOR_EACH (mp, list, &vlog_modules) { struct ds line; @@ -821,6 +862,7 @@ vlog_get_levels(void) svec_add_nocopy(&lines, ds_steal_cstr(&line)); } + ovs_mutex_unlock(&log_file_mutex); svec_sort(&lines); SVEC_FOR_EACH (i, line, &lines) {