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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to