Index: geom_dev.c =================================================================== --- geom_dev.c (revision 272680) +++ geom_dev.c (working copy) @@ -82,6 +82,8 @@ static struct cdevsw g_dev_cdevsw = { .d_flags = D_DISK | D_TRACKCLOSE, }; +static g_init_t g_dev_init; +static g_fini_t g_dev_fini; static g_taste_t g_dev_taste; static g_orphan_t g_dev_orphan; static g_attrchanged_t g_dev_attrchanged; @@ -89,6 +91,8 @@ static g_attrchanged_t g_dev_attrchanged; static struct g_class g_dev_class = { .name = "DEV", .version = G_VERSION, + .init = g_dev_init, + .fini = g_dev_fini, .taste = g_dev_taste, .orphan = g_dev_orphan, .attrchanged = g_dev_attrchanged @@ -107,7 +111,59 @@ SYSCTL_QUAD(_kern_geom_dev, OID_AUTO, delete_max_s "delete request sent to the provider. Larger requests are chunked " "so they can be interrupted. (0 = disable chunking)"); +static char *dumpdev = NULL; static void +g_dev_init(struct g_class *mp) +{ + + dumpdev = getenv("dumpdev"); +} + +static void +g_dev_fini(struct g_class *mp) +{ + + freeenv(dumpdev); +} + +static int +g_dev_setdumpdev(struct cdev *dev) +{ + struct g_kerneldump kd; + struct g_consumer *cp; + int error, len; + + if (dev == NULL) + return (set_dumper(NULL)); + + cp = dev->si_drv2; + len = sizeof(kd); + kd.offset = 0; + kd.length = OFF_MAX; + error = g_io_getattr("GEOM::kerneldump", cp, &len, &kd); + if (error == 0) { + error = set_dumper(&kd.di); + if (error == 0) + dev->si_flags |= SI_DUMPDEV; + } + return (error); +} + +static void +init_dumpdev(struct cdev *dev) +{ + + if (dumpdev == NULL) + return; + if (strcmp(devtoname(dev), dumpdev) != 0) + return; + if (g_dev_setdumpdev(dev) == 0) { + freeenv(dumpdev); + dumpdev = NULL; + } +} + +static void g_dev_destroy(void *arg, int flags __unused) { struct g_consumer *cp; @@ -261,11 +317,13 @@ g_dev_taste(struct g_class *mp, struct g_provider dev->si_flags |= SI_CANDELETE; dev->si_iosize_max = MAXPHYS; dev->si_drv2 = cp; + init_dumpdev(dev); if (adev != NULL) { if (pp->flags & G_PF_CANDELETE) adev->si_flags |= SI_CANDELETE; adev->si_iosize_max = MAXPHYS; adev->si_drv2 = cp; + init_dumpdev(adev); } g_dev_attrchanged(cp, "GEOM::physpath"); @@ -359,10 +417,8 @@ g_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t { struct g_consumer *cp; struct g_provider *pp; - struct g_kerneldump kd; off_t offset, length, chunk; int i, error; - u_int u; cp = dev->si_drv2; pp = cp->provider; @@ -397,21 +453,10 @@ g_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t error = g_io_getattr("GEOM::frontstuff", cp, &i, data); break; case DIOCSKERNELDUMP: - u = *((u_int *)data); - if (!u) { - set_dumper(NULL); - error = 0; - break; - } - kd.offset = 0; - kd.length = OFF_MAX; - i = sizeof kd; - error = g_io_getattr("GEOM::kerneldump", cp, &i, &kd); - if (!error) { - error = set_dumper(&kd.di); - if (!error) - dev->si_flags |= SI_DUMPDEV; - } + if (*(u_int *)data == 0) + error = g_dev_setdumpdev(NULL); + else + error = g_dev_setdumpdev(dev); break; case DIOCGFLUSH: error = g_io_flush(cp);