mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-17 10:26:15 +00:00
Add an ability to set dumpdev via loader(8) tunable.
MFC after: 3 weeks
This commit is contained in:
parent
8e72737119
commit
0478dc0c16
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=272746
@ -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)
|
||||
{
|
||||
@ -261,10 +317,12 @@ 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;
|
||||
adev->si_flags |= SI_UNMAPPED;
|
||||
init_dumpdev(adev);
|
||||
}
|
||||
|
||||
g_dev_attrchanged(cp, "GEOM::physpath");
|
||||
@ -358,7 +416,6 @@ 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;
|
||||
|
||||
@ -395,19 +452,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:
|
||||
if (*(u_int *)data == 0) {
|
||||
error = set_dumper(NULL, NULL);
|
||||
break;
|
||||
}
|
||||
kd.offset = 0;
|
||||
kd.length = OFF_MAX;
|
||||
i = sizeof kd;
|
||||
error = g_io_getattr("GEOM::kerneldump", cp, &i, &kd);
|
||||
if (error == 0) {
|
||||
error = set_dumper(&kd.di, devtoname(dev));
|
||||
if (error == 0)
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user