summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2006-09-08 09:21:21 +0000
committerpjd <pjd@FreeBSD.org>2006-09-08 09:21:21 +0000
commit40cda51553df6f8224eba40ac32f1be90ec6e6b8 (patch)
treea2099dcb67b99fcaff437d787246ce8d58e61ddd
parente5de30ab6d69a8cab27d5b368e5394fea4fbc4e5 (diff)
downloadFreeBSD-src-40cda51553df6f8224eba40ac32f1be90ec6e6b8.zip
FreeBSD-src-40cda51553df6f8224eba40ac32f1be90ec6e6b8.tar.gz
- Split failure probability configuration into read failure probability and
write failure probability. - Allow to specify an error number to return of failure. MFC after: 3 days
-rw-r--r--sbin/geom/class/nop/geom_nop.c19
-rw-r--r--sbin/geom/class/nop/gnop.822
-rw-r--r--sys/geom/nop/g_nop.c92
-rw-r--r--sys/geom/nop/g_nop.h8
4 files changed, 102 insertions, 39 deletions
diff --git a/sbin/geom/class/nop/geom_nop.c b/sbin/geom/class/nop/geom_nop.c
index c1c16b5..0de2856 100644
--- a/sbin/geom/class/nop/geom_nop.c
+++ b/sbin/geom/class/nop/geom_nop.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * Copyright (c) 2004-2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,9 @@ __FBSDID("$FreeBSD$");
uint32_t lib_version = G_LIB_VERSION;
uint32_t version = G_NOP_VERSION;
-static intmax_t failprob = 0;
+static intmax_t error = -1;
+static intmax_t rfailprob = -1;
+static intmax_t wfailprob = -1;
static intmax_t offset = 0;
static intmax_t secsize = 0;
static intmax_t size = 0;
@@ -46,20 +48,25 @@ static intmax_t size = 0;
struct g_command class_commands[] = {
{ "create", G_FLAG_VERBOSE | G_FLAG_LOADKLD, NULL,
{
- { 'f', "failprob", &failprob, G_TYPE_NUMBER },
+ { 'e', "error", &error, G_TYPE_NUMBER },
{ 'o', "offset", &offset, G_TYPE_NUMBER },
+ { 'r', "rfailprob", &rfailprob, G_TYPE_NUMBER },
{ 's', "size", &size, G_TYPE_NUMBER },
{ 'S', "secsize", &secsize, G_TYPE_NUMBER },
+ { 'w', "wfailprob", &wfailprob, G_TYPE_NUMBER },
G_OPT_SENTINEL
},
- "[-v] [-f failprob] [-o offset] [-s size] [-S secsize] dev ..."
+ "[-v] [-e error] [-o offset] [-r rfailprob] [-s size] [-S secsize] "
+ "[-w wfailprob] dev ..."
},
{ "configure", G_FLAG_VERBOSE, NULL,
{
- { 'f', "failprob", &failprob, G_TYPE_NUMBER },
+ { 'e', "error", &error, G_TYPE_NUMBER },
+ { 'r', "rfailprob", &rfailprob, G_TYPE_NUMBER },
+ { 'w', "wfailprob", &wfailprob, G_TYPE_NUMBER },
G_OPT_SENTINEL
},
- "[-v] [-f failprob] prov ..."
+ "[-v] [-e error] [-r rfailprob] [-w wfailprob] prov ..."
},
{ "destroy", G_FLAG_VERBOSE, NULL,
{
diff --git a/sbin/geom/class/nop/gnop.8 b/sbin/geom/class/nop/gnop.8
index 64c04ca..2ec29fa 100644
--- a/sbin/geom/class/nop/gnop.8
+++ b/sbin/geom/class/nop/gnop.8
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+.\" Copyright (c) 2004-2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 21, 2004
+.Dd September 8, 2006
.Dt GNOP 8
.Os
.Sh NAME
@@ -34,15 +34,19 @@
.Nm
.Cm create
.Op Fl v
-.Op Fl f Ar failprob
+.Op Fl e Ar error
.Op Fl o Ar offset
+.Op Fl r Ar rfailprob
.Op Fl s Ar size
.Op Fl S Ar secsize
+.Op Fl w Ar wfailprob
.Ar dev ...
.Nm
.Cm configure
.Op Fl v
-.Op Fl f Ar failprob
+.Op Fl e Ar error
+.Op Fl r Ar rfailprob
+.Op Fl w Ar wfailprob
.Ar prov ...
.Nm
.Cm destroy
@@ -104,17 +108,21 @@ See
.El
.Pp
Additional options:
-.Bl -tag -width ".Fl f Ar failprob"
+.Bl -tag -width ".Fl f Ar rfailprob"
+.It Fl e Ar error
+Specifies the error number to return on failure.
.It Fl f
Force the removal of the specified provider.
-.It Fl f Ar failprob
-Specifies failure probability in percentage.
.It Fl o Ar offset
Where to begin on the original provider.
+.It Fl r Ar rfailprob
+Specifies read failure probability in percent.
.It Fl s Ar size
Size of the transparent provider.
.It Fl S Ar secsize
Sector size of the transparent provider.
+.It Fl w Ar wfailprob
+Specifies write failure probability in percent.
.It Fl v
Be more verbose.
.El
diff --git a/sys/geom/nop/g_nop.c b/sys/geom/nop/g_nop.c
index 359b054..d02416f 100644
--- a/sys/geom/nop/g_nop.c
+++ b/sys/geom/nop/g_nop.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * Copyright (c) 2004-2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -77,6 +77,7 @@ g_nop_start(struct bio *bp)
struct g_geom *gp;
struct g_provider *pp;
struct bio *cbp;
+ u_int failprob = 0;
gp = bp->bio_to->geom;
sc = gp->softc;
@@ -85,19 +86,21 @@ g_nop_start(struct bio *bp)
case BIO_READ:
sc->sc_reads++;
sc->sc_readbytes += bp->bio_length;
+ failprob = sc->sc_rfailprob;
break;
case BIO_WRITE:
sc->sc_writes++;
sc->sc_wrotebytes += bp->bio_length;
+ failprob = sc->sc_wfailprob;
break;
}
- if (sc->sc_failprob > 0) {
+ if (failprob > 0) {
u_int rval;
rval = arc4random() % 100;
- if (rval < sc->sc_failprob) {
- G_NOP_LOGREQ(bp, "Returning EIO.");
- g_io_deliver(bp, EIO);
+ if (rval < failprob) {
+ G_NOP_LOGREQ(bp, "Returning error=%d.", sc->sc_error);
+ g_io_deliver(bp, sc->sc_error);
return;
}
}
@@ -133,7 +136,8 @@ g_nop_access(struct g_provider *pp, int dr, int dw, int de)
static int
g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp,
- u_int failprob, off_t offset, off_t size, u_int secsize)
+ int ioerror, u_int rfailprob, u_int wfailprob, off_t offset, off_t size,
+ u_int secsize)
{
struct g_nop_softc *sc;
struct g_geom *gp;
@@ -186,7 +190,9 @@ g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp,
}
sc = g_malloc(sizeof(*sc), M_WAITOK);
sc->sc_offset = offset;
- sc->sc_failprob = failprob;
+ sc->sc_error = ioerror;
+ sc->sc_rfailprob = rfailprob;
+ sc->sc_wfailprob = wfailprob;
sc->sc_reads = 0;
sc->sc_writes = 0;
sc->sc_readbytes = 0;
@@ -276,7 +282,7 @@ static void
g_nop_ctl_create(struct gctl_req *req, struct g_class *mp)
{
struct g_provider *pp;
- intmax_t *failprob, *offset, *secsize, *size;
+ intmax_t *error, *rfailprob, *wfailprob, *offset, *secsize, *size;
const char *name;
char param[16];
int i, *nargs;
@@ -292,13 +298,27 @@ g_nop_ctl_create(struct gctl_req *req, struct g_class *mp)
gctl_error(req, "Missing device(s).");
return;
}
- failprob = gctl_get_paraml(req, "failprob", sizeof(*failprob));
- if (failprob == NULL) {
- gctl_error(req, "No '%s' argument", "failprob");
+ error = gctl_get_paraml(req, "error", sizeof(*error));
+ if (error == NULL) {
+ gctl_error(req, "No '%s' argument", "error");
return;
}
- if (*failprob < 0 || *failprob > 100) {
- gctl_error(req, "Invalid '%s' argument", "failprob");
+ rfailprob = gctl_get_paraml(req, "rfailprob", sizeof(*rfailprob));
+ if (rfailprob == NULL) {
+ gctl_error(req, "No '%s' argument", "rfailprob");
+ return;
+ }
+ if (*rfailprob < -1 || *rfailprob > 100) {
+ gctl_error(req, "Invalid '%s' argument", "rfailprob");
+ return;
+ }
+ wfailprob = gctl_get_paraml(req, "wfailprob", sizeof(*wfailprob));
+ if (wfailprob == NULL) {
+ gctl_error(req, "No '%s' argument", "wfailprob");
+ return;
+ }
+ if (*wfailprob < -1 || *wfailprob > 100) {
+ gctl_error(req, "Invalid '%s' argument", "wfailprob");
return;
}
offset = gctl_get_paraml(req, "offset", sizeof(*offset));
@@ -344,8 +364,11 @@ g_nop_ctl_create(struct gctl_req *req, struct g_class *mp)
gctl_error(req, "Provider %s is invalid.", name);
return;
}
- if (g_nop_create(req, mp, pp, (u_int)*failprob, (off_t)*offset,
- (off_t)*size, (u_int)*secsize) != 0) {
+ if (g_nop_create(req, mp, pp,
+ *error == -1 ? EIO : (int)*error,
+ *rfailprob == -1 ? 0 : (u_int)*rfailprob,
+ *wfailprob == -1 ? 0 : (u_int)*wfailprob,
+ (off_t)*offset, (off_t)*size, (u_int)*secsize) != 0) {
return;
}
}
@@ -356,7 +379,7 @@ g_nop_ctl_configure(struct gctl_req *req, struct g_class *mp)
{
struct g_nop_softc *sc;
struct g_provider *pp;
- intmax_t *failprob;
+ intmax_t *error, *rfailprob, *wfailprob;
const char *name;
char param[16];
int i, *nargs;
@@ -372,13 +395,27 @@ g_nop_ctl_configure(struct gctl_req *req, struct g_class *mp)
gctl_error(req, "Missing device(s).");
return;
}
- failprob = gctl_get_paraml(req, "failprob", sizeof(*failprob));
- if (failprob == NULL) {
- gctl_error(req, "No '%s' argument", "failprob");
+ error = gctl_get_paraml(req, "error", sizeof(*error));
+ if (error == NULL) {
+ gctl_error(req, "No '%s' argument", "error");
+ return;
+ }
+ rfailprob = gctl_get_paraml(req, "rfailprob", sizeof(*rfailprob));
+ if (rfailprob == NULL) {
+ gctl_error(req, "No '%s' argument", "rfailprob");
+ return;
+ }
+ if (*rfailprob < -1 || *rfailprob > 100) {
+ gctl_error(req, "Invalid '%s' argument", "rfailprob");
+ return;
+ }
+ wfailprob = gctl_get_paraml(req, "wfailprob", sizeof(*wfailprob));
+ if (wfailprob == NULL) {
+ gctl_error(req, "No '%s' argument", "wfailprob");
return;
}
- if (*failprob < 0 || *failprob > 100) {
- gctl_error(req, "Invalid '%s' argument", "failprob");
+ if (*wfailprob < -1 || *wfailprob > 100) {
+ gctl_error(req, "Invalid '%s' argument", "wfailprob");
return;
}
@@ -398,7 +435,12 @@ g_nop_ctl_configure(struct gctl_req *req, struct g_class *mp)
return;
}
sc = pp->geom->softc;
- sc->sc_failprob = (u_int)*failprob;
+ if (*error != -1)
+ sc->sc_error = (int)*error;
+ if (*rfailprob != -1)
+ sc->sc_rfailprob = (u_int)*rfailprob;
+ if (*wfailprob != -1)
+ sc->sc_wfailprob = (u_int)*wfailprob;
}
}
@@ -552,7 +594,11 @@ g_nop_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
sc = gp->softc;
sbuf_printf(sb, "%s<Offset>%jd</Offset>\n", indent,
(intmax_t)sc->sc_offset);
- sbuf_printf(sb, "%s<FailProb>%u</FailProb>\n", indent, sc->sc_failprob);
+ sbuf_printf(sb, "%s<ReadFailProb>%u</ReadFailProb>\n", indent,
+ sc->sc_rfailprob);
+ sbuf_printf(sb, "%s<WriteFailProb>%u</WriteFailProb>\n", indent,
+ sc->sc_wfailprob);
+ sbuf_printf(sb, "%s<Error>%ju</Error>\n", indent, sc->sc_error);
sbuf_printf(sb, "%s<Reads>%ju</Reads>\n", indent, sc->sc_reads);
sbuf_printf(sb, "%s<Writes>%ju</Writes>\n", indent, sc->sc_writes);
sbuf_printf(sb, "%s<ReadBytes>%ju</ReadBytes>\n", indent,
diff --git a/sys/geom/nop/g_nop.h b/sys/geom/nop/g_nop.h
index e8df888..0f83a5f 100644
--- a/sys/geom/nop/g_nop.h
+++ b/sys/geom/nop/g_nop.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * Copyright (c) 2004-2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
#define _G_NOP_H_
#define G_NOP_CLASS_NAME "NOP"
-#define G_NOP_VERSION 3
+#define G_NOP_VERSION 4
#define G_NOP_SUFFIX ".nop"
#ifdef _KERNEL
@@ -55,8 +55,10 @@
} while (0)
struct g_nop_softc {
+ int sc_error;
off_t sc_offset;
- u_int sc_failprob;
+ u_int sc_rfailprob;
+ u_int sc_wfailprob;
uintmax_t sc_reads;
uintmax_t sc_writes;
uintmax_t sc_readbytes;
OpenPOWER on IntegriCloud