<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/15560">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">logging: Introduce mutex API to manage log_target in multi-thread envs<br><br>* log_enable_multithread() enables use of locks inside the<br>implementation. Lock use is disabled by default, this way only<br>multi-thread processes need to enable it and suffer related<br>complexity/performance penalties.<br><br>Locks are required around osmo_log_target_list and items inside it,<br>since targets can be used, modified and deleted by different threads<br>concurrently (for instance, user writing "logging disable" in VTY while<br>another thread is willing to write into that target).<br><br>Multithread apps and libraries aiming at being used in multithread apps<br>should update their code to use the locks introduced here when<br>containing code iterating over osmo_log_target_list explictly or<br>implicitly by obtaining a log_target (eg. osmo_log_vty2tgt()).<br><br>Related: OS#4088<br>Change-Id: Id7711893b34263baacac6caf4d489467053131bb<br>---<br>M include/osmocom/core/logging.h<br>M src/gb/gprs_bssgp_vty.c<br>M src/gb/gprs_ns_vty.c<br>M src/logging.c<br>M src/vty/logging_vty.c<br>M tests/logging/logging_vty_test.c<br>6 files changed, 202 insertions(+), 93 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/60/15560/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/core/logging.h b/include/osmocom/core/logging.h</span><br><span>index c2648f3..73df8e9 100644</span><br><span>--- a/include/osmocom/core/logging.h</span><br><span>+++ b/include/osmocom/core/logging.h</span><br><span>@@ -378,4 +378,18 @@</span><br><span> </span><br><span> struct log_target *log_target_find(int type, const char *fname);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void log_enable_multithread(void);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define LOG_MTX_DEBUG 0</span><br><span style="color: hsl(120, 100%, 40%);">+#if LOG_MTX_DEBUG</span><br><span style="color: hsl(120, 100%, 40%);">+     #include <pthread.h></span><br><span style="color: hsl(120, 100%, 40%);">+    void _log_tgt_mutex_lock(void);</span><br><span style="color: hsl(120, 100%, 40%);">+       void _log_tgt_mutex_unlock(void);</span><br><span style="color: hsl(120, 100%, 40%);">+     #define log_tgt_mutex_lock() do { fprintf(stderr, "[%lu] %s:%d [%s] lock\n", pthread_self(), __FILE__, __LINE__, __func__); _log_tgt_mutex_lock(); } while (0)</span><br><span style="color: hsl(120, 100%, 40%);">+      #define log_tgt_mutex_unlock() do { fprintf(stderr, "[%lu] %s:%d [%s] unlock\n", pthread_self(), __FILE__, __LINE__, __func__); _log_tgt_mutex_unlock(); } while (0)</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+ void log_tgt_mutex_lock(void);</span><br><span style="color: hsl(120, 100%, 40%);">+        void log_tgt_mutex_unlock(void);</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! @} */</span><br><span>diff --git a/src/gb/gprs_bssgp_vty.c b/src/gb/gprs_bssgp_vty.c</span><br><span>index 3af6517..5dab94e 100644</span><br><span>--- a/src/gb/gprs_bssgp_vty.c</span><br><span>+++ b/src/gb/gprs_bssgp_vty.c</span><br><span>@@ -181,21 +181,27 @@</span><br><span>     "BVCI of the BVC to be filtered\n"</span><br><span>         "BSSGP Virtual Connection Identifier (BVCI)\n")</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct log_target *tgt;</span><br><span>      struct bssgp_bvc_ctx *bvc;</span><br><span>   uint16_t nsei = atoi(argv[0]);</span><br><span>       uint16_t bvci = atoi(argv[1]);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      if (!tgt)</span><br><span style="color: hsl(120, 100%, 40%);">+     log_tgt_mutex_lock();</span><br><span style="color: hsl(120, 100%, 40%);">+ tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!tgt) {</span><br><span style="color: hsl(120, 100%, 40%);">+           log_tgt_mutex_unlock();</span><br><span>              return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span> </span><br><span>        bvc = btsctx_by_bvci_nsei(bvci, nsei);</span><br><span>       if (!bvc) {</span><br><span>          vty_out(vty, "No BVC by that identifier%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+           log_tgt_mutex_unlock();</span><br><span>              return CMD_WARNING;</span><br><span>  }</span><br><span> </span><br><span>        log_set_bvc_filter(tgt, bvc);</span><br><span style="color: hsl(120, 100%, 40%);">+ log_tgt_mutex_unlock();</span><br><span>      return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>diff --git a/src/gb/gprs_ns_vty.c b/src/gb/gprs_ns_vty.c</span><br><span>index 53c71a9..4a90436 100644</span><br><span>--- a/src/gb/gprs_ns_vty.c</span><br><span>+++ b/src/gb/gprs_ns_vty.c</span><br><span>@@ -587,12 +587,16 @@</span><br><span>    "Identify NS-VC by NSVCI\n"</span><br><span>        "Numeric identifier\n")</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct log_target *tgt;</span><br><span>      struct gprs_nsvc *nsvc;</span><br><span>      uint16_t id = atoi(argv[1]);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        if (!tgt)</span><br><span style="color: hsl(120, 100%, 40%);">+     log_tgt_mutex_lock();</span><br><span style="color: hsl(120, 100%, 40%);">+ tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!tgt) {</span><br><span style="color: hsl(120, 100%, 40%);">+           log_tgt_mutex_unlock();</span><br><span>              return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span> </span><br><span>        if (!strcmp(argv[0], "nsei"))</span><br><span>              nsvc = gprs_nsvc_by_nsei(vty_nsi, id);</span><br><span>@@ -601,10 +605,12 @@</span><br><span> </span><br><span>   if (!nsvc) {</span><br><span>                 vty_out(vty, "No NS-VC by that identifier%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+         log_tgt_mutex_unlock();</span><br><span>              return CMD_WARNING;</span><br><span>  }</span><br><span> </span><br><span>        log_set_nsvc_filter(tgt, nsvc);</span><br><span style="color: hsl(120, 100%, 40%);">+       log_tgt_mutex_unlock();</span><br><span>      return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>diff --git a/src/logging.c b/src/logging.c</span><br><span>index 1c3544f..57d6ee4 100644</span><br><span>--- a/src/logging.c</span><br><span>+++ b/src/logging.c</span><br><span>@@ -42,6 +42,7 @@</span><br><span> #include <time.h></span><br><span> #include <sys/time.h></span><br><span> #include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <pthread.h></span><br><span> </span><br><span> #include <osmocom/core/talloc.h></span><br><span> #include <osmocom/core/utils.h></span><br><span>@@ -63,6 +64,54 @@</span><br><span> void *tall_log_ctx = NULL;</span><br><span> LLIST_HEAD(osmo_log_target_list);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! This mutex must be hold while using osmo_log_target_list or any of its</span><br><span style="color: hsl(120, 100%, 40%);">+   log_targets. Prevents race conditions between threads like producing</span><br><span style="color: hsl(120, 100%, 40%);">+   unordered timestamps or VTY deleting a target while another thread is writing</span><br><span style="color: hsl(120, 100%, 40%);">+   to it */</span><br><span style="color: hsl(120, 100%, 40%);">+pthread_mutex_t osmo_log_tgt_mutex;</span><br><span style="color: hsl(120, 100%, 40%);">+bool osmo_log_tgt_mutex_on = false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Enable multithread support (mutex) in libosmocore logging system.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Must be called by processes willing to use logging subsystem from several</span><br><span style="color: hsl(120, 100%, 40%);">+ * threads. Once enabled, it's not possible to disable it again.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void log_enable_multithread(void) {</span><br><span style="color: hsl(120, 100%, 40%);">+   if (osmo_log_tgt_mutex_on)</span><br><span style="color: hsl(120, 100%, 40%);">+            return;</span><br><span style="color: hsl(120, 100%, 40%);">+       pthread_mutex_init(&osmo_log_tgt_mutex, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo_log_tgt_mutex_on = true;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Acquire the osmo_log_tgt_mutex.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#if LOG_MTX_DEBUG</span><br><span style="color: hsl(120, 100%, 40%);">+void _log_tgt_mutex_lock(void) {</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+void log_tgt_mutex_lock(void) {</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+/* These lines are useful to debug scenarios where there's only 1 thread and a</span><br><span style="color: hsl(120, 100%, 40%);">+   double lock appears, for instance during startup and some unlock() missing</span><br><span style="color: hsl(120, 100%, 40%);">+   somewhere:</span><br><span style="color: hsl(120, 100%, 40%);">+   if (osmo_log_tgt_mutex_on && pthread_mutex_trylock(&osmo_log_tgt_mutex) != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+             osmo_panic("acquiring already locked mutex!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+    return;</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (osmo_log_tgt_mutex_on)</span><br><span style="color: hsl(120, 100%, 40%);">+            pthread_mutex_lock(&osmo_log_tgt_mutex);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Release the osmo_log_tgt_mutex.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#if LOG_MTX_DEBUG</span><br><span style="color: hsl(120, 100%, 40%);">+void _log_tgt_mutex_unlock(void) {</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+void log_tgt_mutex_unlock(void) {</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+  if (osmo_log_tgt_mutex_on)</span><br><span style="color: hsl(120, 100%, 40%);">+            pthread_mutex_unlock(&osmo_log_tgt_mutex);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> const struct value_string loglevel_strs[] = {</span><br><span>         { LOGL_DEBUG,   "DEBUG" },</span><br><span>         { LOGL_INFO,    "INFO" },</span><br><span>@@ -532,6 +581,8 @@</span><br><span> </span><br><span>        subsys = map_subsys(subsys);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+      log_tgt_mutex_lock();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      llist_for_each_entry(tar, &osmo_log_target_list, entry) {</span><br><span>                va_list bp;</span><br><span> </span><br><span>@@ -548,6 +599,8 @@</span><br><span>                        _output(tar, subsys, level, file, line, cont, format, bp);</span><br><span>           va_end(bp);</span><br><span>  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   log_tgt_mutex_unlock();</span><br><span> }</span><br><span> </span><br><span> /*! logging function used by DEBUGP() macro</span><br><span>@@ -866,7 +919,7 @@</span><br><span> }</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/*! Find a registered log target</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Find a registered log target. Must be called with mutex locked.</span><br><span>  *  \param[in] type Log target type</span><br><span>  *  \param[in] fname File name</span><br><span>  *  \returns Log target (if found), NULL otherwise</span><br><span>@@ -942,6 +995,8 @@</span><br><span>   struct log_target *tar;</span><br><span>      int rc = 0;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       log_tgt_mutex_lock();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      llist_for_each_entry(tar, &osmo_log_target_list, entry) {</span><br><span>                switch (tar->type) {</span><br><span>              case LOG_TGT_TYPE_FILE:</span><br><span>@@ -953,6 +1008,8 @@</span><br><span>               }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ log_tgt_mutex_lock();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      return rc;</span><br><span> }</span><br><span> </span><br><span>@@ -1015,6 +1072,8 @@</span><br><span> {</span><br><span>     struct log_target *tar, *tar2;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+    log_tgt_mutex_lock();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      llist_for_each_entry_safe(tar, tar2, &osmo_log_target_list, entry)</span><br><span>               log_target_destroy(tar);</span><br><span> </span><br><span>@@ -1022,6 +1081,8 @@</span><br><span>         osmo_log_info = NULL;</span><br><span>        talloc_free(tall_log_ctx);</span><br><span>   tall_log_ctx = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        log_tgt_mutex_unlock();</span><br><span> }</span><br><span> </span><br><span> /*! Check whether a log entry will be generated.</span><br><span>@@ -1036,15 +1097,19 @@</span><br><span> </span><br><span>   /* TODO: The following could/should be cached (update on config) */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       log_tgt_mutex_lock();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      llist_for_each_entry(tar, &osmo_log_target_list, entry) {</span><br><span>                if (!should_log_to_target(tar, subsys, level))</span><br><span>                       continue;</span><br><span> </span><br><span>                /* This might get logged (ignoring filters) */</span><br><span style="color: hsl(120, 100%, 40%);">+                log_tgt_mutex_unlock();</span><br><span>              return 1;</span><br><span>    }</span><br><span> </span><br><span>        /* We are sure, that this will not be logged. */</span><br><span style="color: hsl(120, 100%, 40%);">+      log_tgt_mutex_unlock();</span><br><span>      return 0;</span><br><span> }</span><br><span> </span><br><span>diff --git a/src/vty/logging_vty.c b/src/vty/logging_vty.c</span><br><span>index d639a8f..a772fa5 100644</span><br><span>--- a/src/vty/logging_vty.c</span><br><span>+++ b/src/vty/logging_vty.c</span><br><span>@@ -101,6 +101,22 @@</span><br><span>   return target;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Get tgt with log lock acquired, return and release lock if tgt is not found.</span><br><span style="color: hsl(120, 100%, 40%);">+   Lock must be released later with log_tgt_mutex_unlock()  */</span><br><span style="color: hsl(120, 100%, 40%);">+#define ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt) do { \</span><br><span style="color: hsl(120, 100%, 40%);">+              log_tgt_mutex_lock(); \</span><br><span style="color: hsl(120, 100%, 40%);">+               tgt = osmo_log_vty2tgt(vty); \</span><br><span style="color: hsl(120, 100%, 40%);">+                if (!(tgt)) { \</span><br><span style="color: hsl(120, 100%, 40%);">+                       log_tgt_mutex_unlock(); \</span><br><span style="color: hsl(120, 100%, 40%);">+                     return CMD_WARNING; \</span><br><span style="color: hsl(120, 100%, 40%);">+         } \</span><br><span style="color: hsl(120, 100%, 40%);">+           } while (0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define RET_WITH_UNLOCK(ret) do { \</span><br><span style="color: hsl(120, 100%, 40%);">+    log_tgt_mutex_unlock(); \</span><br><span style="color: hsl(120, 100%, 40%);">+     return (ret); \</span><br><span style="color: hsl(120, 100%, 40%);">+       } while (0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> DEFUN(enable_logging,</span><br><span>       enable_logging_cmd,</span><br><span>       "logging enable",</span><br><span>@@ -118,9 +134,9 @@</span><br><span>       conn->dbg = log_target_create_vty(vty);</span><br><span>   if (!conn->dbg)</span><br><span>           return CMD_WARNING;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+   log_tgt_mutex_lock();</span><br><span>        log_add_target(conn->dbg);</span><br><span style="color: hsl(0, 100%, 40%);">-   return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> struct log_target *osmo_log_vty2tgt(struct vty *vty)</span><br><span>@@ -146,13 +162,12 @@</span><br><span>       "Only print messages matched by other filters\n"</span><br><span>   "Bypass filter and print all messages\n")</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     if (!tgt)</span><br><span style="color: hsl(0, 100%, 40%);">-               return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);</span><br><span> </span><br><span>         log_set_all_filter(tgt, atoi(argv[0]));</span><br><span style="color: hsl(0, 100%, 40%);">- return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> DEFUN(logging_use_clr,</span><br><span>@@ -162,13 +177,12 @@</span><br><span>       "Don't use color for printing messages\n"</span><br><span>       "Use color for printing messages\n")</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     if (!tgt)</span><br><span style="color: hsl(0, 100%, 40%);">-               return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);</span><br><span> </span><br><span>         log_set_use_color(tgt, atoi(argv[0]));</span><br><span style="color: hsl(0, 100%, 40%);">-  return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> DEFUN(logging_prnt_timestamp,</span><br><span>@@ -178,13 +192,12 @@</span><br><span>      "Don't prefix each log message\n"</span><br><span>      "Prefix each log message with current timestamp\n")</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     if (!tgt)</span><br><span style="color: hsl(0, 100%, 40%);">-               return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);</span><br><span> </span><br><span>         log_set_print_timestamp(tgt, atoi(argv[0]));</span><br><span style="color: hsl(0, 100%, 40%);">-    return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> DEFUN(logging_prnt_ext_timestamp,</span><br><span>@@ -195,13 +208,12 @@</span><br><span>  "Don't prefix each log message\n"</span><br><span>      "Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn\n")</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     if (!tgt)</span><br><span style="color: hsl(0, 100%, 40%);">-               return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);</span><br><span> </span><br><span>         log_set_print_extended_timestamp(tgt, atoi(argv[0]));</span><br><span style="color: hsl(0, 100%, 40%);">-   return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> DEFUN(logging_prnt_cat,</span><br><span>@@ -212,13 +224,11 @@</span><br><span>    "Don't prefix each log message\n"</span><br><span>      "Prefix each log message with category/subsystem name\n")</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!tgt)</span><br><span style="color: hsl(0, 100%, 40%);">-               return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct log_target *tgt;</span><br><span style="color: hsl(120, 100%, 40%);">+       ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);</span><br><span> </span><br><span>         log_set_print_category(tgt, atoi(argv[0]));</span><br><span style="color: hsl(0, 100%, 40%);">-     return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> DEFUN(logging_prnt_cat_hex,</span><br><span>@@ -229,13 +239,12 @@</span><br><span>        "Don't prefix each log message\n"</span><br><span>      "Prefix each log message with category/subsystem nr in hex ('<000b>')\n")</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     if (!tgt)</span><br><span style="color: hsl(0, 100%, 40%);">-               return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);</span><br><span> </span><br><span>         log_set_print_category_hex(tgt, atoi(argv[0]));</span><br><span style="color: hsl(0, 100%, 40%);">- return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> DEFUN(logging_prnt_level,</span><br><span>@@ -246,13 +255,12 @@</span><br><span>       "Don't prefix each log message\n"</span><br><span>       "Prefix each log message with the log level name\n")</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     if (!tgt)</span><br><span style="color: hsl(0, 100%, 40%);">-               return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);</span><br><span> </span><br><span>         log_set_print_level(tgt, atoi(argv[0]));</span><br><span style="color: hsl(0, 100%, 40%);">-        return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> static const struct value_string logging_print_file_args[] = {</span><br><span>@@ -273,17 +281,16 @@</span><br><span>       "Log source file info at the end of a log line. If omitted, log source file info just"</span><br><span>       " before the log text.\n")</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     if (!tgt)</span><br><span style="color: hsl(0, 100%, 40%);">-               return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);</span><br><span> </span><br><span>         log_set_print_filename2(tgt, get_string_value(logging_print_file_args, argv[0]));</span><br><span>    if (argc > 1)</span><br><span>             log_set_print_filename_pos(tgt, LOG_FILENAME_POS_LINE_END);</span><br><span>  else</span><br><span>                 log_set_print_filename_pos(tgt, LOG_FILENAME_POS_HEADER_END);</span><br><span style="color: hsl(0, 100%, 40%);">-   return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> static void add_category_strings(char **cmd_str_p, char **doc_str_p,</span><br><span>@@ -332,27 +339,26 @@</span><br><span>       NULL, /* cmdstr is dynamically set in logging_vty_add_cmds(). */</span><br><span>       NULL) /* same thing for helpstr. */</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+    struct log_target *tgt;</span><br><span>      int category = log_parse_category(argv[0]);</span><br><span>  int level = log_parse_level(argv[1]);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     if (!tgt)</span><br><span style="color: hsl(0, 100%, 40%);">-               return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);</span><br><span> </span><br><span>         if (level < 0) {</span><br><span>          vty_out(vty, "Invalid level `%s'%s", argv[1], VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-               return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+           RET_WITH_UNLOCK(CMD_WARNING);</span><br><span>        }</span><br><span> </span><br><span>        if (category < 0) {</span><br><span>               vty_out(vty, "Invalid category `%s'%s", argv[0], VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-            return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+           RET_WITH_UNLOCK(CMD_WARNING);</span><br><span>        }</span><br><span> </span><br><span>        tgt->categories[category].enabled = 1;</span><br><span>    tgt->categories[category].loglevel = level;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> DEFUN(logging_level_set_all, logging_level_set_all_cmd,</span><br><span>@@ -362,12 +368,11 @@</span><br><span>       " to take back these changes -- each category is set to the given level, period.\n"</span><br><span>       LOG_LEVEL_STRS)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct log_target *tgt;</span><br><span>      int level = log_parse_level(argv[0]);</span><br><span>        int i;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      if (!tgt)</span><br><span style="color: hsl(0, 100%, 40%);">-               return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);</span><br><span> </span><br><span>         for (i = 0; i < osmo_log_info->num_cat; i++) {</span><br><span>                 struct log_category *cat = &tgt->categories[i];</span><br><span>@@ -378,7 +383,7 @@</span><br><span>                 cat->enabled = 1;</span><br><span>                 cat->loglevel = level;</span><br><span>    }</span><br><span style="color: hsl(0, 100%, 40%);">-       return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> /* logging level (<categories>) everything */</span><br><span>@@ -394,23 +399,25 @@</span><br><span>       "logging level force-all " LOG_LEVEL_ARGS,</span><br><span>       LOGGING_STR LEVEL_STR FORCE_ALL_STR LOG_LEVEL_STRS)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct log_target *tgt;</span><br><span>      int level = log_parse_level(argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!tgt)</span><br><span style="color: hsl(0, 100%, 40%);">-               return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   log_set_log_level(tgt, level);</span><br><span style="color: hsl(0, 100%, 40%);">-  return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> DEFUN(no_logging_level_force_all, no_logging_level_force_all_cmd,</span><br><span>       "no logging level force-all",</span><br><span>       NO_STR LOGGING_STR LEVEL_STR NO_FORCE_ALL_STR)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!tgt)</span><br><span style="color: hsl(0, 100%, 40%);">-               return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct log_target *tgt;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   log_set_log_level(tgt, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-      return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> /* 'logging level all (debug|...|fatal)' */</span><br><span>@@ -438,13 +445,12 @@</span><br><span>       " " OSMO_STRINGIFY(LOGL_FATAL) "=" OSMO_STRINGIFY_VAL(LOGL_FATAL)</span><br><span>       "\n")</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     if (!tgt)</span><br><span style="color: hsl(0, 100%, 40%);">-               return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);</span><br><span> </span><br><span>         log_parse_category_mask(tgt, argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-  return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> ALIAS_DEPRECATED(logging_set_category_mask,</span><br><span>@@ -462,17 +468,16 @@</span><br><span>        LOGGING_STR</span><br><span>       "Disables logging to this vty\n")</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct log_target *tgt;</span><br><span>      struct telnet_connection *conn = (struct telnet_connection *) vty->priv;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (!tgt)</span><br><span style="color: hsl(0, 100%, 40%);">-               return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);</span><br><span> </span><br><span>         log_del_target(tgt);</span><br><span>         talloc_free(tgt);</span><br><span>    conn->dbg = NULL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> static void vty_print_logtarget(struct vty *vty, const struct log_info *info,</span><br><span>@@ -517,14 +522,12 @@</span><br><span>      SHOW_STR SHOW_LOG_STR</span><br><span>        "Show current logging configuration for this vty\n")</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     struct log_target *tgt = osmo_log_vty2tgt(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     if (!tgt)</span><br><span style="color: hsl(0, 100%, 40%);">-               return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);</span><br><span> </span><br><span>         vty_print_logtarget(vty, osmo_log_info, tgt);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> DEFUN(show_alarms,</span><br><span>@@ -535,11 +538,14 @@</span><br><span> {</span><br><span>    int i, num_alarms;</span><br><span>   struct osmo_strrb *rb;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct log_target *tgt = log_target_find(LOG_TGT_TYPE_STRRB, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+   struct log_target *tgt;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     log_tgt_mutex_lock();</span><br><span style="color: hsl(120, 100%, 40%);">+ tgt = log_target_find(LOG_TGT_TYPE_STRRB, NULL);</span><br><span>     if (!tgt) {</span><br><span>          vty_out(vty, "%% No alarms, run 'log alarms <2-32700>'%s",</span><br><span>                   VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-           return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+           RET_WITH_UNLOCK(CMD_WARNING);</span><br><span>        }</span><br><span> </span><br><span>        rb = tgt->tgt_rb.rb;</span><br><span>@@ -550,8 +556,7 @@</span><br><span>        for (i = 0; i < num_alarms; i++)</span><br><span>          vty_out(vty, "%% %s%s", osmo_strrb_get_nth(rb, i),</span><br><span>                         VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> gDEFUN(cfg_description, cfg_description_cmd,</span><br><span>@@ -625,6 +630,7 @@</span><br><span> {</span><br><span>    struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   log_tgt_mutex_lock();</span><br><span>        /* First delete the old syslog target, if any */</span><br><span>     tgt = log_target_find(LOG_TGT_TYPE_SYSLOG, NULL);</span><br><span>    if (tgt)</span><br><span>@@ -633,14 +639,14 @@</span><br><span>     tgt = log_target_create_syslog(host.app_info->name, 0, facility);</span><br><span>         if (!tgt) {</span><br><span>          vty_out(vty, "%% Unable to open syslog%s", VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-              return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+           RET_WITH_UNLOCK(CMD_WARNING);</span><br><span>        }</span><br><span>    log_add_target(tgt);</span><br><span> </span><br><span>     vty->index = tgt;</span><br><span>         vty->node = CFG_LOG_NODE;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> DEFUN(cfg_log_syslog_local, cfg_log_syslog_local_cmd,</span><br><span>@@ -700,16 +706,17 @@</span><br><span> {</span><br><span>         struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   log_tgt_mutex_lock();</span><br><span>        tgt = log_target_find(LOG_TGT_TYPE_SYSLOG, NULL);</span><br><span>    if (!tgt) {</span><br><span>          vty_out(vty, "%% No syslog target found%s",</span><br><span>                        VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-           return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+           RET_WITH_UNLOCK(CMD_WARNING);</span><br><span>        }</span><br><span> </span><br><span>        log_target_destroy(tgt);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> #endif /* HAVE_SYSLOG_H */</span><br><span> </span><br><span>@@ -721,6 +728,7 @@</span><br><span>   const char *hostname = argc ? argv[0] : "127.0.0.1";</span><br><span>       struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   log_tgt_mutex_lock();</span><br><span>        tgt = log_target_find(LOG_TGT_TYPE_GSMTAP, hostname);</span><br><span>        if (!tgt) {</span><br><span>          tgt = log_target_create_gsmtap(hostname, GSMTAP_UDP_PORT,</span><br><span>@@ -729,7 +737,7 @@</span><br><span>              if (!tgt) {</span><br><span>                  vty_out(vty, "%% Unable to create GSMTAP log for %s%s",</span><br><span>                            hostname, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-                 return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+                   RET_WITH_UNLOCK(CMD_WARNING);</span><br><span>                }</span><br><span>            log_add_target(tgt);</span><br><span>         }</span><br><span>@@ -737,7 +745,7 @@</span><br><span>      vty->index = tgt;</span><br><span>         vty->node = CFG_LOG_NODE;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> DEFUN(cfg_log_stderr, cfg_log_stderr_cmd,</span><br><span>@@ -746,13 +754,14 @@</span><br><span> {</span><br><span>     struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   log_tgt_mutex_lock();</span><br><span>        tgt = log_target_find(LOG_TGT_TYPE_STDERR, NULL);</span><br><span>    if (!tgt) {</span><br><span>          tgt = log_target_create_stderr();</span><br><span>            if (!tgt) {</span><br><span>                  vty_out(vty, "%% Unable to create stderr log%s",</span><br><span>                           VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-                   return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+                   RET_WITH_UNLOCK(CMD_WARNING);</span><br><span>                }</span><br><span>            log_add_target(tgt);</span><br><span>         }</span><br><span>@@ -760,7 +769,7 @@</span><br><span>      vty->index = tgt;</span><br><span>         vty->node = CFG_LOG_NODE;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> DEFUN(cfg_no_log_stderr, cfg_no_log_stderr_cmd,</span><br><span>@@ -769,15 +778,16 @@</span><br><span> {</span><br><span>       struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   log_tgt_mutex_lock();</span><br><span>        tgt = log_target_find(LOG_TGT_TYPE_STDERR, NULL);</span><br><span>    if (!tgt) {</span><br><span>          vty_out(vty, "%% No stderr logging active%s", VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-           return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+           RET_WITH_UNLOCK(CMD_WARNING);</span><br><span>        }</span><br><span> </span><br><span>        log_target_destroy(tgt);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> DEFUN(cfg_log_file, cfg_log_file_cmd,</span><br><span>@@ -787,13 +797,14 @@</span><br><span>      const char *fname = argv[0];</span><br><span>         struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   log_tgt_mutex_lock();</span><br><span>        tgt = log_target_find(LOG_TGT_TYPE_FILE, fname);</span><br><span>     if (!tgt) {</span><br><span>          tgt = log_target_create_file(fname);</span><br><span>                 if (!tgt) {</span><br><span>                  vty_out(vty, "%% Unable to create file `%s'%s",</span><br><span>                                fname, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-                    return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+                   RET_WITH_UNLOCK(CMD_WARNING);</span><br><span>                }</span><br><span>            log_add_target(tgt);</span><br><span>         }</span><br><span>@@ -801,7 +812,7 @@</span><br><span>      vty->index = tgt;</span><br><span>         vty->node = CFG_LOG_NODE;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> </span><br><span>@@ -812,16 +823,17 @@</span><br><span>   const char *fname = argv[0];</span><br><span>         struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   log_tgt_mutex_lock();</span><br><span>        tgt = log_target_find(LOG_TGT_TYPE_FILE, fname);</span><br><span>     if (!tgt) {</span><br><span>          vty_out(vty, "%% No such log file `%s'%s",</span><br><span>                     fname, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-            return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+           RET_WITH_UNLOCK(CMD_WARNING);</span><br><span>        }</span><br><span> </span><br><span>        log_target_destroy(tgt);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> DEFUN(cfg_log_alarms, cfg_log_alarms_cmd,</span><br><span>@@ -832,6 +844,8 @@</span><br><span>    struct log_target *tgt;</span><br><span>      unsigned int rbsize = atoi(argv[0]);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    log_tgt_mutex_lock();</span><br><span>        tgt = log_target_find(LOG_TGT_TYPE_STRRB, NULL);</span><br><span>     if (tgt)</span><br><span>             log_target_destroy(tgt);</span><br><span>@@ -840,14 +854,14 @@</span><br><span>     if (!tgt) {</span><br><span>          vty_out(vty, "%% Unable to create osmo_strrb (size %u)%s",</span><br><span>                         rbsize, VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-           return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+           RET_WITH_UNLOCK(CMD_WARNING);</span><br><span>        }</span><br><span>    log_add_target(tgt);</span><br><span> </span><br><span>     vty->index = tgt;</span><br><span>         vty->node = CFG_LOG_NODE;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> DEFUN(cfg_no_log_alarms, cfg_no_log_alarms_cmd,</span><br><span>@@ -856,15 +870,16 @@</span><br><span> {</span><br><span>       struct log_target *tgt;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   log_tgt_mutex_lock();</span><br><span>        tgt = log_target_find(LOG_TGT_TYPE_STRRB, NULL);</span><br><span>     if (!tgt) {</span><br><span>          vty_out(vty, "%% No osmo_strrb target found%s", VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-         return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+           RET_WITH_UNLOCK(CMD_WARNING);</span><br><span>        }</span><br><span> </span><br><span>        log_target_destroy(tgt);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+   RET_WITH_UNLOCK(CMD_SUCCESS);</span><br><span> }</span><br><span> </span><br><span> static int config_write_log_single(struct vty *vty, struct log_target *tgt)</span><br><span>@@ -962,11 +977,13 @@</span><br><span> </span><br><span> static int config_write_log(struct vty *vty)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+        log_tgt_mutex_lock();</span><br><span>        struct log_target *dbg = vty->index;</span><br><span> </span><br><span>  llist_for_each_entry(dbg, &osmo_log_target_list, entry)</span><br><span>          config_write_log_single(vty, dbg);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        log_tgt_mutex_unlock();</span><br><span>      return 1;</span><br><span> }</span><br><span> </span><br><span>diff --git a/tests/logging/logging_vty_test.c b/tests/logging/logging_vty_test.c</span><br><span>index 30426f3..e7019f6 100644</span><br><span>--- a/tests/logging/logging_vty_test.c</span><br><span>+++ b/tests/logging/logging_vty_test.c</span><br><span>@@ -241,6 +241,7 @@</span><br><span>        vty_init(&vty_info);</span><br><span> </span><br><span>         osmo_init_logging2(root_ctx, &log_info);</span><br><span style="color: hsl(120, 100%, 40%);">+  log_enable_multithread();</span><br><span> </span><br><span>        vty_commands_init();</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/15560">change 15560</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmocore/+/15560"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Id7711893b34263baacac6caf4d489467053131bb </div>
<div style="display:none"> Gerrit-Change-Number: 15560 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>