Author: asomers
Date: Thu Jan 18 05:57:10 2018
New Revision: 328108
URL: https://svnweb.freebsd.org/changeset/base/328108

Log:
  gnop(8): add the ability to set a nop provider's physical path
  
  While I'm here, expand the existing tests a bit.
  
  MFC after:    3 weeks
  Differential Revision:        https://reviews.freebsd.org/D13579

Modified:
  head/sbin/geom/class/nop/geom_nop.c
  head/sbin/geom/class/nop/gnop.8
  head/sys/geom/nop/g_nop.c
  head/sys/geom/nop/g_nop.h
  head/tests/sys/geom/class/nop/nop_test.sh

Modified: head/sbin/geom/class/nop/geom_nop.c
==============================================================================
--- head/sbin/geom/class/nop/geom_nop.c Thu Jan 18 04:58:54 2018        
(r328107)
+++ head/sbin/geom/class/nop/geom_nop.c Thu Jan 18 05:57:10 2018        
(r328108)
@@ -51,10 +51,12 @@ struct g_command class_commands[] = {
                { 's', "size", "0", G_TYPE_NUMBER },
                { 'S', "secsize", "0", G_TYPE_NUMBER },
                { 'w', "wfailprob", "-1", G_TYPE_NUMBER },
+               { 'z', "physpath", G_NOP_PHYSPATH_PASSTHROUGH, G_TYPE_STRING },
                G_OPT_SENTINEL
            },
            "[-v] [-e error] [-o offset] [-p stripesize] [-P stripeoffset] "
