diff options
author | 2011-09-19 21:39:31 +0000 | |
---|---|---|
committer | 2011-09-19 21:39:31 +0000 | |
commit | 8fdeb3fd0ef5b99b7535d721ad42d2135acf6844 (patch) | |
tree | 10c696eaff33f0361a774060be80426904638e54 | |
parent | Print 64 bit values with %ll to get a meaningful message at attach time. (diff) | |
download | wireguard-openbsd-8fdeb3fd0ef5b99b7535d721ad42d2135acf6844.tar.xz wireguard-openbsd-8fdeb3fd0ef5b99b7535d721ad42d2135acf6844.zip |
When installboot is run on a softraid volume, add boot optional metadata
to store the DUID of the softraid volume and each of the chunks that it
is assembled from. This allows us to correctly identify the root disk.
ok deraadt@
-rw-r--r-- | sys/dev/softraid.c | 55 | ||||
-rw-r--r-- | sys/dev/softraidvar.h | 7 |
2 files changed, 54 insertions, 8 deletions
diff --git a/sys/dev/softraid.c b/sys/dev/softraid.c index 931037d94be..9a5dd70c291 100644 --- a/sys/dev/softraid.c +++ b/sys/dev/softraid.c @@ -1,4 +1,4 @@ -/* $OpenBSD: softraid.c,v 1.249 2011/09/19 14:55:10 jsing Exp $ */ +/* $OpenBSD: softraid.c,v 1.250 2011/09/19 21:39:31 jsing Exp $ */ /* * Copyright (c) 2007, 2008, 2009 Marco Peereboom <marco@peereboom.us> * Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org> @@ -1497,6 +1497,7 @@ sr_meta_native_probe(struct sr_softc *sc, struct sr_chunk *ch_entry) DEVNAME(sc), devname); goto unwind; } + bcopy(label.d_uid, ch_entry->src_duid, sizeof(ch_entry->src_duid)); /* make sure the partition is of the right type */ if (label.d_partitions[part].p_fstype != FS_RAID) { @@ -3307,7 +3308,11 @@ sr_ioctl_installboot(struct sr_softc *sc, struct bioc_installboot *bb) void *bootblk = NULL, *bootldr = NULL; struct sr_discipline *sd = NULL; struct sr_chunk *chunk; + struct sr_meta_opt_item *omi; + struct sr_meta_boot *sbm; + struct disk *dk; u_int32_t bbs, bls; + u_char duid[8]; int rv = EINVAL; int i; @@ -3327,6 +3332,18 @@ sr_ioctl_installboot(struct sr_softc *sc, struct bioc_installboot *bb) if (sd == NULL) goto done; + bzero(duid, sizeof(duid)); + TAILQ_FOREACH(dk, &disklist, dk_link) + if (!strncmp(dk->dk_name, bb->bb_dev, sizeof(bb->bb_dev))) + break; + if (dk == NULL || dk->dk_label == NULL || + bcmp(dk->dk_label->d_uid, &duid, sizeof(duid)) == 0) { + printf("%s: failed to get DUID for softraid volume!\n", + DEVNAME(sd->sd_sc)); + goto done; + } + bcopy(dk->dk_label->d_uid, duid, sizeof(duid)); + /* Ensure that boot storage area is large enough. */ if (sd->sd_meta->ssd_data_offset < (SR_BOOT_OFFSET + SR_BOOT_SIZE)) { printf("%s: insufficient boot storage!\n", DEVNAME(sd->sd_sc)); @@ -3351,10 +3368,40 @@ sr_ioctl_installboot(struct sr_softc *sc, struct bioc_installboot *bb) if (copyin(bb->bb_bootldr, bootldr, bb->bb_bootldr_size) != 0) goto done; + /* Create or update optional meta for bootable volumes. */ + SLIST_FOREACH(omi, &sd->sd_meta_opt, omi_link) + if (omi->omi_som->som_type == SR_OPT_BOOT) + break; + if (omi == NULL) { + omi = malloc(sizeof(struct sr_meta_opt_item), M_DEVBUF, + M_WAITOK | M_ZERO); + omi->omi_som = malloc(sizeof(struct sr_meta_crypto), M_DEVBUF, + M_WAITOK | M_ZERO); + omi->omi_som->som_type = SR_OPT_BOOT; + omi->omi_som->som_length = sizeof(struct sr_meta_boot); + SLIST_INSERT_HEAD(&sd->sd_meta_opt, omi, omi_link); + sd->sd_meta->ssdi.ssd_opt_no++; + } + sbm = (struct sr_meta_boot *)omi->omi_som; + + bcopy(duid, sbm->sbm_root_duid, sizeof(sbm->sbm_root_duid)); + sbm->sbm_bootblk_size = bbs; + sbm->sbm_bootldr_size = bls; + + DNPRINTF(SR_D_IOCTL, "sr_ioctl_installboot: root duid is " + "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx\n", + sbm->sbm_root_duid[0], sbm->sbm_root_duid[1], + sbm->sbm_root_duid[2], sbm->sbm_root_duid[3], + sbm->sbm_root_duid[4], sbm->sbm_root_duid[5], + sbm->sbm_root_duid[6], sbm->sbm_root_duid[7]); + /* Save boot block and boot loader to each chunk. */ for (i = 0; i < sd->sd_meta->ssdi.ssd_chunk_no; i++) { chunk = sd->sd_vol.sv_chunks[i]; + if (i < SR_MAX_BOOT_DISKS) + bcopy(chunk->src_duid, &sbm->sbm_boot_duid[i], + sizeof(sbm->sbm_boot_duid[i])); /* Save boot blocks. */ DNPRINTF(SR_D_IOCTL, @@ -3383,12 +3430,8 @@ sr_ioctl_installboot(struct sr_softc *sc, struct bioc_installboot *bb) /* XXX - Install boot block on disk - MD code. */ - /* Save boot details in metadata. */ + /* Mark volume as bootable and save metadata. */ sd->sd_meta->ssdi.ssd_vol_flags |= BIOC_SCBOOTABLE; - - /* XXX - Store size of boot block/loader in optional metadata. */ - - /* Save metadata. */ if (sr_meta_save(sd, SR_META_DIRTY)) { printf("%s: could not save metadata to %s\n", DEVNAME(sc), chunk->src_devname); diff --git a/sys/dev/softraidvar.h b/sys/dev/softraidvar.h index a53f55adada..63d64a9231a 100644 --- a/sys/dev/softraidvar.h +++ b/sys/dev/softraidvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: softraidvar.h,v 1.108 2011/09/18 19:40:49 jsing Exp $ */ +/* $OpenBSD: softraidvar.h,v 1.109 2011/09/19 21:39:31 jsing Exp $ */ /* * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us> * Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org> @@ -174,11 +174,13 @@ struct sr_meta_crypto { #define chk_hmac_sha1 _scm_chk.chk_hmac_sha1 } __packed; +#define SR_MAX_BOOT_DISKS 16 struct sr_meta_boot { struct sr_meta_opt_hdr sbm_hdr; - u_int64_t sbm_root_uid; u_int32_t sbm_bootblk_size; u_int32_t sbm_bootldr_size; + u_char sbm_root_duid[8]; + u_char sbm_boot_duid[SR_MAX_BOOT_DISKS][8]; } __packed; struct sr_meta_keydisk { @@ -451,6 +453,7 @@ struct sr_chunk { /* helper members before metadata makes it onto the chunk */ int src_meta_ondisk;/* set when meta is on disk */ char src_devname[32]; + u_char src_duid[8]; /* Chunk disklabel UID. */ int64_t src_size; /* in blocks */ SLIST_ENTRY(sr_chunk) src_link; |