189aaffecSPawel Jakub Dawidek /*- 23728855aSPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 33728855aSPedro F. Giffuni * 46a146a19SPawel Jakub Dawidek * Copyright (c) 2004-2006 Pawel Jakub Dawidek <pjd@FreeBSD.org> 589aaffecSPawel Jakub Dawidek * All rights reserved. 689aaffecSPawel Jakub Dawidek * 789aaffecSPawel Jakub Dawidek * Redistribution and use in source and binary forms, with or without 889aaffecSPawel Jakub Dawidek * modification, are permitted provided that the following conditions 989aaffecSPawel Jakub Dawidek * are met: 1089aaffecSPawel Jakub Dawidek * 1. Redistributions of source code must retain the above copyright 1189aaffecSPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer. 1289aaffecSPawel Jakub Dawidek * 2. Redistributions in binary form must reproduce the above copyright 1389aaffecSPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer in the 1489aaffecSPawel Jakub Dawidek * documentation and/or other materials provided with the distribution. 1589aaffecSPawel Jakub Dawidek * 1689aaffecSPawel Jakub Dawidek * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 1789aaffecSPawel Jakub Dawidek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1889aaffecSPawel Jakub Dawidek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1989aaffecSPawel Jakub Dawidek * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 2089aaffecSPawel Jakub Dawidek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2189aaffecSPawel Jakub Dawidek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2289aaffecSPawel Jakub Dawidek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2389aaffecSPawel Jakub Dawidek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2489aaffecSPawel Jakub Dawidek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2589aaffecSPawel Jakub Dawidek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2689aaffecSPawel Jakub Dawidek * SUCH DAMAGE. 2789aaffecSPawel Jakub Dawidek */ 2889aaffecSPawel Jakub Dawidek 2989aaffecSPawel Jakub Dawidek #include <sys/cdefs.h> 3089aaffecSPawel Jakub Dawidek __FBSDID("$FreeBSD$"); 3189aaffecSPawel Jakub Dawidek 3289aaffecSPawel Jakub Dawidek #include <sys/param.h> 3389aaffecSPawel Jakub Dawidek #include <sys/systm.h> 3489aaffecSPawel Jakub Dawidek #include <sys/kernel.h> 3589aaffecSPawel Jakub Dawidek #include <sys/module.h> 3689aaffecSPawel Jakub Dawidek #include <sys/lock.h> 3789aaffecSPawel Jakub Dawidek #include <sys/mutex.h> 3889aaffecSPawel Jakub Dawidek #include <sys/bio.h> 395d807a0eSAndrey V. Elsukov #include <sys/sbuf.h> 4089aaffecSPawel Jakub Dawidek #include <sys/sysctl.h> 4189aaffecSPawel Jakub Dawidek #include <sys/malloc.h> 4289aaffecSPawel Jakub Dawidek #include <geom/geom.h> 4389aaffecSPawel Jakub Dawidek #include <geom/nop/g_nop.h> 4489aaffecSPawel Jakub Dawidek 4589aaffecSPawel Jakub Dawidek 4689aaffecSPawel Jakub Dawidek SYSCTL_DECL(_kern_geom); 476472ac3dSEd Schouten static SYSCTL_NODE(_kern_geom, OID_AUTO, nop, CTLFLAG_RW, 0, "GEOM_NOP stuff"); 4889aaffecSPawel Jakub Dawidek static u_int g_nop_debug = 0; 4989aaffecSPawel Jakub Dawidek SYSCTL_UINT(_kern_geom_nop, OID_AUTO, debug, CTLFLAG_RW, &g_nop_debug, 0, 5089aaffecSPawel Jakub Dawidek "Debug level"); 5189aaffecSPawel Jakub Dawidek 5289aaffecSPawel Jakub Dawidek static int g_nop_destroy(struct g_geom *gp, boolean_t force); 5389aaffecSPawel Jakub Dawidek static int g_nop_destroy_geom(struct gctl_req *req, struct g_class *mp, 5489aaffecSPawel Jakub Dawidek struct g_geom *gp); 5589aaffecSPawel Jakub Dawidek static void g_nop_config(struct gctl_req *req, struct g_class *mp, 5689aaffecSPawel Jakub Dawidek const char *verb); 5789aaffecSPawel Jakub Dawidek static void g_nop_dumpconf(struct sbuf *sb, const char *indent, 5889aaffecSPawel Jakub Dawidek struct g_geom *gp, struct g_consumer *cp, struct g_provider *pp); 5989aaffecSPawel Jakub Dawidek 6089aaffecSPawel Jakub Dawidek struct g_class g_nop_class = { 6189aaffecSPawel Jakub Dawidek .name = G_NOP_CLASS_NAME, 625721c9c7SPoul-Henning Kamp .version = G_VERSION, 6389aaffecSPawel Jakub Dawidek .ctlreq = g_nop_config, 6489aaffecSPawel Jakub Dawidek .destroy_geom = g_nop_destroy_geom 6589aaffecSPawel Jakub Dawidek }; 6689aaffecSPawel Jakub Dawidek 6789aaffecSPawel Jakub Dawidek 6889aaffecSPawel Jakub Dawidek static void 6989aaffecSPawel Jakub Dawidek g_nop_orphan(struct g_consumer *cp) 7089aaffecSPawel Jakub Dawidek { 7189aaffecSPawel Jakub Dawidek 7289aaffecSPawel Jakub Dawidek g_topology_assert(); 7389aaffecSPawel Jakub Dawidek g_nop_destroy(cp->geom, 1); 7489aaffecSPawel Jakub Dawidek } 7589aaffecSPawel Jakub Dawidek 7689aaffecSPawel Jakub Dawidek static void 777027e4daSEdward Tomasz Napierala g_nop_resize(struct g_consumer *cp) 787027e4daSEdward Tomasz Napierala { 797027e4daSEdward Tomasz Napierala struct g_nop_softc *sc; 807027e4daSEdward Tomasz Napierala struct g_geom *gp; 817027e4daSEdward Tomasz Napierala struct g_provider *pp; 827027e4daSEdward Tomasz Napierala off_t size; 837027e4daSEdward Tomasz Napierala 847027e4daSEdward Tomasz Napierala g_topology_assert(); 857027e4daSEdward Tomasz Napierala 867027e4daSEdward Tomasz Napierala gp = cp->geom; 877027e4daSEdward Tomasz Napierala sc = gp->softc; 887027e4daSEdward Tomasz Napierala 897027e4daSEdward Tomasz Napierala if (sc->sc_explicitsize != 0) 907027e4daSEdward Tomasz Napierala return; 917027e4daSEdward Tomasz Napierala if (cp->provider->mediasize < sc->sc_offset) { 927027e4daSEdward Tomasz Napierala g_nop_destroy(gp, 1); 937027e4daSEdward Tomasz Napierala return; 947027e4daSEdward Tomasz Napierala } 957027e4daSEdward Tomasz Napierala size = cp->provider->mediasize - sc->sc_offset; 967027e4daSEdward Tomasz Napierala LIST_FOREACH(pp, &gp->provider, provider) 977027e4daSEdward Tomasz Napierala g_resize_provider(pp, size); 987027e4daSEdward Tomasz Napierala } 997027e4daSEdward Tomasz Napierala 1007027e4daSEdward Tomasz Napierala static void 10189aaffecSPawel Jakub Dawidek g_nop_start(struct bio *bp) 10289aaffecSPawel Jakub Dawidek { 103e370e911SPawel Jakub Dawidek struct g_nop_softc *sc; 10489aaffecSPawel Jakub Dawidek struct g_geom *gp; 10589aaffecSPawel Jakub Dawidek struct g_provider *pp; 10689aaffecSPawel Jakub Dawidek struct bio *cbp; 1076a146a19SPawel Jakub Dawidek u_int failprob = 0; 10889aaffecSPawel Jakub Dawidek 10989aaffecSPawel Jakub Dawidek gp = bp->bio_to->geom; 110e370e911SPawel Jakub Dawidek sc = gp->softc; 11189aaffecSPawel Jakub Dawidek G_NOP_LOGREQ(bp, "Request received."); 11240ea77a0SAlexander Motin mtx_lock(&sc->sc_lock); 113df3d5a19SPawel Jakub Dawidek switch (bp->bio_cmd) { 114df3d5a19SPawel Jakub Dawidek case BIO_READ: 115df3d5a19SPawel Jakub Dawidek sc->sc_reads++; 116df3d5a19SPawel Jakub Dawidek sc->sc_readbytes += bp->bio_length; 1176a146a19SPawel Jakub Dawidek failprob = sc->sc_rfailprob; 118df3d5a19SPawel Jakub Dawidek break; 119df3d5a19SPawel Jakub Dawidek case BIO_WRITE: 120df3d5a19SPawel Jakub Dawidek sc->sc_writes++; 121df3d5a19SPawel Jakub Dawidek sc->sc_wrotebytes += bp->bio_length; 1226a146a19SPawel Jakub Dawidek failprob = sc->sc_wfailprob; 123df3d5a19SPawel Jakub Dawidek break; 12445d7de1dSEdward Tomasz Napierala case BIO_DELETE: 12545d7de1dSEdward Tomasz Napierala sc->sc_deletes++; 12645d7de1dSEdward Tomasz Napierala break; 12745d7de1dSEdward Tomasz Napierala case BIO_GETATTR: 12845d7de1dSEdward Tomasz Napierala sc->sc_getattrs++; 1296f7f85e0SAlan Somers if (sc->sc_physpath && 1306f7f85e0SAlan Somers g_handleattr_str(bp, "GEOM::physpath", sc->sc_physpath)) { 1316f7f85e0SAlan Somers mtx_unlock(&sc->sc_lock); 1326f7f85e0SAlan Somers return; 1336f7f85e0SAlan Somers } 13445d7de1dSEdward Tomasz Napierala break; 13545d7de1dSEdward Tomasz Napierala case BIO_FLUSH: 13645d7de1dSEdward Tomasz Napierala sc->sc_flushes++; 13745d7de1dSEdward Tomasz Napierala break; 13845d7de1dSEdward Tomasz Napierala case BIO_CMD0: 13945d7de1dSEdward Tomasz Napierala sc->sc_cmd0s++; 14045d7de1dSEdward Tomasz Napierala break; 14145d7de1dSEdward Tomasz Napierala case BIO_CMD1: 14245d7de1dSEdward Tomasz Napierala sc->sc_cmd1s++; 14345d7de1dSEdward Tomasz Napierala break; 14445d7de1dSEdward Tomasz Napierala case BIO_CMD2: 14545d7de1dSEdward Tomasz Napierala sc->sc_cmd2s++; 14645d7de1dSEdward Tomasz Napierala break; 147df3d5a19SPawel Jakub Dawidek } 14840ea77a0SAlexander Motin mtx_unlock(&sc->sc_lock); 1496a146a19SPawel Jakub Dawidek if (failprob > 0) { 15089aaffecSPawel Jakub Dawidek u_int rval; 15189aaffecSPawel Jakub Dawidek 15289aaffecSPawel Jakub Dawidek rval = arc4random() % 100; 1536a146a19SPawel Jakub Dawidek if (rval < failprob) { 154d7078f3bSJohn-Mark Gurney G_NOP_LOGREQLVL(1, bp, "Returning error=%d.", sc->sc_error); 1556a146a19SPawel Jakub Dawidek g_io_deliver(bp, sc->sc_error); 15689aaffecSPawel Jakub Dawidek return; 15789aaffecSPawel Jakub Dawidek } 15889aaffecSPawel Jakub Dawidek } 15954df0743SPawel Jakub Dawidek cbp = g_clone_bio(bp); 16054df0743SPawel Jakub Dawidek if (cbp == NULL) { 16154df0743SPawel Jakub Dawidek g_io_deliver(bp, ENOMEM); 16254df0743SPawel Jakub Dawidek return; 16354df0743SPawel Jakub Dawidek } 16489aaffecSPawel Jakub Dawidek cbp->bio_done = g_std_done; 165e370e911SPawel Jakub Dawidek cbp->bio_offset = bp->bio_offset + sc->sc_offset; 166969ff54dSPawel Jakub Dawidek pp = LIST_FIRST(&gp->provider); 167969ff54dSPawel Jakub Dawidek KASSERT(pp != NULL, ("NULL pp")); 168969ff54dSPawel Jakub Dawidek cbp->bio_to = pp; 16989aaffecSPawel Jakub Dawidek G_NOP_LOGREQ(cbp, "Sending request."); 17089aaffecSPawel Jakub Dawidek g_io_request(cbp, LIST_FIRST(&gp->consumer)); 17189aaffecSPawel Jakub Dawidek } 17289aaffecSPawel Jakub Dawidek 17389aaffecSPawel Jakub Dawidek static int 17489aaffecSPawel Jakub Dawidek g_nop_access(struct g_provider *pp, int dr, int dw, int de) 17589aaffecSPawel Jakub Dawidek { 17689aaffecSPawel Jakub Dawidek struct g_geom *gp; 17789aaffecSPawel Jakub Dawidek struct g_consumer *cp; 17889aaffecSPawel Jakub Dawidek int error; 17989aaffecSPawel Jakub Dawidek 18089aaffecSPawel Jakub Dawidek gp = pp->geom; 18189aaffecSPawel Jakub Dawidek cp = LIST_FIRST(&gp->consumer); 18289aaffecSPawel Jakub Dawidek error = g_access(cp, dr, dw, de); 18389aaffecSPawel Jakub Dawidek 18489aaffecSPawel Jakub Dawidek return (error); 18589aaffecSPawel Jakub Dawidek } 18689aaffecSPawel Jakub Dawidek 18789aaffecSPawel Jakub Dawidek static int 18889aaffecSPawel Jakub Dawidek g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp, 1896a146a19SPawel Jakub Dawidek int ioerror, u_int rfailprob, u_int wfailprob, off_t offset, off_t size, 1906f7f85e0SAlan Somers u_int secsize, u_int stripesize, u_int stripeoffset, const char *physpath) 19189aaffecSPawel Jakub Dawidek { 192e370e911SPawel Jakub Dawidek struct g_nop_softc *sc; 19389aaffecSPawel Jakub Dawidek struct g_geom *gp; 19489aaffecSPawel Jakub Dawidek struct g_provider *newpp; 19589aaffecSPawel Jakub Dawidek struct g_consumer *cp; 1960e11f0a9SPawel Jakub Dawidek char name[64]; 19789aaffecSPawel Jakub Dawidek int error; 1987027e4daSEdward Tomasz Napierala off_t explicitsize; 19989aaffecSPawel Jakub Dawidek 20089aaffecSPawel Jakub Dawidek g_topology_assert(); 20189aaffecSPawel Jakub Dawidek 20289aaffecSPawel Jakub Dawidek gp = NULL; 20389aaffecSPawel Jakub Dawidek newpp = NULL; 20489aaffecSPawel Jakub Dawidek cp = NULL; 20589aaffecSPawel Jakub Dawidek 206e370e911SPawel Jakub Dawidek if ((offset % pp->sectorsize) != 0) { 207e370e911SPawel Jakub Dawidek gctl_error(req, "Invalid offset for provider %s.", pp->name); 208e370e911SPawel Jakub Dawidek return (EINVAL); 209e370e911SPawel Jakub Dawidek } 210e370e911SPawel Jakub Dawidek if ((size % pp->sectorsize) != 0) { 211e370e911SPawel Jakub Dawidek gctl_error(req, "Invalid size for provider %s.", pp->name); 212e370e911SPawel Jakub Dawidek return (EINVAL); 213e370e911SPawel Jakub Dawidek } 214e370e911SPawel Jakub Dawidek if (offset >= pp->mediasize) { 215e370e911SPawel Jakub Dawidek gctl_error(req, "Invalid offset for provider %s.", pp->name); 216e370e911SPawel Jakub Dawidek return (EINVAL); 217e370e911SPawel Jakub Dawidek } 2187027e4daSEdward Tomasz Napierala explicitsize = size; 219e370e911SPawel Jakub Dawidek if (size == 0) 220e370e911SPawel Jakub Dawidek size = pp->mediasize - offset; 221e370e911SPawel Jakub Dawidek if (offset + size > pp->mediasize) { 222e370e911SPawel Jakub Dawidek gctl_error(req, "Invalid size for provider %s.", pp->name); 223e370e911SPawel Jakub Dawidek return (EINVAL); 224e370e911SPawel Jakub Dawidek } 225d5c96d38SPawel Jakub Dawidek if (secsize == 0) 226d5c96d38SPawel Jakub Dawidek secsize = pp->sectorsize; 227d5c96d38SPawel Jakub Dawidek else if ((secsize % pp->sectorsize) != 0) { 228d5c96d38SPawel Jakub Dawidek gctl_error(req, "Invalid secsize for provider %s.", pp->name); 229d5c96d38SPawel Jakub Dawidek return (EINVAL); 230d5c96d38SPawel Jakub Dawidek } 231e76dc512SAndrey V. Elsukov if (secsize > MAXPHYS) { 232e76dc512SAndrey V. Elsukov gctl_error(req, "secsize is too big."); 233e76dc512SAndrey V. Elsukov return (EINVAL); 234e76dc512SAndrey V. Elsukov } 235f2b3e9e8SAndrey V. Elsukov size -= size % secsize; 236bb27d7edSEdward Tomasz Napierala if ((stripesize % pp->sectorsize) != 0) { 237bb27d7edSEdward Tomasz Napierala gctl_error(req, "Invalid stripesize for provider %s.", pp->name); 238bb27d7edSEdward Tomasz Napierala return (EINVAL); 239bb27d7edSEdward Tomasz Napierala } 240bb27d7edSEdward Tomasz Napierala if ((stripeoffset % pp->sectorsize) != 0) { 241bb27d7edSEdward Tomasz Napierala gctl_error(req, "Invalid stripeoffset for provider %s.", pp->name); 242bb27d7edSEdward Tomasz Napierala return (EINVAL); 243bb27d7edSEdward Tomasz Napierala } 244bb27d7edSEdward Tomasz Napierala if (stripesize != 0 && stripeoffset >= stripesize) { 245bb27d7edSEdward Tomasz Napierala gctl_error(req, "stripeoffset is too big."); 246bb27d7edSEdward Tomasz Napierala return (EINVAL); 247bb27d7edSEdward Tomasz Napierala } 2480e11f0a9SPawel Jakub Dawidek snprintf(name, sizeof(name), "%s%s", pp->name, G_NOP_SUFFIX); 2490e11f0a9SPawel Jakub Dawidek LIST_FOREACH(gp, &mp->geom, geom) { 2500e11f0a9SPawel Jakub Dawidek if (strcmp(gp->name, name) == 0) { 2510e11f0a9SPawel Jakub Dawidek gctl_error(req, "Provider %s already exists.", name); 2520e11f0a9SPawel Jakub Dawidek return (EEXIST); 2530e11f0a9SPawel Jakub Dawidek } 2540e11f0a9SPawel Jakub Dawidek } 25502c62349SJaakko Heinonen gp = g_new_geomf(mp, "%s", name); 256aa25ccfaSMateusz Guzik sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO); 257e370e911SPawel Jakub Dawidek sc->sc_offset = offset; 2587027e4daSEdward Tomasz Napierala sc->sc_explicitsize = explicitsize; 259bb27d7edSEdward Tomasz Napierala sc->sc_stripesize = stripesize; 260bb27d7edSEdward Tomasz Napierala sc->sc_stripeoffset = stripeoffset; 2616f7f85e0SAlan Somers if (physpath && strcmp(physpath, G_NOP_PHYSPATH_PASSTHROUGH)) { 2626f7f85e0SAlan Somers sc->sc_physpath = strndup(physpath, MAXPATHLEN, M_GEOM); 2636f7f85e0SAlan Somers } else 2646f7f85e0SAlan Somers sc->sc_physpath = NULL; 2656a146a19SPawel Jakub Dawidek sc->sc_error = ioerror; 2666a146a19SPawel Jakub Dawidek sc->sc_rfailprob = rfailprob; 2676a146a19SPawel Jakub Dawidek sc->sc_wfailprob = wfailprob; 268df3d5a19SPawel Jakub Dawidek sc->sc_reads = 0; 269df3d5a19SPawel Jakub Dawidek sc->sc_writes = 0; 27045d7de1dSEdward Tomasz Napierala sc->sc_deletes = 0; 27145d7de1dSEdward Tomasz Napierala sc->sc_getattrs = 0; 27245d7de1dSEdward Tomasz Napierala sc->sc_flushes = 0; 27345d7de1dSEdward Tomasz Napierala sc->sc_cmd0s = 0; 27445d7de1dSEdward Tomasz Napierala sc->sc_cmd1s = 0; 27545d7de1dSEdward Tomasz Napierala sc->sc_cmd2s = 0; 276df3d5a19SPawel Jakub Dawidek sc->sc_readbytes = 0; 277df3d5a19SPawel Jakub Dawidek sc->sc_wrotebytes = 0; 27840ea77a0SAlexander Motin mtx_init(&sc->sc_lock, "gnop lock", NULL, MTX_DEF); 279e370e911SPawel Jakub Dawidek gp->softc = sc; 28089aaffecSPawel Jakub Dawidek gp->start = g_nop_start; 28189aaffecSPawel Jakub Dawidek gp->orphan = g_nop_orphan; 2827027e4daSEdward Tomasz Napierala gp->resize = g_nop_resize; 28389aaffecSPawel Jakub Dawidek gp->access = g_nop_access; 28489aaffecSPawel Jakub Dawidek gp->dumpconf = g_nop_dumpconf; 28589aaffecSPawel Jakub Dawidek 28602c62349SJaakko Heinonen newpp = g_new_providerf(gp, "%s", gp->name); 28740ea77a0SAlexander Motin newpp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE; 288e370e911SPawel Jakub Dawidek newpp->mediasize = size; 289d5c96d38SPawel Jakub Dawidek newpp->sectorsize = secsize; 290bb27d7edSEdward Tomasz Napierala newpp->stripesize = stripesize; 291bb27d7edSEdward Tomasz Napierala newpp->stripeoffset = stripeoffset; 29289aaffecSPawel Jakub Dawidek 29389aaffecSPawel Jakub Dawidek cp = g_new_consumer(gp); 29440ea77a0SAlexander Motin cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE; 29589aaffecSPawel Jakub Dawidek error = g_attach(cp, pp); 29689aaffecSPawel Jakub Dawidek if (error != 0) { 29789aaffecSPawel Jakub Dawidek gctl_error(req, "Cannot attach to provider %s.", pp->name); 29889aaffecSPawel Jakub Dawidek goto fail; 29989aaffecSPawel Jakub Dawidek } 30089aaffecSPawel Jakub Dawidek 3016c6e13b6SAlexander Motin newpp->flags |= pp->flags & G_PF_ACCEPT_UNMAPPED; 30289aaffecSPawel Jakub Dawidek g_error_provider(newpp, 0); 30389aaffecSPawel Jakub Dawidek G_NOP_DEBUG(0, "Device %s created.", gp->name); 30489aaffecSPawel Jakub Dawidek return (0); 30589aaffecSPawel Jakub Dawidek fail: 30689aaffecSPawel Jakub Dawidek if (cp->provider != NULL) 30789aaffecSPawel Jakub Dawidek g_detach(cp); 30889aaffecSPawel Jakub Dawidek g_destroy_consumer(cp); 309b3f05a2eSMax Khon g_destroy_provider(newpp); 31040ea77a0SAlexander Motin mtx_destroy(&sc->sc_lock); 3116f7f85e0SAlan Somers free(sc->sc_physpath, M_GEOM); 312e370e911SPawel Jakub Dawidek g_free(gp->softc); 31389aaffecSPawel Jakub Dawidek g_destroy_geom(gp); 31489aaffecSPawel Jakub Dawidek return (error); 31589aaffecSPawel Jakub Dawidek } 31689aaffecSPawel Jakub Dawidek 31789aaffecSPawel Jakub Dawidek static int 31889aaffecSPawel Jakub Dawidek g_nop_destroy(struct g_geom *gp, boolean_t force) 31989aaffecSPawel Jakub Dawidek { 32040ea77a0SAlexander Motin struct g_nop_softc *sc; 32189aaffecSPawel Jakub Dawidek struct g_provider *pp; 32289aaffecSPawel Jakub Dawidek 32389aaffecSPawel Jakub Dawidek g_topology_assert(); 32440ea77a0SAlexander Motin sc = gp->softc; 32540ea77a0SAlexander Motin if (sc == NULL) 326969ff54dSPawel Jakub Dawidek return (ENXIO); 3276f7f85e0SAlan Somers free(sc->sc_physpath, M_GEOM); 32889aaffecSPawel Jakub Dawidek pp = LIST_FIRST(&gp->provider); 32989aaffecSPawel Jakub Dawidek if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) { 33089aaffecSPawel Jakub Dawidek if (force) { 33189aaffecSPawel Jakub Dawidek G_NOP_DEBUG(0, "Device %s is still open, so it " 33289aaffecSPawel Jakub Dawidek "can't be definitely removed.", pp->name); 33389aaffecSPawel Jakub Dawidek } else { 33489aaffecSPawel Jakub Dawidek G_NOP_DEBUG(1, "Device %s is still open (r%dw%de%d).", 33589aaffecSPawel Jakub Dawidek pp->name, pp->acr, pp->acw, pp->ace); 33689aaffecSPawel Jakub Dawidek return (EBUSY); 33789aaffecSPawel Jakub Dawidek } 33889aaffecSPawel Jakub Dawidek } else { 33989aaffecSPawel Jakub Dawidek G_NOP_DEBUG(0, "Device %s removed.", gp->name); 34089aaffecSPawel Jakub Dawidek } 341e370e911SPawel Jakub Dawidek gp->softc = NULL; 34240ea77a0SAlexander Motin mtx_destroy(&sc->sc_lock); 34340ea77a0SAlexander Motin g_free(sc); 34489aaffecSPawel Jakub Dawidek g_wither_geom(gp, ENXIO); 34589aaffecSPawel Jakub Dawidek 34689aaffecSPawel Jakub Dawidek return (0); 34789aaffecSPawel Jakub Dawidek } 34889aaffecSPawel Jakub Dawidek 34989aaffecSPawel Jakub Dawidek static int 35089aaffecSPawel Jakub Dawidek g_nop_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp) 35189aaffecSPawel Jakub Dawidek { 35289aaffecSPawel Jakub Dawidek 35389aaffecSPawel Jakub Dawidek return (g_nop_destroy(gp, 0)); 35489aaffecSPawel Jakub Dawidek } 35589aaffecSPawel Jakub Dawidek 35689aaffecSPawel Jakub Dawidek static void 35789aaffecSPawel Jakub Dawidek g_nop_ctl_create(struct gctl_req *req, struct g_class *mp) 35889aaffecSPawel Jakub Dawidek { 35989aaffecSPawel Jakub Dawidek struct g_provider *pp; 360bb27d7edSEdward Tomasz Napierala intmax_t *error, *rfailprob, *wfailprob, *offset, *secsize, *size, 361bb27d7edSEdward Tomasz Napierala *stripesize, *stripeoffset; 3626f7f85e0SAlan Somers const char *name, *physpath; 36389aaffecSPawel Jakub Dawidek char param[16]; 36489aaffecSPawel Jakub Dawidek int i, *nargs; 36589aaffecSPawel Jakub Dawidek 36689aaffecSPawel Jakub Dawidek g_topology_assert(); 36789aaffecSPawel Jakub Dawidek 36889aaffecSPawel Jakub Dawidek nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 36989aaffecSPawel Jakub Dawidek if (nargs == NULL) { 37089aaffecSPawel Jakub Dawidek gctl_error(req, "No '%s' argument", "nargs"); 37189aaffecSPawel Jakub Dawidek return; 37289aaffecSPawel Jakub Dawidek } 37389aaffecSPawel Jakub Dawidek if (*nargs <= 0) { 37489aaffecSPawel Jakub Dawidek gctl_error(req, "Missing device(s)."); 37589aaffecSPawel Jakub Dawidek return; 37689aaffecSPawel Jakub Dawidek } 3776a146a19SPawel Jakub Dawidek error = gctl_get_paraml(req, "error", sizeof(*error)); 3786a146a19SPawel Jakub Dawidek if (error == NULL) { 3796a146a19SPawel Jakub Dawidek gctl_error(req, "No '%s' argument", "error"); 38089aaffecSPawel Jakub Dawidek return; 38189aaffecSPawel Jakub Dawidek } 3826a146a19SPawel Jakub Dawidek rfailprob = gctl_get_paraml(req, "rfailprob", sizeof(*rfailprob)); 3836a146a19SPawel Jakub Dawidek if (rfailprob == NULL) { 3846a146a19SPawel Jakub Dawidek gctl_error(req, "No '%s' argument", "rfailprob"); 3856a146a19SPawel Jakub Dawidek return; 3866a146a19SPawel Jakub Dawidek } 3876a146a19SPawel Jakub Dawidek if (*rfailprob < -1 || *rfailprob > 100) { 3886a146a19SPawel Jakub Dawidek gctl_error(req, "Invalid '%s' argument", "rfailprob"); 3896a146a19SPawel Jakub Dawidek return; 3906a146a19SPawel Jakub Dawidek } 3916a146a19SPawel Jakub Dawidek wfailprob = gctl_get_paraml(req, "wfailprob", sizeof(*wfailprob)); 3926a146a19SPawel Jakub Dawidek if (wfailprob == NULL) { 3936a146a19SPawel Jakub Dawidek gctl_error(req, "No '%s' argument", "wfailprob"); 3946a146a19SPawel Jakub Dawidek return; 3956a146a19SPawel Jakub Dawidek } 3966a146a19SPawel Jakub Dawidek if (*wfailprob < -1 || *wfailprob > 100) { 3976a146a19SPawel Jakub Dawidek gctl_error(req, "Invalid '%s' argument", "wfailprob"); 39889aaffecSPawel Jakub Dawidek return; 39989aaffecSPawel Jakub Dawidek } 400e370e911SPawel Jakub Dawidek offset = gctl_get_paraml(req, "offset", sizeof(*offset)); 401e370e911SPawel Jakub Dawidek if (offset == NULL) { 402e370e911SPawel Jakub Dawidek gctl_error(req, "No '%s' argument", "offset"); 403e370e911SPawel Jakub Dawidek return; 404e370e911SPawel Jakub Dawidek } 405e370e911SPawel Jakub Dawidek if (*offset < 0) { 406e370e911SPawel Jakub Dawidek gctl_error(req, "Invalid '%s' argument", "offset"); 407e370e911SPawel Jakub Dawidek return; 408e370e911SPawel Jakub Dawidek } 409e370e911SPawel Jakub Dawidek size = gctl_get_paraml(req, "size", sizeof(*size)); 410e370e911SPawel Jakub Dawidek if (size == NULL) { 411e370e911SPawel Jakub Dawidek gctl_error(req, "No '%s' argument", "size"); 412e370e911SPawel Jakub Dawidek return; 413e370e911SPawel Jakub Dawidek } 414e370e911SPawel Jakub Dawidek if (*size < 0) { 415e370e911SPawel Jakub Dawidek gctl_error(req, "Invalid '%s' argument", "size"); 416e370e911SPawel Jakub Dawidek return; 417e370e911SPawel Jakub Dawidek } 418d5c96d38SPawel Jakub Dawidek secsize = gctl_get_paraml(req, "secsize", sizeof(*secsize)); 419d5c96d38SPawel Jakub Dawidek if (secsize == NULL) { 420d5c96d38SPawel Jakub Dawidek gctl_error(req, "No '%s' argument", "secsize"); 421d5c96d38SPawel Jakub Dawidek return; 422d5c96d38SPawel Jakub Dawidek } 423d5c96d38SPawel Jakub Dawidek if (*secsize < 0) { 424d5c96d38SPawel Jakub Dawidek gctl_error(req, "Invalid '%s' argument", "secsize"); 425d5c96d38SPawel Jakub Dawidek return; 426d5c96d38SPawel Jakub Dawidek } 427bb27d7edSEdward Tomasz Napierala stripesize = gctl_get_paraml(req, "stripesize", sizeof(*stripesize)); 428bb27d7edSEdward Tomasz Napierala if (stripesize == NULL) { 429bb27d7edSEdward Tomasz Napierala gctl_error(req, "No '%s' argument", "stripesize"); 430bb27d7edSEdward Tomasz Napierala return; 431bb27d7edSEdward Tomasz Napierala } 432bb27d7edSEdward Tomasz Napierala if (*stripesize < 0) { 433bb27d7edSEdward Tomasz Napierala gctl_error(req, "Invalid '%s' argument", "stripesize"); 434bb27d7edSEdward Tomasz Napierala return; 435bb27d7edSEdward Tomasz Napierala } 436bb27d7edSEdward Tomasz Napierala stripeoffset = gctl_get_paraml(req, "stripeoffset", sizeof(*stripeoffset)); 437bb27d7edSEdward Tomasz Napierala if (stripeoffset == NULL) { 438bb27d7edSEdward Tomasz Napierala gctl_error(req, "No '%s' argument", "stripeoffset"); 439bb27d7edSEdward Tomasz Napierala return; 440bb27d7edSEdward Tomasz Napierala } 441bb27d7edSEdward Tomasz Napierala if (*stripeoffset < 0) { 442bb27d7edSEdward Tomasz Napierala gctl_error(req, "Invalid '%s' argument", "stripeoffset"); 443bb27d7edSEdward Tomasz Napierala return; 444bb27d7edSEdward Tomasz Napierala } 4456f7f85e0SAlan Somers physpath = gctl_get_asciiparam(req, "physpath"); 44689aaffecSPawel Jakub Dawidek 44789aaffecSPawel Jakub Dawidek for (i = 0; i < *nargs; i++) { 44889aaffecSPawel Jakub Dawidek snprintf(param, sizeof(param), "arg%d", i); 44989aaffecSPawel Jakub Dawidek name = gctl_get_asciiparam(req, param); 45089aaffecSPawel Jakub Dawidek if (name == NULL) { 45189aaffecSPawel Jakub Dawidek gctl_error(req, "No 'arg%d' argument", i); 45289aaffecSPawel Jakub Dawidek return; 45389aaffecSPawel Jakub Dawidek } 45489aaffecSPawel Jakub Dawidek if (strncmp(name, "/dev/", strlen("/dev/")) == 0) 45589aaffecSPawel Jakub Dawidek name += strlen("/dev/"); 45689aaffecSPawel Jakub Dawidek pp = g_provider_by_name(name); 45789aaffecSPawel Jakub Dawidek if (pp == NULL) { 45889aaffecSPawel Jakub Dawidek G_NOP_DEBUG(1, "Provider %s is invalid.", name); 45989aaffecSPawel Jakub Dawidek gctl_error(req, "Provider %s is invalid.", name); 46089aaffecSPawel Jakub Dawidek return; 46189aaffecSPawel Jakub Dawidek } 4626a146a19SPawel Jakub Dawidek if (g_nop_create(req, mp, pp, 4636a146a19SPawel Jakub Dawidek *error == -1 ? EIO : (int)*error, 4646a146a19SPawel Jakub Dawidek *rfailprob == -1 ? 0 : (u_int)*rfailprob, 4656a146a19SPawel Jakub Dawidek *wfailprob == -1 ? 0 : (u_int)*wfailprob, 466bb27d7edSEdward Tomasz Napierala (off_t)*offset, (off_t)*size, (u_int)*secsize, 4676f7f85e0SAlan Somers (u_int)*stripesize, (u_int)*stripeoffset, 4686f7f85e0SAlan Somers physpath) != 0) { 46989aaffecSPawel Jakub Dawidek return; 47089aaffecSPawel Jakub Dawidek } 47189aaffecSPawel Jakub Dawidek } 472e370e911SPawel Jakub Dawidek } 47389aaffecSPawel Jakub Dawidek 47489aaffecSPawel Jakub Dawidek static void 47502692c51SPawel Jakub Dawidek g_nop_ctl_configure(struct gctl_req *req, struct g_class *mp) 47689aaffecSPawel Jakub Dawidek { 477e370e911SPawel Jakub Dawidek struct g_nop_softc *sc; 47889aaffecSPawel Jakub Dawidek struct g_provider *pp; 4796a146a19SPawel Jakub Dawidek intmax_t *error, *rfailprob, *wfailprob; 48089aaffecSPawel Jakub Dawidek const char *name; 48189aaffecSPawel Jakub Dawidek char param[16]; 48289aaffecSPawel Jakub Dawidek int i, *nargs; 48389aaffecSPawel Jakub Dawidek 48489aaffecSPawel Jakub Dawidek g_topology_assert(); 48589aaffecSPawel Jakub Dawidek 48689aaffecSPawel Jakub Dawidek nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 48789aaffecSPawel Jakub Dawidek if (nargs == NULL) { 48889aaffecSPawel Jakub Dawidek gctl_error(req, "No '%s' argument", "nargs"); 48989aaffecSPawel Jakub Dawidek return; 49089aaffecSPawel Jakub Dawidek } 49189aaffecSPawel Jakub Dawidek if (*nargs <= 0) { 49289aaffecSPawel Jakub Dawidek gctl_error(req, "Missing device(s)."); 49389aaffecSPawel Jakub Dawidek return; 49489aaffecSPawel Jakub Dawidek } 4956a146a19SPawel Jakub Dawidek error = gctl_get_paraml(req, "error", sizeof(*error)); 4966a146a19SPawel Jakub Dawidek if (error == NULL) { 4976a146a19SPawel Jakub Dawidek gctl_error(req, "No '%s' argument", "error"); 49889aaffecSPawel Jakub Dawidek return; 49989aaffecSPawel Jakub Dawidek } 5006a146a19SPawel Jakub Dawidek rfailprob = gctl_get_paraml(req, "rfailprob", sizeof(*rfailprob)); 5016a146a19SPawel Jakub Dawidek if (rfailprob == NULL) { 5026a146a19SPawel Jakub Dawidek gctl_error(req, "No '%s' argument", "rfailprob"); 5036a146a19SPawel Jakub Dawidek return; 5046a146a19SPawel Jakub Dawidek } 5056a146a19SPawel Jakub Dawidek if (*rfailprob < -1 || *rfailprob > 100) { 5066a146a19SPawel Jakub Dawidek gctl_error(req, "Invalid '%s' argument", "rfailprob"); 5076a146a19SPawel Jakub Dawidek return; 5086a146a19SPawel Jakub Dawidek } 5096a146a19SPawel Jakub Dawidek wfailprob = gctl_get_paraml(req, "wfailprob", sizeof(*wfailprob)); 5106a146a19SPawel Jakub Dawidek if (wfailprob == NULL) { 5116a146a19SPawel Jakub Dawidek gctl_error(req, "No '%s' argument", "wfailprob"); 5126a146a19SPawel Jakub Dawidek return; 5136a146a19SPawel Jakub Dawidek } 5146a146a19SPawel Jakub Dawidek if (*wfailprob < -1 || *wfailprob > 100) { 5156a146a19SPawel Jakub Dawidek gctl_error(req, "Invalid '%s' argument", "wfailprob"); 51689aaffecSPawel Jakub Dawidek return; 51789aaffecSPawel Jakub Dawidek } 51889aaffecSPawel Jakub Dawidek 51989aaffecSPawel Jakub Dawidek for (i = 0; i < *nargs; i++) { 52089aaffecSPawel Jakub Dawidek snprintf(param, sizeof(param), "arg%d", i); 52189aaffecSPawel Jakub Dawidek name = gctl_get_asciiparam(req, param); 52289aaffecSPawel Jakub Dawidek if (name == NULL) { 52389aaffecSPawel Jakub Dawidek gctl_error(req, "No 'arg%d' argument", i); 52489aaffecSPawel Jakub Dawidek return; 52589aaffecSPawel Jakub Dawidek } 52689aaffecSPawel Jakub Dawidek if (strncmp(name, "/dev/", strlen("/dev/")) == 0) 52789aaffecSPawel Jakub Dawidek name += strlen("/dev/"); 52889aaffecSPawel Jakub Dawidek pp = g_provider_by_name(name); 52989aaffecSPawel Jakub Dawidek if (pp == NULL || pp->geom->class != mp) { 53089aaffecSPawel Jakub Dawidek G_NOP_DEBUG(1, "Provider %s is invalid.", name); 53189aaffecSPawel Jakub Dawidek gctl_error(req, "Provider %s is invalid.", name); 53289aaffecSPawel Jakub Dawidek return; 53389aaffecSPawel Jakub Dawidek } 534e370e911SPawel Jakub Dawidek sc = pp->geom->softc; 5356a146a19SPawel Jakub Dawidek if (*error != -1) 5366a146a19SPawel Jakub Dawidek sc->sc_error = (int)*error; 5376a146a19SPawel Jakub Dawidek if (*rfailprob != -1) 5386a146a19SPawel Jakub Dawidek sc->sc_rfailprob = (u_int)*rfailprob; 5396a146a19SPawel Jakub Dawidek if (*wfailprob != -1) 5406a146a19SPawel Jakub Dawidek sc->sc_wfailprob = (u_int)*wfailprob; 54189aaffecSPawel Jakub Dawidek } 54289aaffecSPawel Jakub Dawidek } 54389aaffecSPawel Jakub Dawidek 54489aaffecSPawel Jakub Dawidek static struct g_geom * 54589aaffecSPawel Jakub Dawidek g_nop_find_geom(struct g_class *mp, const char *name) 54689aaffecSPawel Jakub Dawidek { 54789aaffecSPawel Jakub Dawidek struct g_geom *gp; 54889aaffecSPawel Jakub Dawidek 54989aaffecSPawel Jakub Dawidek LIST_FOREACH(gp, &mp->geom, geom) { 55089aaffecSPawel Jakub Dawidek if (strcmp(gp->name, name) == 0) 55189aaffecSPawel Jakub Dawidek return (gp); 55289aaffecSPawel Jakub Dawidek } 55389aaffecSPawel Jakub Dawidek return (NULL); 55489aaffecSPawel Jakub Dawidek } 55589aaffecSPawel Jakub Dawidek 55689aaffecSPawel Jakub Dawidek static void 55789aaffecSPawel Jakub Dawidek g_nop_ctl_destroy(struct gctl_req *req, struct g_class *mp) 55889aaffecSPawel Jakub Dawidek { 55989aaffecSPawel Jakub Dawidek int *nargs, *force, error, i; 56089aaffecSPawel Jakub Dawidek struct g_geom *gp; 56189aaffecSPawel Jakub Dawidek const char *name; 56289aaffecSPawel Jakub Dawidek char param[16]; 56389aaffecSPawel Jakub Dawidek 56489aaffecSPawel Jakub Dawidek g_topology_assert(); 56589aaffecSPawel Jakub Dawidek 56689aaffecSPawel Jakub Dawidek nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 56789aaffecSPawel Jakub Dawidek if (nargs == NULL) { 56889aaffecSPawel Jakub Dawidek gctl_error(req, "No '%s' argument", "nargs"); 56989aaffecSPawel Jakub Dawidek return; 57089aaffecSPawel Jakub Dawidek } 57189aaffecSPawel Jakub Dawidek if (*nargs <= 0) { 57289aaffecSPawel Jakub Dawidek gctl_error(req, "Missing device(s)."); 57389aaffecSPawel Jakub Dawidek return; 57489aaffecSPawel Jakub Dawidek } 57589aaffecSPawel Jakub Dawidek force = gctl_get_paraml(req, "force", sizeof(*force)); 57689aaffecSPawel Jakub Dawidek if (force == NULL) { 57789aaffecSPawel Jakub Dawidek gctl_error(req, "No 'force' argument"); 57889aaffecSPawel Jakub Dawidek return; 57989aaffecSPawel Jakub Dawidek } 58089aaffecSPawel Jakub Dawidek 58189aaffecSPawel Jakub Dawidek for (i = 0; i < *nargs; i++) { 58289aaffecSPawel Jakub Dawidek snprintf(param, sizeof(param), "arg%d", i); 58389aaffecSPawel Jakub Dawidek name = gctl_get_asciiparam(req, param); 58489aaffecSPawel Jakub Dawidek if (name == NULL) { 58589aaffecSPawel Jakub Dawidek gctl_error(req, "No 'arg%d' argument", i); 58689aaffecSPawel Jakub Dawidek return; 58789aaffecSPawel Jakub Dawidek } 58889aaffecSPawel Jakub Dawidek if (strncmp(name, "/dev/", strlen("/dev/")) == 0) 58989aaffecSPawel Jakub Dawidek name += strlen("/dev/"); 59089aaffecSPawel Jakub Dawidek gp = g_nop_find_geom(mp, name); 59189aaffecSPawel Jakub Dawidek if (gp == NULL) { 59289aaffecSPawel Jakub Dawidek G_NOP_DEBUG(1, "Device %s is invalid.", name); 59389aaffecSPawel Jakub Dawidek gctl_error(req, "Device %s is invalid.", name); 59489aaffecSPawel Jakub Dawidek return; 59589aaffecSPawel Jakub Dawidek } 59689aaffecSPawel Jakub Dawidek error = g_nop_destroy(gp, *force); 59789aaffecSPawel Jakub Dawidek if (error != 0) { 59889aaffecSPawel Jakub Dawidek gctl_error(req, "Cannot destroy device %s (error=%d).", 59989aaffecSPawel Jakub Dawidek gp->name, error); 60089aaffecSPawel Jakub Dawidek return; 60189aaffecSPawel Jakub Dawidek } 60289aaffecSPawel Jakub Dawidek } 60389aaffecSPawel Jakub Dawidek } 60489aaffecSPawel Jakub Dawidek 60589aaffecSPawel Jakub Dawidek static void 606df3d5a19SPawel Jakub Dawidek g_nop_ctl_reset(struct gctl_req *req, struct g_class *mp) 607df3d5a19SPawel Jakub Dawidek { 608df3d5a19SPawel Jakub Dawidek struct g_nop_softc *sc; 609df3d5a19SPawel Jakub Dawidek struct g_provider *pp; 610df3d5a19SPawel Jakub Dawidek const char *name; 611df3d5a19SPawel Jakub Dawidek char param[16]; 612df3d5a19SPawel Jakub Dawidek int i, *nargs; 613df3d5a19SPawel Jakub Dawidek 614df3d5a19SPawel Jakub Dawidek g_topology_assert(); 615df3d5a19SPawel Jakub Dawidek 616df3d5a19SPawel Jakub Dawidek nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 617df3d5a19SPawel Jakub Dawidek if (nargs == NULL) { 618df3d5a19SPawel Jakub Dawidek gctl_error(req, "No '%s' argument", "nargs"); 619df3d5a19SPawel Jakub Dawidek return; 620df3d5a19SPawel Jakub Dawidek } 621df3d5a19SPawel Jakub Dawidek if (*nargs <= 0) { 622df3d5a19SPawel Jakub Dawidek gctl_error(req, "Missing device(s)."); 623df3d5a19SPawel Jakub Dawidek return; 624df3d5a19SPawel Jakub Dawidek } 625df3d5a19SPawel Jakub Dawidek 626df3d5a19SPawel Jakub Dawidek for (i = 0; i < *nargs; i++) { 627df3d5a19SPawel Jakub Dawidek snprintf(param, sizeof(param), "arg%d", i); 628df3d5a19SPawel Jakub Dawidek name = gctl_get_asciiparam(req, param); 629df3d5a19SPawel Jakub Dawidek if (name == NULL) { 630df3d5a19SPawel Jakub Dawidek gctl_error(req, "No 'arg%d' argument", i); 631df3d5a19SPawel Jakub Dawidek return; 632df3d5a19SPawel Jakub Dawidek } 633df3d5a19SPawel Jakub Dawidek if (strncmp(name, "/dev/", strlen("/dev/")) == 0) 634df3d5a19SPawel Jakub Dawidek name += strlen("/dev/"); 635df3d5a19SPawel Jakub Dawidek pp = g_provider_by_name(name); 636df3d5a19SPawel Jakub Dawidek if (pp == NULL || pp->geom->class != mp) { 637df3d5a19SPawel Jakub Dawidek G_NOP_DEBUG(1, "Provider %s is invalid.", name); 638df3d5a19SPawel Jakub Dawidek gctl_error(req, "Provider %s is invalid.", name); 639df3d5a19SPawel Jakub Dawidek return; 640df3d5a19SPawel Jakub Dawidek } 641df3d5a19SPawel Jakub Dawidek sc = pp->geom->softc; 642df3d5a19SPawel Jakub Dawidek sc->sc_reads = 0; 643df3d5a19SPawel Jakub Dawidek sc->sc_writes = 0; 64445d7de1dSEdward Tomasz Napierala sc->sc_deletes = 0; 64545d7de1dSEdward Tomasz Napierala sc->sc_getattrs = 0; 64645d7de1dSEdward Tomasz Napierala sc->sc_flushes = 0; 64745d7de1dSEdward Tomasz Napierala sc->sc_cmd0s = 0; 64845d7de1dSEdward Tomasz Napierala sc->sc_cmd1s = 0; 64945d7de1dSEdward Tomasz Napierala sc->sc_cmd2s = 0; 650df3d5a19SPawel Jakub Dawidek sc->sc_readbytes = 0; 651df3d5a19SPawel Jakub Dawidek sc->sc_wrotebytes = 0; 652df3d5a19SPawel Jakub Dawidek } 653df3d5a19SPawel Jakub Dawidek } 654df3d5a19SPawel Jakub Dawidek 655df3d5a19SPawel Jakub Dawidek static void 65689aaffecSPawel Jakub Dawidek g_nop_config(struct gctl_req *req, struct g_class *mp, const char *verb) 65789aaffecSPawel Jakub Dawidek { 65889aaffecSPawel Jakub Dawidek uint32_t *version; 65989aaffecSPawel Jakub Dawidek 66089aaffecSPawel Jakub Dawidek g_topology_assert(); 66189aaffecSPawel Jakub Dawidek 66289aaffecSPawel Jakub Dawidek version = gctl_get_paraml(req, "version", sizeof(*version)); 66389aaffecSPawel Jakub Dawidek if (version == NULL) { 66489aaffecSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "version"); 66589aaffecSPawel Jakub Dawidek return; 66689aaffecSPawel Jakub Dawidek } 66789aaffecSPawel Jakub Dawidek if (*version != G_NOP_VERSION) { 66889aaffecSPawel Jakub Dawidek gctl_error(req, "Userland and kernel parts are out of sync."); 66989aaffecSPawel Jakub Dawidek return; 67089aaffecSPawel Jakub Dawidek } 67189aaffecSPawel Jakub Dawidek 67289aaffecSPawel Jakub Dawidek if (strcmp(verb, "create") == 0) { 67389aaffecSPawel Jakub Dawidek g_nop_ctl_create(req, mp); 67489aaffecSPawel Jakub Dawidek return; 67502692c51SPawel Jakub Dawidek } else if (strcmp(verb, "configure") == 0) { 67602692c51SPawel Jakub Dawidek g_nop_ctl_configure(req, mp); 67789aaffecSPawel Jakub Dawidek return; 67889aaffecSPawel Jakub Dawidek } else if (strcmp(verb, "destroy") == 0) { 67989aaffecSPawel Jakub Dawidek g_nop_ctl_destroy(req, mp); 68089aaffecSPawel Jakub Dawidek return; 681df3d5a19SPawel Jakub Dawidek } else if (strcmp(verb, "reset") == 0) { 682df3d5a19SPawel Jakub Dawidek g_nop_ctl_reset(req, mp); 683df3d5a19SPawel Jakub Dawidek return; 68489aaffecSPawel Jakub Dawidek } 68589aaffecSPawel Jakub Dawidek 68689aaffecSPawel Jakub Dawidek gctl_error(req, "Unknown verb."); 68789aaffecSPawel Jakub Dawidek } 68889aaffecSPawel Jakub Dawidek 68989aaffecSPawel Jakub Dawidek static void 69089aaffecSPawel Jakub Dawidek g_nop_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, 69189aaffecSPawel Jakub Dawidek struct g_consumer *cp, struct g_provider *pp) 69289aaffecSPawel Jakub Dawidek { 693e370e911SPawel Jakub Dawidek struct g_nop_softc *sc; 69489aaffecSPawel Jakub Dawidek 6951d723f1dSPawel Jakub Dawidek if (pp != NULL || cp != NULL) 696e370e911SPawel Jakub Dawidek return; 697e370e911SPawel Jakub Dawidek sc = gp->softc; 6981d723f1dSPawel Jakub Dawidek sbuf_printf(sb, "%s<Offset>%jd</Offset>\n", indent, 699e370e911SPawel Jakub Dawidek (intmax_t)sc->sc_offset); 7006a146a19SPawel Jakub Dawidek sbuf_printf(sb, "%s<ReadFailProb>%u</ReadFailProb>\n", indent, 7016a146a19SPawel Jakub Dawidek sc->sc_rfailprob); 7026a146a19SPawel Jakub Dawidek sbuf_printf(sb, "%s<WriteFailProb>%u</WriteFailProb>\n", indent, 7036a146a19SPawel Jakub Dawidek sc->sc_wfailprob); 70446ee0837SPawel Jakub Dawidek sbuf_printf(sb, "%s<Error>%d</Error>\n", indent, sc->sc_error); 705df3d5a19SPawel Jakub Dawidek sbuf_printf(sb, "%s<Reads>%ju</Reads>\n", indent, sc->sc_reads); 706df3d5a19SPawel Jakub Dawidek sbuf_printf(sb, "%s<Writes>%ju</Writes>\n", indent, sc->sc_writes); 70745d7de1dSEdward Tomasz Napierala sbuf_printf(sb, "%s<Deletes>%ju</Deletes>\n", indent, sc->sc_deletes); 70845d7de1dSEdward Tomasz Napierala sbuf_printf(sb, "%s<Getattrs>%ju</Getattrs>\n", indent, sc->sc_getattrs); 70945d7de1dSEdward Tomasz Napierala sbuf_printf(sb, "%s<Flushes>%ju</Flushes>\n", indent, sc->sc_flushes); 71045d7de1dSEdward Tomasz Napierala sbuf_printf(sb, "%s<Cmd0s>%ju</Cmd0s>\n", indent, sc->sc_cmd0s); 71145d7de1dSEdward Tomasz Napierala sbuf_printf(sb, "%s<Cmd1s>%ju</Cmd1s>\n", indent, sc->sc_cmd1s); 71245d7de1dSEdward Tomasz Napierala sbuf_printf(sb, "%s<Cmd2s>%ju</Cmd2s>\n", indent, sc->sc_cmd2s); 713b91df0e2SPawel Jakub Dawidek sbuf_printf(sb, "%s<ReadBytes>%ju</ReadBytes>\n", indent, 714df3d5a19SPawel Jakub Dawidek sc->sc_readbytes); 715df3d5a19SPawel Jakub Dawidek sbuf_printf(sb, "%s<WroteBytes>%ju</WroteBytes>\n", indent, 71664806a73SPawel Jakub Dawidek sc->sc_wrotebytes); 71789aaffecSPawel Jakub Dawidek } 71889aaffecSPawel Jakub Dawidek 71989aaffecSPawel Jakub Dawidek DECLARE_GEOM_CLASS(g_nop_class, g_nop); 720*74d6c131SKyle Evans MODULE_VERSION(geom_nop, 0); 721