Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 Oct 2014 12:18:16 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r272746 - head/sys/geom
Message-ID:  <201410081218.s98CIGPk056631@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Wed Oct  8 12:18:16 2014
New Revision: 272746
URL: https://svnweb.freebsd.org/changeset/base/272746

Log:
  Add an ability to set dumpdev via loader(8) tunable.
  
  MFC after:	3 weeks

Modified:
  head/sys/geom/geom_dev.c

Modified: head/sys/geom/geom_dev.c
==============================================================================
--- head/sys/geom/geom_dev.c	Wed Oct  8 11:12:14 2014	(r272745)
+++ head/sys/geom/geom_dev.c	Wed Oct  8 12:18:16 2014	(r272746)
@@ -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, de
     "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
 
 	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
 {
 	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
 		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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201410081218.s98CIGPk056631>