summaryrefslogtreecommitdiff
path: root/lib/memory_vty.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2016-09-20 21:17:34 -0400
committerDonald Sharp <sharpd@cumulusnetworks.com>2016-09-20 21:17:34 -0400
commit460a768914822df062bc1282296e6bf6a3c6f725 (patch)
tree5997cc60a574e56f4960103caa9d9f35a36bc4e2 /lib/memory_vty.c
parent844ec28cee41395cdd1cc0cdf8cf0168f9dc1adf (diff)
parente3e29b328d161c6d129e479a9564ce216688da81 (diff)
Merge remote-tracking branch 'origin/cmaster-next' into vtysh-grammar
Diffstat (limited to 'lib/memory_vty.c')
-rw-r--r--lib/memory_vty.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/lib/memory_vty.c b/lib/memory_vty.c
new file mode 100644
index 0000000000..e4cb295cf0
--- /dev/null
+++ b/lib/memory_vty.c
@@ -0,0 +1,169 @@
+/*
+ * Memory management routine
+ * Copyright (C) 1998 Kunihiro Ishiguro
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+/* malloc.h is generally obsolete, however GNU Libc mallinfo wants it. */
+#if !defined(HAVE_STDLIB_H) || (defined(GNU_LINUX) && defined(HAVE_MALLINFO))
+#include <malloc.h>
+#endif /* !HAVE_STDLIB_H || HAVE_MALLINFO */
+
+#include "log.h"
+#include "memory.h"
+#include "memory_vty.h"
+
+/* Looking up memory status from vty interface. */
+#include "vector.h"
+#include "vty.h"
+#include "command.h"
+
+#ifdef HAVE_MALLINFO
+static int
+show_memory_mallinfo (struct vty *vty)
+{
+ struct mallinfo minfo = mallinfo();
+ char buf[MTYPE_MEMSTR_LEN];
+
+ vty_out (vty, "System allocator statistics:%s", VTY_NEWLINE);
+ vty_out (vty, " Total heap allocated: %s%s",
+ mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.arena),
+ VTY_NEWLINE);
+ vty_out (vty, " Holding block headers: %s%s",
+ mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.hblkhd),
+ VTY_NEWLINE);
+ vty_out (vty, " Used small blocks: %s%s",
+ mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.usmblks),
+ VTY_NEWLINE);
+ vty_out (vty, " Used ordinary blocks: %s%s",
+ mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.uordblks),
+ VTY_NEWLINE);
+ vty_out (vty, " Free small blocks: %s%s",
+ mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.fsmblks),
+ VTY_NEWLINE);
+ vty_out (vty, " Free ordinary blocks: %s%s",
+ mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.fordblks),
+ VTY_NEWLINE);
+ vty_out (vty, " Ordinary blocks: %ld%s",
+ (unsigned long)minfo.ordblks,
+ VTY_NEWLINE);
+ vty_out (vty, " Small blocks: %ld%s",
+ (unsigned long)minfo.smblks,
+ VTY_NEWLINE);
+ vty_out (vty, " Holding blocks: %ld%s",
+ (unsigned long)minfo.hblks,
+ VTY_NEWLINE);
+ vty_out (vty, "(see system documentation for 'mallinfo' for meaning)%s",
+ VTY_NEWLINE);
+ return 1;
+}
+#endif /* HAVE_MALLINFO */
+
+static int qmem_walker(void *arg, struct memgroup *mg, struct memtype *mt)
+{
+ struct vty *vty = arg;
+ if (!mt)
+ vty_out (vty, "--- qmem %s ---%s", mg->name, VTY_NEWLINE);
+ else {
+ char size[32];
+ snprintf(size, sizeof(size), "%6zu", mt->size);
+ vty_out (vty, "%-30s: %10zu %s%s",
+ mt->name, mt->n_alloc,
+ mt->size == 0 ? "" :
+ mt->size == SIZE_VAR ? "(variably sized)" :
+ size, VTY_NEWLINE);
+ }
+ return 0;
+}
+
+
+DEFUN (show_memory,
+ show_memory_cmd,
+ "show memory",
+ "Show running system information\n"
+ "Memory statistics\n")
+{
+#ifdef HAVE_MALLINFO
+ show_memory_mallinfo (vty);
+#endif /* HAVE_MALLINFO */
+
+ qmem_walk(qmem_walker, vty);
+ return CMD_SUCCESS;
+}
+
+void
+memory_init (void)
+{
+ install_element (RESTRICTED_NODE, &show_memory_cmd);
+
+ install_element (VIEW_NODE, &show_memory_cmd);
+
+ install_element (ENABLE_NODE, &show_memory_cmd);
+}
+
+/* Stats querying from users */
+/* Return a pointer to a human friendly string describing
+ * the byte count passed in. E.g:
+ * "0 bytes", "2048 bytes", "110kB", "500MiB", "11GiB", etc.
+ * Up to 4 significant figures will be given.
+ * The pointer returned may be NULL (indicating an error)
+ * or point to the given buffer, or point to static storage.
+ */
+const char *
+mtype_memstr (char *buf, size_t len, unsigned long bytes)
+{
+ unsigned int m, k;
+
+ /* easy cases */
+ if (!bytes)
+ return "0 bytes";
+ if (bytes == 1)
+ return "1 byte";
+
+ /*
+ * When we pass the 2gb barrier mallinfo() can no longer report
+ * correct data so it just does something odd...
+ * Reporting like Terrabytes of data. Which makes users...
+ * edgy.. yes edgy that's the term for it.
+ * So let's just give up gracefully
+ */
+ if (bytes > 0x7fffffff)
+ return "> 2GB";
+
+ m = bytes >> 20;
+ k = bytes >> 10;
+
+ if (m > 10)
+ {
+ if (bytes & (1 << 19))
+ m++;
+ snprintf (buf, len, "%d MiB", m);
+ }
+ else if (k > 10)
+ {
+ if (bytes & (1 << 9))
+ k++;
+ snprintf (buf, len, "%d KiB", k);
+ }
+ else
+ snprintf (buf, len, "%ld bytes", bytes);
+
+ return buf;
+}