summaryrefslogtreecommitdiff
path: root/usr/src/cmd/boot/installgrub/installgrub.c
diff options
context:
space:
mode:
authorVikram Hegde <Vikram.Hegde@Sun.COM>2009-09-14 21:48:21 -0700
committerVikram Hegde <Vikram.Hegde@Sun.COM>2009-09-14 21:48:21 -0700
commit7fc5d2a453d54fb46bb4a17b2bd1b59b0a711575 (patch)
treeaba4f45a26d8fb3de10736611710ea75c600b94d /usr/src/cmd/boot/installgrub/installgrub.c
parentac48dfe87039078897ed719af26744eca776508c (diff)
downloadillumos-joyent-7fc5d2a453d54fb46bb4a17b2bd1b59b0a711575.tar.gz
6880217 installgrub fails to configure GRUB menu for logical/extended partition
Diffstat (limited to 'usr/src/cmd/boot/installgrub/installgrub.c')
-rw-r--r--usr/src/cmd/boot/installgrub/installgrub.c155
1 files changed, 93 insertions, 62 deletions
diff --git a/usr/src/cmd/boot/installgrub/installgrub.c b/usr/src/cmd/boot/installgrub/installgrub.c
index f37f1430f5..ed552b44ce 100644
--- a/usr/src/cmd/boot/installgrub/installgrub.c
+++ b/usr/src/cmd/boot/installgrub/installgrub.c
@@ -228,11 +228,13 @@ static unsigned int
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 @@ get_start_sector(int fd)
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;
+ }
+ }
+
+ 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);
}
- /* Read extended partition to find a solaris partition */
+ /*
+ * 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 @@ get_start_sector(int fd)
}
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;
- }
- }
-
- 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);
- }
+ start_sect = secnum;
+ partition = pno - 1;
+ log_part = 1;
+found_part:
/* get confirmation for -m */
if (write_mboot && !force_mboot) {
(void) fprintf(stdout, MBOOT_PROMPT);
@@ -336,16 +362,21 @@ get_start_sector(int fd)
}
}
- 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);