changeset 22397:740a0229aaf2

11999 installboot: multiple stage1 locations are mismanaged Reviewed by: Jason King <jason.king@joyent.com> Reviewed by: Andy Fiddaman <omnios@citrus-it.co.uk> Approved by: Dan McDonald <danmcd@joyent.com>
author Toomas Soome <tsoome@me.com>
date Tue, 19 Nov 2019 09:04:42 +0200
parents b99fdd27bfbc
children c237145c3351
files usr/src/cmd/boot/installboot/i386/installboot.c
diffstat 1 files changed, 26 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/boot/installboot/i386/installboot.c	Wed Oct 23 13:58:10 2019 +0000
+++ b/usr/src/cmd/boot/installboot/i386/installboot.c	Tue Nov 19 09:04:42 2019 +0200
@@ -453,8 +453,8 @@
 compare_stage1_cb(struct partlist *plist)
 {
 	if (write_vbr) {
-		(void) printf("%s will be written to %s\n", plist->pl_src_name,
-		    plist->pl_devname);
+		(void) printf("%s is newer than one in %s\n",
+		    plist->pl_src_name, plist->pl_devname);
 	}
 	return (write_vbr);
 }
@@ -1993,7 +1993,29 @@
 	struct partlist *mbr, *stage1, *stage2;
 	uuid_t uuid;
 
+	/*
+	 * Create disk uuid. We only need reasonable amount of uniqueness
+	 * to allow biosdev to identify disk based on mbr differences.
+	 */
+	uuid_generate(uuid);
+
 	mbr = stage1 = stage2 = NULL;
+
+	/* First find stage 2. */
+	STAILQ_FOREACH(pl, data->plist, pl_next) {
+		if (pl->pl_type == IB_BBLK_STAGE2) {
+			stage2 = pl;
+
+			/*
+			 * When stage2 needs update, make sure we also
+			 * update stage1.
+			 */
+			if (pl->pl_cb.compare != NULL &&
+			    pl->pl_cb.compare(pl))
+				write_vbr = true;
+			break;
+		}
+	}
 	/*
 	 * Walk list and pick up BIOS boot blocks. EFI boot programs
 	 * can be set in place.
@@ -2005,10 +2027,10 @@
 			break;
 		case IB_BBLK_STAGE1:
 			stage1 = pl;
+			if (stage2 != NULL)
+				prepare_stage1(stage1, stage2, uuid);
 			break;
 		case IB_BBLK_STAGE2:
-			stage2 = pl;
-			/* FALLTHROUGH */
 		case IB_BBLK_EFI:
 			prepare_bootblock(data, pl, update_str);
 			break;
@@ -2021,12 +2043,6 @@
 	if (stage2 == NULL)
 		return;
 
-	/*
-	 * Create disk uuid. We only need reasonable amount of uniqueness
-	 * to allow biosdev to identify disk based on mbr differences.
-	 */
-	uuid_generate(uuid);
-
 	if (mbr != NULL) {
 		prepare_stage1(mbr, stage2, uuid);
 
@@ -2041,10 +2057,6 @@
 			    stage1->pl_device->stage.start;
 		}
 	}
-
-	if (stage1 != NULL) {
-		prepare_stage1(stage1, stage2, uuid);
-	}
 }
 
 /*