]> git.proxmox.com Git - mirror_ovs.git/blobdiff - lib/vlog.c
ovsdb-idl: Remove prototype for function that is not defined or used.
[mirror_ovs.git] / lib / vlog.c
index 4c36f1b780bf13b5dc803798061690697f431815..533f93755502ccacee37f34da8aeccb8f2ac961c 100644 (file)
 #include "coverage.h"
 #include "dirs.h"
 #include "openvswitch/dynamic-string.h"
-#include "ofpbuf.h"
+#include "openvswitch/ofpbuf.h"
 #include "ovs-thread.h"
 #include "sat-math.h"
 #include "socket-util.h"
 #include "svec.h"
 #include "syslog-direct.h"
 #include "syslog-libc.h"
+#include "syslog-null.h"
 #include "syslog-provider.h"
 #include "timeval.h"
 #include "unixctl.h"
@@ -215,7 +216,7 @@ void
 vlog_insert_module(struct ovs_list *vlog)
 {
     ovs_mutex_lock(&log_file_mutex);
-    list_insert(&vlog_modules, vlog);
+    ovs_list_insert(&vlog_modules, vlog);
     ovs_mutex_unlock(&log_file_mutex);
 }
 
@@ -256,7 +257,7 @@ vlog_get_level(const struct vlog_module *module,
 }
 
 static void
-update_min_level(struct vlog_module *module) OVS_REQUIRES(&log_file_mutex)
+update_min_level(struct vlog_module *module) OVS_REQUIRES(log_file_mutex)
 {
     enum vlog_destination destination;
 
@@ -360,7 +361,7 @@ vlog_set_log_file(const char *file_name)
     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, 0666);
+    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));
@@ -394,11 +395,11 @@ vlog_set_log_file(const char *file_name)
     /* Close old log file, if any, and install new one. */
     ovs_mutex_lock(&log_file_mutex);
     if (log_fd >= 0) {
-        free(log_file_name);
         close(log_fd);
         async_append_destroy(log_writer);
     }
 
