summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/command.c101
-rw-r--r--lib/command.h8
-rw-r--r--lib/log.c4
-rw-r--r--lib/memory.c47
-rw-r--r--lib/memory.h1
-rw-r--r--lib/routemap.c9
-rw-r--r--lib/routemap.h1
-rw-r--r--lib/thread.c22
-rw-r--r--lib/vty.c16
-rw-r--r--lib/vty.h1
-rw-r--r--lib/zclient.c7
-rw-r--r--lib/zclient.h1
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 */
diff --git a/lib/log.c b/lib/log.c
index 8c3e2ddc..0c2f655b 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -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 */
diff --git a/lib/vty.c b/lib/vty.c
index 14a36c16..30a94e11 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -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);
+ }
+}
diff --git a/lib/vty.h b/lib/vty.h
index 65ae6201..7df04b5f 100644
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -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);