Module Name: src Committed By: martin Date: Wed Oct 18 11:44:22 UTC 2023
Modified Files: src/sys/arch/i386/stand/lib [netbsd-10]: biosdisk.c src/sys/dev/raidframe [netbsd-10]: rf_netbsdkintf.c src/sys/rump/librump/rumpkern [netbsd-10]: emul.c Log Message: Pull up following revision(s) (requested by manu in ticket #418): sys/arch/i386/stand/lib/biosdisk.c: revision 1.59 sys/rump/librump/rumpkern/emul.c: revision 1.200 sys/arch/i386/stand/lib/biosdisk.c: revision 1.60 sys/dev/raidframe/rf_netbsdkintf.c: revision 1.416 Align the behavior of different boot methods in RAIDframe We enforce the documented and paritally implemented behavior when looking for the kernel in RAID 1 sets without a partition name given. We search for: - A GPT partition with bootme attribute set - A FFS or LFS patititon - The first partition Fix root search in RAID 1 sets We use the wedge information given by bootstrap, where the kernel was found. This requires src/sys/arch/i386/stand/i386/lib/biosdisk.c 1.59 to work in all cases. Fix build with -DNO_GPT To generate a diff of this commit: cvs rdiff -u -r1.58 -r1.58.4.1 src/sys/arch/i386/stand/lib/biosdisk.c cvs rdiff -u -r1.410.4.2 -r1.410.4.3 src/sys/dev/raidframe/rf_netbsdkintf.c cvs rdiff -u -r1.196 -r1.196.20.1 src/sys/rump/librump/rumpkern/emul.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/i386/stand/lib/biosdisk.c diff -u src/sys/arch/i386/stand/lib/biosdisk.c:1.58 src/sys/arch/i386/stand/lib/biosdisk.c:1.58.4.1 --- src/sys/arch/i386/stand/lib/biosdisk.c:1.58 Tue May 3 10:09:40 2022 +++ src/sys/arch/i386/stand/lib/biosdisk.c Wed Oct 18 11:44:22 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: biosdisk.c,v 1.58 2022/05/03 10:09:40 jmcneill Exp $ */ +/* $NetBSD: biosdisk.c,v 1.58.4.1 2023/10/18 11:44:22 martin Exp $ */ /* * Copyright (c) 1996, 1998 @@ -105,6 +105,7 @@ struct biosdisk { struct biosdisk_ll ll; daddr_t boff; + daddr_t size; char buf[BIOSDISK_BUFSIZE]; #if !defined(NO_DISKLABEL) || !defined(NO_GPT) struct biosdisk_partition part[BIOSDISKNPART]; @@ -327,7 +328,6 @@ guid_is_equal(const struct uuid *a, cons return (memcmp(a, b, sizeof(*a)) == 0 ? true : false); } -#ifndef NO_GPT static void part_name_utf8(const uint16_t *utf16_src, size_t utf16_srclen, char *utf8_dst, size_t utf8_dstlen) @@ -350,7 +350,6 @@ part_name_utf8(const uint16_t *utf16_src return; } -#endif static int check_gpt(struct biosdisk *d, daddr_t rf_offset, daddr_t sector) @@ -666,6 +665,7 @@ read_label(struct biosdisk *d, daddr_t o dflt_lbl.d_npartitions = 8; d->boff = 0; + d->size = 0; if (d->ll.type != BIOSDISK_TYPE_HD) /* No label on floppy and CD */ @@ -1208,7 +1208,7 @@ add_biosdisk_bootinfo(void) #endif #ifndef NO_GPT -static daddr_t +static void raidframe_part_offset(struct biosdisk *d, int part) { struct biosdisk raidframe; @@ -1221,8 +1221,10 @@ raidframe_part_offset(struct biosdisk *d rf_offset = d->part[part].offset + RF_PROTECTED_SECTORS; rf_size = d->part[part].size; - if (read_gpt(&raidframe, rf_offset, rf_size) != 0) - return RF_PROTECTED_SECTORS; + if (read_gpt(&raidframe, rf_offset, rf_size) != 0) { + d->boff += RF_PROTECTED_SECTORS; + return; + } candidate = 0; for (i = 0; i < BIOSDISKNPART; i++) { @@ -1231,12 +1233,20 @@ raidframe_part_offset(struct biosdisk *d if (raidframe.part[i].fstype == FS_UNUSED) continue; #ifndef NO_GPT - if (raidframe.part[i].attr & GPT_ENT_ATTR_BOOTME) + if (raidframe.part[i].attr & GPT_ENT_ATTR_BOOTME) { candidate = i; + break; + } #endif + if (raidframe.part[i].fstype == FS_BSDFFS || + raidframe.part[i].fstype == FS_BSDLFS) { + if (candidate == 0) + candidate = i; + } } - return RF_PROTECTED_SECTORS + raidframe.part[candidate].offset; + d->boff += RF_PROTECTED_SECTORS + raidframe.part[candidate].offset; + d->size = raidframe.part[candidate].size; } #endif @@ -1285,17 +1295,18 @@ biosdisk_open(struct open_file *f, ...) } d->boff = d->part[partition].offset; + d->size = d->part[partition].size; if (d->part[partition].fstype == FS_RAID) #ifndef NO_GPT - d->boff += raidframe_part_offset(d, partition); + raidframe_part_offset(d, partition); #else d->boff += RF_PROTECTED_SECTORS; #endif #ifdef _STANDALONE - bi_wedge.startblk = d->part[partition].offset; - bi_wedge.nblks = d->part[partition].size; + bi_wedge.startblk = d->boff; + bi_wedge.nblks = d->size; #endif nolabel: @@ -1389,6 +1400,8 @@ next_disk: #ifndef NO_RAIDFRAME for (i = 0; i < raidframe_count; i++) { + int first_bootme = -1; + int first_ffs = -1; int candidate = -1; if ((d = alloc_biosdisk(raidframe[i].biosdev)) == NULL) { @@ -1402,12 +1415,20 @@ next_disk: goto next_raidframe; for (part = 0; part < BIOSDISKNPART; part++) { - bool bootme = d->part[part].attr & GPT_ENT_ATTR_BOOTME; if (d->part[part].size == 0) continue; if (d->part[part].fstype == FS_UNUSED) continue; + if (first_bootme == -1 && + d->part[part].attr & GPT_ENT_ATTR_BOOTME) + first_bootme = part; + + if (first_ffs == -1 && + (d->part[part].fstype == FS_BSDFFS || + d->part[part].fstype == FS_BSDLFS)) + first_ffs = part; + if (d->part[part].part_name != NULL && strcmp(d->part[part].part_name, name) == 0) { *biosdev = raidframe[i].biosdev; @@ -1418,11 +1439,13 @@ next_disk: ret = 0; goto out; } - if (strcmp(raidframe[i].parent_name, name) == 0) { - if (candidate == -1 || bootme) - candidate = part; - continue; - } + } + + if (strcmp(raidframe[i].parent_name, name) == 0) { + if (first_bootme != -1) + candidate = first_bootme; + else if (first_ffs != -1) + candidate = first_ffs; } if (candidate != -1) { @@ -1514,6 +1537,10 @@ next_disk: } for (i = 0; i < raidframe_count; i++) { + int first_bootme = -1; + int first_ffs = -1; + int candidate = -1; + if (raidframe[i].last_unit != target_unit) continue; @@ -1532,6 +1559,18 @@ next_disk: continue; if (d->part[part].fstype == FS_UNUSED) continue; + +#ifndef NO_GPT + if (first_bootme == -1 && + d->part[part].attr & GPT_ENT_ATTR_BOOTME) + first_bootme = part; +#endif + + if (first_ffs == -1 && + (d->part[part].fstype == FS_BSDFFS || + d->part[part].fstype == FS_BSDLFS)) + first_ffs = part; + if (part == target_part) { *biosdev = raidframe[i].biosdev; *offset = raidframe[i].offset @@ -1542,6 +1581,22 @@ next_disk: goto out; } } + + if (first_bootme != -1) + candidate = first_bootme; + else if (first_ffs != -1) + candidate = first_ffs; + + if (candidate != -1) { + *biosdev = raidframe[i].biosdev; + *offset = raidframe[i].offset + + RF_PROTECTED_SECTORS + + d->part[candidate].offset; + *size = d->part[candidate].size; + ret = 0; + goto out; + } + next_raidframe: dealloc_biosdisk(d); d = NULL; @@ -1567,11 +1622,11 @@ biosdisk_open_name(struct open_file *f, int error = -1; #ifndef NO_GPT - if (strstr(name, "NAME=") == name) + if (error && strstr(name, "NAME=") == name) error = biosdisk_find_name(name, &biosdev, &offset, &size); #endif #ifndef NO_RAIDFRAME - if (strstr(name, "raid") == name) + if (error && strstr(name, "raid") == name) error = biosdisk_find_raid(name, &biosdev, &offset, &size); #endif Index: src/sys/dev/raidframe/rf_netbsdkintf.c diff -u src/sys/dev/raidframe/rf_netbsdkintf.c:1.410.4.2 src/sys/dev/raidframe/rf_netbsdkintf.c:1.410.4.3 --- src/sys/dev/raidframe/rf_netbsdkintf.c:1.410.4.2 Mon Sep 18 18:57:33 2023 +++ src/sys/dev/raidframe/rf_netbsdkintf.c Wed Oct 18 11:44:22 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: rf_netbsdkintf.c,v 1.410.4.2 2023/09/18 18:57:33 martin Exp $ */ +/* $NetBSD: rf_netbsdkintf.c,v 1.410.4.3 2023/10/18 11:44:22 martin Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2008-2011 The NetBSD Foundation, Inc. @@ -101,7 +101,7 @@ ***********************************************************/ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.410.4.2 2023/09/18 18:57:33 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.410.4.3 2023/10/18 11:44:22 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_raid_autoconfig.h" @@ -158,6 +158,8 @@ int rf_kdebug_level = 0; #define db1_printf(a) { } #endif /* DEBUG */ +#define DEVICE_XNAME(dev) dev ? device_xname(dev) : "null" + #if (RF_INCLUDE_PARITY_DECLUSTERING_DS > 0) static rf_declare_mutex2(rf_sparet_wait_mutex); static rf_declare_cond2(rf_sparet_wait_cv); @@ -524,6 +526,134 @@ rf_rescan(void) return 0; } +/* + * Example setup: + * dk1 at wd0: "raid@wd0", 171965 blocks at 32802, type: raidframe + * dk3 at wd1: "raid@wd1", 171965 blocks at 32802, type: raidframz + * raid1: Components: /dev/dk1 /dev/dk3 + * dk4 at raid1: "empty@raid1", 8192 blocks at 34, type: msdos + * dk5 at raid1: "root@raid1", 163517 blocks at 8226, type: ffs + * + * If booted from wd0, booted_device will be + * disk wd0, startblk = 41092, nblks = 163517 + * + * That is, dk5 with startblk computed from the beginning of wd0 + * instead of beginning of raid1: + * 32802 + 64 (RF_PROTECTED_SECTORS) + 8226 = 41092 + * + * In order to find the boot wedge, we must iterate on each component, + * find its offset from disk beginning, abd look for the boot wedge with + * startblck adjusted. + */ +static device_t +rf_find_bootwedge(struct raid_softc *rsc) +{ + RF_Raid_t *r = &rsc->sc_r; + const char *bootname; + size_t len; + device_t rdev = NULL; + + if (booted_device == NULL) + goto out; + + bootname = device_xname(booted_device); + len = strlen(bootname); + + aprint_debug("%s: booted_device %s, startblk = %"PRId64", " + "nblks = %"PRId64"\n", __func__, + bootname, booted_startblk, booted_nblks); + + for (int col = 0; col < r->numCol; col++) { + const char *devname = r->Disks[col].devname; + const char *parent; + struct disk *dk; + u_int nwedges; + struct dkwedge_info *dkwi; + struct dkwedge_list dkwl; + size_t dkwi_len; + int i; + + devname += sizeof("/dev/") - 1; + if (strncmp(devname, "dk", 2) != 0) + continue; + + parent = dkwedge_get_parent_name(r->Disks[col].dev); + if (parent == NULL) { + aprint_debug("%s: cannot find parent for " + "component /dev/%s", __func__, devname); + continue; + } + + if (strncmp(parent, bootname, len) != 0) + continue; + + aprint_debug("%s: looking up wedge %s in device %s\n", + __func__, devname, parent); + + dk = disk_find(parent); + nwedges = dk->dk_nwedges; + dkwi_len = sizeof(*dkwi) * nwedges; + dkwi = RF_Malloc(dkwi_len); + + dkwl.dkwl_buf = dkwi; + dkwl.dkwl_bufsize = dkwi_len; + dkwl.dkwl_nwedges = 0; + dkwl.dkwl_ncopied = 0; + + if (dkwedge_list(dk, &dkwl, curlwp) == 0) { + daddr_t startblk; + + for (i = 0; i < dkwl.dkwl_ncopied; i++) { + if (strcmp(dkwi[i].dkw_devname, devname) == 0) + break; + } + + KASSERT(i < dkwl.dkwl_ncopied); + + aprint_debug("%s: wedge %s, " + "startblk = %"PRId64", " + "nblks = %"PRId64"\n", + __func__, + dkwi[i].dkw_devname, + dkwi[i].dkw_offset, + dkwi[i].dkw_size); + + startblk = booted_startblk + - dkwi[i].dkw_offset + - RF_PROTECTED_SECTORS; + + aprint_debug("%s: looking for wedge in %s, " + "startblk = %"PRId64", " + "nblks = %"PRId64"\n", + __func__, + DEVICE_XNAME(rsc->sc_dksc.sc_dev), + startblk, booted_nblks); + + rdev = dkwedge_find_partition(rsc->sc_dksc.sc_dev, + startblk, + booted_nblks); + if (rdev) { + aprint_debug("%s: root candidate wedge %s " + "shifted from %s\n", __func__, + device_xname(rdev), + dkwi[i].dkw_devname); + goto done; + } else { + aprint_debug("%s: not found\n", __func__); + } + } + + aprint_debug("%s: nothing found for col %d\n", __func__, col); +done: + RF_Free(dkwi, dkwi_len); + } + +out: + if (!rdev) + aprint_debug("%s: nothing found\n", __func__); + + return rdev; +} static void rf_buildroothack(RF_ConfigSet_t *config_sets) @@ -587,49 +717,33 @@ rf_buildroothack(RF_ConfigSet_t *config_ } /* we found something bootable... */ - - /* - * XXX: The following code assumes that the root raid - * is the first ('a') partition. This is about the best - * we can do with a BSD disklabel, but we might be able - * to do better with a GPT label, by setting a specified - * attribute to indicate the root partition. We can then - * stash the partition number in the r->root_partition - * high bits (the bottom 2 bits are already used). For - * now we just set booted_partition to 0 when we override - * root. - */ if (num_root == 1) { - device_t candidate_root; + device_t candidate_root = NULL; dksc = &rsc->sc_dksc; + if (dksc->sc_dkdev.dk_nwedges != 0) { - char cname[sizeof(cset->ac->devname)]; - /* XXX: assume partition 'a' first */ - snprintf(cname, sizeof(cname), "%s%c", - device_xname(dksc->sc_dev), 'a'); - candidate_root = dkwedge_find_by_wname(cname); - aprint_debug("%s: candidate wedge root=%s\n", __func__, - cname); + + /* Find the wedge we booted from */ + candidate_root = rf_find_bootwedge(rsc); + + /* Try first partition */ if (candidate_root == NULL) { - /* - * If that is not found, because we don't use - * disklabel, return the first dk child - * XXX: we can skip the 'a' check above - * and always do this... - */ size_t i = 0; candidate_root = dkwedge_find_by_parent( device_xname(dksc->sc_dev), &i); } - aprint_debug("%s: candidate wedge root=%p\n", __func__, - candidate_root); - } else + aprint_debug("%s: candidate wedge root %s\n", + __func__, DEVICE_XNAME(candidate_root)); + } else { candidate_root = dksc->sc_dev; - aprint_debug("%s: candidate root=%p booted_device=%p " - "root_partition=%d contains_boot=%d\n", - __func__, candidate_root, booted_device, - rsc->sc_r.root_partition, + } + + aprint_debug("%s: candidate root = %s, booted_device = %s, " + "root_partition = %d, contains_boot=%d\n", + __func__, DEVICE_XNAME(candidate_root), + DEVICE_XNAME(booted_device), rsc->sc_r.root_partition, rf_containsboot(&rsc->sc_r, booted_device)); + /* XXX the check for booted_device == NULL can probably be * dropped, now that rf_containsboot handles that case. */ @@ -639,12 +753,12 @@ rf_buildroothack(RF_ConfigSet_t *config_ booted_device = candidate_root; booted_method = "raidframe/single"; booted_partition = 0; /* XXX assume 'a' */ - aprint_debug("%s: set booted_device=%s(%p)\n", __func__, - device_xname(booted_device), booted_device); + aprint_debug("%s: set booted_device = %s\n", __func__, + DEVICE_XNAME(booted_device)); } } else if (num_root > 1) { - aprint_debug("%s: many roots=%d, %p\n", __func__, num_root, - booted_device); + aprint_debug("%s: many roots=%d, %s\n", __func__, num_root, + DEVICE_XNAME(booted_device)); /* * Maybe the MD code can help. If it cannot, then Index: src/sys/rump/librump/rumpkern/emul.c diff -u src/sys/rump/librump/rumpkern/emul.c:1.196 src/sys/rump/librump/rumpkern/emul.c:1.196.20.1 --- src/sys/rump/librump/rumpkern/emul.c:1.196 Thu Apr 30 03:28:19 2020 +++ src/sys/rump/librump/rumpkern/emul.c Wed Oct 18 11:44:22 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: emul.c,v 1.196 2020/04/30 03:28:19 riastradh Exp $ */ +/* $NetBSD: emul.c,v 1.196.20.1 2023/10/18 11:44:22 martin Exp $ */ /* * Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: emul.c,v 1.196 2020/04/30 03:28:19 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: emul.c,v 1.196.20.1 2023/10/18 11:44:22 martin Exp $"); #include <sys/param.h> #include <sys/cprng.h> @@ -83,6 +83,8 @@ int mem_no = 2; device_t booted_device; device_t booted_wedge; +daddr_t booted_startblk; +uint64_t booted_nblks; int booted_partition; const char *booted_method;