+    free(log_file_name);
     log_file_name = xstrdup(new_log_file_name);
     log_fd = new_log_fd;
     if (log_async) {
@@ -426,7 +427,7 @@ vlog_reopen_log_file(void)
     char *fn;
 
     ovs_mutex_lock(&log_file_mutex);
-    fn = log_file_name ? xstrdup(log_file_name) : NULL;
+    fn = nullable_xstrdup(log_file_name);
     ovs_mutex_unlock(&log_file_mutex);
 
     if (fn) {
@@ -584,7 +585,9 @@ vlog_set_syslog_method(const char *method)
         return;
     }
 
-    if (!strcmp(method, "libc")) {
+    if (!strcmp(method, "null")) {
+        syslogger = syslog_null_create();
+    } else if (!strcmp(method, "libc")) {
         syslogger = syslog_libc_create();
     } else if (!strncmp(method, "udp:", 4) || !strncmp(method, "unix:", 5)) {
         syslogger = syslog_direct_create(method);
@@ -599,7 +602,7 @@ vlog_set_syslog_target(const char *target)
 {
     int new_fd;
 
-    inet_open_active(SOCK_DGRAM, target, 0, NULL, &new_fd, 0);
+    inet_open_active(SOCK_DGRAM, target, -1, NULL, &new_fd, 0);
 
     ovs_rwlock_wrlock(&pattern_rwlock);
     if (syslog_fd >= 0) {
@@ -609,6 +612,21 @@ vlog_set_syslog_target(const char *target)
     ovs_rwlock_unlock(&pattern_rwlock);
 }
 
+/*
+ * This function writes directly to log file without using async writer or
+ * taking a lock.  Caller must hold 'log_file_mutex' or be sure that it's
+ * not necessary.  Could be used in exceptional cases like dumping of backtrace
+ * on fatal signals.
+ */
+void
+vlog_direct_write_to_log_file_unsafe(const char *s)
+    OVS_NO_THREAD_SAFETY_ANALYSIS
+{
+    if (log_fd >= 0) {
+        ignore(write(log_fd, s, strlen(s)));
+    }
+}
+
 /* Returns 'false' if 'facility' is not a valid string. If 'facility'
  * is a valid string, sets 'value' with the integer value of 'facility'
  * and returns 'true'. */
@@ -631,6 +649,10 @@ vlog_unixctl_set(struct unixctl_conn *conn, int argc, const char *argv[],
 {
     int i;
 
+    /* With no argument, set all destinations and modules to "dbg". */
+    if (argc == 1) {
+        vlog_set_levels(NULL, VLF_ANY_DESTINATION, VLL_DBG);
+    }
     for (i = 1; i < argc; i++) {
         char *msg = vlog_set_levels_from_string(argv[i]);
         if (msg) {
@@ -774,7 +796,12 @@ vlog_init(void)
          * log anything before calling ovsthread_once_done() will deadlock. */
         atomic_read_explicit(&log_facility, &facility, memory_order_relaxed);
         if (!syslogger) {
-            syslogger = syslog_libc_create();
+            char *env = getenv("OVS_SYSLOG_METHOD");
+            if (env && env[0]) {
+                vlog_set_syslog_method(env);
+            } else {
+                syslogger = syslog_libc_create();
+            }
         }
         syslogger->class->openlog(syslogger, facility ? facility : LOG_DAEMON);
         ovsthread_once_done(&once);
@@ -791,7 +818,7 @@ vlog_init(void)
 
         unixctl_command_register(
             "vlog/set", "{spec | PATTERN:destination:pattern}",
-            1, INT_MAX, vlog_unixctl_set, NULL);
+            0, INT_MAX, vlog_unixctl_set, NULL);
         unixctl_command_register("vlog/list", "", 0, 0, vlog_unixctl_list,
                                  NULL);
         unixctl_command_register("vlog/list-pattern", "", 0, 0,
@@ -832,6 +859,16 @@ vlog_enable_async(void)
     ovs_mutex_unlock(&log_file_mutex);
 }
 
+void
+vlog_disable_async(void)
+{
+    ovs_mutex_lock(&log_file_mutex);
+    log_async = false;
+    async_append_destroy(log_writer);
+    log_writer = NULL;
+    ovs_mutex_unlock(&log_file_mutex);
+}
+
 /* Print the current logging level for each module. */
 char *
 vlog_get_levels(void)
@@ -839,7 +876,6 @@ vlog_get_levels(void)
     struct ds s = DS_EMPTY_INITIALIZER;
     struct vlog_module *mp;
     struct svec lines = SVEC_EMPTY_INITIALIZER;
-    char *line;
     size_t i;
 
     ds_put_format(&s, "                 console    syslog    file\n");
@@ -865,6 +901,8 @@ vlog_get_levels(void)
     ovs_mutex_unlock(&log_file_mutex);
 
     svec_sort(&lines);
+
+    char *line;
     SVEC_FOR_EACH (i, line, &lines) {
         ds_put_cstr(&s, line);
     }
@@ -937,7 +975,7 @@ format_log_message(const struct vlog_module *module, enum vlog_level level,
     for (p = pattern; *p != '\0'; ) {
         const char *subprogram_name;
         enum { LEFT, RIGHT } justify = RIGHT;
-        int pad = '0';
+        int pad = ' ';
         size_t length, field, used;
 
         if (*p != '%') {
@@ -1065,10 +1103,17 @@ vlog_valist(const struct vlog_module *module, enum vlog_level level,
 {
     bool log_to_console = module->levels[VLF_CONSOLE] >= level;
     bool log_to_syslog = module->levels[VLF_SYSLOG] >= level;
-    bool log_to_file;
+    bool log_to_file = module->levels[VLF_FILE]  >= level;
+
+    if (!(log_to_console || log_to_syslog || log_to_file)) {
+        /* fast path - all logging levels specify no logging, no
+         * need to hog the log mutex
+         */
+        return;
+    }
 
     ovs_mutex_lock(&log_file_mutex);
-    log_to_file = module->levels[VLF_FILE] >= level && log_fd >= 0;
+    log_to_file &= (log_fd >= 0);
     ovs_mutex_unlock(&log_file_mutex);
     if (log_to_console || log_to_syslog || log_to_file) {
         int save_errno = errno;