Properly isolate the locking domains of sysctl from the topology lock
for the sysctls which report the configuration. Sponsored by: DARPA & NAI Labs.
This commit is contained in:
parent
0cc3011d52
commit
2874f1cf36
@ -231,7 +231,9 @@ g_dev_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
|
||||
int i, error;
|
||||
u_int u;
|
||||
struct g_ioctl *gio;
|
||||
#if 0
|
||||
struct sbuf *usb, *sb;
|
||||
#endif
|
||||
|
||||
gp = dev->si_drv1;
|
||||
cp = dev->si_drv2;
|
||||
@ -272,6 +274,7 @@ g_dev_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
|
||||
if (!error)
|
||||
dev->si_flags |= SI_DUMPDEV;
|
||||
break;
|
||||
#if 0
|
||||
case GEOMGETCONF:
|
||||
/* we bogusly pass cp to avoid getting any consumers listed */
|
||||
sb = g_conf_specific(gp2->class, gp2, pp2, cp);
|
||||
@ -283,6 +286,7 @@ g_dev_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
|
||||
if (!error)
|
||||
usb->s_len = sbuf_len(sb);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
gio = g_malloc(sizeof *gio, M_WAITOK);
|
||||
gio->cmd = cmd;
|
||||
|
@ -99,20 +99,20 @@ g_confdot_class(struct sbuf *sb, struct g_class *mp)
|
||||
g_confdot_geom(sb, gp);
|
||||
}
|
||||
|
||||
struct sbuf *
|
||||
g_confdot(void)
|
||||
void
|
||||
g_confdot(void *p)
|
||||
{
|
||||
struct g_class *mp;
|
||||
struct sbuf *sb;
|
||||
|
||||
sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
|
||||
sbuf_clear(sb);
|
||||
sb = p;
|
||||
g_topology_assert();
|
||||
sbuf_printf(sb, "digraph geom {\n");
|
||||
LIST_FOREACH(mp, &g_classes, class)
|
||||
g_confdot_class(sb, mp);
|
||||
sbuf_printf(sb, "};\n");
|
||||
sbuf_finish(sb);
|
||||
return (sb);
|
||||
wakeup(p);
|
||||
}
|
||||
|
||||
|
||||
@ -196,14 +196,12 @@ g_conf_class(struct sbuf *sb, struct g_class *mp, struct g_geom *gp, struct g_pr
|
||||
sbuf_printf(sb, " </class>\n");
|
||||
}
|
||||
|
||||
struct sbuf *
|
||||
g_conf_specific(struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp)
|
||||
void
|
||||
g_conf_specific(struct sbuf *sb, struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp)
|
||||
{
|
||||
struct g_class *mp2;
|
||||
struct sbuf *sb;
|
||||
|
||||
sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
|
||||
sbuf_clear(sb);
|
||||
g_topology_assert();
|
||||
sbuf_printf(sb, "<mesh>\n");
|
||||
#ifndef _KERNEL
|
||||
sbuf_printf(sb, " <FreeBSD>%cFreeBSD%c</FreeBSD>\n", '$', '$');
|
||||
@ -215,14 +213,14 @@ g_conf_specific(struct g_class *mp, struct g_geom *gp, struct g_provider *pp, st
|
||||
}
|
||||
sbuf_printf(sb, "</mesh>\n");
|
||||
sbuf_finish(sb);
|
||||
return (sb);
|
||||
}
|
||||
|
||||
struct sbuf *
|
||||
g_conf()
|
||||
void
|
||||
g_confxml(void *p)
|
||||
{
|
||||
|
||||
return (g_conf_specific(NULL, NULL, NULL, NULL));
|
||||
g_conf_specific(p, NULL, NULL, NULL, NULL);
|
||||
wakeup(p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -70,9 +70,9 @@ struct g_event {
|
||||
};
|
||||
|
||||
/* geom_dump.c */
|
||||
struct sbuf * g_conf(void);
|
||||
struct sbuf * g_conf_specific(struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp);
|
||||
struct sbuf * g_confdot(void);
|
||||
void g_confxml(void *);
|
||||
void g_conf_specific(struct sbuf *sb, struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp);
|
||||
void g_confdot(void *);
|
||||
|
||||
|
||||
/* geom_event.c */
|
||||
|
@ -162,39 +162,47 @@ g_init(void)
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_kern_geom_dotconf(SYSCTL_HANDLER_ARGS)
|
||||
sysctl_kern_geom_confdot(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int i, error;
|
||||
int error;
|
||||
struct sbuf *sb;
|
||||
|
||||
i = 0;
|
||||
sb = g_confdot();
|
||||
error = sysctl_handle_opaque(oidp, sbuf_data(sb), sbuf_len(sb), req);
|
||||
sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
|
||||
sbuf_clear(sb);
|
||||
g_call_me(g_confdot, sb);
|
||||
do {
|
||||
tsleep(sb, PZERO, "g_dot", hz);
|
||||
} while(!sbuf_done(sb));
|
||||
error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb));
|
||||
sbuf_delete(sb);
|
||||
return (error);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sysctl_kern_geom_xmlconf(SYSCTL_HANDLER_ARGS)
|
||||
sysctl_kern_geom_confxml(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int i, error;
|
||||
int error;
|
||||
struct sbuf *sb;
|
||||
|
||||
i = 0;
|
||||
sb = g_conf();
|
||||
error = sysctl_handle_opaque(oidp, sbuf_data(sb), sbuf_len(sb), req);
|
||||
sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
|
||||
sbuf_clear(sb);
|
||||
g_call_me(g_confxml, sb);
|
||||
do {
|
||||
tsleep(sb, PZERO, "g_xml", hz);
|
||||
} while(!sbuf_done(sb));
|
||||
error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb));
|
||||
sbuf_delete(sb);
|
||||
return (error);
|
||||
return error;
|
||||
}
|
||||
|
||||
SYSCTL_NODE(_kern, OID_AUTO, geom, CTLFLAG_RW, 0, "GEOMetry management");
|
||||
|
||||
SYSCTL_PROC(_kern_geom, OID_AUTO, xmlconf, CTLTYPE_STRING|CTLFLAG_RD,
|
||||
0, 0, sysctl_kern_geom_xmlconf, "A",
|
||||
SYSCTL_PROC(_kern_geom, OID_AUTO, confxml, CTLTYPE_STRING|CTLFLAG_RD,
|
||||
0, 0, sysctl_kern_geom_confxml, "A",
|
||||
"Dump the GEOM config");
|
||||
|
||||
SYSCTL_PROC(_kern_geom, OID_AUTO, dotconf, CTLTYPE_STRING|CTLFLAG_RD,
|
||||
0, 0, sysctl_kern_geom_dotconf, "A",
|
||||
SYSCTL_PROC(_kern_geom, OID_AUTO, confdot, CTLTYPE_STRING|CTLFLAG_RD,
|
||||
0, 0, sysctl_kern_geom_confdot, "A",
|
||||
"Dump the GEOM config");
|
||||
|
||||
SYSCTL_INT(_kern_geom, OID_AUTO, debugflags, CTLTYPE_INT|CTLFLAG_RW,
|
||||
|
Loading…
x
Reference in New Issue
Block a user