Index: head/lib/geom/nop/geom_nop.c =================================================================== --- head/lib/geom/nop/geom_nop.c +++ head/lib/geom/nop/geom_nop.c @@ -56,12 +56,13 @@ { 'w', "wfailprob", "-1", G_TYPE_NUMBER }, { 'x', "wdelayprob", "-1", G_TYPE_NUMBER }, { 'z', "physpath", G_NOP_PHYSPATH_PASSTHROUGH, G_TYPE_STRING }, + { 'Z', "gnopname", G_VAL_OPTIONAL, G_TYPE_STRING }, G_OPT_SENTINEL }, "[-v] [-c count_until_fail] [-d delaymsec] [-e error] [-o offset] " "[-p stripesize] [-P stripeoffset] [-q rdelayprob] [-r rfailprob] " "[-s size] [-S secsize] [-w wfailprob] [-x wdelayprob] " - "[-z physpath] dev ..." + "[-z physpath] [-Z gnopname] dev ..." }, { "configure", G_FLAG_VERBOSE, NULL, { Index: head/lib/geom/nop/gnop.8 =================================================================== --- head/lib/geom/nop/gnop.8 +++ head/lib/geom/nop/gnop.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 13, 2019 +.Dd December 29, 2019 .Dt GNOP 8 .Os .Sh NAME @@ -47,6 +47,7 @@ .Op Fl w Ar wfailprob .Op Fl x Ar wdelayprob .Op Fl z Ar physpath +.Op Fl Z Ar gnopname .Ar dev ... .Nm .Cm configure @@ -153,6 +154,11 @@ Specifies write delay probability in percent. .It Fl z Ar physpath Physical path of the transparent provider. +.It Fl Z Ar gnopname +The name of the new provider. +The suffix +.Dq .nop +will be appended to the provider name. .El .Sh SYSCTL VARIABLES The following Index: head/sys/geom/nop/g_nop.c =================================================================== --- head/sys/geom/nop/g_nop.c +++ head/sys/geom/nop/g_nop.c @@ -2,6 +2,7 @@ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2004-2006 Pawel Jakub Dawidek + * Copyright (c) 2019 Mariusz Zaborski * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -81,6 +83,20 @@ TAILQ_ENTRY(g_nop_delay) dl_next; }; +static bool +g_nop_verify_nprefix(const char *name) +{ + int i; + + for (i = 0; i < strlen(name); i++) { + if (isalpha(name[i]) == 0 && isdigit(name[i]) == 0) { + return (false); + } + } + + return (true); +} + static void g_nop_orphan(struct g_consumer *cp) { @@ -312,17 +328,17 @@ static int g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp, - int ioerror, u_int count_until_fail, u_int rfailprob, u_int wfailprob, - u_int delaymsec, u_int rdelayprob, u_int wdelayprob, off_t offset, - off_t size, u_int secsize, off_t stripesize, off_t stripeoffset, - const char *physpath) + const char *gnopname, int ioerror, u_int count_until_fail, + u_int rfailprob, u_int wfailprob, u_int delaymsec, u_int rdelayprob, + u_int wdelayprob, off_t offset, off_t size, u_int secsize, off_t stripesize, + off_t stripeoffset, const char *physpath) { struct g_nop_softc *sc; struct g_geom *gp; struct g_provider *newpp; struct g_consumer *cp; char name[64]; - int error; + int error, n; off_t explicitsize; g_topology_assert(); @@ -373,7 +389,22 @@ gctl_error(req, "stripeoffset is too big."); return (EINVAL); } - snprintf(name, sizeof(name), "%s%s", pp->name, G_NOP_SUFFIX); + if (gnopname != NULL && !g_nop_verify_nprefix(gnopname)) { + gctl_error(req, "Name %s is invalid.", gnopname); + return (EINVAL); + } + + if (gnopname != NULL) { + n = snprintf(name, sizeof(name), "%s%s", gnopname, + G_NOP_SUFFIX); + } else { + n = snprintf(name, sizeof(name), "%s%s", pp->name, + G_NOP_SUFFIX); + } + if (n <= 0 || n >= sizeof(name)) { + gctl_error(req, "Invalid provider name."); + return (EINVAL); + } LIST_FOREACH(gp, &mp->geom, geom) { if (strcmp(gp->name, name) == 0) { gctl_error(req, "Provider %s already exists.", name); @@ -500,7 +531,7 @@ intmax_t *val, error, rfailprob, wfailprob, count_until_fail, offset, secsize, size, stripesize, stripeoffset, delaymsec, rdelayprob, wdelayprob; - const char *name, *physpath; + const char *name, *physpath, *gnopname; char param[16]; int i, *nargs; @@ -623,6 +654,7 @@ } } physpath = gctl_get_asciiparam(req, "physpath"); + gnopname = gctl_get_asciiparam(req, "gnopname"); for (i = 0; i < *nargs; i++) { snprintf(param, sizeof(param), "arg%d", i); @@ -640,6 +672,7 @@ return; } if (g_nop_create(req, mp, pp, + gnopname, error == -1 ? EIO : (int)error, count_until_fail == -1 ? 0 : (u_int)count_until_fail, rfailprob == -1 ? 0 : (u_int)rfailprob,