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;
 

Reply via email to