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;