diff options
Diffstat (limited to 'usr/src/cmd/format')
| -rw-r--r-- | usr/src/cmd/format/Makefile | 5 | ||||
| -rw-r--r-- | usr/src/cmd/format/menu_fdisk.c | 255 |
2 files changed, 213 insertions, 47 deletions
diff --git a/usr/src/cmd/format/Makefile b/usr/src/cmd/format/Makefile index 1060271ac4..e19d8342a7 100644 --- a/usr/src/cmd/format/Makefile +++ b/usr/src/cmd/format/Makefile @@ -53,8 +53,11 @@ $(ROOTETCDATA) := FILEMODE = 0644 $(ROOTETCDATA) := OWNER = root $(ROOTETCDATA) := GROUP = sys -LDLIBS += -ladm -lefi -ldiskmgt -lnvpair -ldevid +LDLIBS_i386= -lfdisk +LDLIBS_sparc= +LDLIBS += -ladm -lefi -ldiskmgt -lnvpair -ldevid $(LDLIBS_$(MACH)) +LINTFLAGS += -xerroff=E_NAME_DEF_NOT_USED2 CPPFLAGS += -D_EXTVTOC .KEEP_STATE: diff --git a/usr/src/cmd/format/menu_fdisk.c b/usr/src/cmd/format/menu_fdisk.c index 4ebadee5ab..01c4fadd57 100644 --- a/usr/src/cmd/format/menu_fdisk.c +++ b/usr/src/cmd/format/menu_fdisk.c @@ -38,6 +38,9 @@ #include <sys/dktp/fdisk.h> #include <sys/stat.h> #include <sys/dklabel.h> +#ifdef i386 +#include <libfdisk.h> +#endif #include "main.h" #include "analyze.h" @@ -105,6 +108,10 @@ static int get_solaris_part(); #endif /* __STDC__ */ + +#ifdef i386 +int extpart_init(ext_part_t **epp); +#endif /* * Handling the alignment problem of struct ipart. */ @@ -274,22 +281,23 @@ open_cur_file(int mode) char pbuf[MAXPATHLEN]; switch (mode) { - case FD_USE_P0_PATH: - (void) get_pname(&pbuf[0]); - dkpath = pbuf; - break; - case FD_USE_CUR_DISK_PATH: - if (cur_disk->fdisk_part.systid == SUNIXOS || - cur_disk->fdisk_part.systid == SUNIXOS2) { - (void) get_sname(&pbuf[0]); + case FD_USE_P0_PATH: + (void) get_pname(&pbuf[0]); dkpath = pbuf; - } else { - dkpath = cur_disk->disk_path; - } - break; - default: - err_print("Error: Invalid mode option for opening cur_file\n"); - fullabort(); + break; + case FD_USE_CUR_DISK_PATH: + if (cur_disk->fdisk_part.systid == SUNIXOS || + cur_disk->fdisk_part.systid == SUNIXOS2) { + (void) get_sname(&pbuf[0]); + dkpath = pbuf; + } else { + dkpath = cur_disk->disk_path; + } + break; + default: + err_print("Error: Invalid mode option for opening " + "cur_file\n"); + fullabort(); } /* Close previous cur_file */ @@ -388,7 +396,7 @@ update_cur_parts() for (i = 0; i < NDKMAP; i++) { #if defined(_SUNOS_VTOC_16) if (cur_parts->vtoc.v_part[i].p_tag && - cur_parts->vtoc.v_part[i].p_tag != V_ALTSCTR) { + cur_parts->vtoc.v_part[i].p_tag != V_ALTSCTR) { cur_parts->vtoc.v_part[i].p_start = 0; cur_parts->vtoc.v_part[i].p_size = 0; @@ -396,9 +404,9 @@ update_cur_parts() cur_parts->pinfo_map[i].dkl_nblk = 0; cur_parts->pinfo_map[i].dkl_cylno = 0; cur_parts->vtoc.v_part[i].p_tag = - default_vtoc_map[i].p_tag; + default_vtoc_map[i].p_tag; cur_parts->vtoc.v_part[i].p_flag = - default_vtoc_map[i].p_flag; + default_vtoc_map[i].p_flag; #if defined(_SUNOS_VTOC_16) } #endif @@ -412,14 +420,14 @@ update_cur_parts() cur_parts->pinfo_map[I_PARTITION].dkl_nblk = spc(); cur_parts->pinfo_map[I_PARTITION].dkl_cylno = 0; cur_parts->vtoc.v_part[C_PARTITION].p_start = - cur_parts->pinfo_map[C_PARTITION].dkl_cylno * nhead * nsect; + cur_parts->pinfo_map[C_PARTITION].dkl_cylno * nhead * nsect; cur_parts->vtoc.v_part[C_PARTITION].p_size = - cur_parts->pinfo_map[C_PARTITION].dkl_nblk; + cur_parts->pinfo_map[C_PARTITION].dkl_nblk; cur_parts->vtoc.v_part[I_PARTITION].p_start = - cur_parts->pinfo_map[I_PARTITION].dkl_cylno; + cur_parts->pinfo_map[I_PARTITION].dkl_cylno; cur_parts->vtoc.v_part[I_PARTITION].p_size = - cur_parts->pinfo_map[I_PARTITION].dkl_nblk; + cur_parts->pinfo_map[I_PARTITION].dkl_nblk; #endif /* defined(_SUNOS_VTOC_16) */ parts = cur_dtype->dtype_plist; @@ -440,6 +448,12 @@ get_solaris_part(int fd, struct ipart *ipart) int status; char *bootptr; struct dk_label update_label; + ushort_t found = 0; +#ifdef i386 + uint32_t relsec, numsec; + int pno, rval, ext_part_found = 0; + ext_part_t *epp; +#endif (void) lseek(fd, 0, 0); status = read(fd, (caddr_t)&boot_sec, NBPSCTR); @@ -459,6 +473,41 @@ get_solaris_part(int fd, struct ipart *ipart) bootptr = &boot_sec.parts[ipc]; (void) fill_ipart(bootptr, &ip); +#ifdef i386 + if (fdisk_is_dos_extended(ip.systid) && (ext_part_found == 0)) { + /* We support only one extended partition per disk */ + ext_part_found = 1; + (void) extpart_init(&epp); + rval = fdisk_get_solaris_part(epp, &pno, &relsec, + &numsec); + if (rval == FDISK_SUCCESS) { + /* + * Found a solaris partition inside the + * extended partition. Update the statistics. + */ + if (nhead != 0 && nsect != 0) { + pcyl = numsec / (nhead * nsect); + xstart = relsec / (nhead * nsect); + ncyl = pcyl - acyl; + } + solaris_offset = relsec; + found = 2; + ip.bootid = 0; + ip.beghead = ip.begsect = ip.begcyl = 0xff; + ip.endhead = ip.endsect = ip.endcyl = 0xff; + ip.systid = SUNIXOS2; + ip.relsect = relsec; + ip.numsect = numsec; + ipart->bootid = ip.bootid; + status = bcmp(&ip, ipart, + sizeof (struct ipart)); + bcopy(&ip, ipart, sizeof (struct ipart)); + } + libfdisk_fini(&epp); + continue; + } +#endif + /* * we are interested in Solaris and EFI partition types */ @@ -478,29 +527,31 @@ get_solaris_part(int fd, struct ipart *ipart) #ifdef DEBUG else { err_print("Critical geometry values are zero:\n" - "\tnhead = %d; nsect = %d\n", nhead, - nsect); + "\tnhead = %d; nsect = %d\n", nhead, nsect); } #endif /* DEBUG */ solaris_offset = (uint_t)lel(ip.relsect); + found = 1; break; } } - if (i == FD_NUMPART) { + if (!found) { err_print("Solaris fdisk partition not found\n"); return (-1); - } - - /* - * compare the previous and current Solaris partition - * but don't use bootid in determination of Solaris partition changes - */ - ipart->bootid = ip.bootid; - status = bcmp(&ip, ipart, sizeof (struct ipart)); + } else if (found == 1) { + /* + * Found a primary solaris partition. + * compare the previous and current Solaris partition + * but don't use bootid in determination of Solaris partition + * changes + */ + ipart->bootid = ip.bootid; + status = bcmp(&ip, ipart, sizeof (struct ipart)); - bcopy(&ip, ipart, sizeof (struct ipart)); + bcopy(&ip, ipart, sizeof (struct ipart)); + } /* if the disk partitioning has changed - get the VTOC */ if (status) { @@ -569,12 +620,17 @@ copy_solaris_part(struct ipart *ipart) char buf[MAXPATHLEN]; char *bootptr; struct stat statbuf; +#ifdef i386 + uint32_t relsec, numsec; + int pno, rval, ext_part_found = 0; + ext_part_t *epp; +#endif (void) get_pname(&buf[0]); if (stat(buf, &statbuf) == -1 || !S_ISCHR(statbuf.st_mode) || ((cur_label == L_TYPE_EFI) && - (cur_disk->disk_flags & DSK_LABEL_DIRTY))) { + (cur_disk->disk_flags & DSK_LABEL_DIRTY))) { /* * Make sure to reset solaris_offset to zero if it is * previously set by a selected disk that @@ -612,6 +668,36 @@ copy_solaris_part(struct ipart *ipart) bootptr = &mboot.parts[ipc]; (void) fill_ipart(bootptr, &ip); +#ifdef i386 + if (fdisk_is_dos_extended(ip.systid) && (ext_part_found == 0)) { + /* We support only one extended partition per disk */ + ext_part_found = 1; + (void) extpart_init(&epp); + rval = fdisk_get_solaris_part(epp, &pno, &relsec, + &numsec); + if (rval == FDISK_SUCCESS) { + /* + * Found a solaris partition inside the + * extended partition. Update the statistics. + */ + if (nhead != 0 && nsect != 0) { + pcyl = numsec / (nhead * nsect); + ncyl = pcyl - acyl; + } + solaris_offset = relsec; + ip.bootid = 0; + ip.beghead = ip.begsect = ip.begcyl = 0xff; + ip.endhead = ip.endsect = ip.endcyl = 0xff; + ip.systid = SUNIXOS2; + ip.relsect = relsec; + ip.numsect = numsec; + bcopy(&ip, ipart, sizeof (struct ipart)); + } + libfdisk_fini(&epp); + continue; + } +#endif + if (ip.systid == SUNIXOS || ip.systid == SUNIXOS2 || ip.systid == EFI_PMBR) { @@ -631,8 +717,7 @@ copy_solaris_part(struct ipart *ipart) #ifdef DEBUG else { err_print("Critical geometry values are zero:\n" - "\tnhead = %d; nsect = %d\n", nhead, - nsect); + "\tnhead = %d; nsect = %d\n", nhead, nsect); } #endif /* DEBUG */ @@ -655,7 +740,11 @@ auto_solaris_part(struct dk_label *label) struct ipart ip; char *bootptr; char pbuf[MAXPATHLEN]; - +#ifdef i386 + uint32_t relsec, numsec; + int pno, rval, ext_part_found = 0; + ext_part_t *epp; +#endif (void) get_pname(&pbuf[0]); if ((fd = open_disk(pbuf, O_RDONLY)) < 0) { @@ -679,6 +768,33 @@ auto_solaris_part(struct dk_label *label) bootptr = &mboot.parts[ipc]; (void) fill_ipart(bootptr, &ip); +#ifdef i386 + if (fdisk_is_dos_extended(ip.systid) && (ext_part_found == 0)) { + /* We support only one extended partition per disk */ + ext_part_found = 1; + (void) extpart_init(&epp); + rval = fdisk_get_solaris_part(epp, &pno, &relsec, + &numsec); + if (rval == FDISK_SUCCESS) { + /* + * Found a solaris partition inside the + * extended partition. Update the statistics. + */ + if ((label->dkl_nhead != 0) && + (label->dkl_nsect != 0)) { + label->dkl_pcyl = + numsec / (label->dkl_nhead * + label->dkl_nsect); + label->dkl_ncyl = label->dkl_pcyl - + label->dkl_acyl; + } + solaris_offset = relsec; + } + libfdisk_fini(&epp); + continue; + } +#endif + /* * if the disk has an EFI label, the nhead and nsect fields * the label may be zero. This protects us from FPE's, and @@ -697,11 +813,11 @@ auto_solaris_part(struct dk_label *label) #ifdef DEBUG else { err_print("Critical label fields aren't " - "non-zero:\n" - "\tlabel->dkl_nhead = %d; " - "label->dkl_nsect = " - "%d\n", label->dkl_nhead, - label->dkl_nsect); + "non-zero:\n" + "\tlabel->dkl_nhead = %d; " + "label->dkl_nsect = " + "%d\n", label->dkl_nhead, + label->dkl_nsect); } #endif /* DEBUG */ @@ -739,9 +855,56 @@ good_fdisk() } else { err_print("WARNING - "); err_print("This disk may be in use by an application " - "that has\n\t modified the fdisk table. Ensure " - "that this disk is\n\t not currently in use " - "before proceeding to use fdisk.\n"); + "that has\n\t modified the fdisk table. Ensure " + "that this disk is\n\t not currently in use " + "before proceeding to use fdisk.\n"); return (0); } } + + +#ifdef i386 +int +extpart_init(ext_part_t **epp) +{ + int rval, lf_op_flag = 0; + char p0_path[MAXPATHLEN]; + + get_pname(&p0_path[0]); + lf_op_flag |= FDISK_READ_DISK; + if ((rval = libfdisk_init(epp, p0_path, NULL, lf_op_flag)) != + 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: + err_print("Could not get virtual geometry for" + " this device\n"); + fullabort(); + break; + case FDISK_ENOPGEOM: + err_print("Could not get physical geometry for" + " this device\n"); + fullabort(); + break; + case FDISK_ENOLGEOM: + err_print("Could not get label geometry for " + " this device\n"); + fullabort(); + break; + default: + err_print("Failed to initialise libfdisk.\n"); + fullabort(); + break; + } + } + return (0); +} +#endif |
