]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #768 from qlyoung/fix-gitignore2
authorJafar Al-Gharaibeh <Jafaral@users.noreply.github.com>
Fri, 30 Jun 2017 15:38:20 +0000 (10:38 -0500)
committerGitHub <noreply@github.com>
Fri, 30 Jun 2017 15:38:20 +0000 (10:38 -0500)
lib, bgpd: fix .gitignore

45 files changed:
babeld/babel_zebra.c
bgpd/bgp_zebra.c
bgpd/bgpd.c
eigrpd/eigrpd.c
isisd/isis_main.c
isisd/isis_zebra.c
isisd/isis_zebra.h
ldpd/lde.c
ldpd/ldpe.c
lib/frr_pthread.c
lib/grammar_sandbox_main.c
lib/if.c
lib/if.h
lib/json.c
lib/json.h
lib/libfrr.c
lib/log.c
lib/thread.c
lib/thread.h
nhrpd/nhrp_route.c
ospf6d/ospf6_main.c
ospfclient/ospfclient.c
ospfd/ospfd.c
pimd/pim_zlookup.c
pimd/pimd.c
ripd/rip_main.c
ripd/rip_zebra.c
ripd/ripd.h
ripngd/ripng_main.c
ripngd/ripng_zebra.c
ripngd/ripngd.h
tests/bgpd/test_aspath.c
tests/bgpd/test_capability.c
tests/bgpd/test_mp_attr.c
tests/bgpd/test_mpath.c
tests/helpers/c/main.c
tests/lib/cli/common_cli.c
tests/lib/test_segv.c
tests/lib/test_sig.c
tests/lib/test_timer_correctness.c
tests/lib/test_timer_performance.c
tests/test_lblmgr.c
zebra/client_main.c
zebra/if_netlink.c
zebra/interface.c

index d8b8919e215ac99810d3c16fc9929bfdb53ea507..3a7a52cccadbfb2c2a0c6e4ef260d67fb650e29c 100644 (file)
@@ -400,4 +400,5 @@ void
 babel_zebra_close_connexion(void)
 {
     zclient_stop(zclient);
+    zclient_free(zclient);
 }
index 4fff339b85a08e07ed197bd180b7c7077980a952..66c18c8e57451c0f5309748aa2f4cd7b9c0dfdee 100644 (file)
@@ -581,7 +581,7 @@ bgp_interface_vrf_update (int command, struct zclient *zclient, zebra_size_t len
       }
   }
 
-  if_update (ifp, ifp->name, strlen (ifp->name), new_vrf_id);
+  if_update_to_new_vrf (ifp, new_vrf_id);
 
   bgp = bgp_lookup_by_vrf_id (new_vrf_id);
   if (!bgp)
index aed78cb35abe50456a30f7e7b2a8309a37c08eae..033a3d194d398265d052dea54b95206ff269ca6e 100644 (file)
@@ -6405,7 +6405,7 @@ peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object
     {
       epoch_tbuf = time(NULL) - uptime1;
       json_object_string_add(json, "peerUptime", buf);
-      json_object_long_add(json, "peerUptimeMsec", uptime1 * 1000);
+      json_object_int_add(json, "peerUptimeMsec", uptime1 * 1000);
       json_object_int_add(json, "peerUptimeEstablishedEpoch", epoch_tbuf);
     }
 
index a0ead05224acfbef6c208c903faa716ef90da9d2..2fa8296ce2677f84a681b7c60aaf356fd055e4af 100644 (file)
@@ -267,8 +267,10 @@ eigrp_finish (struct eigrp *eigrp)
       && (listcount(eigrp_om->eigrp) == 0))
     {
       if (zclient)
-        zclient_free (zclient);
-
+       {
+         zclient_stop (zclient);
+         zclient_free (zclient);
+       }
       exit(0);
     }
 
index 58070c7f2ad1bad7a22f310793277696f879b06e..674592f46b4243ed0db8ed152c296a85cd85328d 100644 (file)
@@ -101,6 +101,7 @@ void sigusr1(void);
 static __attribute__((__noreturn__)) void
 terminate (int i)
 {
+  isis_zebra_stop ();
   exit (i);
 }
 
index 0009dd5e27fb593df9f96737cf91c7d407d83d41..af77250a01ec9883ccf09e9fca04c45b37aef27b 100644 (file)
@@ -720,3 +720,10 @@ isis_zebra_init (struct thread_master *master)
 
   return;
 }
+
+void
+isis_zebra_stop (void)
+{
+  zclient_stop (zclient);
+  zclient_free (zclient);
+}
index 621c32c3636da9e2660538756eb9e690d46935f1..82d5a48d3e04383161249bded203c3bb6f65717c 100644 (file)
@@ -25,6 +25,8 @@
 extern struct zclient *zclient;
 
 void isis_zebra_init(struct thread_master *);
+void isis_zebra_stop(void);
+
 void isis_zebra_route_update (struct prefix *prefix,
                              struct isis_route_info *route_info);
 int isis_distribute_list_update (int routetype);
index 0ef46dab3d0837fa1632e8272663601a13347c26..602dc8805e54096a2547afce1847170884566252 100644 (file)
@@ -131,7 +131,7 @@ lde(void)
        ldpd_process = PROC_LDE_ENGINE;
        log_procname = log_procnames[PROC_LDE_ENGINE];
 
-       master = thread_master_create();
+       master = thread_master_create(NULL);
 
        /* setup signal handler */
        signal_init(master, array_size(lde_signals), lde_signals);
index ba153dfde23f66488758d177bb416dc541219b26..b2f9fdce55797e848b6fd6815c76fdae902d790e 100644 (file)
@@ -109,7 +109,7 @@ ldpe(void)
        ldpd_process = PROC_LDP_ENGINE;
        log_procname = log_procnames[ldpd_process];
 
