netdev-dpdk: fix mbuf leaks
[cascardo/ovs.git] / lib / vlog.c
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2015, 2016 Nicira, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <config.h>
18 #include "openvswitch/vlog.h"
19 #include <assert.h>
20 #include <ctype.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <syslog.h>
29 #include <time.h>
30 #include <unistd.h>
31 #include "async-append.h"
32 #include "coverage.h"
33 #include "dirs.h"
34 #include "dynamic-string.h"
35 #include "ofpbuf.h"
36 #include "ovs-thread.h"
37 #include "sat-math.h"
38 #include "socket-util.h"
39 #include "svec.h"
40 #include "syslog-direct.h"
41 #include "syslog-libc.h"
42 #include "syslog-provider.h"
43 #include "timeval.h"
44 #include "unixctl.h"
45 #include "util.h"
46
47 VLOG_DEFINE_THIS_MODULE(vlog);
48
49 /* ovs_assert() logs the assertion message, so using ovs_assert() in this
50  * source file could cause recursion. */
51 #undef ovs_assert
52 #define ovs_assert use_assert_instead_of_ovs_assert_in_this_module
53
54 /* Name for each logging level. */
55 static const char *const level_names[VLL_N_LEVELS] = {
56 #define VLOG_LEVEL(NAME, SYSLOG_LEVEL, RFC5424) #NAME,
57     VLOG_LEVELS
58 #undef VLOG_LEVEL
59 };
60
61 /* Syslog value for each logging level. */
62 static const int syslog_levels[VLL_N_LEVELS] = {
63 #define VLOG_LEVEL(NAME, SYSLOG_LEVEL, RFC5424) SYSLOG_LEVEL,
64     VLOG_LEVELS
65 #undef VLOG_LEVEL
66 };
67
68 /* RFC 5424 defines specific values for each syslog level.  Normally LOG_* use
69  * the same values.  Verify that in fact they're the same.  If we get assertion
70  * failures here then we need to define a separate rfc5424_levels[] array. */
71 #define VLOG_LEVEL(NAME, SYSLOG_LEVEL, RFC5424) \
72     BUILD_ASSERT_DECL(SYSLOG_LEVEL == RFC5424);
73 VLOG_LEVELS
74 #undef VLOG_LEVELS
75
76 /* Similarly, RFC 5424 defines the local0 facility with the value ordinarily
77  * used for LOG_LOCAL0. */
78 BUILD_ASSERT_DECL(LOG_LOCAL0 == (16 << 3));
79
80 /* Protects the 'pattern' in all "struct destination"s, so that a race between
81  * changing and reading the pattern does not cause an access to freed
82  * memory. */
83 static struct ovs_rwlock pattern_rwlock = OVS_RWLOCK_INITIALIZER;
84
85 /* Information about each destination. */
86 struct destination {
87     const char *name;           /* Name. */
88     char *pattern OVS_GUARDED_BY(pattern_rwlock); /* Current pattern. */
89     bool default_pattern;       /* Whether current pattern is the default. */
90 };
91 static struct destination destinations[VLF_N_DESTINATIONS] = {
92 #define VLOG_DESTINATION(NAME, PATTERN) {#NAME, PATTERN, true},
93     VLOG_DESTINATIONS
94 #undef VLOG_DESTINATION
95 };
96
97 /* Sequence number for the message currently being composed. */
98 DEFINE_STATIC_PER_THREAD_DATA(unsigned int, msg_num, 0);
99
100 /* VLF_FILE configuration.
101  *
102  * All of the following is protected by 'log_file_mutex', which nests inside
103  * pattern_rwlock. */
104 static struct ovs_mutex log_file_mutex OVS_ACQ_AFTER(pattern_rwlock)
105     = OVS_MUTEX_INITIALIZER;
106 static char *log_file_name OVS_GUARDED_BY(log_file_mutex) = NULL;
107 static int log_fd OVS_GUARDED_BY(log_file_mutex) = -1;
108 static struct async_append *log_writer OVS_GUARDED_BY(log_file_mutex);
109 static bool log_async OVS_GUARDED_BY(log_file_mutex);
110 static struct syslogger *syslogger = NULL;
111
112 /* The log modules. */
113 static struct ovs_list vlog_modules OVS_GUARDED_BY(log_file_mutex)
114     = OVS_LIST_INITIALIZER(&vlog_modules);
115
116 /* Syslog export configuration. */
117 static int syslog_fd OVS_GUARDED_BY(pattern_rwlock) = -1;
118
119 /* Log facility configuration. */
120 static atomic_int log_facility = ATOMIC_VAR_INIT(0);
121
122 /* Facility name and its value. */
123 struct vlog_facility {
124     char *name;           /* Name. */
125     unsigned int value;   /* Facility associated with 'name'. */
126 };
127 static struct vlog_facility vlog_facilities[] = {
128     {"kern", LOG_KERN},
129     {"user", LOG_USER},
130     {"mail", LOG_MAIL},
131     {"daemon", LOG_DAEMON},
132     {"auth", LOG_AUTH},
133     {"syslog", LOG_SYSLOG},
134     {"lpr", LOG_LPR},
135     {"news", LOG_NEWS},
136     {"uucp", LOG_UUCP},
137     {"clock", LOG_CRON},
138     {"ftp", LOG_FTP},
139     {"ntp", 12<<3},
140     {"audit", 13<<3},
141     {"alert", 14<<3},
142     {"clock2", 15<<3},
143     {"local0", LOG_LOCAL0},
144     {"local1", LOG_LOCAL1},
145     {"local2", LOG_LOCAL2},
146     {"local3", LOG_LOCAL3},
147     {"local4", LOG_LOCAL4},
148     {"local5", LOG_LOCAL5},
149     {"local6", LOG_LOCAL6},
150     {"local7", LOG_LOCAL7}
151 };
152 static bool vlog_facility_exists(const char* facility, int *value);
153
154 static void format_log_message(const struct vlog_module *, enum vlog_level,
155                                const char *pattern,
156                                const char *message, va_list, struct ds *)
157     OVS_PRINTF_FORMAT(4, 0);
158
159 /* Searches the 'n_names' in 'names'.  Returns the index of a match for
160  * 'target', or 'n_names' if no name matches. */
161 static size_t
162 search_name_array(const char *target, const char *const *names, size_t n_names)
163 {
164     size_t i;
165
166     for (i = 0; i < n_names; i++) {
167         assert(names[i]);
168         if (!strcasecmp(names[i], target)) {
169             break;
170         }
171     }
172     return i;
173 }
174
175 /* Returns the name for logging level 'level'. */
176 const char *
177 vlog_get_level_name(enum vlog_level level)
178 {
179     assert(level < VLL_N_LEVELS);
180     return level_names[level];
181 }
182
183 /* Returns the logging level with the given 'name', or VLL_N_LEVELS if 'name'
184  * is not the name of a logging level. */
185 enum vlog_level
186 vlog_get_level_val(const char *name)
187 {
188     return search_name_array(name, level_names, ARRAY_SIZE(level_names));
189 }
190
191 /* Returns the name for logging destination 'destination'. */
192 const char *
193 vlog_get_destination_name(enum vlog_destination destination)
194 {
195     assert(destination < VLF_N_DESTINATIONS);
196     return destinations[destination].name;
197 }
198
199 /* Returns the logging destination named 'name', or VLF_N_DESTINATIONS if
200  * 'name' is not the name of a logging destination. */
201 enum vlog_destination
202 vlog_get_destination_val(const char *name)
203 {
204     size_t i;
205
206     for (i = 0; i < VLF_N_DESTINATIONS; i++) {
207         if (!strcasecmp(destinations[i].name, name)) {
208             break;
209         }
210     }
211     return i;
212 }
213
214 void
215 vlog_insert_module(struct ovs_list *vlog)
216 {
217     ovs_mutex_lock(&log_file_mutex);
218     list_insert(&vlog_modules, vlog);
219     ovs_mutex_unlock(&log_file_mutex);
220 }
221
222 /* Returns the name for logging module 'module'. */
223 const char *
224 vlog_get_module_name(const struct vlog_module *module)
225 {
226     return module->name;
227 }
228
229 /* Returns the logging module named 'name', or NULL if 'name' is not the name
230  * of a logging module. */
231 struct vlog_module *
232 vlog_module_from_name(const char *name)
233 {
234     struct vlog_module *mp;
235
236     ovs_mutex_lock(&log_file_mutex);
237     LIST_FOR_EACH (mp, list, &vlog_modules) {
238         if (!strcasecmp(name, mp->name)) {
239             ovs_mutex_unlock(&log_file_mutex);
240             return mp;
241         }
242     }
243     ovs_mutex_unlock(&log_file_mutex);
244
245     return NULL;
246 }
247
248 /* Returns the current logging level for the given 'module' and
249  * 'destination'. */
250 enum vlog_level
251 vlog_get_level(const struct vlog_module *module,
252                enum vlog_destination destination)
253 {
254     assert(destination < VLF_N_DESTINATIONS);
255     return module->levels[destination];
256 }
257
258 static void
259 update_min_level(struct vlog_module *module) OVS_REQUIRES(&log_file_mutex)
260 {
261     enum vlog_destination destination;
262
263     module->min_level = VLL_OFF;
264     for (destination = 0; destination < VLF_N_DESTINATIONS; destination++) {
265         if (log_fd >= 0 || destination != VLF_FILE) {
266             enum vlog_level level = module->levels[destination];
267             if (level > module->min_level) {
268                 module->min_level = level;
269             }
270         }
271     }
272 }
273
274 static void
275 set_destination_level(enum vlog_destination destination,
276                       struct vlog_module *module, enum vlog_level level)
277 {
278     assert(destination >= 0 && destination < VLF_N_DESTINATIONS);
279     assert(level < VLL_N_LEVELS);
280
281     ovs_mutex_lock(&log_file_mutex);
282     if (!module) {
283         struct vlog_module *mp;
284         LIST_FOR_EACH (mp, list, &vlog_modules) {
285             mp->levels[destination] = level;
286             update_min_level(mp);
287         }
288     } else {
289         module->levels[destination] = level;
290         update_min_level(module);
291     }
292     ovs_mutex_unlock(&log_file_mutex);
293 }
294
295 /* Sets the logging level for the given 'module' and 'destination' to 'level'.
296  * A null 'module' or a 'destination' of VLF_ANY_DESTINATION is treated as a
297  * wildcard across all modules or destinations, respectively. */
298 void
299 vlog_set_levels(struct vlog_module *module, enum vlog_destination destination,
300                 enum vlog_level level)
301 {
302     assert(destination < VLF_N_DESTINATIONS ||
303            destination == VLF_ANY_DESTINATION);
304     if (destination == VLF_ANY_DESTINATION) {
305         for (destination = 0; destination < VLF_N_DESTINATIONS;
306              destination++) {
307             set_destination_level(destination, module, level);
308         }
309     } else {
310         set_destination_level(destination, module, level);
311     }
312 }
313
314 static void
315 do_set_pattern(enum vlog_destination destination, const char *pattern)
316 {
317     struct destination *f = &destinations[destination];
318
319     ovs_rwlock_wrlock(&pattern_rwlock);
320     if (!f->default_pattern) {
321         free(f->pattern);
322     } else {
323         f->default_pattern = false;
324     }
325     f->pattern = xstrdup(pattern);
326     ovs_rwlock_unlock(&pattern_rwlock);
327 }
328
329 /* Sets the pattern for the given 'destination' to 'pattern'. */
330 void
331 vlog_set_pattern(enum vlog_destination destination, const char *pattern)
332 {
333     assert(destination < VLF_N_DESTINATIONS ||
334            destination == VLF_ANY_DESTINATION);
335     if (destination == VLF_ANY_DESTINATION) {
336         for (destination = 0; destination < VLF_N_DESTINATIONS;
337              destination++) {
338             do_set_pattern(destination, pattern);
339         }
340     } else {
341         do_set_pattern(destination, pattern);
342     }
343 }
344
345 /* Sets the name of the log file used by VLF_FILE to 'file_name', or to the
346  * default file name if 'file_name' is null.  Returns 0 if successful,
347  * otherwise a positive errno value. */
348 int
349 vlog_set_log_file(const char *file_name)
350 {
351     char *new_log_file_name;
352     struct vlog_module *mp;
353     struct stat old_stat;
354     struct stat new_stat;
355     int new_log_fd;
356     bool same_file;
357     bool log_close;
358
359     /* Open new log file. */
360     new_log_file_name = (file_name
361                          ? xstrdup(file_name)
362                          : xasprintf("%s/%s.log", ovs_logdir(), program_name));
363     new_log_fd = open(new_log_file_name, O_WRONLY | O_CREAT | O_APPEND, 0666);
364     if (new_log_fd < 0) {
365         VLOG_WARN("failed to open %s for logging: %s",
366                   new_log_file_name, ovs_strerror(errno));
367         free(new_log_file_name);
368         return errno;
369     }
370
371     /* If the new log file is the same one we already have open, bail out. */
372     ovs_mutex_lock(&log_file_mutex);
373     same_file = (log_fd >= 0
374                  && new_log_fd >= 0
375                  && !fstat(log_fd, &old_stat)
376                  && !fstat(new_log_fd, &new_stat)
377                  && old_stat.st_dev == new_stat.st_dev
378                  && old_stat.st_ino == new_stat.st_ino);
379     ovs_mutex_unlock(&log_file_mutex);
380     if (same_file) {
381         close(new_log_fd);
382         free(new_log_file_name);
383         return 0;
384     }
385
386     /* Log closing old log file (we can't log while holding log_file_mutex). */
387     ovs_mutex_lock(&log_file_mutex);
388     log_close = log_fd >= 0;
389     ovs_mutex_unlock(&log_file_mutex);
390     if (log_close) {
391         VLOG_INFO("closing log file");
392     }
393
394     /* Close old log file, if any, and install new one. */
395     ovs_mutex_lock(&log_file_mutex);
396     if (log_fd >= 0) {
397         free(log_file_name);
398         close(log_fd);
399         async_append_destroy(log_writer);
400     }
401
402     log_file_name = xstrdup(new_log_file_name);
403     log_fd = new_log_fd;
404     if (log_async) {
405         log_writer = async_append_create(new_log_fd);
406     }
407
408     LIST_FOR_EACH (mp, list, &vlog_modules) {
409         update_min_level(mp);
410     }
411     ovs_mutex_unlock(&log_file_mutex);
412
413     /* Log opening new log file (we can't log while holding log_file_mutex). */
414     VLOG_INFO("opened log file %s", new_log_file_name);
415     free(new_log_file_name);
416
417     return 0;
418 }
419
420 /* Closes and then attempts to re-open the current log file.  (This is useful
421  * just after log rotation, to ensure that the new log file starts being used.)
422  * Returns 0 if successful, otherwise a positive errno value. */
423 int
424 vlog_reopen_log_file(void)
425 {
426     char *fn;
427
428     ovs_mutex_lock(&log_file_mutex);
429     fn = log_file_name ? xstrdup(log_file_name) : NULL;
430     ovs_mutex_unlock(&log_file_mutex);
431
432     if (fn) {
433         int error = vlog_set_log_file(fn);
434         free(fn);
435         return error;
436     } else {
437         return 0;
438     }
439 }
440
441 #ifndef _WIN32
442 /* In case a log file exists, change its owner to new 'user' and 'group'.
443  *
444  * This is useful for handling cases where the --log-file option is
445  * specified ahead of the --user option.  */
446 void
447 vlog_change_owner_unix(uid_t user, gid_t group)
448 {
449     struct ds err = DS_EMPTY_INITIALIZER;
450     int error;
451
452     ovs_mutex_lock(&log_file_mutex);
453     error = log_file_name ? chown(log_file_name, user, group) : 0;
454     if (error) {
455         /* Build the error message. We can not call VLOG_FATAL directly
456          * here because VLOG_FATAL() will try again to to acquire
457          * 'log_file_mutex' lock, causing deadlock.
458          */
459         ds_put_format(&err, "Failed to change %s ownership: %s.",
460                       log_file_name, ovs_strerror(errno));
461     }
462     ovs_mutex_unlock(&log_file_mutex);
463
464     if (error) {
465         VLOG_FATAL("%s", ds_steal_cstr(&err));
466     }
467 }
468 #endif
469
470 /* Set debugging levels.  Returns null if successful, otherwise an error
471  * message that the caller must free(). */
472 char *
473 vlog_set_levels_from_string(const char *s_)
474 {
475     char *s = xstrdup(s_);
476     char *save_ptr = NULL;
477     char *msg = NULL;
478     char *word;
479
480     word = strtok_r(s, " ,:\t", &save_ptr);
481     if (word && !strcasecmp(word, "PATTERN")) {
482         enum vlog_destination destination;
483
484         word = strtok_r(NULL, " ,:\t", &save_ptr);
485         if (!word) {
486             msg = xstrdup("missing destination");
487             goto exit;
488         }
489
490         destination = (!strcasecmp(word, "ANY")
491                        ? VLF_ANY_DESTINATION
492                        : vlog_get_destination_val(word));
493         if (destination == VLF_N_DESTINATIONS) {
494             msg = xasprintf("unknown destination \"%s\"", word);
495             goto exit;
496         }
497         vlog_set_pattern(destination, save_ptr);
498     } else if (word && !strcasecmp(word, "FACILITY")) {
499         int value;
500
501         if (!vlog_facility_exists(save_ptr, &value)) {
502             msg = xstrdup("invalid facility");
503             goto exit;
504         }
505         atomic_store_explicit(&log_facility, value, memory_order_relaxed);
506     } else {
507         struct vlog_module *module = NULL;
508         enum vlog_level level = VLL_N_LEVELS;
509         enum vlog_destination destination = VLF_N_DESTINATIONS;
510
511         for (; word != NULL; word = strtok_r(NULL, " ,:\t", &save_ptr)) {
512             if (!strcasecmp(word, "ANY")) {
513                 continue;
514             } else if (vlog_get_destination_val(word) != VLF_N_DESTINATIONS) {
515                 if (destination != VLF_N_DESTINATIONS) {
516                     msg = xstrdup("cannot specify multiple destinations");
517                     goto exit;
518                 }
519                 destination = vlog_get_destination_val(word);
520             } else if (vlog_get_level_val(word) != VLL_N_LEVELS) {
521                 if (level != VLL_N_LEVELS) {
522                     msg = xstrdup("cannot specify multiple levels");
523                     goto exit;
524                 }
525                 level = vlog_get_level_val(word);
526             } else if (vlog_module_from_name(word)) {
527                 if (module) {
528                     msg = xstrdup("cannot specify multiple modules");
529                     goto exit;
530                 }
531                 module = vlog_module_from_name(word);
532             } else {
533                 msg = xasprintf("no destination, level, or module \"%s\"",
534                                 word);
535                 goto exit;
536             }
537         }
538
539         if (destination == VLF_N_DESTINATIONS) {
540             destination = VLF_ANY_DESTINATION;
541         }
542         if (level == VLL_N_LEVELS) {
543             level = VLL_DBG;
544         }
545         vlog_set_levels(module, destination, level);
546     }
547
548 exit:
549     free(s);
550     return msg;
551 }
552
553 /* Set debugging levels.  Abort with an error message if 's' is invalid. */
554 void
555 vlog_set_levels_from_string_assert(const char *s)
556 {
557     char *error = vlog_set_levels_from_string(s);
558     if (error) {
559         ovs_fatal(0, "%s", error);
560     }
561 }
562
563 /* If 'arg' is null, configure maximum verbosity.  Otherwise, sets
564  * configuration according to 'arg' (see vlog_set_levels_from_string()). */
565 void
566 vlog_set_verbosity(const char *arg)
567 {
568     if (arg) {
569         char *msg = vlog_set_levels_from_string(arg);
570         if (msg) {
571             ovs_fatal(0, "processing \"%s\": %s", arg, msg);
572         }
573     } else {
574         vlog_set_levels(NULL, VLF_ANY_DESTINATION, VLL_DBG);
575     }
576 }
577
578 void
579 vlog_set_syslog_method(const char *method)
580 {
581     if (syslogger) {
582         /* Set syslogger only, if one is not already set.  This effectively
583          * means that only the first --syslog-method argument is honored. */
584         return;
585     }
586
587     if (!strcmp(method, "libc")) {
588         syslogger = syslog_libc_create();
589     } else if (!strncmp(method, "udp:", 4) || !strncmp(method, "unix:", 5)) {
590         syslogger = syslog_direct_create(method);
591     } else {
592         ovs_fatal(0, "unsupported syslog method '%s'", method);
593     }
594 }
595
596 /* Set the vlog udp syslog target. */
597 void
598 vlog_set_syslog_target(const char *target)
599 {
600     int new_fd;
601
602     inet_open_active(SOCK_DGRAM, target, 0, NULL, &new_fd, 0);
603
604     ovs_rwlock_wrlock(&pattern_rwlock);
605     if (syslog_fd >= 0) {
606         close(syslog_fd);
607     }
608     syslog_fd = new_fd;
609     ovs_rwlock_unlock(&pattern_rwlock);
610 }
611
612 /* Returns 'false' if 'facility' is not a valid string. If 'facility'
613  * is a valid string, sets 'value' with the integer value of 'facility'
614  * and returns 'true'. */
615 static bool
616 vlog_facility_exists(const char* facility, int *value)
617 {
618     size_t i;
619     for (i = 0; i < ARRAY_SIZE(vlog_facilities); i++) {
620         if (!strcasecmp(vlog_facilities[i].name, facility)) {
621             *value = vlog_facilities[i].value;
622             return true;
623         }
624     }
625     return false;
626 }
627
628 static void
629 vlog_unixctl_set(struct unixctl_conn *conn, int argc, const char *argv[],
630                  void *aux OVS_UNUSED)
631 {
632     int i;
633
634     for (i = 1; i < argc; i++) {
635         char *msg = vlog_set_levels_from_string(argv[i]);
636         if (msg) {
637             unixctl_command_reply_error(conn, msg);
638             free(msg);
639             return;
640         }
641     }
642     unixctl_command_reply(conn, NULL);
643 }
644
645 static void
646 vlog_unixctl_list(struct unixctl_conn *conn, int argc OVS_UNUSED,
647                   const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
648 {
649     char *msg = vlog_get_levels();
650     unixctl_command_reply(conn, msg);
651     free(msg);
652 }
653
654 static void
655 vlog_unixctl_list_pattern(struct unixctl_conn *conn, int argc OVS_UNUSED,
656                           const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
657 {
658     char *msg;
659
660     msg = vlog_get_patterns();
661     unixctl_command_reply(conn, msg);
662     free(msg);
663 }
664
665 static void
666 vlog_unixctl_reopen(struct unixctl_conn *conn, int argc OVS_UNUSED,
667                     const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
668 {
669     bool has_log_file;
670
671     ovs_mutex_lock(&log_file_mutex);
672     has_log_file = log_file_name != NULL;
673     ovs_mutex_unlock(&log_file_mutex);
674
675     if (has_log_file) {
676         int error = vlog_reopen_log_file();
677         if (error) {
678             unixctl_command_reply_error(conn, ovs_strerror(errno));
679         } else {
680             unixctl_command_reply(conn, NULL);
681         }
682     } else {
683         unixctl_command_reply_error(conn, "Logging to file not configured");
684     }
685 }
686
687 static void
688 vlog_unixctl_close(struct unixctl_conn *conn, int argc OVS_UNUSED,
689                    const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
690 {
691     ovs_mutex_lock(&log_file_mutex);
692     if (log_fd >= 0) {
693         close(log_fd);
694         log_fd = -1;
695
696         async_append_destroy(log_writer);
697         log_writer = NULL;
698
699         struct vlog_module *mp;
700         LIST_FOR_EACH (mp, list, &vlog_modules) {
701             update_min_level(mp);
702         }
703     }
704     ovs_mutex_unlock(&log_file_mutex);
705
706     unixctl_command_reply(conn, NULL);
707 }
708
709 static void
710 set_all_rate_limits(bool enable)
711 {
712     struct vlog_module *mp;
713
714     ovs_mutex_lock(&log_file_mutex);
715     LIST_FOR_EACH (mp, list, &vlog_modules) {
716         mp->honor_rate_limits = enable;
717     }
718     ovs_mutex_unlock(&log_file_mutex);
719 }
720
721 static void
722 set_rate_limits(struct unixctl_conn *conn, int argc,
723                 const char *argv[], bool enable)
724 {
725     if (argc > 1) {
726         int i;
727
728         for (i = 1; i < argc; i++) {
729             if (!strcasecmp(argv[i], "ANY")) {
730                 set_all_rate_limits(enable);
731             } else {
732                 struct vlog_module *module = vlog_module_from_name(argv[i]);
733                 if (!module) {
734                     unixctl_command_reply_error(conn, "unknown module");
735                     return;
736                 }
737                 module->honor_rate_limits = enable;
738             }
739         }
740     } else {
741         set_all_rate_limits(enable);
742     }
743     unixctl_command_reply(conn, NULL);
744 }
745
746 static void
747 vlog_enable_rate_limit(struct unixctl_conn *conn, int argc,
748                        const char *argv[], void *aux OVS_UNUSED)
749 {
750     set_rate_limits(conn, argc, argv, true);
751 }
752
753 static void
754 vlog_disable_rate_limit(struct unixctl_conn *conn, int argc,
755                        const char *argv[], void *aux OVS_UNUSED)
756 {
757     set_rate_limits(conn, argc, argv, false);
758 }
759
760 /* Initializes the logging subsystem and registers its unixctl server
761  * commands. */
762 void
763 vlog_init(void)
764 {
765     static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
766
767     if (ovsthread_once_start(&once)) {
768         long long int now;
769         int facility;
770         bool print_syslog_target_deprecation;
771
772         /* Do initialization work that needs to be done before any logging
773          * occurs.  We want to keep this really minimal because any attempt to
774          * log anything before calling ovsthread_once_done() will deadlock. */
775         atomic_read_explicit(&log_facility, &facility, memory_order_relaxed);
776         if (!syslogger) {
777             syslogger = syslog_libc_create();
778         }
779         syslogger->class->openlog(syslogger, facility ? facility : LOG_DAEMON);
780         ovsthread_once_done(&once);
781
782         /* Now do anything that we want to happen only once but doesn't have to
783          * finish before we start logging. */
784
785         now = time_wall_msec();
786         if (now < 0) {
787             char *s = xastrftime_msec("%a, %d %b %Y %H:%M:%S", now, true);
788             VLOG_ERR("current time is negative: %s (%lld)", s, now);
789             free(s);
790         }
791
792         unixctl_command_register(
793             "vlog/set", "{spec | PATTERN:destination:pattern}",
794             1, INT_MAX, vlog_unixctl_set, NULL);
795         unixctl_command_register("vlog/list", "", 0, 0, vlog_unixctl_list,
796                                  NULL);
797         unixctl_command_register("vlog/list-pattern", "", 0, 0,
798                                  vlog_unixctl_list_pattern, NULL);
799         unixctl_command_register("vlog/enable-rate-limit", "[module]...",
800                                  0, INT_MAX, vlog_enable_rate_limit, NULL);
801         unixctl_command_register("vlog/disable-rate-limit", "[module]...",
802                                  0, INT_MAX, vlog_disable_rate_limit, NULL);
803         unixctl_command_register("vlog/reopen", "", 0, 0,
804                                  vlog_unixctl_reopen, NULL);
805         unixctl_command_register("vlog/close", "", 0, 0,
806                                  vlog_unixctl_close, NULL);
807
808         ovs_rwlock_rdlock(&pattern_rwlock);
809         print_syslog_target_deprecation = syslog_fd >= 0;
810         ovs_rwlock_unlock(&pattern_rwlock);
811
812         if (print_syslog_target_deprecation) {
813             VLOG_WARN("--syslog-target flag is deprecated, use "
814                       "--syslog-method instead");
815         }
816     }
817 }
818
819 /* Enables VLF_FILE log output to be written asynchronously to disk.
820  * Asynchronous file writes avoid blocking the process in the case of a busy
821  * disk, but on the other hand they are less robust: there is a chance that the
822  * write will not make it to the log file if the process crashes soon after the
823  * log call. */
824 void
825 vlog_enable_async(void)
826 {
827     ovs_mutex_lock(&log_file_mutex);
828     log_async = true;
829     if (log_fd >= 0 && !log_writer) {
830         log_writer = async_append_create(log_fd);
831     }
832     ovs_mutex_unlock(&log_file_mutex);
833 }
834
835 /* Print the current logging level for each module. */
836 char *
837 vlog_get_levels(void)
838 {
839     struct ds s = DS_EMPTY_INITIALIZER;
840     struct vlog_module *mp;
841     struct svec lines = SVEC_EMPTY_INITIALIZER;
842     char *line;
843     size_t i;
844
845     ds_put_format(&s, "                 console    syslog    file\n");
846     ds_put_format(&s, "                 -------    ------    ------\n");
847
848     ovs_mutex_lock(&log_file_mutex);
849     LIST_FOR_EACH (mp, list, &vlog_modules) {
850         struct ds line;
851
852         ds_init(&line);
853         ds_put_format(&line, "%-16s  %4s       %4s       %4s",
854                       vlog_get_module_name(mp),
855                       vlog_get_level_name(vlog_get_level(mp, VLF_CONSOLE)),
856                       vlog_get_level_name(vlog_get_level(mp, VLF_SYSLOG)),
857                       vlog_get_level_name(vlog_get_level(mp, VLF_FILE)));
858         if (!mp->honor_rate_limits) {
859             ds_put_cstr(&line, "    (rate limiting disabled)");
860         }
861         ds_put_char(&line, '\n');
862
863         svec_add_nocopy(&lines, ds_steal_cstr(&line));
864     }
865     ovs_mutex_unlock(&log_file_mutex);
866
867     svec_sort(&lines);
868     SVEC_FOR_EACH (i, line, &lines) {
869         ds_put_cstr(&s, line);
870     }
871     svec_destroy(&lines);
872
873     return ds_cstr(&s);
874 }
875
876 /* Returns as a string current logging patterns for each destination.
877  * This string must be released by caller. */
878 char *
879 vlog_get_patterns(void)
880 {
881     struct ds ds = DS_EMPTY_INITIALIZER;
882     enum vlog_destination destination;
883
884     ovs_rwlock_rdlock(&pattern_rwlock);
885     ds_put_format(&ds, "         prefix                            format\n");
886     ds_put_format(&ds, "         ------                            ------\n");
887
888     for (destination = 0; destination < VLF_N_DESTINATIONS; destination++) {
889         struct destination *f = &destinations[destination];
890         const char *prefix = "none";
891
892         if (destination == VLF_SYSLOG && syslogger) {
893             prefix = syslog_get_prefix(syslogger);
894         }
895         ds_put_format(&ds, "%-7s  %-32s  %s\n", f->name, prefix, f->pattern);
896     }
897     ovs_rwlock_unlock(&pattern_rwlock);
898
899     return ds_cstr(&ds);
900 }
901
902 /* Returns true if a log message emitted for the given 'module' and 'level'
903  * would cause some log output, false if that module and level are completely
904  * disabled. */
905 bool
906 vlog_is_enabled(const struct vlog_module *module, enum vlog_level level)
907 {
908     return module->min_level >= level;
909 }
910
911 static const char *
912 fetch_braces(const char *p, const char *def, char *out, size_t out_size)
913 {
914     if (*p == '{') {
915         size_t n = strcspn(p + 1, "}");
916         size_t n_copy = MIN(n, out_size - 1);
917         memcpy(out, p + 1, n_copy);
918         out[n_copy] = '\0';
919         p += n + 2;
920     } else {
921         ovs_strlcpy(out, def, out_size);
922     }
923     return p;
924 }
925
926 static void
927 format_log_message(const struct vlog_module *module, enum vlog_level level,
928                    const char *pattern, const char *message,
929                    va_list args_, struct ds *s)
930 {
931     char tmp[128];
932     va_list args;
933     const char *p;
934     int facility;
935
936     ds_clear(s);
937     for (p = pattern; *p != '\0'; ) {
938         const char *subprogram_name;
939         enum { LEFT, RIGHT } justify = RIGHT;
940         int pad = '0';
941         size_t length, field, used;
942
943         if (*p != '%') {
944             ds_put_char(s, *p++);
945             continue;
946         }
947
948         p++;
949         if (*p == '-') {
950             justify = LEFT;
951             p++;
952         }
953         if (*p == '0') {
954             pad = '0';
955             p++;
956         }
957         field = 0;
958         while (isdigit((unsigned char)*p)) {
959             field = (field * 10) + (*p - '0');
960             p++;
961         }
962
963         length = s->length;
964         switch (*p++) {
965         case 'A':
966             ds_put_cstr(s, program_name);
967             break;
968         case 'B':
969             atomic_read_explicit(&log_facility, &facility,
970                                  memory_order_relaxed);
971             facility = facility ? facility : LOG_LOCAL0;
972             ds_put_format(s, "%d", facility + syslog_levels[level]);
973             break;
974         case 'c':
975             p = fetch_braces(p, "", tmp, sizeof tmp);
976             ds_put_cstr(s, vlog_get_module_name(module));
977             break;
978         case 'd':
979             p = fetch_braces(p, "%Y-%m-%d %H:%M:%S.###", tmp, sizeof tmp);
980             ds_put_strftime_msec(s, tmp, time_wall_msec(), false);
981             break;
982         case 'D':
983             p = fetch_braces(p, "%Y-%m-%d %H:%M:%S.###", tmp, sizeof tmp);
984             ds_put_strftime_msec(s, tmp, time_wall_msec(), true);
985             break;
986         case 'E':
987             gethostname(tmp, sizeof tmp);
988             tmp[sizeof tmp - 1] = '\0';
989             ds_put_cstr(s, tmp);
990             break;
991         case 'm':
992             /* Format user-supplied log message and trim trailing new-lines. */
993             length = s->length;
994             va_copy(args, args_);
995             ds_put_format_valist(s, message, args);
996             va_end(args);
997             while (s->length > length && s->string[s->length - 1] == '\n') {
998                 s->length--;
999             }
1000             break;
1001         case 'N':
1002             ds_put_format(s, "%u", *msg_num_get_unsafe());
1003             break;
1004         case 'n':
1005             ds_put_char(s, '\n');
1006             break;
1007         case 'p':
1008             ds_put_cstr(s, vlog_get_level_name(level));
1009             break;
1010         case 'P':
1011             ds_put_format(s, "%ld", (long int) getpid());
1012             break;
1013         case 'r':
1014             ds_put_format(s, "%lld", time_msec() - time_boot_msec());
1015             break;
1016         case 't':
1017             subprogram_name = get_subprogram_name();
1018             ds_put_cstr(s, subprogram_name[0] ? subprogram_name : "main");
1019             break;
1020         case 'T':
1021             subprogram_name = get_subprogram_name();
1022             if (subprogram_name[0]) {
1023                 ds_put_format(s, "(%s)", subprogram_name);
1024             }
1025             break;
1026         default:
1027             ds_put_char(s, p[-1]);
1028             break;
1029         }
1030         used = s->length - length;
1031         if (used < field) {
1032             size_t n_pad = field - used;
1033             if (justify == RIGHT) {
1034                 ds_put_uninit(s, n_pad);
1035                 memmove(&s->string[length + n_pad], &s->string[length], used);
1036                 memset(&s->string[length], pad, n_pad);
1037             } else {
1038                 ds_put_char_multiple(s, pad, n_pad);
1039             }
1040         }
1041     }
1042 }
1043
1044 /* Exports the given 'syslog_message' to the configured udp syslog sink. */
1045 static void
1046 send_to_syslog_fd(const char *s, size_t length)
1047     OVS_REQ_RDLOCK(pattern_rwlock)
1048 {
1049     static size_t max_length = SIZE_MAX;
1050     size_t send_len = MIN(length, max_length);
1051
1052     while (write(syslog_fd, s, send_len) < 0 && errno == EMSGSIZE) {
1053         send_len -= send_len / 20;
1054         max_length = send_len;
1055     }
1056 }
1057
1058 /* Writes 'message' to the log at the given 'level' and as coming from the
1059  * given 'module'.
1060  *
1061  * Guaranteed to preserve errno. */
1062 void
1063 vlog_valist(const struct vlog_module *module, enum vlog_level level,
1064             const char *message, va_list args)
1065 {
1066     bool log_to_console = module->levels[VLF_CONSOLE] >= level;
1067     bool log_to_syslog = module->levels[VLF_SYSLOG] >= level;
1068     bool log_to_file;
1069
1070     ovs_mutex_lock(&log_file_mutex);
1071     log_to_file = module->levels[VLF_FILE] >= level && log_fd >= 0;
1072     ovs_mutex_unlock(&log_file_mutex);
1073     if (log_to_console || log_to_syslog || log_to_file) {
1074         int save_errno = errno;
1075         struct ds s;
1076
1077         vlog_init();
1078
1079         ds_init(&s);
1080         ds_reserve(&s, 1024);
1081         ++*msg_num_get();
1082
1083         ovs_rwlock_rdlock(&pattern_rwlock);
1084         if (log_to_console) {
1085             format_log_message(module, level,
1086                                destinations[VLF_CONSOLE].pattern, message,
1087                                args, &s);
1088             ds_put_char(&s, '\n');
1089             fputs(ds_cstr(&s), stderr);
1090         }
1091
1092         if (log_to_syslog) {
1093             int syslog_level = syslog_levels[level];
1094             char *save_ptr = NULL;
1095             char *line;
1096             int facility;
1097
1098             format_log_message(module, level, destinations[VLF_SYSLOG].pattern,
1099                                message, args, &s);
1100             for (line = strtok_r(s.string, "\n", &save_ptr); line;
1101                  line = strtok_r(NULL, "\n", &save_ptr)) {
1102                 atomic_read_explicit(&log_facility, &facility,
1103                                      memory_order_relaxed);
1104                 syslogger->class->syslog(syslogger, syslog_level|facility, line);
1105             }
1106
1107             if (syslog_fd >= 0) {
1108                 format_log_message(module, level,
1109                                    "<%B>1 %D{%Y-%m-%dT%H:%M:%S.###Z} "
1110                                    "%E %A %P %c - \xef\xbb\xbf%m",
1111                                    message, args, &s);
1112                 send_to_syslog_fd(ds_cstr(&s), s.length);
1113             }
1114         }
1115
1116         if (log_to_file) {
1117             format_log_message(module, level, destinations[VLF_FILE].pattern,
1118                                message, args, &s);
1119             ds_put_char(&s, '\n');
1120
1121             ovs_mutex_lock(&log_file_mutex);
1122             if (log_fd >= 0) {
1123                 if (log_writer) {
1124                     async_append_write(log_writer, s.string, s.length);
1125                     if (level == VLL_EMER) {
1126                         async_append_flush(log_writer);
1127                     }
1128                 } else {
1129                     ignore(write(log_fd, s.string, s.length));
1130                 }
1131             }
1132             ovs_mutex_unlock(&log_file_mutex);
1133         }
1134         ovs_rwlock_unlock(&pattern_rwlock);
1135
1136         ds_destroy(&s);
1137         errno = save_errno;
1138     }
1139 }
1140
1141 void
1142 vlog(const struct vlog_module *module, enum vlog_level level,
1143      const char *message, ...)
1144 {
1145     va_list args;
1146
1147     va_start(args, message);
1148     vlog_valist(module, level, message, args);
1149     va_end(args);
1150 }
1151
1152 /* Logs 'message' to 'module' at maximum verbosity, then exits with a failure
1153  * exit code.  Always writes the message to stderr, even if the console
1154  * destination is disabled.
1155  *
1156  * Choose this function instead of vlog_abort_valist() if the daemon monitoring
1157  * facility shouldn't automatically restart the current daemon.  */
1158 void
1159 vlog_fatal_valist(const struct vlog_module *module_,
1160                   const char *message, va_list args)
1161 {
1162     struct vlog_module *module = CONST_CAST(struct vlog_module *, module_);
1163
1164     /* Don't log this message to the console to avoid redundancy with the
1165      * message written by the later ovs_fatal_valist(). */
1166     module->levels[VLF_CONSOLE] = VLL_OFF;
1167
1168     vlog_valist(module, VLL_EMER, message, args);
1169     ovs_fatal_valist(0, message, args);
1170 }
1171
1172 /* Logs 'message' to 'module' at maximum verbosity, then exits with a failure
1173  * exit code.  Always writes the message to stderr, even if the console
1174  * destination is disabled.
1175  *
1176  * Choose this function instead of vlog_abort() if the daemon monitoring
1177  * facility shouldn't automatically restart the current daemon.  */
1178 void
1179 vlog_fatal(const struct vlog_module *module, const char *message, ...)
1180 {
1181     va_list args;
1182
1183     va_start(args, message);
1184     vlog_fatal_valist(module, message, args);
1185     va_end(args);
1186 }
1187
1188 /* Logs 'message' to 'module' at maximum verbosity, then calls abort().  Always
1189  * writes the message to stderr, even if the console destination is disabled.
1190  *
1191  * Choose this function instead of vlog_fatal_valist() if the daemon monitoring
1192  * facility should automatically restart the current daemon.  */
1193 void
1194 vlog_abort_valist(const struct vlog_module *module_,
1195                   const char *message, va_list args)
1196 {
1197     struct vlog_module *module = (struct vlog_module *) module_;
1198
1199     /* Don't log this message to the console to avoid redundancy with the
1200      * message written by the later ovs_abort_valist(). */
1201     module->levels[VLF_CONSOLE] = VLL_OFF;
1202
1203     vlog_valist(module, VLL_EMER, message, args);
1204     ovs_abort_valist(0, message, args);
1205 }
1206
1207 /* Logs 'message' to 'module' at maximum verbosity, then calls abort().  Always
1208  * writes the message to stderr, even if the console destination is disabled.
1209  *
1210  * Choose this function instead of vlog_fatal() if the daemon monitoring
1211  * facility should automatically restart the current daemon.  */
1212 void
1213 vlog_abort(const struct vlog_module *module, const char *message, ...)
1214 {
1215     va_list args;
1216
1217     va_start(args, message);
1218     vlog_abort_valist(module, message, args);
1219     va_end(args);
1220 }
1221
1222 bool
1223 vlog_should_drop(const struct vlog_module *module, enum vlog_level level,
1224                  struct vlog_rate_limit *rl)
1225 {
1226     if (!module->honor_rate_limits) {
1227         return false;
1228     }
1229
1230     if (!vlog_is_enabled(module, level)) {
1231         return true;
1232     }
1233
1234     ovs_mutex_lock(&rl->mutex);
1235     if (!token_bucket_withdraw(&rl->token_bucket, VLOG_MSG_TOKENS)) {
1236         time_t now = time_now();
1237         if (!rl->n_dropped) {
1238             rl->first_dropped = now;
1239         }
1240         rl->last_dropped = now;
1241         rl->n_dropped++;
1242         ovs_mutex_unlock(&rl->mutex);
1243         return true;
1244     }
1245
1246     if (!rl->n_dropped) {
1247         ovs_mutex_unlock(&rl->mutex);
1248     } else {
1249         time_t now = time_now();
1250         unsigned int n_dropped = rl->n_dropped;
1251         unsigned int first_dropped_elapsed = now - rl->first_dropped;
1252         unsigned int last_dropped_elapsed = now - rl->last_dropped;
1253         rl->n_dropped = 0;
1254         ovs_mutex_unlock(&rl->mutex);
1255
1256         vlog(module, level,
1257              "Dropped %u log messages in last %u seconds (most recently, "
1258              "%u seconds ago) due to excessive rate",
1259              n_dropped, first_dropped_elapsed, last_dropped_elapsed);
1260     }
1261
1262     return false;
1263 }
1264
1265 void
1266 vlog_rate_limit(const struct vlog_module *module, enum vlog_level level,
1267                 struct vlog_rate_limit *rl, const char *message, ...)
1268 {
1269     if (!vlog_should_drop(module, level, rl)) {
1270         va_list args;
1271
1272         va_start(args, message);
1273         vlog_valist(module, level, message, args);
1274         va_end(args);
1275     }
1276 }
1277
1278 void
1279 vlog_usage(void)
1280 {
1281     printf("\n\
1282 Logging options:\n\
1283   -vSPEC, --verbose=SPEC   set logging levels\n\
1284   -v, --verbose            set maximum verbosity level\n\
1285   --log-file[=FILE]        enable logging to specified FILE\n\
1286                            (default: %s/%s.log)\n\
1287   --syslog-method=(libc|unix:file|udp:ip:port)\n\
1288                            specify how to send messages to syslog daemon\n\
1289   --syslog-target=HOST:PORT  also send syslog msgs to HOST:PORT via UDP\n",
1290            ovs_logdir(), program_name);
1291 }