summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2008-06-12 00:19:16 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2008-06-12 00:19:16 +0000
commitc2ced4ec3a978149165544ddd9a9c469e1d86dd0 (patch)
tree31f37978b222b45e1a729dcb7f46fe4b4767b712
parentdb3961ce742ee00729295e07ff7a57cb0a2bb10c (diff)
Add delete volume functionality.
discussed with krw, kettenis & drahn ok hshoexer
-rw-r--r--sbin/bioctl/bioctl.c25
-rw-r--r--sys/dev/biovar.h11
-rw-r--r--sys/dev/softraid.c46
-rw-r--r--sys/dev/softraidvar.h4
4 files changed, 80 insertions, 6 deletions
diff --git a/sbin/bioctl/bioctl.c b/sbin/bioctl/bioctl.c
index e42ef153261..e9579e37ecc 100644
--- a/sbin/bioctl/bioctl.c
+++ b/sbin/bioctl/bioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bioctl.c,v 1.62 2008/01/19 23:53:53 marco Exp $ */
+/* $OpenBSD: bioctl.c,v 1.63 2008/06/12 00:19:15 marco Exp $ */
/*
* Copyright (c) 2004, 2005 Marco Peereboom
@@ -65,6 +65,7 @@ void bio_setstate(char *);
void bio_setblink(char *, char *, int);
void bio_blink(char *, int, int);
void bio_createraid(u_int16_t, char *);
+void bio_deleteraid(char *);
u_int32_t bio_createflags(char *);
char *bio_vis(char *);
void bio_diskinq(char *);
@@ -91,7 +92,7 @@ main(int argc, char *argv[])
if (argc < 2)
usage();
- while ((ch = getopt(argc, argv, "b:C:c:l:u:H:ha:ivq")) != -1) {
+ while ((ch = getopt(argc, argv, "b:C:c:dl:u:H:ha:ivq")) != -1) {
switch (ch) {
case 'a': /* alarm */
func |= BIOC_ALARM;
@@ -112,6 +113,10 @@ main(int argc, char *argv[])
else
cr_level = *optarg;
break;
+ case 'd':
+ /* delete volume */
+ func |= BIOC_DELETERAID;
+ break;
case 'u': /* unblink */
func |= BIOC_BLINK;
blink = BIOC_SBUNBLINK;
@@ -185,6 +190,8 @@ main(int argc, char *argv[])
bio_setblink(sd_dev, bl_arg, blink);
} else if (func == BIOC_SETSTATE) {
bio_setstate(al_arg);
+ } else if (func == BIOC_DELETERAID && sd_dev != NULL) {
+ bio_deleteraid(sd_dev);
} else if (func & BIOC_CREATERAID || func & BIOC_DEVLIST) {
if (!(func & BIOC_CREATERAID))
errx(1, "need -c parameter");
@@ -209,7 +216,7 @@ usage(void)
"\t[-C flag[,flag,...]] [-c raidlevel] "
"[-H channel:target[.lun]]\n"
"\t[-l special[,special,...]] "
- "[-u channel:target[.lun]] device\n", __progname);
+ "[-u channel:target[.lun]] [-d] device\n", __progname);
exit(1);
}
@@ -707,6 +714,18 @@ bio_createflags(char *lst)
return (flags);
}
+void
+bio_deleteraid(char *dev)
+{
+ struct bioc_deleteraid bd;
+ memset(&bd, 0, sizeof(bd));
+
+ bd.bd_cookie = bd.bd_cookie;
+ strlcpy(bd.bd_dev, dev, sizeof bd.bd_dev);
+ if (ioctl(devh, BIOCDELETERAID, &bd))
+ errx(1, "delete volume %s failed", dev);
+}
+
#define BIOCTL_VIS_NBUF 4
#define BIOCTL_VIS_BUFLEN 80
diff --git a/sys/dev/biovar.h b/sys/dev/biovar.h
index 4054cb90c1d..53158e83fb3 100644
--- a/sys/dev/biovar.h
+++ b/sys/dev/biovar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: biovar.h,v 1.29 2008/06/10 23:44:59 marco Exp $ */
+/* $OpenBSD: biovar.h,v 1.30 2008/06/12 00:19:15 marco Exp $ */
/*
* Copyright (c) 2002 Niklas Hallqvist. All rights reserved.
@@ -188,6 +188,14 @@ struct bioc_createraid {
void *bc_opaque;
};
+#define BIOCDELETERAID _IOWR('B', 39, struct bioc_deleteraid)
+struct bioc_deleteraid {
+ void *bd_cookie;
+ u_int32_t bd_flags;
+#define BIOC_SDCLEARMETA 0x01 /* clear metadata region */
+ char bd_dev[16]; /* device */
+};
+
/* kernel and userspace defines */
#define BIOC_INQ 0x0001
#define BIOC_DISK 0x0002
@@ -196,6 +204,7 @@ struct bioc_createraid {
#define BIOC_BLINK 0x0010
#define BIOC_SETSTATE 0x0020
#define BIOC_CREATERAID 0x0040
+#define BIOC_DELETERAID 0x0080
/* user space defines */
#define BIOC_DEVLIST 0x10000
diff --git a/sys/dev/softraid.c b/sys/dev/softraid.c
index 021920e7c1f..f192ae39fb2 100644
--- a/sys/dev/softraid.c
+++ b/sys/dev/softraid.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid.c,v 1.107 2008/06/11 00:26:18 hshoexer Exp $ */
+/* $OpenBSD: softraid.c,v 1.108 2008/06/12 00:19:15 marco Exp $ */
/*
* Copyright (c) 2007 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org>
@@ -91,6 +91,8 @@ int sr_ioctl_setstate(struct sr_softc *,
struct bioc_setstate *);
int sr_ioctl_createraid(struct sr_softc *,
struct bioc_createraid *, int);
+int sr_ioctl_deleteraid(struct sr_softc *,
+ struct bioc_deleteraid *);
int sr_open_chunks(struct sr_softc *,
struct sr_chunk_head *, dev_t *, int);
int sr_read_meta(struct sr_discipline *);
@@ -423,6 +425,12 @@ sr_scsi_cmd(struct scsi_xfer *xs)
}
}
+ if (sd->sd_deleted) {
+ printf("%s: %s device is being deleted, failing io\n",
+ DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname);
+ goto stuffup;
+ }
+
if ((wu = sr_get_wu(sd)) == NULL) {
DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd no wu\n", DEVNAME(sc));
return (TRY_AGAIN_LATER);
@@ -568,6 +576,9 @@ sr_ioctl(struct device *dev, u_long cmd, caddr_t addr)
rv = sr_ioctl_createraid(sc, (struct bioc_createraid *)addr, 1);
break;
+ case BIOCDELETERAID:
+ rv = sr_ioctl_deleteraid(sc, (struct bioc_deleteraid *)addr);
+ break;
default:
DNPRINTF(SR_D_IOCTL, "invalid ioctl\n");
rv = ENOTTY;
@@ -1024,6 +1035,37 @@ unwind:
}
int
+sr_ioctl_deleteraid(struct sr_softc *sc, struct bioc_deleteraid *dr)
+{
+ struct sr_discipline *sd = NULL;
+ int rv = 1;
+ int i;
+
+ DNPRINTF(SR_D_IOCTL, "%s: sr_ioctl_deleteraid %s\n", DEVNAME(sc),
+ dr->bd_dev);
+
+ for (i = 0; i < SR_MAXSCSIBUS; i++)
+ if (sc->sc_dis[i]) {
+ if (!strncmp(sc->sc_dis[i]->sd_vol.sv_meta.svm_devname, dr->bd_dev,
+ sizeof(sc->sc_dis[i]->sd_vol.sv_meta.svm_devname))) {
+ sd = sc->sc_dis[i];
+ break;
+ }
+ }
+
+ if (sd == NULL)
+ goto bad;
+
+ sd->sd_deleted = 1;
+ sd->sd_meta->ssd_flags = BIOC_SCNOAUTOASSEMBLE;
+ sr_shutdown(sd);
+
+ rv = 0;
+bad:
+ return (rv);
+}
+
+int
sr_open_chunks(struct sr_softc *sc, struct sr_chunk_head *cl, dev_t *dt,
int no_chunk)
{
@@ -1374,6 +1416,8 @@ sr_shutdown_discipline(struct sr_discipline *sd)
s = splbio();
+ shutdownhook_disestablish(sd->sd_shutdownhook);
+
/* make sure there isn't a sync pending and yield */
wakeup(sd);
while (sd->sd_sync || sd->sd_must_flush)
diff --git a/sys/dev/softraidvar.h b/sys/dev/softraidvar.h
index e6d4a8dbea5..93de4e4b6b2 100644
--- a/sys/dev/softraidvar.h
+++ b/sys/dev/softraidvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraidvar.h,v 1.50 2008/06/11 00:26:18 hshoexer Exp $ */
+/* $OpenBSD: softraidvar.h,v 1.51 2008/06/12 00:19:15 marco Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org>
@@ -307,6 +307,8 @@ struct sr_discipline {
int sd_sync;
int sd_must_flush;
+ int sd_deleted;
+
struct device *sd_scsibus_dev;
void (*sd_shutdownhook)(void *);