192108Sphk/*-
292108Sphk * Copyright (c) 2002 Poul-Henning Kamp
392108Sphk * Copyright (c) 2002 Networks Associates Technology, Inc.
492108Sphk * All rights reserved.
592108Sphk *
692108Sphk * This software was developed for the FreeBSD Project by Poul-Henning Kamp
792108Sphk * and NAI Labs, the Security Research Division of Network Associates, Inc.
892108Sphk * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
992108Sphk * DARPA CHATS research program.
1092108Sphk *
1192108Sphk * Redistribution and use in source and binary forms, with or without
1292108Sphk * modification, are permitted provided that the following conditions
1392108Sphk * are met:
1492108Sphk * 1. Redistributions of source code must retain the above copyright
1592108Sphk *    notice, this list of conditions and the following disclaimer.
1692108Sphk * 2. Redistributions in binary form must reproduce the above copyright
1792108Sphk *    notice, this list of conditions and the following disclaimer in the
1892108Sphk *    documentation and/or other materials provided with the distribution.
1992108Sphk * 3. The names of the authors may not be used to endorse or promote
2092108Sphk *    products derived from this software without specific prior written
2192108Sphk *    permission.
2292108Sphk *
2392108Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2492108Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2592108Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2692108Sphk * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2792108Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2892108Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2992108Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3092108Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3192108Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3292108Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3392108Sphk * SUCH DAMAGE.
3492108Sphk */
3592108Sphk
36116196Sobrien#include <sys/cdefs.h>
37116196Sobrien__FBSDID("$FreeBSD$");
3892108Sphk
3992108Sphk#include <sys/param.h>
4092108Sphk#include <sys/sbuf.h>
4192108Sphk#include <sys/systm.h>
4292108Sphk#include <sys/malloc.h>
4392108Sphk#include <machine/stdarg.h>
4492108Sphk
4592108Sphk#include <geom/geom.h>
4693250Sphk#include <geom/geom_int.h>
47249507Sivoras#include <geom/geom_disk.h>
4892108Sphk
4992108Sphk
5092108Sphkstatic void
5192108Sphkg_confdot_consumer(struct sbuf *sb, struct g_consumer *cp)
5292108Sphk{
5392108Sphk
54110523Sphk	sbuf_printf(sb, "z%p [label=\"r%dw%de%d\"];\n",
55110523Sphk	    cp, cp->acr, cp->acw, cp->ace);
5692108Sphk	if (cp->provider)
5792108Sphk		sbuf_printf(sb, "z%p -> z%p;\n", cp, cp->provider);
5892108Sphk}
5992108Sphk
6092108Sphkstatic void
6192108Sphkg_confdot_provider(struct sbuf *sb, struct g_provider *pp)
6292108Sphk{
6392108Sphk
6492108Sphk	sbuf_printf(sb, "z%p [shape=hexagon,label=\"%s\\nr%dw%de%d\\nerr#%d\"];\n",
6592108Sphk	    pp, pp->name, pp->acr, pp->acw, pp->ace, pp->error);
6692108Sphk}
6792108Sphk
6892108Sphkstatic void
6992108Sphkg_confdot_geom(struct sbuf *sb, struct g_geom *gp)
7092108Sphk{
7192108Sphk	struct g_consumer *cp;
7292108Sphk	struct g_provider *pp;
7392108Sphk
7492108Sphk	sbuf_printf(sb, "z%p [shape=box,label=\"%s\\n%s\\nr#%d\"];\n",
7593248Sphk	    gp, gp->class->name, gp->name, gp->rank);
7692108Sphk	LIST_FOREACH(cp, &gp->consumer, consumer) {
7792108Sphk		g_confdot_consumer(sb, cp);
7892108Sphk		sbuf_printf(sb, "z%p -> z%p;\n", gp, cp);
7992108Sphk	}
8092108Sphk
8192108Sphk	LIST_FOREACH(pp, &gp->provider, provider) {
8292108Sphk		g_confdot_provider(sb, pp);
8392108Sphk		sbuf_printf(sb, "z%p -> z%p;\n", pp, gp);
8492108Sphk	}
8592108Sphk}
8692108Sphk
8792108Sphkstatic void
8893248Sphkg_confdot_class(struct sbuf *sb, struct g_class *mp)
8992108Sphk{
9092108Sphk	struct g_geom *gp;
9192108Sphk
9292108Sphk	LIST_FOREACH(gp, &mp->geom, geom)
9392108Sphk		g_confdot_geom(sb, gp);
9492108Sphk}
9592108Sphk
96104452Sphkvoid
97112989Sphkg_confdot(void *p, int flag )
9892108Sphk{
9993248Sphk	struct g_class *mp;
10092108Sphk	struct sbuf *sb;
10192108Sphk
102112989Sphk	KASSERT(flag != EV_CANCEL, ("g_confdot was cancelled"));
103104452Sphk	sb = p;
104104452Sphk	g_topology_assert();
10592108Sphk	sbuf_printf(sb, "digraph geom {\n");
10693774Sphk	LIST_FOREACH(mp, &g_classes, class)
10793248Sphk		g_confdot_class(sb, mp);
108250868Sjh	sbuf_printf(sb, "}\n");
10992108Sphk	sbuf_finish(sb);
11092108Sphk}
11192108Sphk
112106101Sphkstatic void
113106101Sphkg_conftxt_geom(struct sbuf *sb, struct g_geom *gp, int level)
114106101Sphk{
115106101Sphk	struct g_provider *pp;
116106101Sphk	struct g_consumer *cp;
11792108Sphk
118117342Sphk	if (gp->flags & G_GEOM_WITHER)
119117342Sphk		return;
120106101Sphk	LIST_FOREACH(pp, &gp->provider, provider) {
121106101Sphk		sbuf_printf(sb, "%d %s %s %ju %u", level, gp->class->name,
122106101Sphk		    pp->name, (uintmax_t)pp->mediasize, pp->sectorsize);
123107111Sphk		if (gp->dumpconf != NULL)
124107111Sphk			gp->dumpconf(sb, NULL, gp, NULL, pp);
125106101Sphk		sbuf_printf(sb, "\n");
126106101Sphk		LIST_FOREACH(cp, &pp->consumers, consumers)
127106101Sphk			g_conftxt_geom(sb, cp->geom, level + 1);
128106101Sphk	}
129106101Sphk}
130106101Sphk
13192108Sphkstatic void
132106101Sphkg_conftxt_class(struct sbuf *sb, struct g_class *mp)
133106101Sphk{
134106101Sphk	struct g_geom *gp;
135106101Sphk
136106101Sphk	LIST_FOREACH(gp, &mp->geom, geom)
137106101Sphk		g_conftxt_geom(sb, gp, 0);
138106101Sphk}
139106101Sphk
140106101Sphkvoid
141112989Sphkg_conftxt(void *p, int flag)
142106101Sphk{
143106101Sphk	struct g_class *mp;
144106101Sphk	struct sbuf *sb;
145106101Sphk
146112989Sphk	KASSERT(flag != EV_CANCEL, ("g_conftxt was cancelled"));
147106101Sphk	sb = p;
148106101Sphk	g_topology_assert();
149152342Smarcel	LIST_FOREACH(mp, &g_classes, class) {
150249507Sivoras		if (!strcmp(mp->name, G_DISK_CLASS_NAME) || !strcmp(mp->name, "MD"))
151152342Smarcel			g_conftxt_class(sb, mp);
152152342Smarcel	}
153106101Sphk	sbuf_finish(sb);
154106101Sphk}
155106101Sphk
156106101Sphk
157260479Smavvoid
158260479Smavg_conf_printf_escaped(struct sbuf *sb, const char *fmt, ...)
159205385Sjh{
160205385Sjh	struct sbuf *s;
161205385Sjh	const u_char *c;
162260479Smav	va_list ap;
163205385Sjh
164205385Sjh	s = sbuf_new_auto();
165260479Smav	va_start(ap, fmt);
166260479Smav	sbuf_vprintf(s, fmt, ap);
167260479Smav	va_end(ap);
168260479Smav	sbuf_finish(s);
169205385Sjh
170260479Smav	for (c = sbuf_data(s); *c != '\0'; c++) {
171205385Sjh		if (*c == '&' || *c == '<' || *c == '>' ||
172205385Sjh		    *c == '\'' || *c == '"' || *c > 0x7e)
173260479Smav			sbuf_printf(sb, "&#x%X;", *c);
174205385Sjh		else if (*c == '\t' || *c == '\n' || *c == '\r' || *c > 0x1f)
175260479Smav			sbuf_putc(sb, *c);
176205385Sjh		else
177260479Smav			sbuf_putc(sb, '?');
178205385Sjh	}
179205385Sjh	sbuf_delete(s);
180205385Sjh}
181205385Sjh
182205385Sjhstatic void
18392108Sphkg_conf_consumer(struct sbuf *sb, struct g_consumer *cp)
18492108Sphk{
18592108Sphk
18695405Sphk	sbuf_printf(sb, "\t<consumer id=\"%p\">\n", cp);
18795405Sphk	sbuf_printf(sb, "\t  <geom ref=\"%p\"/>\n", cp->geom);
18895405Sphk	if (cp->provider != NULL)
18995405Sphk		sbuf_printf(sb, "\t  <provider ref=\"%p\"/>\n", cp->provider);
19092108Sphk	sbuf_printf(sb, "\t  <mode>r%dw%de%d</mode>\n",
19192108Sphk	    cp->acr, cp->acw, cp->ace);
192117342Sphk	if (cp->geom->flags & G_GEOM_WITHER)
193117342Sphk		;
194117342Sphk	else if (cp->geom->dumpconf != NULL) {
19592108Sphk		sbuf_printf(sb, "\t  <config>\n");
19692108Sphk		cp->geom->dumpconf(sb, "\t    ", cp->geom, cp, NULL);
19792108Sphk		sbuf_printf(sb, "\t  </config>\n");
19892108Sphk	}
19992108Sphk	sbuf_printf(sb, "\t</consumer>\n");
20092108Sphk}
20192108Sphk
20292108Sphkstatic void
20392108Sphkg_conf_provider(struct sbuf *sb, struct g_provider *pp)
20492108Sphk{
20592108Sphk
20695405Sphk	sbuf_printf(sb, "\t<provider id=\"%p\">\n", pp);
20795405Sphk	sbuf_printf(sb, "\t  <geom ref=\"%p\"/>\n", pp->geom);
20892108Sphk	sbuf_printf(sb, "\t  <mode>r%dw%de%d</mode>\n",
20992108Sphk	    pp->acr, pp->acw, pp->ace);
210260479Smav	sbuf_printf(sb, "\t  <name>");
211260479Smav	g_conf_printf_escaped(sb, "%s", pp->name);
212260479Smav	sbuf_printf(sb, "</name>\n");
213105540Sphk	sbuf_printf(sb, "\t  <mediasize>%jd</mediasize>\n",
214105540Sphk	    (intmax_t)pp->mediasize);
215105542Sphk	sbuf_printf(sb, "\t  <sectorsize>%u</sectorsize>\n", pp->sectorsize);
216222603Sae	sbuf_printf(sb, "\t  <stripesize>%u</stripesize>\n", pp->stripesize);
217222603Sae	sbuf_printf(sb, "\t  <stripeoffset>%u</stripeoffset>\n", pp->stripeoffset);
218281301Smav	if (pp->flags & G_PF_WITHER)
219281301Smav		sbuf_printf(sb, "\t  <wither/>\n");
220281301Smav	else if (pp->geom->flags & G_GEOM_WITHER)
221117342Sphk		;
222117342Sphk	else if (pp->geom->dumpconf != NULL) {
22392108Sphk		sbuf_printf(sb, "\t  <config>\n");
22492108Sphk		pp->geom->dumpconf(sb, "\t    ", pp->geom, NULL, pp);
22592108Sphk		sbuf_printf(sb, "\t  </config>\n");
22692108Sphk	}
22792108Sphk	sbuf_printf(sb, "\t</provider>\n");
22892108Sphk}
22992108Sphk
23092108Sphk
23192108Sphkstatic void
23292108Sphkg_conf_geom(struct sbuf *sb, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp)
23392108Sphk{
23492108Sphk	struct g_consumer *cp2;
23592108Sphk	struct g_provider *pp2;
23692108Sphk
23795405Sphk	sbuf_printf(sb, "    <geom id=\"%p\">\n", gp);
23895405Sphk	sbuf_printf(sb, "      <class ref=\"%p\"/>\n", gp->class);
239260479Smav	sbuf_printf(sb, "      <name>");
240260479Smav	g_conf_printf_escaped(sb, "%s", gp->name);
241260479Smav	sbuf_printf(sb, "</name>\n");
24292108Sphk	sbuf_printf(sb, "      <rank>%d</rank>\n", gp->rank);
243117342Sphk	if (gp->flags & G_GEOM_WITHER)
244117342Sphk		sbuf_printf(sb, "      <wither/>\n");
245117342Sphk	else if (gp->dumpconf != NULL) {
24692108Sphk		sbuf_printf(sb, "      <config>\n");
24792108Sphk		gp->dumpconf(sb, "\t", gp, NULL, NULL);
24892108Sphk		sbuf_printf(sb, "      </config>\n");
24992108Sphk	}
25092108Sphk	LIST_FOREACH(cp2, &gp->consumer, consumer) {
25192108Sphk		if (cp != NULL && cp != cp2)
25292108Sphk			continue;
25392108Sphk		g_conf_consumer(sb, cp2);
25492108Sphk	}
25592108Sphk
25692108Sphk	LIST_FOREACH(pp2, &gp->provider, provider) {
25792108Sphk		if (pp != NULL && pp != pp2)
25892108Sphk			continue;
25992108Sphk		g_conf_provider(sb, pp2);
26092108Sphk	}
26192108Sphk	sbuf_printf(sb, "    </geom>\n");
26292108Sphk}
26392108Sphk
26492108Sphkstatic void
26593248Sphkg_conf_class(struct sbuf *sb, struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp)
26692108Sphk{
26792108Sphk	struct g_geom *gp2;
26892108Sphk
26995405Sphk	sbuf_printf(sb, "  <class id=\"%p\">\n", mp);
270260479Smav	sbuf_printf(sb, "    <name>");
271260479Smav	g_conf_printf_escaped(sb, "%s", mp->name);
272260479Smav	sbuf_printf(sb, "</name>\n");
27392108Sphk	LIST_FOREACH(gp2, &mp->geom, geom) {
27492108Sphk		if (gp != NULL && gp != gp2)
27592108Sphk			continue;
27692108Sphk		g_conf_geom(sb, gp2, pp, cp);
27792108Sphk	}
27893248Sphk	sbuf_printf(sb, "  </class>\n");
27992108Sphk}
28092108Sphk
281104452Sphkvoid
282104452Sphkg_conf_specific(struct sbuf *sb, struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp)
28392108Sphk{
28493248Sphk	struct g_class *mp2;
28592108Sphk
286104452Sphk	g_topology_assert();
28792108Sphk	sbuf_printf(sb, "<mesh>\n");
28893774Sphk	LIST_FOREACH(mp2, &g_classes, class) {
28992108Sphk		if (mp != NULL && mp != mp2)
29092108Sphk			continue;
29193248Sphk		g_conf_class(sb, mp2, gp, pp, cp);
29292108Sphk	}
29392108Sphk	sbuf_printf(sb, "</mesh>\n");
29492108Sphk	sbuf_finish(sb);
29592108Sphk}
29692108Sphk
297104452Sphkvoid
298112989Sphkg_confxml(void *p, int flag)
29992108Sphk{
30092108Sphk
301112989Sphk	KASSERT(flag != EV_CANCEL, ("g_confxml was cancelled"));
302105091Sphk	g_topology_assert();
303104452Sphk	g_conf_specific(p, NULL, NULL, NULL, NULL);
30492108Sphk}
30592108Sphk
30692108Sphkvoid
307107953Sphkg_trace(int level, const char *fmt, ...)
30892108Sphk{
30992108Sphk	va_list ap;
31092108Sphk
31192108Sphk	if (!(g_debugflags & level))
31292108Sphk		return;
31392108Sphk	va_start(ap, fmt);
314104195Sphk	vprintf(fmt, ap);
315115949Sphk	va_end(ap);
316104195Sphk	printf("\n");
31792108Sphk}
318