]> git.proxmox.com Git - mirror_frr.git/blame - lib/memory_vty.c
debianpkg: Remove -werror from Ubuntu 14.04 and 12.04 build to skip warnings from...
[mirror_frr.git] / lib / memory_vty.c
CommitLineData
718e3744 1/*
b249c083 2 * Memory and dynamic module VTY routine
718e3744 3 *
b249c083
DL
4 * Copyright (C) 1998 Kunihiro Ishiguro
5 * Copyright (C) 2016-2017 David Lamparter for NetDEF, Inc.
718e3744 6 *
b249c083
DL
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
718e3744 11 *
b249c083
DL
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
718e3744 16 *
b249c083
DL
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
718e3744 20 */
21
22#include <zebra.h>
d09552d0 23/* malloc.h is generally obsolete, however GNU Libc mallinfo wants it. */
24f5e2fc 24#if (defined(GNU_LINUX) && defined(HAVE_MALLINFO))
41be32bf 25#include <malloc.h>
24f5e2fc 26#endif /* HAVE_MALLINFO */
b249c083
DL
27#include <dlfcn.h>
28#include <link.h>
718e3744 29
30#include "log.h"
31#include "memory.h"
b249c083 32#include "module.h"
fc7948fa 33#include "memory_vty.h"
6b0655a2 34
718e3744 35/* Looking up memory status from vty interface. */
36#include "vector.h"
37#include "vty.h"
38#include "command.h"
39
41be32bf 40#ifdef HAVE_MALLINFO
ac4d0be5 41static int show_memory_mallinfo(struct vty *vty)
41be32bf 42{
ac4d0be5 43 struct mallinfo minfo = mallinfo();
44 char buf[MTYPE_MEMSTR_LEN];
45
46 vty_out(vty, "System allocator statistics:%s", VTY_NEWLINE);
47 vty_out(vty, " Total heap allocated: %s%s",
48 mtype_memstr(buf, MTYPE_MEMSTR_LEN, minfo.arena), VTY_NEWLINE);
49 vty_out(vty, " Holding block headers: %s%s",
50 mtype_memstr(buf, MTYPE_MEMSTR_LEN, minfo.hblkhd), VTY_NEWLINE);
51 vty_out(vty, " Used small blocks: %s%s",
52 mtype_memstr(buf, MTYPE_MEMSTR_LEN, minfo.usmblks),
53 VTY_NEWLINE);
54 vty_out(vty, " Used ordinary blocks: %s%s",
55 mtype_memstr(buf, MTYPE_MEMSTR_LEN, minfo.uordblks),
56 VTY_NEWLINE);
57 vty_out(vty, " Free small blocks: %s%s",
58 mtype_memstr(buf, MTYPE_MEMSTR_LEN, minfo.fsmblks),
59 VTY_NEWLINE);
60 vty_out(vty, " Free ordinary blocks: %s%s",
61 mtype_memstr(buf, MTYPE_MEMSTR_LEN, minfo.fordblks),
62 VTY_NEWLINE);
63 vty_out(vty, " Ordinary blocks: %ld%s",
64 (unsigned long)minfo.ordblks, VTY_NEWLINE);
65 vty_out(vty, " Small blocks: %ld%s",
66 (unsigned long)minfo.smblks, VTY_NEWLINE);
67 vty_out(vty, " Holding blocks: %ld%s",
68 (unsigned long)minfo.hblks, VTY_NEWLINE);
69 vty_out(vty, "(see system documentation for 'mallinfo' for meaning)%s",
70 VTY_NEWLINE);
71 return 1;
41be32bf
PJ
72}
73#endif /* HAVE_MALLINFO */
74
3b4cd783
DL
75static int qmem_walker(void *arg, struct memgroup *mg, struct memtype *mt)
76{
77 struct vty *vty = arg;
78 if (!mt)
ac4d0be5 79 vty_out(vty, "--- qmem %s ---%s", mg->name, VTY_NEWLINE);
3b4cd783 80 else {
3694c43a
DS
81 if (mt->n_alloc != 0) {
82 char size[32];
83 snprintf(size, sizeof(size), "%6zu", mt->size);
ac4d0be5 84 vty_out(vty, "%-30s: %10zu %s%s", mt->name,
85 mt->n_alloc,
86 mt->size == 0 ? ""
87 : mt->size == SIZE_VAR
88 ? "(variably sized)"
89 : size,
90 VTY_NEWLINE);
3694c43a 91 }
3b4cd783
DL
92 }
93 return 0;
94}
95
96
0d05fa51
DS
97DEFUN (show_memory,
98 show_memory_cmd,
99 "show memory",
718e3744 100 "Show running system information\n"
0d05fa51 101 "Memory statistics\n")
718e3744 102{
41be32bf 103#ifdef HAVE_MALLINFO
ac4d0be5 104 show_memory_mallinfo(vty);
41be32bf 105#endif /* HAVE_MALLINFO */
fc7948fa 106
ac4d0be5 107 qmem_walk(qmem_walker, vty);
108 return CMD_SUCCESS;
718e3744 109}
110
b249c083
DL
111DEFUN (show_modules,
112 show_modules_cmd,
113 "show modules",
114 "Show running system information\n"
115 "Loaded modules\n")
116{
ac4d0be5 117 struct frrmod_runtime *plug = frrmod_list;
118
119 vty_out(vty, "%-12s %-25s %s%s%s", "Module Name", "Version",
120 "Description", VTY_NEWLINE, VTY_NEWLINE);
121 while (plug) {
122 const struct frrmod_info *i = plug->info;
123
124 vty_out(vty, "%-12s %-25s %s%s", i->name, i->version,
125 i->description, VTY_NEWLINE);
126 if (plug->dl_handle) {
b249c083 127#ifdef HAVE_DLINFO_ORIGIN
ac4d0be5 128 char origin[MAXPATHLEN] = "";
129 dlinfo(plug->dl_handle, RTLD_DI_ORIGIN, &origin);
130#ifdef HAVE_DLINFO_LINKMAP
131 const char *name;
132 struct link_map *lm = NULL;
133 dlinfo(plug->dl_handle, RTLD_DI_LINKMAP, &lm);
134 if (lm) {
135 name = strrchr(lm->l_name, '/');
136 name = name ? name + 1 : lm->l_name;
137 vty_out(vty, "\tfrom: %s/%s%s", origin, name,
138 VTY_NEWLINE);
139 }
140#else
141 vty_out(vty, "\tfrom: %s %s", origin, plug->load_name,
142 VTY_NEWLINE);
143#endif
b249c083 144#else
ac4d0be5 145 vty_out(vty, "\tfrom: %s%s", plug->load_name,
146 VTY_NEWLINE);
b249c083 147#endif
ac4d0be5 148 }
149 plug = plug->next;
150 }
151 return CMD_SUCCESS;
b249c083
DL
152}
153
ac4d0be5 154void memory_init(void)
718e3744 155{
ac4d0be5 156 install_element(VIEW_NODE, &show_memory_cmd);
157 install_element(VIEW_NODE, &show_modules_cmd);
718e3744 158}
6b0655a2 159
41be32bf
PJ
160/* Stats querying from users */
161/* Return a pointer to a human friendly string describing
162 * the byte count passed in. E.g:
163 * "0 bytes", "2048 bytes", "110kB", "500MiB", "11GiB", etc.
164 * Up to 4 significant figures will be given.
165 * The pointer returned may be NULL (indicating an error)
166 * or point to the given buffer, or point to static storage.
167 */
ac4d0be5 168const char *mtype_memstr(char *buf, size_t len, unsigned long bytes)
41be32bf 169{
ac4d0be5 170 unsigned int m, k;
171
172 /* easy cases */
173 if (!bytes)
174 return "0 bytes";
175 if (bytes == 1)
176 return "1 byte";
177
178 /*
179 * When we pass the 2gb barrier mallinfo() can no longer report
180 * correct data so it just does something odd...
181 * Reporting like Terrabytes of data. Which makes users...
182 * edgy.. yes edgy that's the term for it.
183 * So let's just give up gracefully
184 */
185 if (bytes > 0x7fffffff)
186 return "> 2GB";
187
188 m = bytes >> 20;
189 k = bytes >> 10;
190
191 if (m > 10) {
192 if (bytes & (1 << 19))
193 m++;
194 snprintf(buf, len, "%d MiB", m);
195 } else if (k > 10) {
196 if (bytes & (1 << 9))
197 k++;
198 snprintf(buf, len, "%d KiB", k);
199 } else
200 snprintf(buf, len, "%ld bytes", bytes);
201
202 return buf;
41be32bf 203}