]> git.proxmox.com Git - mirror_frr.git/blame - lib/memory_vty.c
lib: migrate to new memory-type handling
[mirror_frr.git] / lib / memory_vty.c
CommitLineData
718e3744 1/*
2 * Memory management routine
3 * Copyright (C) 1998 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra 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
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
d09552d0 24/* malloc.h is generally obsolete, however GNU Libc mallinfo wants it. */
74176d22 25#if !defined(HAVE_STDLIB_H) || (defined(GNU_LINUX) && defined(HAVE_MALLINFO))
41be32bf 26#include <malloc.h>
d09552d0 27#endif /* !HAVE_STDLIB_H || HAVE_MALLINFO */
718e3744 28
29#include "log.h"
30#include "memory.h"
fc7948fa 31#include "memory_vty.h"
6b0655a2 32
718e3744 33/* Looking up memory status from vty interface. */
34#include "vector.h"
35#include "vty.h"
36#include "command.h"
37
228da428
CC
38void
39log_memstats_stderr (const char *prefix)
40{
fc7948fa 41#if 0
228da428
CC
42 struct mlist *ml;
43 struct memory_list *m;
44 int i;
45 int j = 0;
46
47 for (ml = mlists; ml->list; ml++)
48 {
49 i = 0;
50
51 for (m = ml->list; m->index >= 0; m++)
52 if (m->index && mstat[m->index].alloc)
53 {
54 if (!i)
55 fprintf (stderr,
56 "%s: memstats: Current memory utilization in module %s:\n",
57 prefix,
58 ml->name);
59 fprintf (stderr,
60 "%s: memstats: %-30s: %10ld%s\n",
61 prefix,
62 m->format,
63 mstat[m->index].alloc,
64 mstat[m->index].alloc < 0 ? " (REPORT THIS BUG!)" : "");
65 i = j = 1;
66 }
67 }
68
69 if (j)
70 fprintf (stderr,
71 "%s: memstats: NOTE: If configuration exists, utilization may be "
72 "expected.\n",
73 prefix);
74 else
75 fprintf (stderr,
76 "%s: memstats: No remaining tracked memory utilization.\n",
77 prefix);
fc7948fa 78#endif
228da428
CC
79}
80
fc7948fa 81#if 0
24065a3d 82static void
83show_separator(struct vty *vty)
718e3744 84{
24065a3d 85 vty_out (vty, "-----------------------------\r\n");
86}
718e3744 87
24065a3d 88static int
718e3744 89show_memory_vty (struct vty *vty, struct memory_list *list)
90{
91 struct memory_list *m;
24065a3d 92 int needsep = 0;
718e3744 93
94 for (m = list; m->index >= 0; m++)
95 if (m->index == 0)
24065a3d 96 {
97 if (needsep)
98 {
99 show_separator (vty);
100 needsep = 0;
101 }
102 }
103 else if (mstat[m->index].alloc)
104 {
105 vty_out (vty, "%-30s: %10ld\r\n", m->format, mstat[m->index].alloc);
106 needsep = 1;
107 }
108 return needsep;
718e3744 109}
fc7948fa 110#endif
718e3744 111
41be32bf
PJ
112#ifdef HAVE_MALLINFO
113static int
114show_memory_mallinfo (struct vty *vty)
115{
116 struct mallinfo minfo = mallinfo();
117 char buf[MTYPE_MEMSTR_LEN];
118
119 vty_out (vty, "System allocator statistics:%s", VTY_NEWLINE);
120 vty_out (vty, " Total heap allocated: %s%s",
121 mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.arena),
122 VTY_NEWLINE);
123 vty_out (vty, " Holding block headers: %s%s",
124 mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.hblkhd),
125 VTY_NEWLINE);
126 vty_out (vty, " Used small blocks: %s%s",
127 mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.usmblks),
128 VTY_NEWLINE);
129 vty_out (vty, " Used ordinary blocks: %s%s",
130 mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.uordblks),
131 VTY_NEWLINE);
132 vty_out (vty, " Free small blocks: %s%s",
133 mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.fsmblks),
134 VTY_NEWLINE);
135 vty_out (vty, " Free ordinary blocks: %s%s",
136 mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.fordblks),
137 VTY_NEWLINE);
138 vty_out (vty, " Ordinary blocks: %ld%s",
139 (unsigned long)minfo.ordblks,
140 VTY_NEWLINE);
141 vty_out (vty, " Small blocks: %ld%s",
142 (unsigned long)minfo.smblks,
143 VTY_NEWLINE);
144 vty_out (vty, " Holding blocks: %ld%s",
145 (unsigned long)minfo.hblks,
146 VTY_NEWLINE);
147 vty_out (vty, "(see system documentation for 'mallinfo' for meaning)%s",
148 VTY_NEWLINE);
149 return 1;
150}
151#endif /* HAVE_MALLINFO */
152
3b4cd783
DL
153static int qmem_walker(void *arg, struct memgroup *mg, struct memtype *mt)
154{
155 struct vty *vty = arg;
156 if (!mt)
157 vty_out (vty, "--- qmem %s ---%s", mg->name, VTY_NEWLINE);
158 else {
159 char size[32];
160 snprintf(size, sizeof(size), "%6zu", mt->size);
161 vty_out (vty, "%-30s: %10zu %s%s",
162 mt->name, mt->n_alloc,
163 mt->size == 0 ? "" :
164 mt->size == SIZE_VAR ? "(variably sized)" :
165 size, VTY_NEWLINE);
166 }
167 return 0;
168}
169
170
0d05fa51
DS
171DEFUN (show_memory,
172 show_memory_cmd,
173 "show memory",
718e3744 174 "Show running system information\n"
0d05fa51 175 "Memory statistics\n")
718e3744 176{
24065a3d 177 int needsep = 0;
41be32bf
PJ
178
179#ifdef HAVE_MALLINFO
180 needsep = show_memory_mallinfo (vty);
181#endif /* HAVE_MALLINFO */
fc7948fa
DL
182
183 (void) needsep;
184#if 0
185 struct mlist *ml;
7fa25ff6 186 for (ml = mlists; ml->list; ml++)
187 {
24065a3d 188 if (needsep)
189 show_separator (vty);
190 needsep = show_memory_vty (vty, ml->list);
7fa25ff6 191 }
fc7948fa 192#endif
718e3744 193
3b4cd783 194 qmem_walk(qmem_walker, vty);
718e3744 195 return CMD_SUCCESS;
196}
197
718e3744 198void
f858e49b 199memory_init (void)
718e3744 200{
62687ff1 201 install_element (RESTRICTED_NODE, &show_memory_cmd);
62687ff1 202
718e3744 203 install_element (VIEW_NODE, &show_memory_cmd);
718e3744 204
205 install_element (ENABLE_NODE, &show_memory_cmd);
718e3744 206}
6b0655a2 207
41be32bf
PJ
208/* Stats querying from users */
209/* Return a pointer to a human friendly string describing
210 * the byte count passed in. E.g:
211 * "0 bytes", "2048 bytes", "110kB", "500MiB", "11GiB", etc.
212 * Up to 4 significant figures will be given.
213 * The pointer returned may be NULL (indicating an error)
214 * or point to the given buffer, or point to static storage.
215 */
216const char *
217mtype_memstr (char *buf, size_t len, unsigned long bytes)
218{
6896f650
DS
219 unsigned int m, k;
220
41be32bf
PJ
221 /* easy cases */
222 if (!bytes)
223 return "0 bytes";
224 if (bytes == 1)
225 return "1 byte";
6896f650
DS
226
227 /*
228 * When we pass the 2gb barrier mallinfo() can no longer report
229 * correct data so it just does something odd...
230 * Reporting like Terrabytes of data. Which makes users...
231 * edgy.. yes edgy that's the term for it.
232 * So let's just give up gracefully
233 */
234 if (bytes > 0x7fffffff)
235 return "> 2GB";
236
41be32bf
PJ
237 m = bytes >> 20;
238 k = bytes >> 10;
6896f650
DS
239
240 if (m > 10)
41be32bf
PJ
241 {
242 if (bytes & (1 << 19))
243 m++;
244 snprintf (buf, len, "%d MiB", m);
245 }
246 else if (k > 10)
247 {
248 if (bytes & (1 << 9))
249 k++;
250 snprintf (buf, len, "%d KiB", k);
251 }
252 else
253 snprintf (buf, len, "%ld bytes", bytes);
254
255 return buf;
256}