Module Name: src Committed By: manu Date: Thu Sep 28 15:50:24 UTC 2023
Modified Files: src/sys/dev/raidframe: rf_netbsdkintf.c src/sys/rump/librump/rumpkern: emul.c Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.415 -r1.416 src/sys/dev/raidframe/rf_netbsdkintf.c cvs rdiff -u -r1.199 -r1.200 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/dev/raidframe/rf_netbsdkintf.c diff -u src/sys/dev/raidframe/rf_netbsdkintf.c:1.415 src/sys/dev/raidframe/rf_netbsdkintf.c:1.416 --- src/sys/dev/raidframe/rf_netbsdkintf.c:1.415 Mon Sep 25 21:59:38 2023 +++ src/sys/dev/raidframe/rf_netbsdkintf.c Thu Sep 28 15:50:23 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: rf_netbsdkintf.c,v 1.415 2023/09/25 21:59:38 oster Exp $ */ +/* $NetBSD: rf_netbsdkintf.c,v 1.416 2023/09/28 15:50:23 manu 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.415 2023/09/25 21:59:38 oster Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.416 2023/09/28 15:50:23 manu Exp $"); #ifdef _KERNEL_OPT #include "opt_raid_autoconfig.h" @@ -157,6 +157,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); @@ -522,6 +524,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) @@ -585,49 +715,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. */ @@ -637,12 +751,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.199 src/sys/rump/librump/rumpkern/emul.c:1.200 --- src/sys/rump/librump/rumpkern/emul.c:1.199 Sat Apr 22 13:53:44 2023 +++ src/sys/rump/librump/rumpkern/emul.c Thu Sep 28 15:50:24 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: emul.c,v 1.199 2023/04/22 13:53:44 riastradh Exp $ */ +/* $NetBSD: emul.c,v 1.200 2023/09/28 15:50:24 manu 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.199 2023/04/22 13:53:44 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: emul.c,v 1.200 2023/09/28 15:50:24 manu 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;