diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/command.c | 101 | ||||
-rw-r--r-- | lib/command.h | 8 | ||||
-rw-r--r-- | lib/log.c | 4 | ||||
-rw-r--r-- | lib/memory.c | 47 | ||||
-rw-r--r-- | lib/memory.h | 1 | ||||
-rw-r--r-- | lib/routemap.c | 9 | ||||
-rw-r--r-- | lib/routemap.h | 1 | ||||
-rw-r--r-- | lib/thread.c | 22 | ||||
-rw-r--r-- | lib/vty.c | 16 | ||||
-rw-r--r-- | lib/vty.h | 1 | ||||
-rw-r--r-- | lib/zclient.c | 7 | ||||
-rw-r--r-- | lib/zclient.h | 1 |
12 files changed, 195 insertions, 23 deletions
diff --git a/lib/command.c b/lib/command.c index 0bbd99e5..31c067a3 100644 --- a/lib/command.c +++ b/lib/command.c @@ -37,6 +37,9 @@ Boston, MA 02111-1307, USA. */ each daemon maintains each own cmdvec. */ vector cmdvec = NULL; +struct desc desc_cr; +char *command_cr = NULL; + /* Host information structure. */ struct host host; @@ -199,8 +202,8 @@ install_node (struct cmd_node *node, static int cmp_node (const void *p, const void *q) { - const struct cmd_element *a = *(struct cmd_element **)p; - const struct cmd_element *b = *(struct cmd_element **)q; + const struct cmd_element *a = *(struct cmd_element * const *)p; + const struct cmd_element *b = *(struct cmd_element * const *)q; return strcmp (a->string, b->string); } @@ -208,8 +211,8 @@ cmp_node (const void *p, const void *q) static int cmp_desc (const void *p, const void *q) { - const struct desc *a = *(struct desc **)p; - const struct desc *b = *(struct desc **)q; + const struct desc *a = *(struct desc * const *)p; + const struct desc *b = *(struct desc * const *)q; return strcmp (a->cmd, b->cmd); } @@ -223,7 +226,7 @@ sort_node () vector descvec; struct cmd_element *cmd_element; - for (i = 0; i < vector_active (cmdvec); i++) + for (i = 0; i < vector_active (cmdvec); i++) if ((cnode = vector_slot (cmdvec, i)) != NULL) { vector cmd_vector = cnode->cmd_vector; @@ -497,7 +500,9 @@ install_element (enum node_type ntype, struct cmd_element *cmd) vector_set (cnode->cmd_vector, cmd); - cmd->strvec = cmd_make_descvec (cmd->string, cmd->doc); + if (cmd->strvec == NULL) + cmd->strvec = cmd_make_descvec (cmd->string, cmd->doc); + cmd->cmdsize = cmd_cmdsize (cmd->strvec); } @@ -1588,7 +1593,6 @@ cmd_describe_command_real (vector vline, struct vty *vty, int *status) int ret; enum match_type match; char *command; - static struct desc desc_cr = { "<cr>", "" }; /* Set index. */ if (vector_active (vline) == 0) @@ -1665,7 +1669,6 @@ cmd_describe_command_real (vector vline, struct vty *vty, int *status) for (i = 0; i < vector_active (cmd_vector); i++) if ((cmd_element = vector_slot (cmd_vector, i)) != NULL) { - const char *string = NULL; vector strvec = cmd_element->strvec; /* if command is NULL, index may be equal to vector_active */ @@ -1676,8 +1679,7 @@ cmd_describe_command_real (vector vline, struct vty *vty, int *status) /* Check if command is completed. */ if (command == NULL && index == vector_active (strvec)) { - string = "<cr>"; - if (!desc_unique_string (matchvec, string)) + if (!desc_unique_string (matchvec, command_cr)) vector_set (matchvec, &desc_cr); } else @@ -1689,6 +1691,8 @@ cmd_describe_command_real (vector vline, struct vty *vty, int *status) for (j = 0; j < vector_active (descvec); j++) if ((desc = vector_slot (descvec, j))) { + const char *string; + string = cmd_entry_function_desc (command, desc->cmd); if (string) { @@ -3506,6 +3510,8 @@ DEFUN (no_banner_motd, void host_config_set (char *filename) { + if (host.config) + XFREE (MTYPE_HOST, host.config); host.config = XSTRDUP (MTYPE_HOST, filename); } @@ -3529,6 +3535,10 @@ install_default (enum node_type node) void cmd_init (int terminal) { + command_cr = XSTRDUP(MTYPE_STRVEC, "<cr>"); + desc_cr.cmd = command_cr; + desc_cr.str = XSTRDUP(MTYPE_STRVEC, ""); + /* Allocate initial top vector of commands. */ cmdvec = vector_init (VECTOR_MIN_SIZE); @@ -3645,3 +3655,74 @@ cmd_init (int terminal) } srand(time(NULL)); } + +void +cmd_terminate () +{ + unsigned int i, j, k, l; + struct cmd_node *cmd_node; + struct cmd_element *cmd_element; + struct desc *desc; + vector cmd_node_v, cmd_element_v, desc_v; + + if (cmdvec) + { + for (i = 0; i < vector_active (cmdvec); i++) + if ((cmd_node = vector_slot (cmdvec, i)) != NULL) + { + cmd_node_v = cmd_node->cmd_vector; + + for (j = 0; j < vector_active (cmd_node_v); j++) + if ((cmd_element = vector_slot (cmd_node_v, j)) != NULL && + cmd_element->strvec != NULL) + { + cmd_element_v = cmd_element->strvec; + + for (k = 0; k < vector_active (cmd_element_v); k++) + if ((desc_v = vector_slot (cmd_element_v, k)) != NULL) + { + for (l = 0; l < vector_active (desc_v); l++) + if ((desc = vector_slot (desc_v, l)) != NULL) + { + if (desc->cmd) + XFREE (MTYPE_STRVEC, desc->cmd); + if (desc->str) + XFREE (MTYPE_STRVEC, desc->str); + + XFREE (MTYPE_DESC, desc); + } + vector_free (desc_v); + } + + cmd_element->strvec = NULL; + vector_free (cmd_element_v); + } + + vector_free (cmd_node_v); + } + + vector_free (cmdvec); + cmdvec = NULL; + } + + if (command_cr) + XFREE(MTYPE_STRVEC, command_cr); + if (desc_cr.str) + XFREE(MTYPE_STRVEC, desc_cr.str); + if (host.name) + XFREE (MTYPE_HOST, host.name); + if (host.password) + XFREE (MTYPE_HOST, host.password); + if (host.password_encrypt) + XFREE (MTYPE_HOST, host.password_encrypt); + if (host.enable) + XFREE (MTYPE_HOST, host.enable); + if (host.enable_encrypt) + XFREE (MTYPE_HOST, host.enable_encrypt); + if (host.logfile) + XFREE (MTYPE_HOST, host.logfile); + if (host.motdfile) + XFREE (MTYPE_HOST, host.motdfile); + if (host.config) + XFREE (MTYPE_HOST, host.config); +} diff --git a/lib/command.h b/lib/command.h index d093df3c..1275efee 100644 --- a/lib/command.h +++ b/lib/command.h @@ -147,8 +147,8 @@ struct cmd_element /* Command description structure. */ struct desc { - const char *cmd; /* Command string. */ - const char *str; /* Command's description. */ + char *cmd; /* Command string. */ + char *str; /* Command's description. */ }; /* Return value of the commands. */ @@ -347,6 +347,7 @@ extern int cmd_execute_command (vector, struct vty *, struct cmd_element **, int extern int cmd_execute_command_strict (vector, struct vty *, struct cmd_element **); extern void config_replace_string (struct cmd_element *, char *, ...); extern void cmd_init (int); +extern void cmd_terminate (void); /* Export typical functions. */ extern struct cmd_element config_end_cmd; @@ -361,4 +362,7 @@ extern void print_version (const char *); /* struct host global, ick */ extern struct host host; + +/* "<cr>" global */ +extern char *command_cr; #endif /* _ZEBRA_COMMAND_H */ @@ -649,7 +649,9 @@ void closezlog (struct zlog *zl) { closelog(); - fclose (zl->fp); + + if (zl->fp != NULL) + fclose (zl->fp); XFREE (MTYPE_ZLOG, zl); } diff --git a/lib/memory.c b/lib/memory.c index f5d0cba6..dc09d8a6 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -127,7 +127,7 @@ zstrdup (int type, const char *str) static struct { const char *name; - unsigned long alloc; + long alloc; unsigned long t_malloc; unsigned long c_malloc; unsigned long t_calloc; @@ -214,9 +214,9 @@ mtype_zstrdup (const char *file, int line, int type, const char *str) static struct { char *name; - unsigned long alloc; + long alloc; } mstat [MTYPE_MAX]; -#endif /* MTPYE_LOG */ +#endif /* MEMORY_LOG */ /* Increment allocation counter. */ static void @@ -253,6 +253,47 @@ log_memstats(int pri) } } +void +log_memstats_stderr (const char *prefix) +{ + struct mlist *ml; + struct memory_list *m; + int i; + int j = 0; + + for (ml = mlists; ml->list; ml++) + { + i = 0; + + for (m = ml->list; m->index >= 0; m++) + if (m->index && mstat[m->index].alloc) + { + if (!i) + fprintf (stderr, + "%s: memstats: Current memory utilization in module %s:\n", + prefix, + ml->name); + fprintf (stderr, + "%s: memstats: %-30s: %10ld%s\n", + prefix, + m->format, + mstat[m->index].alloc, + mstat[m->index].alloc < 0 ? " (REPORT THIS BUG!)" : ""); + i = j = 1; + } + } + + if (j) + fprintf (stderr, + "%s: memstats: NOTE: If configuration exists, utilization may be " + "expected.\n", + prefix); + else + fprintf (stderr, + "%s: memstats: No remaining tracked memory utilization.\n", + prefix); +} + static void show_separator(struct vty *vty) { diff --git a/lib/memory.h b/lib/memory.h index a23c2787..42eb5cae 100644 --- a/lib/memory.h +++ b/lib/memory.h @@ -81,6 +81,7 @@ extern void mtype_zfree (const char *file, int line, int type, extern char *mtype_zstrdup (const char *file, int line, int type, const char *str); extern void memory_init (void); +extern void log_memstats_stderr (const char *); /* return number of allocations outstanding for the type */ extern unsigned long mtype_stats_alloc (int); diff --git a/lib/routemap.c b/lib/routemap.c index 5f7a3182..4f4e6d62 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -889,6 +889,15 @@ route_map_init (void) route_match_vec = vector_init (1); route_set_vec = vector_init (1); } + +void +route_map_finish (void) +{ + vector_free (route_match_vec); + route_match_vec = NULL; + vector_free (route_set_vec); + route_set_vec = NULL; +} /* VTY related functions. */ DEFUN (route_map, diff --git a/lib/routemap.h b/lib/routemap.h index 321e1927..1402f5c8 100644 --- a/lib/routemap.h +++ b/lib/routemap.h @@ -153,6 +153,7 @@ struct route_map /* Prototypes. */ extern void route_map_init (void); extern void route_map_init_vty (void); +extern void route_map_finish (void); /* Add match statement to route map. */ extern int route_map_add_match (struct route_map_index *index, diff --git a/lib/thread.c b/lib/thread.c index 47a9dc43..e89af541 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -239,6 +239,15 @@ cpu_record_hash_alloc (struct cpu_thread_history *a) return new; } +static void +cpu_record_hash_free (void *a) +{ + struct cpu_thread_history *hist = a; + + XFREE (MTYPE_THREAD_FUNCNAME, hist->funcname); + XFREE (MTYPE_THREAD_STATS, hist); +} + static inline void vty_out_cpu_thread_history(struct vty* vty, struct cpu_thread_history *a) @@ -485,7 +494,8 @@ thread_list_free (struct thread_master *m, struct thread_list *list) for (t = list->head; t; t = next) { next = t->next; - XFREE (MTYPE_THREAD_FUNCNAME, t->funcname); + if (t->funcname) + XFREE (MTYPE_THREAD_FUNCNAME, t->funcname); XFREE (MTYPE_THREAD, t); list->count--; m->alloc--; @@ -505,6 +515,13 @@ thread_master_free (struct thread_master *m) thread_list_free (m, &m->background); XFREE (MTYPE_THREAD_MASTER, m); + + if (cpu_record) + { + hash_clean (cpu_record, cpu_record_hash_free); + hash_free (cpu_record); + cpu_record = NULL; + } } /* Thread list is empty or not. */ @@ -836,6 +853,7 @@ thread_run (struct thread_master *m, struct thread *thread, { *fetch = *thread; thread->type = THREAD_UNUSED; + thread->funcname = NULL; /* thread_call will free fetch's copied pointer */ thread_add_unuse (m, thread); return fetch; } @@ -1079,6 +1097,8 @@ thread_call (struct thread *thread) realtime/1000, cputime/1000); } #endif /* CONSUMED_TIME_CHECK */ + + XFREE (MTYPE_THREAD_FUNCNAME, thread->funcname); } /* Execute thread */ @@ -1034,7 +1034,7 @@ vty_describe_command (struct vty *vty) if (desc->cmd[0] == '\0') continue; - if (strcmp (desc->cmd, "<cr>") == 0) + if (strcmp (desc->cmd, command_cr) == 0) { desc_cr = desc; continue; @@ -2988,3 +2988,17 @@ vty_init (struct thread_master *master_thread) install_element (VTY_NODE, &no_vty_ipv6_access_class_cmd); #endif /* HAVE_IPV6 */ } + +void +vty_terminate (void) +{ + if (vty_cwd) + XFREE (MTYPE_TMP, vty_cwd); + + if (vtyvec && Vvty_serv_thread) + { + vty_reset (); + vector_free (vtyvec); + vector_free (Vvty_serv_thread); + } +} @@ -203,6 +203,7 @@ extern char integrate_default[]; /* Prototypes. */ extern void vty_init (struct thread_master *); extern void vty_init_vtysh (void); +extern void vty_terminate (void); extern void vty_reset (void); extern struct vty *vty_new (void); extern int vty_out (struct vty *, const char *, ...) PRINTF_ATTRIBUTE(2, 3); diff --git a/lib/zclient.c b/lib/zclient.c index 4a716a66..d3d53227 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -58,13 +58,11 @@ zclient_new () return zclient; } -#if 0 -/* This function is never used. And it must not be used, because +/* This function is only called when exiting, because many parts of the code do not check for I/O errors, so they could reference an invalid pointer if the structure was ever freed. -*/ -/* Free zclient structure. */ + Free zclient structure. */ void zclient_free (struct zclient *zclient) { @@ -77,7 +75,6 @@ zclient_free (struct zclient *zclient) XFREE (MTYPE_ZCLIENT, zclient); } -#endif /* Initialize zebra client. Argument redist_default is unwanted redistribute route type. */ diff --git a/lib/zclient.h b/lib/zclient.h index 69ada144..21786ab8 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -125,6 +125,7 @@ extern void zclient_init (struct zclient *, int); extern int zclient_start (struct zclient *); extern void zclient_stop (struct zclient *); extern void zclient_reset (struct zclient *); +extern void zclient_free (struct zclient *); /* Get TCP socket connection to zebra daemon at loopback address. */ extern int zclient_socket (void); |