The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/geom/nop/g_nop.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2004-2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD: releng/10.2/sys/geom/nop/g_nop.c 260385 2014-01-07 01:32:23Z scottl $");
   29 
   30 #include <sys/param.h>
   31 #include <sys/systm.h>
   32 #include <sys/kernel.h>
   33 #include <sys/module.h>
   34 #include <sys/lock.h>
   35 #include <sys/mutex.h>
   36 #include <sys/bio.h>
   37 #include <sys/sbuf.h>
   38 #include <sys/sysctl.h>
   39 #include <sys/malloc.h>
   40 #include <geom/geom.h>
   41 #include <geom/nop/g_nop.h>
   42 
   43 
   44 SYSCTL_DECL(_kern_geom);
   45 static SYSCTL_NODE(_kern_geom, OID_AUTO, nop, CTLFLAG_RW, 0, "GEOM_NOP stuff");
   46 static u_int g_nop_debug = 0;
   47 SYSCTL_UINT(_kern_geom_nop, OID_AUTO, debug, CTLFLAG_RW, &g_nop_debug, 0,
   48     "Debug level");
   49 
   50 static int g_nop_destroy(struct g_geom *gp, boolean_t force);
   51 static int g_nop_destroy_geom(struct gctl_req *req, struct g_class *mp,
   52     struct g_geom *gp);
   53 static void g_nop_config(struct gctl_req *req, struct g_class *mp,
   54     const char *verb);
   55 static void g_nop_dumpconf(struct sbuf *sb, const char *indent,
   56     struct g_geom *gp, struct g_consumer *cp, struct g_provider *pp);
   57 
   58 struct g_class g_nop_class = {
   59         .name = G_NOP_CLASS_NAME,
   60         .version = G_VERSION,
   61         .ctlreq = g_nop_config,
   62         .destroy_geom = g_nop_destroy_geom
   63 };
   64 
   65 
   66 static void
   67 g_nop_orphan(struct g_consumer *cp)
   68 {
   69 
   70         g_topology_assert();
   71         g_nop_destroy(cp->geom, 1);
   72 }
   73 
   74 static void
   75 g_nop_resize(struct g_consumer *cp)
   76 {
   77         struct g_nop_softc *sc;
   78         struct g_geom *gp;
   79         struct g_provider *pp;
   80         off_t size;
   81 
   82         g_topology_assert();
   83 
   84         gp = cp->geom;
   85         sc = gp->softc;
   86 
   87         if (sc->sc_explicitsize != 0)
   88                 return;
   89         if (cp->provider->mediasize < sc->sc_offset) {
   90                 g_nop_destroy(gp, 1);
   91                 return;
   92         }
   93         size = cp->provider->mediasize - sc->sc_offset;
   94         LIST_FOREACH(pp, &gp->provider, provider)
   95                 g_resize_provider(pp, size);
   96 }
   97 
   98 static void
   99 g_nop_start(struct bio *bp)
  100 {
  101         struct g_nop_softc *sc;
  102         struct g_geom *gp;
  103         struct g_provider *pp;
  104         struct bio *cbp;
  105         u_int failprob = 0;
  106 
  107         gp = bp->bio_to->geom;
  108         sc = gp->softc;
  109         G_NOP_LOGREQ(bp, "Request received.");
  110         mtx_lock(&sc->sc_lock);
  111         switch (bp->bio_cmd) {
  112         case BIO_READ:
  113                 sc->sc_reads++;
  114                 sc->sc_readbytes += bp->bio_length;
  115                 failprob = sc->sc_rfailprob;
  116                 break;
  117         case BIO_WRITE:
  118                 sc->sc_writes++;
  119                 sc->sc_wrotebytes += bp->bio_length;
  120                 failprob = sc->sc_wfailprob;
  121                 break;
  122         }
  123         mtx_unlock(&sc->sc_lock);
  124         if (failprob > 0) {
  125                 u_int rval;
  126 
  127                 rval = arc4random() % 100;
  128                 if (rval < failprob) {
  129                         G_NOP_LOGREQLVL(1, bp, "Returning error=%d.", sc->sc_error);
  130                         g_io_deliver(bp, sc->sc_error);
  131                         return;
  132                 }
  133         }
  134         cbp = g_clone_bio(bp);
  135         if (cbp == NULL) {
  136                 g_io_deliver(bp, ENOMEM);
  137                 return;
  138         }
  139         cbp->bio_done = g_std_done;
  140         cbp->bio_offset = bp->bio_offset + sc->sc_offset;
  141         pp = LIST_FIRST(&gp->provider);
  142         KASSERT(pp != NULL, ("NULL pp"));
  143         cbp->bio_to = pp;
  144         G_NOP_LOGREQ(cbp, "Sending request.");
  145         g_io_request(cbp, LIST_FIRST(&gp->consumer));
  146 }
  147 
  148 static int
  149 g_nop_access(struct g_provider *pp, int dr, int dw, int de)
  150 {
  151         struct g_geom *gp;
  152         struct g_consumer *cp;
  153         int error;
  154 
  155         gp = pp->geom;
  156         cp = LIST_FIRST(&gp->consumer);
  157         error = g_access(cp, dr, dw, de);
  158 
  159         return (error);
  160 }
  161 
  162 static int
  163 g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp,
  164     int ioerror, u_int rfailprob, u_int wfailprob, off_t offset, off_t size,
  165     u_int secsize)
  166 {
  167         struct g_nop_softc *sc;
  168         struct g_geom *gp;
  169         struct g_provider *newpp;
  170         struct g_consumer *cp;
  171         char name[64];
  172         int error;
  173         off_t explicitsize;
  174 
  175         g_topology_assert();
  176 
  177         gp = NULL;
  178         newpp = NULL;
  179         cp = NULL;
  180 
  181         if ((offset % pp->sectorsize) != 0) {
  182                 gctl_error(req, "Invalid offset for provider %s.", pp->name);
  183                 return (EINVAL);
  184         }
  185         if ((size % pp->sectorsize) != 0) {
  186                 gctl_error(req, "Invalid size for provider %s.", pp->name);
  187                 return (EINVAL);
  188         }
  189         if (offset >= pp->mediasize) {
  190                 gctl_error(req, "Invalid offset for provider %s.", pp->name);
  191                 return (EINVAL);
  192         }
  193         explicitsize = size;
  194         if (size == 0)
  195                 size = pp->mediasize - offset;
  196         if (offset + size > pp->mediasize) {
  197                 gctl_error(req, "Invalid size for provider %s.", pp->name);
  198                 return (EINVAL);
  199         }
  200         if (secsize == 0)
  201                 secsize = pp->sectorsize;
  202         else if ((secsize % pp->sectorsize) != 0) {
  203                 gctl_error(req, "Invalid secsize for provider %s.", pp->name);
  204                 return (EINVAL);
  205         }
  206         if (secsize > MAXPHYS) {
  207                 gctl_error(req, "secsize is too big.");
  208                 return (EINVAL);
  209         }
  210         size -= size % secsize;
  211         snprintf(name, sizeof(name), "%s%s", pp->name, G_NOP_SUFFIX);
  212         LIST_FOREACH(gp, &mp->geom, geom) {
  213                 if (strcmp(gp->name, name) == 0) {
  214                         gctl_error(req, "Provider %s already exists.", name);
  215                         return (EEXIST);
  216                 }
  217         }
  218         gp = g_new_geomf(mp, "%s", name);
  219         sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO);
  220         sc->sc_offset = offset;
  221         sc->sc_explicitsize = explicitsize;
  222         sc->sc_error = ioerror;
  223         sc->sc_rfailprob = rfailprob;
  224         sc->sc_wfailprob = wfailprob;
  225         sc->sc_reads = 0;
  226         sc->sc_writes = 0;
  227         sc->sc_readbytes = 0;
  228         sc->sc_wrotebytes = 0;
  229         mtx_init(&sc->sc_lock, "gnop lock", NULL, MTX_DEF);
  230         gp->softc = sc;
  231         gp->start = g_nop_start;
  232         gp->orphan = g_nop_orphan;
  233         gp->resize = g_nop_resize;
  234         gp->access = g_nop_access;
  235         gp->dumpconf = g_nop_dumpconf;
  236 
  237         newpp = g_new_providerf(gp, "%s", gp->name);
  238         newpp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE;
  239         newpp->mediasize = size;
  240         newpp->sectorsize = secsize;
  241 
  242         cp = g_new_consumer(gp);
  243         cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE;
  244         error = g_attach(cp, pp);
  245         if (error != 0) {
  246                 gctl_error(req, "Cannot attach to provider %s.", pp->name);
  247                 goto fail;
  248         }
  249 
  250         newpp->flags |= pp->flags & G_PF_ACCEPT_UNMAPPED;
  251         g_error_provider(newpp, 0);
  252         G_NOP_DEBUG(0, "Device %s created.", gp->name);
  253         return (0);
  254 fail:
  255         if (cp->provider != NULL)
  256                 g_detach(cp);
  257         g_destroy_consumer(cp);
  258         g_destroy_provider(newpp);
  259         mtx_destroy(&sc->sc_lock);
  260         g_free(gp->softc);
  261         g_destroy_geom(gp);
  262         return (error);
  263 }
  264 
  265 static int
  266 g_nop_destroy(struct g_geom *gp, boolean_t force)
  267 {
  268         struct g_nop_softc *sc;
  269         struct g_provider *pp;
  270 
  271         g_topology_assert();
  272         sc = gp->softc;
  273         if (sc == NULL)
  274                 return (ENXIO);
  275         pp = LIST_FIRST(&gp->provider);
  276         if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) {
  277                 if (force) {
  278                         G_NOP_DEBUG(0, "Device %s is still open, so it "
  279                             "can't be definitely removed.", pp->name);
  280                 } else {
  281                         G_NOP_DEBUG(1, "Device %s is still open (r%dw%de%d).",
  282                             pp->name, pp->acr, pp->acw, pp->ace);
  283                         return (EBUSY);
  284                 }
  285         } else {
  286                 G_NOP_DEBUG(0, "Device %s removed.", gp->name);
  287         }
  288         gp->softc = NULL;
  289         mtx_destroy(&sc->sc_lock);
  290         g_free(sc);
  291         g_wither_geom(gp, ENXIO);
  292 
  293         return (0);
  294 }
  295 
  296 static int
  297 g_nop_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp)
  298 {
  299 
  300         return (g_nop_destroy(gp, 0));
  301 }
  302 
  303 static void
  304 g_nop_ctl_create(struct gctl_req *req, struct g_class *mp)
  305 {
  306         struct g_provider *pp;
  307         intmax_t *error, *rfailprob, *wfailprob, *offset, *secsize, *size;
  308         const char *name;
  309         char param[16];
  310         int i, *nargs;
  311 
  312         g_topology_assert();
  313 
  314         nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
  315         if (nargs == NULL) {
  316                 gctl_error(req, "No '%s' argument", "nargs");
  317                 return;
  318         }
  319         if (*nargs <= 0) {
  320                 gctl_error(req, "Missing device(s).");
  321                 return;
  322         }
  323         error = gctl_get_paraml(req, "error", sizeof(*error));
  324         if (error == NULL) {
  325                 gctl_error(req, "No '%s' argument", "error");
  326                 return;
  327         }
  328         rfailprob = gctl_get_paraml(req, "rfailprob", sizeof(*rfailprob));
  329         if (rfailprob == NULL) {
  330                 gctl_error(req, "No '%s' argument", "rfailprob");
  331                 return;
  332         }
  333         if (*rfailprob < -1 || *rfailprob > 100) {
  334                 gctl_error(req, "Invalid '%s' argument", "rfailprob");
  335                 return;
  336         }
  337         wfailprob = gctl_get_paraml(req, "wfailprob", sizeof(*wfailprob));
  338         if (wfailprob == NULL) {
  339                 gctl_error(req, "No '%s' argument", "wfailprob");
  340                 return;
  341         }
  342         if (*wfailprob < -1 || *wfailprob > 100) {
  343                 gctl_error(req, "Invalid '%s' argument", "wfailprob");
  344                 return;
  345         }
  346         offset = gctl_get_paraml(req, "offset", sizeof(*offset));
  347         if (offset == NULL) {
  348                 gctl_error(req, "No '%s' argument", "offset");
  349                 return;
  350         }
  351         if (*offset < 0) {
  352                 gctl_error(req, "Invalid '%s' argument", "offset");
  353                 return;
  354         }
  355         size = gctl_get_paraml(req, "size", sizeof(*size));
  356         if (size == NULL) {
  357                 gctl_error(req, "No '%s' argument", "size");
  358                 return;
  359         }
  360         if (*size < 0) {
  361                 gctl_error(req, "Invalid '%s' argument", "size");
  362                 return;
  363         }
  364         secsize = gctl_get_paraml(req, "secsize", sizeof(*secsize));
  365         if (secsize == NULL) {
  366                 gctl_error(req, "No '%s' argument", "secsize");
  367                 return;
  368         }
  369         if (*secsize < 0) {
  370                 gctl_error(req, "Invalid '%s' argument", "secsize");
  371                 return;
  372         }
  373 
  374         for (i = 0; i < *nargs; i++) {
  375                 snprintf(param, sizeof(param), "arg%d", i);
  376                 name = gctl_get_asciiparam(req, param);
  377                 if (name == NULL) {
  378                         gctl_error(req, "No 'arg%d' argument", i);
  379                         return;
  380                 }
  381                 if (strncmp(name, "/dev/", strlen("/dev/")) == 0)
  382                         name += strlen("/dev/");
  383                 pp = g_provider_by_name(name);
  384                 if (pp == NULL) {
  385                         G_NOP_DEBUG(1, "Provider %s is invalid.", name);
  386                         gctl_error(req, "Provider %s is invalid.", name);
  387                         return;
  388                 }
  389                 if (g_nop_create(req, mp, pp,
  390                     *error == -1 ? EIO : (int)*error,
  391                     *rfailprob == -1 ? 0 : (u_int)*rfailprob,
  392                     *wfailprob == -1 ? 0 : (u_int)*wfailprob,
  393                     (off_t)*offset, (off_t)*size, (u_int)*secsize) != 0) {
  394                         return;
  395                 }
  396         }
  397 }
  398 
  399 static void
  400 g_nop_ctl_configure(struct gctl_req *req, struct g_class *mp)
  401 {
  402         struct g_nop_softc *sc;
  403         struct g_provider *pp;
  404         intmax_t *error, *rfailprob, *wfailprob;
  405         const char *name;
  406         char param[16];
  407         int i, *nargs;
  408 
  409         g_topology_assert();
  410 
  411         nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
  412         if (nargs == NULL) {
  413                 gctl_error(req, "No '%s' argument", "nargs");
  414                 return;
  415         }
  416         if (*nargs <= 0) {
  417                 gctl_error(req, "Missing device(s).");
  418                 return;
  419         }
  420         error = gctl_get_paraml(req, "error", sizeof(*error));
  421         if (error == NULL) {
  422                 gctl_error(req, "No '%s' argument", "error");
  423                 return;
  424         }
  425         rfailprob = gctl_get_paraml(req, "rfailprob", sizeof(*rfailprob));
  426         if (rfailprob == NULL) {
  427                 gctl_error(req, "No '%s' argument", "rfailprob");
  428                 return;
  429         }
  430         if (*rfailprob < -1 || *rfailprob > 100) {
  431                 gctl_error(req, "Invalid '%s' argument", "rfailprob");
  432                 return;
  433         }
  434         wfailprob = gctl_get_paraml(req, "wfailprob", sizeof(*wfailprob));
  435         if (wfailprob == NULL) {
  436                 gctl_error(req, "No '%s' argument", "wfailprob");
  437                 return;
  438         }
  439         if (*wfailprob < -1 || *wfailprob > 100) {
  440                 gctl_error(req, "Invalid '%s' argument", "wfailprob");
  441                 return;
  442         }
  443 
  444         for (i = 0; i < *nargs; i++) {
  445                 snprintf(param, sizeof(param), "arg%d", i);
  446                 name = gctl_get_asciiparam(req, param);
  447                 if (name == NULL) {
  448                         gctl_error(req, "No 'arg%d' argument", i);
  449                         return;
  450                 }
  451                 if (strncmp(name, "/dev/", strlen("/dev/")) == 0)
  452                         name += strlen("/dev/");
  453                 pp = g_provider_by_name(name);
  454                 if (pp == NULL || pp->geom->class != mp) {
  455                         G_NOP_DEBUG(1, "Provider %s is invalid.", name);
  456                         gctl_error(req, "Provider %s is invalid.", name);
  457                         return;
  458                 }
  459                 sc = pp->geom->softc;
  460                 if (*error != -1)
  461                         sc->sc_error = (int)*error;
  462                 if (*rfailprob != -1)
  463                         sc->sc_rfailprob = (u_int)*rfailprob;
  464                 if (*wfailprob != -1)
  465                         sc->sc_wfailprob = (u_int)*wfailprob;
  466         }
  467 }
  468 
  469 static struct g_geom *
  470 g_nop_find_geom(struct g_class *mp, const char *name)
  471 {
  472         struct g_geom *gp;
  473 
  474         LIST_FOREACH(gp, &mp->geom, geom) {
  475                 if (strcmp(gp->name, name) == 0)
  476                         return (gp);
  477         }
  478         return (NULL);
  479 }
  480 
  481 static void
  482 g_nop_ctl_destroy(struct gctl_req *req, struct g_class *mp)
  483 {
  484         int *nargs, *force, error, i;
  485         struct g_geom *gp;
  486         const char *name;
  487         char param[16];
  488 
  489         g_topology_assert();
  490 
  491         nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
  492         if (nargs == NULL) {
  493                 gctl_error(req, "No '%s' argument", "nargs");
  494                 return;
  495         }
  496         if (*nargs <= 0) {
  497                 gctl_error(req, "Missing device(s).");
  498                 return;
  499         }
  500         force = gctl_get_paraml(req, "force", sizeof(*force));
  501         if (force == NULL) {
  502                 gctl_error(req, "No 'force' argument");
  503                 return;
  504         }
  505 
  506         for (i = 0; i < *nargs; i++) {
  507                 snprintf(param, sizeof(param), "arg%d", i);
  508                 name = gctl_get_asciiparam(req, param);
  509                 if (name == NULL) {
  510                         gctl_error(req, "No 'arg%d' argument", i);
  511                         return;
  512                 }
  513                 if (strncmp(name, "/dev/", strlen("/dev/")) == 0)
  514                         name += strlen("/dev/");
  515                 gp = g_nop_find_geom(mp, name);
  516                 if (gp == NULL) {
  517                         G_NOP_DEBUG(1, "Device %s is invalid.", name);
  518                         gctl_error(req, "Device %s is invalid.", name);
  519                         return;
  520                 }
  521                 error = g_nop_destroy(gp, *force);
  522                 if (error != 0) {
  523                         gctl_error(req, "Cannot destroy device %s (error=%d).",
  524                             gp->name, error);
  525                         return;
  526                 }
  527         }
  528 }
  529 
  530 static void
  531 g_nop_ctl_reset(struct gctl_req *req, struct g_class *mp)
  532 {
  533         struct g_nop_softc *sc;
  534         struct g_provider *pp;
  535         const char *name;
  536         char param[16];
  537         int i, *nargs;
  538 
  539         g_topology_assert();
  540 
  541         nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
  542         if (nargs == NULL) {
  543                 gctl_error(req, "No '%s' argument", "nargs");
  544                 return;
  545         }
  546         if (*nargs <= 0) {
  547                 gctl_error(req, "Missing device(s).");
  548                 return;
  549         }
  550 
  551         for (i = 0; i < *nargs; i++) {
  552                 snprintf(param, sizeof(param), "arg%d", i);
  553                 name = gctl_get_asciiparam(req, param);
  554                 if (name == NULL) {
  555                         gctl_error(req, "No 'arg%d' argument", i);
  556                         return;
  557                 }
  558                 if (strncmp(name, "/dev/", strlen("/dev/")) == 0)
  559                         name += strlen("/dev/");
  560                 pp = g_provider_by_name(name);
  561                 if (pp == NULL || pp->geom->class != mp) {
  562                         G_NOP_DEBUG(1, "Provider %s is invalid.", name);
  563                         gctl_error(req, "Provider %s is invalid.", name);
  564                         return;
  565                 }
  566                 sc = pp->geom->softc;
  567                 sc->sc_reads = 0;
  568                 sc->sc_writes = 0;
  569                 sc->sc_readbytes = 0;
  570                 sc->sc_wrotebytes = 0;
  571         }
  572 }
  573 
  574 static void
  575 g_nop_config(struct gctl_req *req, struct g_class *mp, const char *verb)
  576 {
  577         uint32_t *version;
  578 
  579         g_topology_assert();
  580 
  581         version = gctl_get_paraml(req, "version", sizeof(*version));
  582         if (version == NULL) {
  583                 gctl_error(req, "No '%s' argument.", "version");
  584                 return;
  585         }
  586         if (*version != G_NOP_VERSION) {
  587                 gctl_error(req, "Userland and kernel parts are out of sync.");
  588                 return;
  589         }
  590 
  591         if (strcmp(verb, "create") == 0) {
  592                 g_nop_ctl_create(req, mp);
  593                 return;
  594         } else if (strcmp(verb, "configure") == 0) {
  595                 g_nop_ctl_configure(req, mp);
  596                 return;
  597         } else if (strcmp(verb, "destroy") == 0) {
  598                 g_nop_ctl_destroy(req, mp);
  599                 return;
  600         } else if (strcmp(verb, "reset") == 0) {
  601                 g_nop_ctl_reset(req, mp);
  602                 return;
  603         }
  604 
  605         gctl_error(req, "Unknown verb.");
  606 }
  607 
  608 static void
  609 g_nop_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
  610     struct g_consumer *cp, struct g_provider *pp)
  611 {
  612         struct g_nop_softc *sc;
  613 
  614         if (pp != NULL || cp != NULL)
  615                 return;
  616         sc = gp->softc;
  617         sbuf_printf(sb, "%s<Offset>%jd</Offset>\n", indent,
  618             (intmax_t)sc->sc_offset);
  619         sbuf_printf(sb, "%s<ReadFailProb>%u</ReadFailProb>\n", indent,
  620             sc->sc_rfailprob);
  621         sbuf_printf(sb, "%s<WriteFailProb>%u</WriteFailProb>\n", indent,
  622             sc->sc_wfailprob);
  623         sbuf_printf(sb, "%s<Error>%d</Error>\n", indent, sc->sc_error);
  624         sbuf_printf(sb, "%s<Reads>%ju</Reads>\n", indent, sc->sc_reads);
  625         sbuf_printf(sb, "%s<Writes>%ju</Writes>\n", indent, sc->sc_writes);
  626         sbuf_printf(sb, "%s<ReadBytes>%ju</ReadBytes>\n", indent,
  627             sc->sc_readbytes);
  628         sbuf_printf(sb, "%s<WroteBytes>%ju</WroteBytes>\n", indent,
  629             sc->sc_wrotebytes);
  630 }
  631 
  632 DECLARE_GEOM_CLASS(g_nop_class, g_nop);

Cache object: 0ae375f0e71f47f91584b4a97306cce3


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.