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