diff options
Diffstat (limited to 'usr/src/cmd/boot/installgrub/installgrub.c')
-rw-r--r-- | usr/src/cmd/boot/installgrub/installgrub.c | 67 |
1 files changed, 58 insertions, 9 deletions
diff --git a/usr/src/cmd/boot/installgrub/installgrub.c b/usr/src/cmd/boot/installgrub/installgrub.c index c233cded29..f37f1430f5 100644 --- a/usr/src/cmd/boot/installgrub/installgrub.c +++ b/usr/src/cmd/boot/installgrub/installgrub.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -43,6 +43,7 @@ #include <locale.h> #include "message.h" #include <errno.h> +#include <libfdisk.h> #include <md5.h> #ifndef TEXT_DOMAIN @@ -83,7 +84,8 @@ static int is_bootpar = 0; static int strip = 0; static int stage2_fd; static int partition, slice = 0xff; -static unsigned int stage2_first_sector, stage2_second_sector; +static char *device_p0; +static uint32_t stage2_first_sector, stage2_second_sector; static char bpb_sect[SECTOR_SIZE]; @@ -226,10 +228,11 @@ static unsigned int get_start_sector(int fd) { static unsigned int start_sect = 0; - - int i; + uint32_t secnum, numsec; + int i, pno, rval, ext_sol_part_found = 0; struct mboot *mboot; struct ipart *part; + ext_part_t *epp; if (start_sect) return (start_sect); @@ -243,6 +246,44 @@ get_start_sector(int fd) } } + /* Read extended partition to find a solaris partition */ + 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 + */ + case FDISK_EBADLOGDRIVE: + break; + case FDISK_ENOLOGDRIVE: + break; + case FDISK_ENOVGEOM: + (void) fprintf(stderr, NO_VIRT_GEOM); + exit(1); + break; + case FDISK_ENOPGEOM: + (void) fprintf(stderr, NO_PHYS_GEOM); + exit(1); + break; + case FDISK_ENOLGEOM: + (void) fprintf(stderr, NO_LABEL_GEOM); + exit(1); + break; + default: + (void) fprintf(stderr, LIBFDISK_INIT_FAIL); + exit(1); + break; + } + } + + rval = fdisk_get_solaris_part(epp, &pno, &secnum, &numsec); + if (rval == FDISK_SUCCESS) { + ext_sol_part_found = 1; + } + libfdisk_fini(&epp); + /* * If there is no boot partition, find the solaris partition */ @@ -272,6 +313,7 @@ get_start_sector(int fd) (void) fprintf(stderr, BAD_PART, i); exit(-1); } + if (edkpi.p_start >= part->relsect && edkpi.p_start < (part->relsect + part->numsect)) { /* Found the partition */ @@ -280,7 +322,7 @@ get_start_sector(int fd) } } - if (i == FD_NUMPART) { + if ((i == FD_NUMPART) && (!ext_sol_part_found)) { (void) fprintf(stderr, BOOTPAR); exit(-1); } @@ -294,12 +336,18 @@ get_start_sector(int fd) } } - start_sect = part->relsect; + if (fdisk_is_dos_extended(part->systid)) { + start_sect = secnum; + partition = pno; + } else { + start_sect = part->relsect; + partition = i; + } + if (part->bootid != 128 && write_mboot == 0) { (void) fprintf(stdout, BOOTPAR_INACTIVE, i + 1); } - partition = i; return (start_sect); } @@ -395,6 +443,7 @@ read_boot_sect(char *device) device[i - 2] = 'p'; device[i - 1] = '0'; + device_p0 = strdup(device); fd = open(device, O_RDONLY); if (fd == -1 || read(fd, boot_sect, SECTOR_SIZE) != SECTOR_SIZE) { (void) fprintf(stderr, READ_FAIL_MBR, device); @@ -623,8 +672,8 @@ modify_and_write_stage2(int dev_fd) if (is_floppy || is_bootpar) { int i = 0; - uint_t partition_offset; - uint_t install_addr = 0x8200; + uint32_t partition_offset; + uint32_t install_addr = 0x8200; uchar_t *pos = (uchar_t *)stage2_buffer + STAGE2_BLOCKLIST; stage2_first_sector = blocklist[0]; |