-.\" $OpenBSD: bioctl.8,v 1.108 2020/10/30 13:55:48 schwarze Exp $
+.\" $OpenBSD: bioctl.8,v 1.109 2021/02/08 11:20:03 stsp Exp $
.\"
.\" Copyright (c) 2004, 2005 Marco Peereboom
.\"
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd $Mdocdate: October 30 2020 $
+.Dd $Mdocdate: February 8 2021 $
.Dt BIOCTL 8
.Os
.Sh NAME
.It Cm c
CONCAT:
A concatenating discipline.
+.It Cm 1C
+RAID 1 + CRYPTO:
+An encrypting and mirroring discipline.
.El
.Pp
The CONCAT discipline requires a minimum of one chunk, RAID 0 and RAID 1
of three chunks and the CRYPTO discipline requires exactly one chunk to
be provided via
.Fl l .
+.Pp
+The RAID 1C discipline requires a minimum of two chunks when a new volume
+is created, and a minimum of one chunk when an existing volume is assembled.
+Missing RAID 1C chunks will be marked as offline and must be rebuilt before
+they become part of the array again.
.It Fl d
Detach volume specified by
.Ar device .
-/* $OpenBSD: bioctl.c,v 1.145 2020/10/30 13:55:48 schwarze Exp $ */
+/* $OpenBSD: bioctl.c,v 1.146 2021/02/08 11:20:03 stsp Exp $ */
/*
* Copyright (c) 2004, 2005 Marco Peereboom
break;
case 'c': /* create */
func |= BIOC_CREATERAID;
- if (isdigit((unsigned char)*optarg)) {
+ if (strcmp(optarg, "1C") == 0) {
+ cr_level = 0x1C;
+ } else if (isdigit((unsigned char)*optarg)) {
cr_level = strtonum(optarg, 0, 10, &errstr);
if (errstr != NULL)
errx(1, "Invalid RAID level");
volname, status, size, bv.bv_dev,
percent, seconds);
break;
+ case 0x1C:
+ printf("%11s %-10s %14s %-7s RAID%X%s%s %s\n",
+ volname, status, size, bv.bv_dev,
+ bv.bv_level, percent, seconds, cache);
+ break;
default:
printf("%11s %-10s %14s %-7s RAID%u%s%s %s\n",
volname, status, size, bv.bv_dev,
min_disks = 3;
break;
case 'C':
+ case 0x1C:
min_disks = 1;
break;
case 'c':
create.bc_flags = BIOC_SCDEVT | cflags;
create.bc_key_disk = NODEV;
- if (level == 'C' && key_disk == NULL) {
+ if ((level == 'C' || level == 0x1C) && key_disk == NULL) {
memset(&kdfinfo, 0, sizeof(kdfinfo));
memset(&kdfhint, 0, sizeof(kdfhint));
create.bc_opaque_size = sizeof(kdfinfo);
create.bc_opaque_flags = BIOC_SOIN;
- } else if (level == 'C' && key_disk != NULL) {
+ } else if ((level == 'C' || level == 0x1C) && key_disk != NULL) {
/* Get device number for key disk. */
fd = opendev(key_disk, O_RDONLY, OPENDEV_BLCK, NULL);
-# $OpenBSD: files,v 1.693 2021/01/28 14:53:20 visa Exp $
+# $OpenBSD: files,v 1.694 2021/02/08 11:20:03 stsp Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
file dev/softraid_raid1.c softraid
file dev/softraid_raid5.c softraid
file dev/softraid_raid6.c softraid
+file dev/softraid_raid1c.c softraid & crypto
# SPD Memory EEPROM
device spdmem
-/* $OpenBSD: softraid.c,v 1.417 2020/12/16 18:16:34 cheloha Exp $ */
+/* $OpenBSD: softraid.c,v 1.418 2021/02/08 11:20:03 stsp Exp $ */
/*
* Copyright (c) 2007, 2008, 2009 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org>
* key disk...
*/
bcr.bc_key_disk = NODEV;
- if (bv->sbv_level == 'C') {
+ if (bv->sbv_level == 'C' || bv->sbv_level == 0x1C) {
SLIST_FOREACH(bc, &kdh, sbc_link) {
if (bcmp(&bc->sbc_metadata->ssdi.ssd_uuid,
&bv->sbv_uuid,
bcr.bc_flags = BIOC_SCDEVT |
(bv->sbv_flags & BIOC_SCNOAUTOASSEMBLE);
- if (bv->sbv_level == 'C' &&
+ if ((bv->sbv_level == 'C' || bv->sbv_level == 0x1C) &&
bcmp(&sr_bootuuid, &bv->sbv_uuid, sizeof(sr_bootuuid)) == 0)
data = sr_bootkey;
bv->bv_nodisk = sd->sd_meta->ssdi.ssd_chunk_no;
#ifdef CRYPTO
- if (sd->sd_meta->ssdi.ssd_level == 'C' &&
+ if ((sd->sd_meta->ssdi.ssd_level == 'C' ||
+ sd->sd_meta->ssdi.ssd_level == 0x1C) &&
sd->mds.mdd_crypto.key_disk != NULL)
bv->bv_nodisk++;
#endif
src = sd->sd_vol.sv_chunks[bd->bd_diskid];
#ifdef CRYPTO
else if (bd->bd_diskid == sd->sd_meta->ssdi.ssd_chunk_no &&
- sd->sd_meta->ssdi.ssd_level == 'C' &&
+ (sd->sd_meta->ssdi.ssd_level == 'C' ||
+ sd->sd_meta->ssdi.ssd_level == 0x1C) &&
sd->mds.mdd_crypto.key_disk != NULL)
src = sd->mds.mdd_crypto.key_disk;
#endif
} else {
/* Ensure we are assembling the correct # of chunks. */
- if (sd->sd_meta->ssdi.ssd_chunk_no != no_chunk) {
+ if (bc->bc_level == 0x1C &&
+ sd->sd_meta->ssdi.ssd_chunk_no > no_chunk) {
+ sr_warn(sc, "trying to bring up %s degraded",
+ sd->sd_meta->ssd_devname);
+ } else if (sd->sd_meta->ssdi.ssd_chunk_no != no_chunk) {
sr_error(sc, "volume chunk count does not match metadata "
"chunk count");
goto unwind;
case 'C':
sr_crypto_discipline_init(sd);
break;
+ case 0x1C:
+ sr_raid1c_discipline_init(sd);
+ break;
#endif
case 'c':
sr_concat_discipline_init(sd);
-/* $OpenBSD: softraid_crypto.c,v 1.139 2020/07/13 00:06:22 kn Exp $ */
+/* $OpenBSD: softraid_crypto.c,v 1.140 2021/02/08 11:20:04 stsp Exp $ */
/*
* Copyright (c) 2007 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2008 Hans-Joerg Hoexer <hshoexer@openbsd.org>
#include <dev/softraidvar.h>
-/*
- * The per-I/O data that we need to preallocate. We cannot afford to allow I/O
- * to start failing when memory pressure kicks in. We can store this in the WU
- * because we assert that only one ccb per WU will ever be active.
- */
-struct sr_crypto_wu {
- struct sr_workunit cr_wu; /* Must be first. */
- struct uio cr_uio;
- struct iovec cr_iov;
- struct cryptop *cr_crp;
- void *cr_dmabuf;
-};
-
-
struct sr_crypto_wu *sr_crypto_prepare(struct sr_workunit *, int);
int sr_crypto_create_keys(struct sr_discipline *);
int sr_crypto_get_kdf(struct bioc_createraid *,
struct sr_crypto_kdfinfo *, struct sr_crypto_kdfinfo *);
int sr_crypto_create(struct sr_discipline *,
struct bioc_createraid *, int, int64_t);
+int sr_crypto_meta_create(struct sr_discipline *,
+ struct bioc_createraid *);
int sr_crypto_assemble(struct sr_discipline *,
struct bioc_createraid *, int, void *);
int sr_crypto_alloc_resources(struct sr_discipline *);
sr_crypto_create(struct sr_discipline *sd, struct bioc_createraid *bc,
int no_chunk, int64_t coerced_size)
{
- struct sr_meta_opt_item *omi;
- int rv = EINVAL;
+ int rv = EINVAL;
if (no_chunk != 1) {
sr_error(sd->sd_sc, "%s requires exactly one chunk",
sd->sd_name);
- goto done;
+ return (rv);
}
- if (coerced_size > SR_CRYPTO_MAXSIZE) {
+ sd->sd_meta->ssdi.ssd_size = coerced_size;
+
+ rv = sr_crypto_meta_create(sd, bc);
+ if (rv)
+ return (rv);
+
+ sd->sd_max_ccb_per_wu = no_chunk;
+ return (0);
+}
+
+int
+sr_crypto_meta_create(struct sr_discipline *sd, struct bioc_createraid *bc)
+{
+ struct sr_meta_opt_item *omi;
+ int rv = EINVAL;
+
+ if (sd->sd_meta->ssdi.ssd_size > SR_CRYPTO_MAXSIZE) {
sr_error(sd->sd_sc, "%s exceeds maximum size (%lli > %llu)",
- sd->sd_name, coerced_size, SR_CRYPTO_MAXSIZE);
+ sd->sd_name, sd->sd_meta->ssdi.ssd_size,
+ SR_CRYPTO_MAXSIZE);
goto done;
}
if (!(bc->bc_flags & BIOC_SCNOAUTOASSEMBLE) && bc->bc_key_disk == NODEV)
goto done;
- sd->sd_meta->ssdi.ssd_size = coerced_size;
-
sr_crypto_create_keys(sd);
- sd->sd_max_ccb_per_wu = no_chunk;
-
rv = 0;
done:
return (rv);
struct sr_crypto_wu *crwu;
int s;
+ if (ISSET(wu->swu_flags, SR_WUF_REBUILD)) /* RAID 1C */
+ return;
+
/* If this was a successful read, initiate decryption of the data. */
if (ISSET(xs->flags, SCSI_DATA_IN) && xs->error == XS_NOERROR) {
crwu = sr_crypto_prepare(wu, 0);
-/* $OpenBSD: softraidvar.h,v 1.171 2020/07/22 13:16:04 krw Exp $ */
+/* $OpenBSD: softraidvar.h,v 1.172 2021/02/08 11:20:04 stsp Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org>
TAILQ_HEAD(sr_crypto_wu_head, sr_crypto_wu);
#define SR_CRYPTO_NOWU 16
+/*
+ * The per-I/O data that we need to preallocate. We cannot afford to allow I/O
+ * to start failing when memory pressure kicks in. We can store this in the WU
+ * because we assert that only one ccb per WU will ever be active during crypto.
+ */
+struct sr_crypto_wu {
+ struct sr_workunit cr_wu; /* Must be first. */
+ struct uio cr_uio;
+ struct iovec cr_iov;
+ struct cryptop *cr_crp;
+ void *cr_dmabuf;
+};
+
struct sr_crypto {
struct sr_meta_crypto *scr_meta;
struct sr_chunk *key_disk;
u_int8_t scr_key[SR_CRYPTO_MAXKEYS][SR_CRYPTO_KEYBYTES];
u_int8_t scr_maskkey[SR_CRYPTO_MAXKEYBYTES];
u_int64_t scr_sid[SR_CRYPTO_MAXKEYS];
+
+ struct sr_raid1 scr_raid1; /* for RAID1C */
};
#define SR_CONCAT_NOWU 16
struct sr_concat {
};
+/* RAID 1C */
+#define SR_RAID1C_NOWU 16
+/* Uses sr_crypto */
+
struct sr_chunk {
struct sr_meta_chunk src_meta; /* chunk meta data */
/* SR_MD_RAID4 was 7. */
#define SR_MD_RAID6 8
#define SR_MD_CONCAT 9
+#define SR_MD_RAID1C 10
char sd_name[10]; /* human readable dis name */
u_int16_t sd_target; /* scsibus target discipline uses */
void sr_raid6_discipline_init(struct sr_discipline *);
void sr_crypto_discipline_init(struct sr_discipline *);
void sr_concat_discipline_init(struct sr_discipline *);
+void sr_raid1c_discipline_init(struct sr_discipline *);
/* Crypto discipline hooks. */
int sr_crypto_get_kdf(struct bioc_createraid *,