geom_dump.c revision 105091
1/*-
2 * Copyright (c) 2002 Poul-Henning Kamp
3 * Copyright (c) 2002 Networks Associates Technology, Inc.
4 * All rights reserved.
5 *
6 * This software was developed for the FreeBSD Project by Poul-Henning Kamp
7 * and NAI Labs, the Security Research Division of Network Associates, Inc.
8 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
9 * DARPA CHATS research program.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 * 3. The names of the authors may not be used to endorse or promote
20 *    products derived from this software without specific prior written
21 *    permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * $FreeBSD: head/sys/geom/geom_dump.c 105091 2002-10-14 10:02:24Z phk $
36 */
37
38
39#include <sys/param.h>
40#include <sys/sbuf.h>
41#ifndef _KERNEL
42#include <stdio.h>
43#include <unistd.h>
44#include <stdlib.h>
45#include <err.h>
46#else
47#include <sys/systm.h>
48#include <sys/malloc.h>
49#endif
50#include <machine/stdarg.h>
51
52#include <geom/geom.h>
53#include <geom/geom_int.h>
54
55
56static void
57g_confdot_consumer(struct sbuf *sb, struct g_consumer *cp)
58{
59
60	sbuf_printf(sb, "z%p [label=\"r%dw%de%d\\nbio #%d\"];\n",
61	    cp, cp->acr, cp->acw, cp->ace, cp->biocount);
62	if (cp->provider)
63		sbuf_printf(sb, "z%p -> z%p;\n", cp, cp->provider);
64}
65
66static void
67g_confdot_provider(struct sbuf *sb, struct g_provider *pp)
68{
69
70	sbuf_printf(sb, "z%p [shape=hexagon,label=\"%s\\nr%dw%de%d\\nerr#%d\"];\n",
71	    pp, pp->name, pp->acr, pp->acw, pp->ace, pp->error);
72}
73
74static void
75g_confdot_geom(struct sbuf *sb, struct g_geom *gp)
76{
77	struct g_consumer *cp;
78	struct g_provider *pp;
79
80	sbuf_printf(sb, "z%p [shape=box,label=\"%s\\n%s\\nr#%d\"];\n",
81	    gp, gp->class->name, gp->name, gp->rank);
82	LIST_FOREACH(cp, &gp->consumer, consumer) {
83		g_confdot_consumer(sb, cp);
84		sbuf_printf(sb, "z%p -> z%p;\n", gp, cp);
85	}
86
87	LIST_FOREACH(pp, &gp->provider, provider) {
88		g_confdot_provider(sb, pp);
89		sbuf_printf(sb, "z%p -> z%p;\n", pp, gp);
90	}
91}
92
93static void
94g_confdot_class(struct sbuf *sb, struct g_class *mp)
95{
96	struct g_geom *gp;
97
98	LIST_FOREACH(gp, &mp->geom, geom)
99		g_confdot_geom(sb, gp);
100}
101
102void
103g_confdot(void *p)
104{
105	struct g_class *mp;
106	struct sbuf *sb;
107
108	sb = p;
109	g_topology_assert();
110	sbuf_printf(sb, "digraph geom {\n");
111	LIST_FOREACH(mp, &g_classes, class)
112		g_confdot_class(sb, mp);
113	sbuf_printf(sb, "};\n");
114	sbuf_finish(sb);
115	wakeup(p);
116}
117
118
119static void
120g_conf_consumer(struct sbuf *sb, struct g_consumer *cp)
121{
122
123	sbuf_printf(sb, "\t<consumer id=\"%p\">\n", cp);
124	sbuf_printf(sb, "\t  <geom ref=\"%p\"/>\n", cp->geom);
125	if (cp->provider != NULL)
126		sbuf_printf(sb, "\t  <provider ref=\"%p\"/>\n", cp->provider);
127	sbuf_printf(sb, "\t  <mode>r%dw%de%d</mode>\n",
128	    cp->acr, cp->acw, cp->ace);
129	if (cp->geom->dumpconf) {
130		sbuf_printf(sb, "\t  <config>\n");
131		cp->geom->dumpconf(sb, "\t    ", cp->geom, cp, NULL);
132		sbuf_printf(sb, "\t  </config>\n");
133	}
134	sbuf_printf(sb, "\t</consumer>\n");
135}
136
137static void
138g_conf_provider(struct sbuf *sb, struct g_provider *pp)
139{
140
141	sbuf_printf(sb, "\t<provider id=\"%p\">\n", pp);
142	sbuf_printf(sb, "\t  <geom ref=\"%p\"/>\n", pp->geom);
143	sbuf_printf(sb, "\t  <mode>r%dw%de%d</mode>\n",
144	    pp->acr, pp->acw, pp->ace);
145	sbuf_printf(sb, "\t  <name>%s</name>\n", pp->name);
146	if (pp->geom->dumpconf) {
147		sbuf_printf(sb, "\t  <config>\n");
148		pp->geom->dumpconf(sb, "\t    ", pp->geom, NULL, pp);
149		sbuf_printf(sb, "\t  </config>\n");
150	}
151	sbuf_printf(sb, "\t</provider>\n");
152}
153
154
155static void
156g_conf_geom(struct sbuf *sb, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp)
157{
158	struct g_consumer *cp2;
159	struct g_provider *pp2;
160
161	sbuf_printf(sb, "    <geom id=\"%p\">\n", gp);
162	sbuf_printf(sb, "      <class ref=\"%p\"/>\n", gp->class);
163	sbuf_printf(sb, "      <name>%s</name>\n", gp->name);
164	sbuf_printf(sb, "      <rank>%d</rank>\n", gp->rank);
165	if (gp->dumpconf) {
166		sbuf_printf(sb, "      <config>\n");
167		gp->dumpconf(sb, "\t", gp, NULL, NULL);
168		sbuf_printf(sb, "      </config>\n");
169	}
170	LIST_FOREACH(cp2, &gp->consumer, consumer) {
171		if (cp != NULL && cp != cp2)
172			continue;
173		g_conf_consumer(sb, cp2);
174	}
175
176	LIST_FOREACH(pp2, &gp->provider, provider) {
177		if (pp != NULL && pp != pp2)
178			continue;
179		g_conf_provider(sb, pp2);
180	}
181	sbuf_printf(sb, "    </geom>\n");
182}
183
184static void
185g_conf_class(struct sbuf *sb, struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp)
186{
187	struct g_geom *gp2;
188
189	sbuf_printf(sb, "  <class id=\"%p\">\n", mp);
190	sbuf_printf(sb, "    <name>%s</name>\n", mp->name);
191	LIST_FOREACH(gp2, &mp->geom, geom) {
192		if (gp != NULL && gp != gp2)
193			continue;
194		g_conf_geom(sb, gp2, pp, cp);
195	}
196	sbuf_printf(sb, "  </class>\n");
197}
198
199void
200g_conf_specific(struct sbuf *sb, struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp)
201{
202	struct g_class *mp2;
203
204	g_topology_assert();
205	sbuf_printf(sb, "<mesh>\n");
206#ifndef _KERNEL
207	sbuf_printf(sb, "  <FreeBSD>%cFreeBSD%c</FreeBSD>\n", '$', '$');
208#endif
209	LIST_FOREACH(mp2, &g_classes, class) {
210		if (mp != NULL && mp != mp2)
211			continue;
212		g_conf_class(sb, mp2, gp, pp, cp);
213	}
214	sbuf_printf(sb, "</mesh>\n");
215	sbuf_finish(sb);
216}
217
218void
219g_confxml(void *p)
220{
221
222	g_topology_assert();
223	g_conf_specific(p, NULL, NULL, NULL, NULL);
224	wakeup(p);
225}
226
227void
228g_trace(int level, char *fmt, ...)
229{
230	va_list ap;
231
232	g_sanity(NULL);
233	if (!(g_debugflags & level))
234		return;
235	va_start(ap, fmt);
236	vprintf(fmt, ap);
237	printf("\n");
238}
239
240void
241g_hexdump(void *ptr, int length)
242{
243	int i, j, k;
244	unsigned char *cp;
245
246	cp = ptr;
247	for (i = 0; i < length; i+= 16) {
248		printf("%04x  ", i);
249		for (j = 0; j < 16; j++) {
250			k = i + j;
251			if (k < length)
252				printf(" %02x", cp[k]);
253			else
254				printf("   ");
255		}
256		printf("  |");
257		for (j = 0; j < 16; j++) {
258			k = i + j;
259			if (k >= length)
260				printf(" ");
261			else if (cp[k] >= ' ' && cp[k] <= '~')
262				printf("%c", cp[k]);
263			else
264				printf(".");
265		}
266		printf("|\n");
267	}
268}
269
270