changeset 10568:05d6365b5963

6880217 installgrub fails to configure GRUB menu for logical/extended partition
author Vikram Hegde <Vikram.Hegde@Sun.COM>
date Mon, 14 Sep 2009 21:48:21 -0700
parents f8c0a7fe6191
children 4d3eb0bc0c83
files usr/src/cmd/boot/installgrub/installgrub.c usr/src/cmd/boot/installgrub/message.h
diffstat 2 files changed, 104 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/boot/installgrub/installgrub.c	Mon Sep 14 21:48:22 2009 -0700
+++ b/usr/src/cmd/boot/installgrub/installgrub.c	Mon Sep 14 21:48:21 2009 -0700
@@ -228,11 +228,13 @@
 get_start_sector(int fd)
 {
 	static unsigned int start_sect = 0;
-	uint32_t secnum, numsec;
-	int i, pno, rval, ext_sol_part_found = 0;
+	uint32_t secnum = 0, numsec = 0;
+	int i, pno, rval, log_part = 0;
 	struct mboot *mboot;
 	struct ipart *part;
 	ext_part_t *epp;
+	struct part_info dkpi;
+	struct extpart_info edkpi;
 
 	if (start_sect)
 		return (start_sect);
@@ -241,24 +243,84 @@
 	for (i = 0; i < FD_NUMPART; i++) {
 		part = (struct ipart *)mboot->parts + i;
 		if (is_bootpar) {
-			if (part->systid == 0xbe)
-				break;
+			if (part->systid == 0xbe) {
+				start_sect = part->relsect;
+				partition = i;
+				goto found_part;
+			}
+		}
+	}
+
+	/*
+	 * We will not support x86 boot partition on extended partitions
+	 */
+	if (is_bootpar) {
+		(void) fprintf(stderr, NOBOOTPAR);
+		exit(-1);
+	}
+
+	/*
+	 * Not an x86 boot partition. Search for Solaris fdisk partition
+	 * Get the solaris partition information from the device
+	 * and compare the offset of S2 with offset of solaris partition
+	 * from fdisk partition table.
+	 */
+	if (ioctl(fd, DKIOCEXTPARTINFO, &edkpi) < 0) {
+		if (ioctl(fd, DKIOCPARTINFO, &dkpi) < 0) {
+			(void) fprintf(stderr, PART_FAIL);
+			exit(-1);
+		} else {
+			edkpi.p_start = dkpi.p_start;
 		}
 	}
 
-	/* Read extended partition to find a solaris partition */
+	for (i = 0; i < FD_NUMPART; i++) {
+		part = (struct ipart *)mboot->parts + i;
+
+		if (part->relsect == 0) {
+			(void) fprintf(stderr, BAD_PART, i);
+			exit(-1);
+		}
+
+		if (edkpi.p_start >= part->relsect &&
+		    edkpi.p_start < (part->relsect + part->numsect)) {
+			/* Found the partition */
+			break;
+		}
+	}
+
+	if (i == FD_NUMPART) {
+		/* No solaris fdisk partitions (primary or logical) */
+		(void) fprintf(stderr, NOSOLPAR);
+		exit(-1);
+	}
+
+	/*
+	 * We have found a Solaris fdisk partition (primary or extended)
+	 * Handle the simple case first: Solaris in a primary partition
+	 */
+	if (!fdisk_is_dos_extended(part->systid)) {
+		start_sect = part->relsect;
+		partition = i;
+		goto found_part;
+	}
+
+	/*
+	 * Solaris in a logical partition. Find that partition in the
+	 * extended part.
+	 */
 	if ((rval = libfdisk_init(&epp, device_p0, NULL, FDISK_READ_DISK))
 	    != FDISK_SUCCESS) {
 		switch (rval) {
 			/*
-			 * FDISK_EBADLOGDRIVE and FDISK_ENOLOGDRIVE can
-			 * be considered as soft errors and hence
-			 * we do not exit
+			 * The first 2 cases are not an error per-se, just that
+			 * there is no Solaris logical partition
 			 */
 			case FDISK_EBADLOGDRIVE:
-				break;
 			case FDISK_ENOLOGDRIVE:
-				break;
+				(void) fprintf(stderr, NOSOLPAR);
+				exit(-1);
+				/*NOTREACHED*/
 			case FDISK_ENOVGEOM:
 				(void) fprintf(stderr, NO_VIRT_GEOM);
 				exit(1);
@@ -279,54 +341,18 @@
 	}
 
 	rval = fdisk_get_solaris_part(epp, &pno, &secnum, &numsec);
-	if (rval == FDISK_SUCCESS) {
-		ext_sol_part_found = 1;
+	if (rval != FDISK_SUCCESS) {
+		/* No solaris logical partition */
+		(void) fprintf(stderr, NOSOLPAR);
+		exit(-1);
 	}
 	libfdisk_fini(&epp);
 
-	/*
-	 * If there is no boot partition, find the solaris partition
-	 */
-
-	if (i == FD_NUMPART) {
-		struct part_info dkpi;
-		struct extpart_info edkpi;
-
-		/*
-		 * Get the solaris partition information from the device
-		 * and compare the offset of S2 with offset of solaris partition
-		 * from fdisk partition table.
-		 */
-		if (ioctl(fd, DKIOCEXTPARTINFO, &edkpi) < 0) {
-			if (ioctl(fd, DKIOCPARTINFO, &dkpi) < 0) {
-				(void) fprintf(stderr, PART_FAIL);
-				exit(-1);
-			} else {
-				edkpi.p_start = dkpi.p_start;
-			}
-		}
+	start_sect = secnum;
+	partition = pno - 1;
+	log_part = 1;
 
-		for (i = 0; i < FD_NUMPART; i++) {
-			part = (struct ipart *)mboot->parts + i;
-
-			if (part->relsect == 0) {
-				(void) fprintf(stderr, BAD_PART, i);
-				exit(-1);
-			}
-
-			if (edkpi.p_start >= part->relsect &&
-			    edkpi.p_start < (part->relsect + part->numsect)) {
-				/* Found the partition */
-				break;
-			}
-		}
-	}
-
-	if ((i == FD_NUMPART) && (!ext_sol_part_found)) {
-		(void) fprintf(stderr, BOOTPAR);
-		exit(-1);
-	}
-
+found_part:
 	/* get confirmation for -m */
 	if (write_mboot && !force_mboot) {
 		(void) fprintf(stdout, MBOOT_PROMPT);
@@ -336,16 +362,21 @@
 		}
 	}
 
-	if (fdisk_is_dos_extended(part->systid)) {
-		start_sect = secnum;
-		partition = pno;
-	} else {
-		start_sect = part->relsect;
-		partition = i;
+	/*
+	 * Currently if Solaris is in an extended partition we need to
+	 * write GRUB to the MBR. Check for this.
+	 */
+	if (log_part && !write_mboot) {
+		(void) fprintf(stderr, EXTSOLPAR);
+		exit(-1);
 	}
 
-	if (part->bootid != 128 && write_mboot == 0) {
-		(void) fprintf(stdout, BOOTPAR_INACTIVE, i + 1);
+	/*
+	 * warn, if Solaris in primary partition and GRUB not in MBR and
+	 * partition is not active
+	 */
+	if (!log_part && part->bootid != 128 && !write_mboot) {
+		(void) fprintf(stdout, SOLPAR_INACTIVE, partition + 1);
 	}
 
 	return (start_sect);
--- a/usr/src/cmd/boot/installgrub/message.h	Mon Sep 14 21:48:22 2009 -0700
+++ b/usr/src/cmd/boot/installgrub/message.h	Mon Sep 14 21:48:21 2009 -0700
@@ -34,13 +34,20 @@
 
 #define	DRY_RUN	gettext("dry run--nothing will be written to disk\n")
 
-#define	BOOTPAR	gettext("Solaris partition not found. Abort operation.\n")
+#define	NOSOLPAR	\
+	gettext("Solaris partition not found. Aborting operation.\n")
 
-#define	BOOTPAR_INACTIVE	gettext("Solaris boot partition inactive.\n")
+#define	NOBOOTPAR	\
+	gettext("Solaris x86 boot partition not found. Aborting operation.\n")
+
+#define	SOLPAR_INACTIVE	gettext("Solaris fdisk partition is inactive.\n")
 
 #define	BOOTPAR_NOTFOUND	\
     gettext("Solaris boot partition not found on %s\n")
 
+#define	EXTSOLPAR	\
+	gettext("Solaris in extended partition. -m (MBR) option required\n")
+
 #define	NOT_RAW_DEVICE	gettext("device %s is not a char special device\n")
 
 #define	NOT_ROOT_SLICE	gettext("raw device must be a root slice (not s2)\n")
@@ -112,6 +119,8 @@
 
 #define	LIBFDISK_INIT_FAIL	gettext("Failed to initialize libfdisk.\n")
 
+
+
 #ifdef	__cplusplus
 }
 #endif