summaryrefslogtreecommitdiff
path: root/usr/src/cmd/format
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/format')
-rw-r--r--usr/src/cmd/format/Makefile5
-rw-r--r--usr/src/cmd/format/menu_fdisk.c255
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