-           "[-r rfailprob] [-s size] [-S secsize] [-w wfailprob] dev ..."
+           "[-r rfailprob] [-s size] [-S secsize] [-w wfailprob] "
+           "[-z physpath] dev ..."
        },
        { "configure", G_FLAG_VERBOSE, NULL,
            {

Modified: head/sbin/geom/class/nop/gnop.8
==============================================================================
--- head/sbin/geom/class/nop/gnop.8     Thu Jan 18 04:58:54 2018        
(r328107)
+++ head/sbin/geom/class/nop/gnop.8     Thu Jan 18 05:57:10 2018        
(r328108)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd October 10, 2015
+.Dd January 17, 2018
 .Dt GNOP 8
 .Os
 .Sh NAME
@@ -42,6 +42,7 @@
 .Op Fl s Ar size
 .Op Fl S Ar secsize
 .Op Fl w Ar wfailprob
+.Op Fl z Ar physpath
 .Ar dev ...
 .Nm
 .Cm configure
@@ -132,6 +133,8 @@ Sector size of the transparent provider.
 Specifies write failure probability in percent.
 .It Fl v
 Be more verbose.
+.It Fl z Ar physpath
+Physical path of the transparent provider.
 .El
 .Sh SYSCTL VARIABLES
 The following

Modified: head/sys/geom/nop/g_nop.c
==============================================================================
--- head/sys/geom/nop/g_nop.c   Thu Jan 18 04:58:54 2018        (r328107)
+++ head/sys/geom/nop/g_nop.c   Thu Jan 18 05:57:10 2018        (r328108)
@@ -126,6 +126,11 @@ g_nop_start(struct bio *bp)
                break;
        case BIO_GETATTR:
                sc->sc_getattrs++;
+               if (sc->sc_physpath && 
+                   g_handleattr_str(bp, "GEOM::physpath", sc->sc_physpath)) {
+                       mtx_unlock(&sc->sc_lock);
+                       return;
+               }
                break;
        case BIO_FLUSH:
                sc->sc_flushes++;
@@ -182,7 +187,7 @@ g_nop_access(struct g_provider *pp, int dr, int dw, in
 static int
 g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp,
     int ioerror, u_int rfailprob, u_int wfailprob, off_t offset, off_t size,
-    u_int secsize, u_int stripesize, u_int stripeoffset)
+    u_int secsize, u_int stripesize, u_int stripeoffset, const char *physpath)
 {
        struct g_nop_softc *sc;
        struct g_geom *gp;
@@ -253,6 +258,10 @@ g_nop_create(struct gctl_req *req, struct g_class *mp,
        sc->sc_explicitsize = explicitsize;
        sc->sc_stripesize = stripesize;
        sc->sc_stripeoffset = stripeoffset;
+       if (physpath && strcmp(physpath, G_NOP_PHYSPATH_PASSTHROUGH)) {
+               sc->sc_physpath = strndup(physpath, MAXPATHLEN, M_GEOM);
+       } else
+               sc->sc_physpath = NULL;
        sc->sc_error = ioerror;
        sc->sc_rfailprob = rfailprob;
        sc->sc_wfailprob = wfailprob;
@@ -299,6 +308,7 @@ fail:
        g_destroy_consumer(cp);
        g_destroy_provider(newpp);
        mtx_destroy(&sc->sc_lock);
+       free(sc->sc_physpath, M_GEOM);
        g_free(gp->softc);
        g_destroy_geom(gp);
        return (error);
@@ -314,6 +324,7 @@ g_nop_destroy(struct g_geom *gp, boolean_t force)
        sc = gp->softc;
        if (sc == NULL)
                return (ENXIO);
+       free(sc->sc_physpath, M_GEOM);
        pp = LIST_FIRST(&gp->provider);
        if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) {
                if (force) {
@@ -348,7 +359,7 @@ g_nop_ctl_create(struct gctl_req *req, struct g_class 
        struct g_provider *pp;
        intmax_t *error, *rfailprob, *wfailprob, *offset, *secsize, *size,
            *stripesize, *stripeoffset;
-       const char *name;
+       const char *name, *physpath;
        char param[16];
        int i, *nargs;
 
@@ -431,6 +442,7 @@ g_nop_ctl_create(struct gctl_req *req, struct g_class 
                gctl_error(req, "Invalid '%s' argument", "stripeoffset");
                return;
        }
+       physpath = gctl_get_asciiparam(req, "physpath");
 
        for (i = 0; i < *nargs; i++) {
                snprintf(param, sizeof(param), "arg%d", i);
@@ -452,7 +464,8 @@ g_nop_ctl_create(struct gctl_req *req, struct g_class 
                    *rfailprob == -1 ? 0 : (u_int)*rfailprob,
                    *wfailprob == -1 ? 0 : (u_int)*wfailprob,
                    (off_t)*offset, (off_t)*size, (u_int)*secsize,
-                   (u_int)*stripesize, (u_int)*stripeoffset) != 0) {
+                   (u_int)*stripesize, (u_int)*stripeoffset,
+                   physpath) != 0) {
                        return;
                }
        }

Modified: head/sys/geom/nop/g_nop.h
==============================================================================
--- head/sys/geom/nop/g_nop.h   Thu Jan 18 04:58:54 2018        (r328107)
+++ head/sys/geom/nop/g_nop.h   Thu Jan 18 05:57:10 2018        (r328108)
@@ -34,6 +34,11 @@
 #define        G_NOP_CLASS_NAME        "NOP"
 #define        G_NOP_VERSION           4
 #define        G_NOP_SUFFIX            ".nop"
+/*
+ * Special flag to instruct gnop to passthrough the underlying provider's
+ * physical path
+ */
+#define G_NOP_PHYSPATH_PASSTHROUGH "\255"
 
 #ifdef _KERNEL
 #define        G_NOP_DEBUG(lvl, ...)   do {                                    
\
@@ -75,6 +80,7 @@ struct g_nop_softc {
        uintmax_t       sc_cmd2s;
        uintmax_t       sc_readbytes;
        uintmax_t       sc_wrotebytes;
+       char*           sc_physpath;
        struct mtx      sc_lock;
 };
 #endif /* _KERNEL */

Modified: head/tests/sys/geom/class/nop/nop_test.sh
==============================================================================
--- head/tests/sys/geom/class/nop/nop_test.sh   Thu Jan 18 04:58:54 2018        
(r328107)
+++ head/tests/sys/geom/class/nop/nop_test.sh   Thu Jan 18 05:57:10 2018        
(r328108)
@@ -27,14 +27,14 @@
 MD_DEVS="md.devs"
 PLAINFILES=plainfiles
 
-atf_test_case diskinfo cleanup
-diskinfo_head()
+atf_test_case preserve_props cleanup
+preserve_props_head()
 {
-       atf_set "descr" "gnop should preserve diskinfo's basic properties"
+       atf_set "descr" "gnop should preserve basic GEOM properties"
        atf_set "require.user" "root"
        atf_set "timeout" 15
 }
-diskinfo_body()
+preserve_props_body()
 {
        load_gnop
        us=$(alloc_md)
@@ -49,11 +49,54 @@ diskinfo_body()
        atf_check_equal "$md_mediasize" "$nop_mediasize"
        atf_check_equal "$md_stripesize" "$nop_stripesize"
 }
-diskinfo_cleanup()
+preserve_props_cleanup()
 {
        common_cleanup
 }
 
+atf_test_case preserve_disk_props cleanup
+preserve_disk_props_head()
+{
+       atf_set "descr" "gnop should preserve properties for disks"
+       atf_set "require.user" "root"
+       atf_set "require.config" "disks"
+       atf_set "timeout" 15
+}
+preserve_disk_props_body()
+{
+       load_gnop
+       disks=`atf_config_get disks`
+       disk=${disks%% *}
+       if [ -z "$disk" ]; then
+               atf_skip "Must define disks (see tests(7))"
+       fi
+       atf_check gnop create ${disk}
+
+       disk_ident=$(diskinfo -s ${disk})
+       disk_physpath=$(diskinfo -p ${disk})
+       disk_descr=$(diskinfo -v ${disk} | awk '/Disk descr/ {print $1}')
+       disk_trim=$(diskinfo -v ${disk} | awk '/TRIM.UNMAP/ {print $1}')
+       disk_rotrate=$(diskinfo -v ${disk} | awk '/Rotation rate/ {print $1}')
+       disk_zonemode=$(diskinfo -v ${disk} | awk '/Zone Mode/ {print $1}')
+       nop_ident=$(diskinfo -s ${disk}.nop)
+       nop_physpath=$(diskinfo -p ${disk}.nop)
+       nop_descr=$(diskinfo -v ${disk}.nop | awk '/Disk descr/ {print $1}')
+       nop_trim=$(diskinfo -v ${disk}.nop | awk '/TRIM.UNMAP/ {print $1}')
+       nop_rotrate=$(diskinfo -v ${disk}.nop | awk '/Rotation/ {print $1}')
+       nop_zonemode=$(diskinfo -v ${disk}.nop | awk '/Zone Mode/ {print $1}')
+       atf_check_equal "$disk_ident" "$nop_ident"
+       atf_check_equal "$disk_physpath" "$nop_physpath"
+       atf_check_equal "$disk_descr" "$nop_descr"
+       atf_check_equal "$disk_trim" "$nop_trim"
+       atf_check_equal "$disk_rotrate" "$nop_rotrate"
+       atf_check_equal "$disk_zonemode" "$nop_zonemode"
+}
+preserve_disk_props_cleanup()
+{
+       disk_cleanup
+       common_cleanup
+}
+
 atf_test_case io cleanup
 io_head()
 {
@@ -80,6 +123,54 @@ io_cleanup()
        common_cleanup
 }
 
+atf_test_case physpath cleanup
+physpath_head()
+{
+       atf_set "descr" "Test gnop's -z option"
+       atf_set "require.user" "root"
+       atf_set "timeout" 15
+}
+physpath_body()
+{
+       load_gnop
+       us=$(alloc_md)
+       physpath="some/physical/path"
+       atf_check gnop create -z $physpath /dev/${us}
+       gnop_physpath=$(diskinfo -p ${us}.nop)
+       atf_check_equal "$physpath" "$gnop_physpath"
+}
+physpath_cleanup()
+{
+       common_cleanup
+}
+
+atf_test_case physpath_blank cleanup
+physpath_blank_head()
+{
+       atf_set "descr" "gnop can set physical path to the empty string"
+       atf_set "require.user" "root"
+       atf_set "require.config" "disks"
+       atf_set "timeout" 15
+}
+physpath_blank_body()
+{
+       load_gnop
+       disks=`atf_config_get disks`
+       disk=${disks%% *}
+       if [ -z "$disk" ]; then
+               atf_skip "Must define disks (see tests(7))"
+       fi
+
+       atf_check gnop create -z "" ${disk}
+       gnop_physpath=$(diskinfo -p ${disk}.nop)
+       atf_check_equal "" "$gnop_physpath"
+}
+physpath_blank_cleanup()
+{
+       disk_cleanup
+       common_cleanup
+}
+
 atf_test_case size cleanup
 size_head()
 {
@@ -136,7 +227,10 @@ stripesize_cleanup()
 atf_init_test_cases()
 {
        atf_add_test_case io
-       atf_add_test_case diskinfo
+       atf_add_test_case physpath
+       atf_add_test_case physpath_blank
+       atf_add_test_case preserve_props
+       atf_add_test_case preserve_disk_props
        atf_add_test_case stripesize
        atf_add_test_case size
 }
@@ -167,6 +261,15 @@ common_cleanup()
                rm ${PLAINFILES}
        fi
        true
+}
+
+disk_cleanup()
+{
+       disks=`atf_config_get disks`
+       disk=${disks%% *}
+       if [ -n "$disk" ]; then
+               gnop destroy -f ${disk}.nop 2>/dev/null
+       fi
 }
 
 load_gnop()
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to