Module Name: src
Committed By: manu
Date: Thu Sep 28 15:46:55 UTC 2023
Modified Files:
src/sys/arch/i386/stand/lib: biosdisk.c
Log Message:
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
To generate a diff of this commit:
cvs rdiff -u -r1.58 -r1.59 src/sys/arch/i386/stand/lib/biosdisk.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.59
--- 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 Thu Sep 28 15:46:55 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: biosdisk.c,v 1.58 2022/05/03 10:09:40 jmcneill Exp $ */
+/* $NetBSD: biosdisk.c,v 1.59 2023/09/28 15:46:55 manu 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];
@@ -666,6 +667,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 +1210,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 +1223,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 +1235,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 +1297,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 +1402,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 +1417,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 +1441,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 +1539,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 +1561,15 @@ next_disk:
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 (part == target_part) {
*biosdev = raidframe[i].biosdev;
*offset = raidframe[i].offset
@@ -1542,6 +1580,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 +1621,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