diff options
author | 2011-09-19 21:39:31 +0000 | |
---|---|---|
committer | 2011-09-19 21:39:31 +0000 | |
commit | 8fdeb3fd0ef5b99b7535d721ad42d2135acf6844 (patch) | |
tree | 10c696eaff33f0361a774060be80426904638e54 /sys/dev/softraid.c | |
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@
Diffstat (limited to 'sys/dev/softraid.c')
-rw-r--r-- | sys/dev/softraid.c | 55 |
1 files changed, 49 insertions, 6 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); |