-       master = thread_master_create();
+       master = thread_master_create(NULL);
 
        /* setup signal handler */
        signal_init(master, array_size(ldpe_signals), ldpe_signals);
index 17bc82f5da94f9bcc344a085a91a15706da6dc5f..614c722be1e1c30d72b92c516178c77cdce5b6cb 100644 (file)
@@ -86,7 +86,7 @@ struct frr_pthread *frr_pthread_new(const char *name, unsigned int id,
                             XCALLOC(MTYPE_FRR_PTHREAD,
                                     sizeof(struct frr_pthread));
                         fpt->id = id;
-                        fpt->master = thread_master_create();
+                        fpt->master = thread_master_create(name);
                         fpt->start_routine = start_routine;
                         fpt->stop_routine = stop_routine;
                         fpt->name = XSTRDUP(MTYPE_FRR_PTHREAD, name);
index 3bf0e268cfd16becff34a1eb08c2ebabe58ae7dd..02aefd603d773916285933bee18904664c8bf475 100644 (file)
@@ -38,7 +38,7 @@ int main(int argc, char **argv)
 {
   struct thread thread;
 
-  master = thread_master_create ();
+  master = thread_master_create(NULL);
 
   openzlog ("grammar_sandbox", "NONE", 0,
                            LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
index d9b4544271b636e7dc470e041e75de6327b565dd..1d6a8cb529f68f769debce2203e957c15fcfc440 100644 (file)
--- a/lib/if.c
+++ b/lib/if.c
@@ -158,7 +158,7 @@ if_create (const char *name, int namelen, vrf_id_t vrf_id)
 
 /* Create new interface structure. */
 void
-if_update (struct interface *ifp, const char *name, int namelen, vrf_id_t vrf_id)
+if_update_to_new_vrf (struct interface *ifp, vrf_id_t vrf_id)
 {
   struct list *intf_list = vrf_iflist_get (vrf_id);
 
@@ -166,10 +166,6 @@ if_update (struct interface *ifp, const char *name, int namelen, vrf_id_t vrf_id
   if (vrf_iflist (ifp->vrf_id))
     listnode_delete (vrf_iflist (ifp->vrf_id), ifp);
 
-  assert (name);
-  assert (namelen <= INTERFACE_NAMSIZ);        /* Need space for '\0' at end. */
-  strncpy (ifp->name, name, namelen);
-  ifp->name[namelen] = '\0';
   ifp->vrf_id = vrf_id;
   if (if_lookup_by_name (ifp->name, vrf_id) == NULL)
     listnode_add_sort (intf_list, ifp);
@@ -453,7 +449,7 @@ if_get_by_name_len (const char *name, size_t namelen, vrf_id_t vrf_id, int vty)
                 }
              else
                {
-                 if_update (ifp, name, namelen, vrf_id);
+                 if_update_to_new_vrf (ifp, vrf_id);
                  return ifp;
                }
            }
index fa95901a58fb8bfd49f4a2a1360e11184cb74a0b..a061110a4ae33692e49f2949507c9aabaf92d725 100644 (file)
--- a/lib/if.h
+++ b/lib/if.h
@@ -393,8 +393,7 @@ struct nbr_connected
 /* Prototypes. */
 extern int if_cmp_name_func (char *, char *);
 
-extern void if_update (struct interface *, const char *name, int namelen,
-                       vrf_id_t vrf_id);
+extern void if_update_to_new_vrf (struct interface *, vrf_id_t vrf_id);
 extern struct interface *if_create (const char *name, int namelen,
                                     vrf_id_t vrf_id);
 extern struct interface *if_lookup_by_index (ifindex_t, vrf_id_t vrf_id);
index 5b7c3e9ffa8cc770be4d3478fcc0681a91e3e78b..d8c97e448667b8d664001d26077c32308a5afe0f 100644 (file)
@@ -48,13 +48,7 @@ json_object_string_add(struct json_object* obj, const char *key,
 }
 
 void
-json_object_int_add(struct json_object* obj, const char *key, int32_t i)
-{
-  json_object_object_add(obj, key, json_object_new_int(i));
-}
-
-void
-json_object_long_add(struct json_object* obj, const char *key, int64_t i)
+json_object_int_add(struct json_object* obj, const char *key, int64_t i)
 {
 #if defined(HAVE_JSON_C_JSON_H)
   json_object_object_add(obj, key, json_object_new_int64(i));
index 5faaaa841ab06186927bc563442ece5d08384c81..86271703f48017d070e93ec8bd8a03dce7a1b0e1 100644 (file)
@@ -43,8 +43,6 @@ extern int use_json(const int argc, struct cmd_token *argv[]);
 extern void json_object_string_add(struct json_object* obj, const char *key,
                                    const char *s);
 extern void json_object_int_add(struct json_object* obj, const char *key,
-                                int32_t i);
-extern void json_object_long_add(struct json_object* obj, const char *key,
                                  int64_t i);
 extern void json_object_boolean_false_add(struct json_object* obj,
                                           const char *key);
index 132f7d4d2cba7676eaa30747c108fa5b54cc0364..8d816437cbfcf9ef297fc3a6faf0a9a41d3584e9 100644 (file)
@@ -366,7 +366,7 @@ struct thread_master *frr_init(void)
 
        zprivs_init(di->privs);
 
-       master = thread_master_create();
+       master = thread_master_create(NULL);
        signal_init(master, di->n_signals, di->signals);
 
        if (di->flags & FRR_LIMITED_CLI)
index a8b221fd64e1db192817fdf33769e6fe5be89e2a..1c61d72168ed35f507c360a14463bdade3157b1c 100644 (file)
--- a/lib/log.c
+++ b/lib/log.c
@@ -509,16 +509,18 @@ zlog_signal(int signo, const char *action
                        );
 
   s = buf;
-  if (!thread_current)
+  struct thread *tc;
+  tc = pthread_getspecific (thread_current);
+  if (!tc)
     s = str_append (LOC, "no thread information available\n");
   else
     {
       s = str_append (LOC, "in thread ");
-      s = str_append (LOC, thread_current->funcname);
+      s = str_append (LOC, tc->funcname);
       s = str_append (LOC, " scheduled from ");
-      s = str_append (LOC, thread_current->schedfrom);
+      s = str_append (LOC, tc->schedfrom);
       s = str_append (LOC, ":");
-      s = num_append (LOC, thread_current->schedfrom_line);
+      s = num_append (LOC, tc->schedfrom_line);
       s = str_append (LOC, "\n");
     }
 
@@ -700,10 +702,13 @@ ZLOG_FUNC(zlog_debug, LOG_DEBUG)
 
 void zlog_thread_info (int log_level)
 {
-  if (thread_current)
+  struct thread *tc;
+  tc = pthread_getspecific (thread_current);
+
+  if (tc)
     zlog(log_level, "Current thread function %s, scheduled from "
-        "file %s, line %u", thread_current->funcname,
-        thread_current->schedfrom, thread_current->schedfrom_line);
+        "file %s, line %u", tc->funcname,
+        tc->schedfrom, tc->schedfrom_line);
   else
     zlog(log_level, "Current thread not known/applicable");
 }
index a1a9e7c359745de7e5a2e70cc17a8ef135d9a63a..801168a79944ef448247ebc3a5af24f13aa1775d 100644 (file)
@@ -47,16 +47,15 @@ DEFINE_MTYPE_STATIC(LIB, THREAD_STATS,  "Thread stats")
       write (m->io_pipe[1], &wakebyte, 1); \
   } while (0);
 
-static pthread_mutex_t cpu_record_mtx = PTHREAD_MUTEX_INITIALIZER;
-static struct hash *cpu_record = NULL;
+/* control variable for initializer */
+pthread_once_t init_once = PTHREAD_ONCE_INIT;
+pthread_key_t thread_current;
 
-static unsigned long
-timeval_elapsed (struct timeval a, struct timeval b)
-{
-  return (((a.tv_sec - b.tv_sec) * TIMER_SECOND_MICRO)
-         + (a.tv_usec - b.tv_usec));
-}
+pthread_mutex_t masters_mtx = PTHREAD_MUTEX_INITIALIZER;
+static struct list *masters;
 
+
+/* CLI start ---------------------------------------------------------------- */
 static unsigned int
 cpu_record_hash_key (struct cpu_thread_history *a)
 {
@@ -106,12 +105,12 @@ vty_out_cpu_thread_history(struct vty* vty,
 }
 
 static void
-cpu_record_hash_print(struct hash_backet *bucket, 
-                     void *args[])
+cpu_record_hash_print(struct hash_backet *bucket, void *args[])
 {
   struct cpu_thread_history *totals = args[0];
   struct vty *vty = args[1];
   thread_type *filter = args[2];
+
   struct cpu_thread_history *a = bucket->data;
 
   if ( !(a->types & *filter) )
@@ -132,169 +131,174 @@ cpu_record_print(struct vty *vty, thread_type filter)
 {
   struct cpu_thread_history tmp;
   void *args[3] = {&tmp, vty, &filter};
+  struct thread_master *m;
+  struct listnode *ln;
 
   memset(&tmp, 0, sizeof tmp);
   tmp.funcname = "TOTAL";
   tmp.types = filter;
 
-  vty_outln (vty, "%21s %18s %18s",
-         "", "CPU (user+system):", "Real (wall-clock):");
-  vty_out(vty, "Active   Runtime(ms)   Invoked Avg uSec Max uSecs");
-  vty_out(vty, " Avg uSec Max uSecs");
-  vty_outln (vty, "  Type  Thread");
-
-  pthread_mutex_lock (&cpu_record_mtx);
+  pthread_mutex_lock (&masters_mtx);
   {
-    hash_iterate(cpu_record,
-                 (void(*)(struct hash_backet*,void*))cpu_record_hash_print,
-                 args);
+    for (ALL_LIST_ELEMENTS_RO (masters, ln, m)) {
+      const char *name = m->name ? m->name : "main";
+
+      char underline[strlen(name) + 1];
+      memset (underline, '-', sizeof (underline));
+      underline[sizeof(underline)] = '\0';
+
+      vty_out (vty, VTYNL);
+      vty_outln(vty, "Showing statistics for pthread %s", name);
+      vty_outln(vty, "-------------------------------%s", underline);
+      vty_outln(vty, "%21s %18s %18s", "", "CPU (user+system):", "Real (wall-clock):");
+      vty_out(vty, "Active   Runtime(ms)   Invoked Avg uSec Max uSecs");
+      vty_out(vty, " Avg uSec Max uSecs");
+      vty_outln(vty, "  Type  Thread");
+
+      if (m->cpu_record->count)
+        hash_iterate(m->cpu_record,
+                     (void (*)(struct hash_backet *, void *))
+                     cpu_record_hash_print,
+                     args);
+      else
+        vty_outln(vty, "No data to display yet.");
+
+      vty_out(vty, VTYNL);
+    }
   }
-  pthread_mutex_unlock (&cpu_record_mtx);
+  pthread_mutex_unlock (&masters_mtx);
+
+  vty_out(vty, VTYNL);
+  vty_outln(vty, "Total thread statistics");
+  vty_outln(vty, "-------------------------");
+  vty_outln(vty, "%21s %18s %18s", "", "CPU (user+system):", "Real (wall-clock):");
+  vty_out(vty, "Active   Runtime(ms)   Invoked Avg uSec Max uSecs");
+  vty_out(vty, " Avg uSec Max uSecs");
+  vty_outln(vty, "  Type  Thread");
 
   if (tmp.total_calls > 0)
     vty_out_cpu_thread_history(vty, &tmp);
 }
 
-DEFUN (show_thread_cpu,
-       show_thread_cpu_cmd,
-       "show thread cpu [FILTER]",
-       SHOW_STR
-       "Thread information\n"
-       "Thread CPU usage\n"
-       "Display filter (rwtexb)\n")
-{
-  int idx_filter = 3;
-  int i = 0;
-  thread_type filter = (thread_type) -1U;
-
-  if (argc > 3)
-    {
-      filter = 0;
-      while (argv[idx_filter]->arg[i] != '\0')
-       {
-         switch ( argv[idx_filter]->arg[i] )
-           {
-           case 'r':
-           case 'R':
-             filter |= (1 << THREAD_READ);
-             break;
-           case 'w':
-           case 'W':
-             filter |= (1 << THREAD_WRITE);
-             break;
-           case 't':
-           case 'T':
-             filter |= (1 << THREAD_TIMER);
-             break;
-           case 'e':
-           case 'E':
-             filter |= (1 << THREAD_EVENT);
-             break;
-           case 'x':
-           case 'X':
-             filter |= (1 << THREAD_EXECUTE);
-             break;
-           default:
-             break;
-           }
-         ++i;
-       }
-      if (filter == 0)
-       {
-         vty_outln (vty, "Invalid filter \"%s\" specified,"
-                  " must contain at least one of 'RWTEXB'",
-                 argv[idx_filter]->arg);
-         return CMD_WARNING;
-       }
-    }
-
-  cpu_record_print(vty, filter);
-  return CMD_SUCCESS;
-}
-
 static void
-cpu_record_hash_clear (struct hash_backet *bucket, 
-                     void *args)
+cpu_record_hash_clear (struct hash_backet *bucket, void *args[])
 {
-  thread_type *filter = args;
+  thread_type *filter = args[0];
+  struct hash *cpu_record = args[1];
+
   struct cpu_thread_history *a = bucket->data;
 
   if ( !(a->types & *filter) )
        return;
   
-  pthread_mutex_lock (&cpu_record_mtx);
-  {
-    hash_release (cpu_record, bucket->data);
-  }
-  pthread_mutex_unlock (&cpu_record_mtx);
+  hash_release (cpu_record, bucket->data);
 }
 
 static void
 cpu_record_clear (thread_type filter)
 {
   thread_type *tmp = &filter;
+  struct thread_master *m;
+  struct listnode *ln;
 
-  pthread_mutex_lock (&cpu_record_mtx);
+  pthread_mutex_lock (&masters_mtx);
   {
-    hash_iterate (cpu_record,
-                  (void (*) (struct hash_backet*,void*)) cpu_record_hash_clear,
-                  tmp);
+    for (ALL_LIST_ELEMENTS_RO (masters, ln, m)) {
+      pthread_mutex_lock (&m->mtx);
+      {
+        void *args[2] = { tmp, m->cpu_record };
+        hash_iterate (m->cpu_record,
+                      (void (*) (struct hash_backet*,void*))
+                      cpu_record_hash_clear,
+                      args);
+      }
+      pthread_mutex_unlock (&m->mtx);
+    }
   }
-  pthread_mutex_unlock (&cpu_record_mtx);
+  pthread_mutex_unlock (&masters_mtx);
+}
+
+static thread_type
+parse_filter (const char *filterstr)
+{
+  int i = 0;
+  int filter = 0;
+
+  while (filterstr[i] != '\0')
+    {
+      switch (filterstr[i])
+        {
+        case 'r':
+        case 'R':
+          filter |= (1 << THREAD_READ);
+          break;
+        case 'w':
+        case 'W':
+          filter |= (1 << THREAD_WRITE);
+          break;
+        case 't':
+        case 'T':
+          filter |= (1 << THREAD_TIMER);
+          break;
+        case 'e':
+        case 'E':
+          filter |= (1 << THREAD_EVENT);
+          break;
+        case 'x':
+        case 'X':
+          filter |= (1 << THREAD_EXECUTE);
+          break;
+        default:
+          break;
+        }
+      ++i;
+    }
+  return filter;
+}
+
+DEFUN (show_thread_cpu,
+       show_thread_cpu_cmd,
+       "show thread cpu [FILTER]",
+       SHOW_STR
+       "Thread information\n"
+       "Thread CPU usage\n"
+       "Display filter (rwtexb)\n")
+{
+  thread_type filter = (thread_type) -1U;
+  int idx = 0;
+
+  if (argv_find (argv, argc, "FILTER", &idx)) {
+    filter = parse_filter (argv[idx]->arg);
+    if (!filter) {
+      vty_outln(vty, "Invalid filter \"%s\" specified; must contain at least"
+                     "one of 'RWTEXB'%s", argv[idx]->arg);
+      return CMD_WARNING;
+    }
+  }
+
+  cpu_record_print(vty, filter);
+  return CMD_SUCCESS;
 }
 
 DEFUN (clear_thread_cpu,
        clear_thread_cpu_cmd,
        "clear thread cpu [FILTER]",
-       "Clear stored data\n"
+       "Clear stored data in all pthreads\n"
        "Thread information\n"
        "Thread CPU usage\n"
        "Display filter (rwtexb)\n")
 {
-  int idx_filter = 3;
-  int i = 0;
   thread_type filter = (thread_type) -1U;
-
-  if (argc > 3)
-    {
-      filter = 0;
-      while (argv[idx_filter]->arg[i] != '\0')
-       {
-         switch ( argv[idx_filter]->arg[i] )
-           {
-           case 'r':
-           case 'R':
-             filter |= (1 << THREAD_READ);
-             break;
-           case 'w':
-           case 'W':
-             filter |= (1 << THREAD_WRITE);
-             break;
-           case 't':
-           case 'T':
-             filter |= (1 << THREAD_TIMER);
-             break;
-           case 'e':
-           case 'E':
-             filter |= (1 << THREAD_EVENT);
-             break;
-           case 'x':
-           case 'X':
-             filter |= (1 << THREAD_EXECUTE);
-             break;
-           default:
-             break;
-           }
-         ++i;
-       }
-      if (filter == 0)
-       {
-         vty_outln (vty, "Invalid filter \"%s\" specified,"
-                  " must contain at least one of 'RWTEXB'",
-                 argv[idx_filter]->arg);
-         return CMD_WARNING;
-       }
+  int idx = 0;
+
+  if (argv_find (argv, argc, "FILTER", &idx)) {
+    filter = parse_filter (argv[idx]->arg);
+    if (!filter) {
+      vty_outln(vty, "Invalid filter \"%s\" specified; must contain at least"
+                     "one of 'RWTEXB'%s", argv[idx]->arg);
+      return CMD_WARNING;
     }
+  }
 
   cpu_record_clear (filter);
   return CMD_SUCCESS;
@@ -306,6 +310,8 @@ thread_cmd_init (void)
   install_element (VIEW_NODE, &show_thread_cpu_cmd);
   install_element (ENABLE_NODE, &clear_thread_cpu_cmd);
 }
+/* CLI end ------------------------------------------------------------------ */
+
 
 static int
 thread_timer_cmp(void *a, void *b)
@@ -334,31 +340,37 @@ cancelreq_del (void *cr)
   XFREE (MTYPE_TMP, cr);
 }
 
+/* initializer, only ever called once */
+static void initializer ()
+{
+  if (!masters)
+    masters = list_new();
+
+  pthread_key_create (&thread_current, NULL);
+}
+
 /* Allocate new thread master.  */
 struct thread_master *
-thread_master_create (void)
+thread_master_create (const char *name)
 {
   struct thread_master *rv;
   struct rlimit limit;
 
-  getrlimit(RLIMIT_NOFILE, &limit);
-
-  pthread_mutex_lock (&cpu_record_mtx);
-  {
-    if (cpu_record == NULL)
-      cpu_record = hash_create ((unsigned int (*) (void *))cpu_record_hash_key,
-                                (int (*) (const void *, const void *))
-                                cpu_record_hash_cmp);
-  }
-  pthread_mutex_unlock (&cpu_record_mtx);
+  pthread_once (&init_once, &initializer);
 
   rv = XCALLOC (MTYPE_THREAD_MASTER, sizeof (struct thread_master));
   if (rv == NULL)
     return NULL;
 
+  /* Initialize master mutex */
   pthread_mutex_init (&rv->mtx, NULL);
   pthread_cond_init (&rv->cancel_cond, NULL);
 
+  /* Set name */
+  rv->name = name ? XSTRDUP (MTYPE_THREAD_MASTER, name) : NULL;
+
+  /* Initialize I/O task data structures */
+  getrlimit(RLIMIT_NOFILE, &limit);
   rv->fd_limit = (int)limit.rlim_cur;
   rv->read = XCALLOC (MTYPE_THREAD, sizeof (struct thread *) * rv->fd_limit);
   if (rv->read == NULL)
@@ -366,7 +378,6 @@ thread_master_create (void)
       XFREE (MTYPE_THREAD_MASTER, rv);
       return NULL;
     }
-
   rv->write = XCALLOC (MTYPE_THREAD, sizeof (struct thread *) * rv->fd_limit);
   if (rv->write == NULL)
     {
@@ -375,20 +386,32 @@ thread_master_create (void)
       return NULL;
     }
 
+  rv->cpu_record = hash_create ((unsigned int (*) (void *))cpu_record_hash_key,
+                                (int (*) (const void *, const void *))
+                                cpu_record_hash_cmp);
+
+
   /* Initialize the timer queues */
   rv->timer = pqueue_create();
   rv->timer->cmp = thread_timer_cmp;
   rv->timer->update = thread_timer_update;
+
+  /* Initialize thread_fetch() settings */
   rv->spin = true;
   rv->handle_signals = true;
+
+  /* Set pthread owner, should be updated by actual owner */
   rv->owner = pthread_self();
   rv->cancel_req = list_new ();
   rv->cancel_req->del = cancelreq_del;
   rv->canceled = true;
+
+  /* Initialize pipe poker */
   pipe (rv->io_pipe);
   set_nonblocking (rv->io_pipe[0]);
   set_nonblocking (rv->io_pipe[1]);
 
+  /* Initialize data structures for poll() */
   rv->handler.pfdsize = rv->fd_limit;
   rv->handler.pfdcount = 0;
   rv->handler.pfds = XCALLOC (MTYPE_THREAD_MASTER,
@@ -396,6 +419,13 @@ thread_master_create (void)
   rv->handler.copy = XCALLOC (MTYPE_THREAD_MASTER,
                               sizeof (struct pollfd) * rv->handler.pfdsize);
 
+  /* add to list */
+  pthread_mutex_lock (&masters_mtx);
+  {
+    listnode_add (masters, rv);
+  }
+  pthread_mutex_unlock (&masters_mtx);
+
   return rv;
 }
 
@@ -545,20 +575,13 @@ thread_master_free (struct thread_master *m)
   close (m->io_pipe[1]);
   list_delete (m->cancel_req);
 
+  hash_clean (m->cpu_record, cpu_record_hash_free);
+  hash_free (m->cpu_record);
+  m->cpu_record = NULL;
+
   XFREE (MTYPE_THREAD_MASTER, m->handler.pfds);
   XFREE (MTYPE_THREAD_MASTER, m->handler.copy);
   XFREE (MTYPE_THREAD_MASTER, m);
-
-  pthread_mutex_lock (&cpu_record_mtx);
-  {
-    if (cpu_record)
-      {
-        hash_clean (cpu_record, cpu_record_hash_free);
-        hash_free (cpu_record);
-        cpu_record = NULL;
-      }
-  }
-  pthread_mutex_unlock (&cpu_record_mtx);
 }
 
 /* Return remain time in second. */
@@ -630,12 +653,8 @@ thread_get (struct thread_master *m, u_char type,
     {
       tmp.func = func;
       tmp.funcname = funcname;
-      pthread_mutex_lock (&cpu_record_mtx);
-      {
-        thread->hist = hash_get (cpu_record, &tmp,
-                                 (void * (*) (void *))cpu_record_hash_alloc);
-      }
-      pthread_mutex_unlock (&cpu_record_mtx);
+      thread->hist = hash_get (m->cpu_record, &tmp,
+                               (void * (*) (void *))cpu_record_hash_alloc);
     }
   thread->hist->total_active++;
   thread->func = func;
@@ -676,7 +695,7 @@ fd_poll (struct thread_master *m, struct pollfd *pfds, nfds_t pfdsize,
 
   num = poll (pfds, count + 1, timeout);
 
-  static unsigned char trash[64];
+  unsigned char trash[64];
   if (num > 0 && pfds[count].revents != 0 && num--)
     while (read (m->io_pipe[0], &trash, sizeof (trash)) > 0);
 
@@ -1301,7 +1320,7 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
   struct timeval now;
   struct timeval zerotime = { 0, 0 };
   struct timeval tv;
-  struct timeval *tw;
+  struct timeval *tw = NULL;
 
   int num = 0;
 
@@ -1401,6 +1420,13 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
   return fetch;
 }
 
+static unsigned long
+timeval_elapsed (struct timeval a, struct timeval b)
+{
+  return (((a.tv_sec - b.tv_sec) * TIMER_SECOND_MICRO)
+         + (a.tv_usec - b.tv_usec));
+}
+
 unsigned long
 thread_consumed_time (RUSAGE_T *now, RUSAGE_T *start, unsigned long *cputime)
 {
@@ -1449,8 +1475,6 @@ thread_getrusage (RUSAGE_T *r)
   getrusage(RUSAGE_SELF, &(r->cpu));
 }
 
-struct thread *thread_current = NULL;
-
 /* We check thread consumed time. If the system has getrusage, we'll
    use that to get in-depth stats on the performance of the thread in addition
    to wall clock time stats from gettimeofday. */
@@ -1463,9 +1487,9 @@ thread_call (struct thread *thread)
   GETRUSAGE (&before);
   thread->real = before.real;
 
-  thread_current = thread;
+  pthread_setspecific (thread_current, thread);
   (*thread->func) (thread);
-  thread_current = NULL;
+  pthread_setspecific (thread_current, NULL);
 
   GETRUSAGE (&after);
 
@@ -1518,12 +1542,8 @@ funcname_thread_execute (struct thread_master *m,
 
   tmp.func = dummy.func = func;
   tmp.funcname = dummy.funcname = funcname;
-  pthread_mutex_lock (&cpu_record_mtx);
-  {
-    dummy.hist = hash_get (cpu_record, &tmp,
-                           (void * (*) (void *))cpu_record_hash_alloc);
-  }
-  pthread_mutex_unlock (&cpu_record_mtx);
+  dummy.hist = hash_get (m->cpu_record, &tmp,
+                         (void * (*) (void *))cpu_record_hash_alloc);
 
   dummy.schedfrom = schedfrom;
   dummy.schedfrom_line = fromln;
index e48068b174e5a38f9986dcc036edc078af645106..ad923c413f45e565ec04bf565fda9f73dea13dfd 100644 (file)
@@ -71,6 +71,8 @@ struct cancel_req {
 /* Master of the theads. */
 struct thread_master
 {
+  char *name;
+
   struct thread **read;
   struct thread **write;
   struct pqueue *timer;
@@ -80,6 +82,7 @@ struct thread_master
   struct list *cancel_req;
   bool canceled;
   pthread_cond_t cancel_cond;
+  struct hash *cpu_record;
   int io_pipe[2];
   int fd_limit;
   struct fd_handler handler;
@@ -177,7 +180,7 @@ struct cpu_thread_history
 #define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f,__FILE__,__LINE__)
 
 /* Prototypes. */
-extern struct thread_master *thread_master_create (void);
+extern struct thread_master *thread_master_create (const char *);
 extern void thread_master_free (struct thread_master *);
 extern void thread_master_free_unused(struct thread_master *);
 
@@ -220,6 +223,6 @@ extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
                                          unsigned long *cpu_time_elapsed);
 
 /* only for use in logging functions! */
-extern struct thread *thread_current;
+extern pthread_key_t thread_current;
 
 #endif /* _ZEBRA_THREAD_H */
index 7f8cad6e92180f19a763c7bf52f5d37efe50a1ef..89972f8f981054281e48fe74092149e975dd6960 100644 (file)
@@ -379,6 +379,7 @@ void nhrp_zebra_init(void)
 void nhrp_zebra_terminate(void)
 {
        zclient_stop(zclient);
+       zclient_free(zclient);
        route_table_finish(zebra_rib[AFI_IP]);
        route_table_finish(zebra_rib[AFI_IP6]);
 }
index f69c1e1bca4c2f1c26ea639963c9223bd6fc7b75..0a4a3a28c3a36c0bd6f88baa909e396a12a70238 100644 (file)
@@ -110,7 +110,10 @@ ospf6_exit (int status)
   cmd_terminate ();
 
   if (zclient)
-    zclient_free (zclient);
+    {
+      zclient_stop (zclient);
+      zclient_free (zclient);
+    }
 
   if (master)
     thread_master_free (master);
index affcbc9d6a50683b348fa79df03cfc92e30c445e..63fcafb736a1ab077ad43728e2d525aeab458d52 100644 (file)
@@ -326,7 +326,7 @@ main (int argc, char *argv[])
 
   /* Initialization */
   zprivs_init (&ospfd_privs);
-  master = thread_master_create ();
+  master = thread_master_create(NULL);
 
   /* Open connection to OSPF daemon */
   oclient = ospf_apiclient_connect (args[1], ASYNCPORT);
index 38213aeb6ad41ad31a642b639daa17b89c0b99dd..9af9f7f31455c000d844e3858f2fa0a0a155067a 100644 (file)
@@ -497,6 +497,8 @@ ospf_terminate (void)
    * One or more ospf_finish()'s may have deferred shutdown to a timer
    * thread
    */
+  zclient_stop (zclient);
+  zclient_free (zclient);
 }
 
 void
index 779cc1418383681442c02ca379e882579ba106bf..e7ffe0f4adc9a31160cb570a929a59113ecaf06a 100644 (file)
@@ -115,6 +115,7 @@ static void zclient_lookup_failed(struct zclient *zlookup)
 void
 zclient_lookup_free (void)
 {
+  zclient_stop (zlookup);
   zclient_free (zlookup);
   zlookup = NULL;
 }
index c31d2a99a11a035eca9aa8023dcb37bcd4aded78..ec1fe5b6d0f2c34abf5213b4c4c6cb4ee4b529be 100644 (file)
@@ -313,6 +313,8 @@ void pim_init()
 
 void pim_terminate()
 {
+  struct zclient *zclient;
+
   pim_free();
 
   /* reverse prefix_list_init */
@@ -321,4 +323,11 @@ void pim_terminate()
   prefix_list_reset ();
 
   pim_vrf_terminate ();
+
+  zclient = pim_zebra_zclient_get ();
+  if (zclient)
+    {
+      zclient_stop (zclient);
+      zclient_free (zclient);
+    }
 }
index 38c2875949fec23a1fd0ca941bd05c8d583f9073..1a7d03bca173df764244b0b5ce06eca8eee2af99 100644 (file)
@@ -100,6 +100,8 @@ sigint (void)
   if (! retain_mode)
     rip_clean ();
 
+  rip_zclient_stop ();
+
   exit (0);
 }
 
index 337555b0b70526fa03de1abc5f9a7f99de61882b..31204872acf3aef4a57b261e31f7fb4ec1d5548e 100644 (file)
@@ -711,3 +711,10 @@ rip_zclient_init (struct thread_master *master)
   install_element (RIP_NODE, &rip_default_information_originate_cmd);
   install_element (RIP_NODE, &no_rip_default_information_originate_cmd);
 }
+
+void
+rip_zclient_stop (void)
+{
+  zclient_stop (zclient);
+  zclient_free (zclient);
+}
index d52df0d9921c715555a6b23a194bfb04b2b21804..a8e65d12366281b8f1c79fa0e9368231c0c9e78f 100644 (file)
@@ -388,6 +388,7 @@ extern void rip_if_down_all (void);
 extern void rip_route_map_init (void);
 extern void rip_route_map_reset (void);
 extern void rip_zclient_init(struct thread_master *);
+extern void rip_zclient_stop(void);
 extern void rip_zclient_reset (void);
 extern void rip_offset_init (void);
 extern int if_check_address (struct in_addr addr);
index e5178171471f3b9d05792d1aefd834826dd6815e..9d700305edd7f8e38bd933006a6cee378fb29092 100644 (file)
@@ -103,6 +103,7 @@ sigint (void)
   if (! retain_mode)
     ripng_clean ();
 
+  ripng_zebra_stop ();
   exit (0);
 }
 
index 2d62823b115fee00ec08d8c94e97c15ce92fcf42..465d33992f26363e4a59ade8928a9524a1d4e47e 100644 (file)
@@ -557,3 +557,10 @@ zebra_init (struct thread_master *master)
   install_element (RIPNG_NODE, &ripng_redistribute_type_metric_routemap_cmd);
   install_element (RIPNG_NODE, &no_ripng_redistribute_type_cmd);
 }
+
+void
+ripng_zebra_stop (void)
+{
+  zclient_stop (zclient);
+  zclient_free (zclient);
+}
index 62b7b073f87c04a677ecc265816d3ccc675ceabf..ce8ea07a41e13a66be1790ad9663a1bad1efc85b 100644 (file)
@@ -353,6 +353,7 @@ extern void ripng_route_map_reset (void);
 extern void ripng_terminate (void);
  /* zclient_init() is done by ripng_zebra.c:zebra_init() */
 extern void zebra_init(struct thread_master *);
+extern void ripng_zebra_stop (void);
 extern void ripng_zclient_reset (void);
 extern void ripng_offset_init (void);
 
index 2d83fe682853c26a0e8ff10b571f9fc75cf06294..461fb829d40ec99c54928d3032103eebc816bb40 100644 (file)
@@ -1331,7 +1331,7 @@ main (void)
 {
   int i = 0;
   qobj_init ();
-  bgp_master_init (thread_master_create ());
+  bgp_master_init (thread_master_create(NULL));
   master = bm->master;
   bgp_option_set (BGP_OPT_NO_LISTEN);
   bgp_attr_init ();
index 1e3a5be4e3142011cf569c49fcd92c70d39f3a68..be0ca37b1f0fd74e21a60ab73239e620de1ce644 100644 (file)
@@ -648,7 +648,7 @@ main (void)
   term_bgp_debug_as4 = -1UL;
   
   qobj_init ();
-  master = thread_master_create ();
+  master = thread_master_create(NULL);
   bgp_master_init (master);
   vrf_init (NULL, NULL, NULL, NULL);
   bgp_option_set (BGP_OPT_NO_LISTEN);
index e323748e97cc95a040bfab1bdc0ce5ad8acb9fce..f6f0fb70a54a1e5107e5e9582fe5e38c053545b2 100644 (file)
@@ -748,7 +748,7 @@ main (void)
   term_bgp_debug_as4 = -1UL;
   
   qobj_init ();
-  master = thread_master_create ();
+  master = thread_master_create(NULL);
   bgp_master_init (master);
   vrf_init (NULL, NULL, NULL, NULL);
   bgp_option_set (BGP_OPT_NO_LISTEN);
index affebbafeac0a7adac3c0663e99a932012015b83..3309a93227665021d10948f3ce1103796f25ef87 100644 (file)
@@ -376,7 +376,7 @@ static int
 global_test_init (void)
 {
   qobj_init ();
-  master = thread_master_create ();
+  master = thread_master_create(NULL);
   zclient = zclient_new(master);
   bgp_master_init (master);
   vrf_init (NULL, NULL, NULL, NULL);
index b0e80fb674c3405c4036218c70e673346f77018c..f842b037278635f0bc1cb5f03564003716a01507 100644 (file)
@@ -116,7 +116,7 @@ main (int argc, char **argv)
   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
 
   /* master init. */
-  master = thread_master_create ();
+  master = thread_master_create(NULL);
 
   while (1) 
     {
index 27b28b126f15cf03600d442a01a4b00d86c4153c..728ae8cb040a4bf28241831baf8c3e8ca181a98c 100644 (file)
@@ -67,7 +67,7 @@ main (int argc, char **argv)
   umask (0027);
 
   /* master init. */
-  master = thread_master_create ();
+  master = thread_master_create(NULL);
 
   openzlog("common-cli", "NONE", 0, LOG_CONS | LOG_NDELAY | LOG_PID,
            LOG_DAEMON);
index c43431622da0de5f67cf0c0e3af7d9ba13d3f30f..14384f4327891693445b6d3d2988a3212278ce53 100644 (file)
@@ -45,7 +45,7 @@ threadfunc (struct thread *thread)
 int
 main (void)
 {
-  master = thread_master_create ();
+  master = thread_master_create(NULL);
   signal_init (master, array_size(sigs), sigs);
 
   openzlog("testsegv", "NONE", 0, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
index a04c9f420639dc410ceea73619d4852c5df82ac6..1ffc6692f1c511a72706cdf3dfefd9eb6f1d9ef3 100644 (file)
@@ -61,7 +61,7 @@ struct thread t;
 int
 main (void)
 {
-  master = thread_master_create ();
+  master = thread_master_create(NULL);
   signal_init (master, array_size(sigs), sigs);
 
   openzlog("testsig", "NONE", 0, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
index 10461be1effff16c62525d6c0155063cae2e5f95..8fbe5bcbd74cf6727da7b8555612938a72dc3148 100644 (file)
@@ -115,7 +115,7 @@ int main(int argc, char **argv)
   struct thread t;
   struct timeval **alarms;
 
-  master = thread_master_create();
+  master = thread_master_create(NULL);
 
   log_buf_len = SCHEDULE_TIMERS * (TIMESTR_LEN + 1) + 1;
   log_buf_pos = 0;
index b67af19aeaa3467e6fb81d82e97119f63954b840..2bd02b5b0161e3623bc1cb49f0e084d4f568d774 100644 (file)
@@ -49,7 +49,7 @@ int main(int argc, char **argv)
   struct timeval tv_start, tv_lap, tv_stop;
   unsigned long t_schedule, t_remove;
 
-  master = thread_master_create();
+  master = thread_master_create(NULL);
   prng = prng_new(0);
   timers = calloc(SCHEDULE_TIMERS, sizeof(*timers));
 
index d830094badbbce27204631137a33f727d594adc3..a659447e728ea493a51acd6a6d2ee939ca334869 100644 (file)
@@ -140,7 +140,7 @@ int main (int argc, char *argv[])
 
                printf ("Sequence to be tested: %s\n", sequence);
 
-               master = thread_master_create();
+               master = thread_master_create(NULL);
                init_zclient (master, ZSERV_PATH);
 
                zebra_send_label_manager_connect ();
index 0e77ea4aecbc56cebb3c055b0f968c40695d0950..2903b8425de18532c507529b7ac69d27ccf36daa 100644 (file)
@@ -200,7 +200,7 @@ main (int argc, char **argv)
   if (argc == 1)
       usage_exit ();
 
-  master = thread_master_create();
+  master = thread_master_create(NULL);
   /* Establish connection to zebra. */
   zclient = zclient_new(master);
   zclient->enable = 1;
index dba916403dc378770d5b0a5a2b43d7ca78cf8df6..8c50a950651d684911f72b12900abeb252a51493 100644 (file)
@@ -774,7 +774,7 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
             {
               /* pre-configured interface, learnt now */
               if (ifp->vrf_id != vrf_id)
-                if_update (ifp, name, strlen(name), vrf_id);
+                if_update_to_new_vrf (ifp, vrf_id);
             }
 
           /* Update interface information. */
index a8ac405e3634d64d1e4730716b876f3654ecbbdb..b8426c6890b73f0cdc6700bd9b8442dcf187fda2 100644 (file)
@@ -737,7 +737,7 @@ if_handle_vrf_change (struct interface *ifp, vrf_id_t vrf_id)
   zebra_interface_vrf_update_del (ifp, vrf_id);
 
   /* update VRF */
-  if_update (ifp, ifp->name, strlen (ifp->name), vrf_id);
+  if_update_to_new_vrf (ifp, vrf_id);
 
   /* Send out notification on interface VRF change. */
   /* This is to issue an ADD, if needed. */