int fdisk_ext_part_exists(ext_part_t *epp) { int i; struct ipart *part_table = epp->mtable; if (part_table == NULL) { /* No extended partition found */ return (0); } for (i = 0; i < FD_NUMPART; i++) { if (fdisk_is_dos_extended(LE_8(part_table[i].systid))) { break; } } if (i == FD_NUMPART) { /* No extended partition found */ return (0); } return (1); }
/* * Procedure to walk through the extended partitions and build a Singly * Linked List out of the data. */ static int fdisk_read_extpart(ext_part_t *epp) { struct ipart *fdp, *ext_fdp; int i = 0, j = 0, ext_part_found = 0, lpart = 5; off_t secnum, offset; logical_drive_t *temp, *ep_ptr; unsigned char *ext_buf; int sectsize = epp->disk_geom.sectsize; if ((ext_buf = (uchar_t *)malloc(sectsize)) == NULL) { return (ENOMEM); } fdp = epp->mtable; for (i = 0; (i < FD_NUMPART) && (!ext_part_found); i++, fdp++) { if (fdisk_is_dos_extended(LE_8(fdp->systid))) { ext_part_found = 1; secnum = LE_32(fdp->relsect); offset = secnum * sectsize; epp->ext_beg_sec = secnum; epp->ext_end_sec = secnum + LE_32(fdp->numsect) - 1; epp->ext_beg_cyl = FDISK_SECT_TO_CYL(epp, epp->ext_beg_sec); epp->ext_end_cyl = FDISK_SECT_TO_CYL(epp, epp->ext_end_sec); /*LINTED*/ while (B_TRUE) { if (lseek(epp->dev_fd, offset, SEEK_SET) < 0) { return (EIO); } if (read(epp->dev_fd, ext_buf, sectsize) < sectsize) { return (EIO); } /*LINTED*/ ext_fdp = (struct ipart *) (&ext_buf[FDISK_PART_TABLE_START]); if ((LE_32(ext_fdp->relsect) == 0) && (epp->logical_drive_count == 0)) { /* No logical drives defined */ epp->first_ebr_is_null = 0; return (FDISK_ENOLOGDRIVE); } temp = fdisk_alloc_ld_node(); temp->abs_secnum = secnum; temp->logdrive_offset = LE_32(ext_fdp->relsect); temp ->numsect = LE_32(ext_fdp->numsect); if (epp->ld_head == NULL) { /* adding first logical drive */ if (temp->logdrive_offset > MAX_LOGDRIVE_OFFSET) { /* out of order */ temp->abs_secnum += temp->logdrive_offset; temp->logdrive_offset = 0; } } temp->begcyl = FDISK_SECT_TO_CYL(epp, temp->abs_secnum); temp->endcyl = FDISK_SECT_TO_CYL(epp, temp->abs_secnum + temp->logdrive_offset + temp->numsect - 1); /* * Check for sanity of logical drives */ if (fdisk_validate_logical_drive(epp, temp->abs_secnum, temp->logdrive_offset, temp->numsect)) { epp->corrupt_logical_drives = 1; free(temp); return (FDISK_EBADLOGDRIVE); } temp->parts[0] = *ext_fdp; ext_fdp++; temp->parts[1] = *ext_fdp; if (epp->ld_head == NULL) { epp->ld_head = temp; epp->sorted_ld_head = temp; ep_ptr = temp; epp->logical_drive_count = 1; } else { ep_ptr->next = temp; ep_ptr = temp; fdisk_ext_place_in_sorted_list(epp, temp); epp->logical_drive_count++; } /*LINTED*/ if (LE_16((*(uint16_t *)&ext_buf[510])) != MBB_MAGIC) { epp->invalid_bb_sig[j++] = lpart; temp->modified = FDISK_MINOR_WRITE; } if (LE_32(ext_fdp->relsect) == 0) break; else { secnum = LE_32(fdp->relsect) + LE_32(ext_fdp->relsect); offset = secnum * sectsize; } lpart++; } } } return (FDISK_SUCCESS); }
static int get_start_sector(ig_device_t *device) { 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 (is_efi(device->type)) { struct dk_gpt *vtoc; if (efi_alloc_and_read(device->disk_fd, &vtoc) < 0) return (BC_ERROR); device->start_sector = vtoc->efi_parts[device->slice].p_start; /* GPT doesn't use traditional slice letters */ device->slice = 0xff; device->partition = 0; efi_free(vtoc); goto found_part; } mboot = (struct mboot *)device->boot_sector; if (is_bootpar(device->type)) { if (find_x86_bootpar(mboot, &pno, &secnum) != BC_SUCCESS) { (void) fprintf(stderr, NOBOOTPAR); return (BC_ERROR); } else { device->start_sector = secnum; device->partition = pno; goto found_part; } } /* * 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(device->part_fd, DKIOCEXTPARTINFO, &edkpi) < 0) { if (ioctl(device->part_fd, DKIOCPARTINFO, &dkpi) < 0) { (void) fprintf(stderr, PART_FAIL); return (BC_ERROR); } 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); return (BC_ERROR); } 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); return (BC_ERROR); } /* * 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)) { device->start_sector = part->relsect; device->partition = i; goto found_part; } /* * Solaris in a logical partition. Find that partition in the * extended part. */ if ((rval = libfdisk_init(&epp, device->path_p0, NULL, FDISK_READ_DISK)) != FDISK_SUCCESS) { switch (rval) { /* * The first 3 cases are not an error per-se, just that * there is no Solaris logical partition */ case FDISK_EBADLOGDRIVE: case FDISK_ENOLOGDRIVE: case FDISK_EBADMAGIC: (void) fprintf(stderr, NOSOLPAR); return (BC_ERROR); case FDISK_ENOVGEOM: (void) fprintf(stderr, NO_VIRT_GEOM); return (BC_ERROR); case FDISK_ENOPGEOM: (void) fprintf(stderr, NO_PHYS_GEOM); return (BC_ERROR); case FDISK_ENOLGEOM: (void) fprintf(stderr, NO_LABEL_GEOM); return (BC_ERROR); default: (void) fprintf(stderr, LIBFDISK_INIT_FAIL); return (BC_ERROR); } } rval = fdisk_get_solaris_part(epp, &pno, &secnum, &numsec); libfdisk_fini(&epp); if (rval != FDISK_SUCCESS) { /* No solaris logical partition */ (void) fprintf(stderr, NOSOLPAR); return (BC_ERROR); } device->start_sector = secnum; device->partition = pno - 1; log_part = 1; found_part: /* get confirmation for -m */ if (write_mbr && !force_mbr) { (void) fprintf(stdout, MBOOT_PROMPT); if (!yes()) { write_mbr = 0; (void) fprintf(stdout, MBOOT_NOT_UPDATED); return (BC_ERROR); } } /* * Currently if Solaris is in an extended partition we need to * write GRUB to the MBR. Check for this. */ if (log_part && !write_mbr) { (void) fprintf(stdout, gettext("Installing Solaris on an " "extended partition... forcing MBR update\n")); write_mbr = 1; } /* * warn, if Solaris in primary partition and GRUB not in MBR and * partition is not active */ if (!log_part && part->bootid != 128 && !write_mbr) { (void) fprintf(stdout, SOLPAR_INACTIVE, device->partition + 1); } return (BC_SUCCESS); }