diff options
-rw-r--r-- | sbin/dumpon/dumpon.8 | 16 | ||||
-rw-r--r-- | sys/geom/geom_dev.c | 79 |
2 files changed, 75 insertions, 20 deletions
diff --git a/sbin/dumpon/dumpon.8 b/sbin/dumpon/dumpon.8 index 6be8090..c2601b2 100644 --- a/sbin/dumpon/dumpon.8 +++ b/sbin/dumpon/dumpon.8 @@ -28,7 +28,7 @@ .\" From: @(#)swapon.8 8.1 (Berkeley) 6/5/93 .\" $FreeBSD$ .\" -.Dd April 29, 2013 +.Dd October 8, 2014 .Dt DUMPON 8 .Os .Sh NAME @@ -124,9 +124,18 @@ performs a on .Pa /dev/null and thus instructs the kernel not to save crash dumps. +.Pp +Since +.Nm +cannot be used during kernel initialization, the +.Va dumpdev +variable of +.Xr loader 8 +must be used to enable dumps for system panics which occur +during kernel initialization. .Sh FILES -.Bl -tag -width "/dev/{ad,da}?s?b" -compact -.It Pa /dev/{ad,da}?s?b +.Bl -tag -width "/dev/{ada,da}?s?b" -compact +.It Pa /dev/{ada,da}?s?b standard swap areas .It Pa /etc/rc.conf boot-time system configuration @@ -136,6 +145,7 @@ boot-time system configuration .Xr rc.conf 5 , .Xr config 8 , .Xr init 8 , +.Xr loader 8 , .Xr rc 8 , .Xr savecore 8 , .Xr swapon 8 , diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c index 2c113e6..c051ea7 100644 --- a/sys/geom/geom_dev.c +++ b/sys/geom/geom_dev.c @@ -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,6 +111,58 @@ SYSCTL_QUAD(_kern_geom_dev, OID_AUTO, delete_max_sectors, CTLFLAG_RW, "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, 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, devtoname(dev)); + 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) { @@ -260,9 +316,11 @@ g_dev_taste(struct g_class *mp, struct g_provider *pp, int insist __unused) dev->si_iosize_max = MAXPHYS; dev->si_drv2 = cp; + init_dumpdev(dev); if (adev != NULL) { adev->si_iosize_max = MAXPHYS; adev->si_drv2 = cp; + init_dumpdev(adev); } g_dev_attrchanged(cp, "GEOM::physpath"); @@ -356,10 +414,8 @@ g_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread { 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; @@ -394,21 +450,10 @@ g_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread error = g_io_getattr("GEOM::frontstuff", cp, &i, data); break; case DIOCSKERNELDUMP: - u = *((u_int *)data); - if (!u) { - set_dumper(NULL, 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, devtoname(dev)); - 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); |