PSARC/2006/379 Solaris on Extended partition
[illumos-gate.git] / usr / src / cmd / format / menu_fdisk.c
blob01c4fadd5774906af96acd1a2f9a6b31b3c50445
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * This file contains functions that implement the fdisk menu commands.
29 #include "global.h"
30 #include <errno.h>
31 #include <sys/time.h>
32 #include <sys/resource.h>
33 #include <sys/wait.h>
34 #include <signal.h>
35 #include <string.h>
36 #include <fcntl.h>
37 #include <stdlib.h>
38 #include <sys/dktp/fdisk.h>
39 #include <sys/stat.h>
40 #include <sys/dklabel.h>
41 #ifdef i386
42 #include <libfdisk.h>
43 #endif
45 #include "main.h"
46 #include "analyze.h"
47 #include "menu.h"
48 #include "menu_command.h"
49 #include "menu_defect.h"
50 #include "menu_partition.h"
51 #include "menu_fdisk.h"
52 #include "param.h"
53 #include "misc.h"
54 #include "label.h"
55 #include "startup.h"
56 #include "partition.h"
57 #include "prompts.h"
58 #include "checkdev.h"
59 #include "io.h"
60 #include "ctlr_scsi.h"
61 #include "auto_sense.h"
63 extern struct menu_item menu_fdisk[];
66 * Byte swapping macros for accessing struct ipart
67 * to resolve little endian on Sparc.
69 #if defined(sparc)
70 #define les(val) ((((val)&0xFF)<<8)|(((val)>>8)&0xFF))
71 #define lel(val) (((unsigned)(les((val)&0x0000FFFF))<<16) | \
72 (les((unsigned)((val)&0xffff0000)>>16)))
74 #elif defined(i386)
76 #define les(val) (val)
77 #define lel(val) (val)
79 #else /* defined(sparc) */
81 #error No Platform defined
83 #endif /* defined(sparc) */
86 /* Function prototypes */
87 #ifdef __STDC__
89 #if defined(sparc)
91 static int getbyte(uchar_t **);
92 static int getlong(uchar_t **);
94 #endif /* defined(sparc) */
96 static int get_solaris_part(int fd, struct ipart *ipart);
98 #else /* __STDC__ */
100 #if defined(sparc)
102 static int getbyte();
103 static int getlong();
105 #endif /* defined(sparc) */
107 static int get_solaris_part();
109 #endif /* __STDC__ */
112 #ifdef i386
113 int extpart_init(ext_part_t **epp);
114 #endif
116 * Handling the alignment problem of struct ipart.
118 static void
119 fill_ipart(char *bootptr, struct ipart *partp)
121 #if defined(sparc)
123 * Sparc platform:
125 * Packing short/word for struct ipart to resolve
126 * little endian on Sparc since it is not
127 * properly aligned on Sparc.
129 partp->bootid = getbyte((uchar_t **)&bootptr);
130 partp->beghead = getbyte((uchar_t **)&bootptr);
131 partp->begsect = getbyte((uchar_t **)&bootptr);
132 partp->begcyl = getbyte((uchar_t **)&bootptr);
133 partp->systid = getbyte((uchar_t **)&bootptr);
134 partp->endhead = getbyte((uchar_t **)&bootptr);
135 partp->endsect = getbyte((uchar_t **)&bootptr);
136 partp->endcyl = getbyte((uchar_t **)&bootptr);
137 partp->relsect = getlong((uchar_t **)&bootptr);
138 partp->numsect = getlong((uchar_t **)&bootptr);
139 #elif defined(i386)
141 * i386 platform:
143 * The fdisk table does not begin on a 4-byte boundary within
144 * the master boot record; so, we need to recopy its contents
145 * to another data structure to avoid an alignment exception.
147 (void) bcopy(bootptr, partp, sizeof (struct ipart));
148 #else
149 #error No Platform defined
150 #endif /* defined(sparc) */
154 * Get a correct byte/short/word routines for Sparc platform.
156 #if defined(sparc)
157 static int
158 getbyte(uchar_t **bp)
160 int b;
162 b = **bp;
163 *bp = *bp + 1;
164 return (b);
167 #ifdef DEADCODE
168 static int
169 getshort(uchar_t **bp)
171 int b;
173 b = ((**bp) << 8) | *(*bp + 1);
174 *bp += 2;
175 return (b);
177 #endif /* DEADCODE */
179 static int
180 getlong(uchar_t **bp)
182 int b, bh, bl;
184 bh = ((**bp) << 8) | *(*bp + 1);
185 *bp += 2;
186 bl = ((**bp) << 8) | *(*bp + 1);
187 *bp += 2;
189 b = (bh << 16) | bl;
190 return (b);
192 #endif /* defined(sparc) */
195 * Convert cn[tn]dn to cn[tn]dns2 path
197 static void
198 get_sname(char *name)
200 char buf[MAXPATHLEN];
201 char *devp = "/dev/dsk";
202 char *rdevp = "/dev/rdsk";
203 char np[MAXNAMELEN];
204 char *npt;
207 * If it is a full path /dev/[r]dsk/cn[tn]dn, use this path
209 (void) strcpy(np, cur_disk->disk_name);
210 if (strncmp(rdevp, cur_disk->disk_name, strlen(rdevp)) == 0 ||
211 strncmp(devp, cur_disk->disk_name, strlen(devp)) == 0) {
213 * Skip if the path is already included with sN
215 if (strchr(np, 's') == strrchr(np, 's')) {
216 npt = strrchr(np, 'p');
217 /* If pN is found, do not include it */
218 if (npt != NULL) {
219 *npt = '\0';
221 (void) snprintf(buf, sizeof (buf), "%ss2", np);
222 } else {
223 (void) snprintf(buf, sizeof (buf), "%s", np);
225 } else {
226 (void) snprintf(buf, sizeof (buf), "/dev/rdsk/%ss2", np);
228 (void) strcpy(name, buf);
232 * Convert cn[tn]dnsn to cn[tn]dnp0 path
234 static void
235 get_pname(char *name)
237 char buf[MAXPATHLEN];
238 char *devp = "/dev/dsk";
239 char *rdevp = "/dev/rdsk";
240 char np[MAXNAMELEN];
241 char *npt;
244 * If it is a full path /dev/[r]dsk/cn[tn]dnsn, use this path
246 if (cur_disk == NULL) {
247 (void) strcpy(np, x86_devname);
248 } else {
249 (void) strcpy(np, cur_disk->disk_name);
252 if (strncmp(rdevp, np, strlen(rdevp)) == 0 ||
253 strncmp(devp, np, strlen(devp)) == 0) {
255 * Skip if the path is already included with pN
257 if (strchr(np, 'p') == NULL) {
258 npt = strrchr(np, 's');
259 /* If sN is found, do not include it */
260 if (isdigit(*++npt)) {
261 *--npt = '\0';
263 (void) snprintf(buf, sizeof (buf), "%sp0", np);
264 } else {
265 (void) snprintf(buf, sizeof (buf), "%s", np);
267 } else {
268 (void) snprintf(buf, sizeof (buf), "/dev/rdsk/%sp0", np);
270 (void) strcpy(name, buf);
274 * Open file descriptor for current disk (cur_file)
275 * with "p0" path or cur_disk->disk_path
277 void
278 open_cur_file(int mode)
280 char *dkpath;
281 char pbuf[MAXPATHLEN];
283 switch (mode) {
284 case FD_USE_P0_PATH:
285 (void) get_pname(&pbuf[0]);
286 dkpath = pbuf;
287 break;
288 case FD_USE_CUR_DISK_PATH:
289 if (cur_disk->fdisk_part.systid == SUNIXOS ||
290 cur_disk->fdisk_part.systid == SUNIXOS2) {
291 (void) get_sname(&pbuf[0]);
292 dkpath = pbuf;
293 } else {
294 dkpath = cur_disk->disk_path;
296 break;
297 default:
298 err_print("Error: Invalid mode option for opening "
299 "cur_file\n");
300 fullabort();
303 /* Close previous cur_file */
304 (void) close(cur_file);
305 /* Open cur_file with the required path dkpath */
306 if ((cur_file = open_disk(dkpath, O_RDWR | O_NDELAY)) < 0) {
307 err_print(
308 "Error: can't open selected disk '%s'.\n", dkpath);
309 fullabort();
315 * This routine implements the 'fdisk' command. It simply runs
316 * the fdisk command on the current disk.
317 * Use of this is restricted to interactive mode only.
320 c_fdisk()
323 char buf[MAXPATHLEN];
324 char pbuf[MAXPATHLEN];
325 struct stat statbuf;
328 * We must be in interactive mode to use the fdisk command
330 if (option_f != (char *)NULL || isatty(0) != 1 || isatty(1) != 1) {
331 err_print("Fdisk command is for interactive use only!\n");
332 return (-1);
336 * There must be a current disk type and a current disk
338 if (cur_dtype == NULL) {
339 err_print("Current Disk Type is not set.\n");
340 return (-1);
344 * Before running the fdisk command, get file status of
345 * /dev/rdsk/cn[tn]dnp0 path to see if this disk
346 * supports fixed disk partition table.
348 (void) get_pname(&pbuf[0]);
349 if (stat(pbuf, (struct stat *)&statbuf) == -1 ||
350 !S_ISCHR(statbuf.st_mode)) {
351 err_print(
352 "Disk does not support fixed disk partition table\n");
353 return (0);
357 * Run the fdisk program.
359 (void) snprintf(buf, sizeof (buf), "fdisk %s\n", pbuf);
360 (void) system(buf);
363 * Open cur_file with "p0" path for accessing the fdisk table
365 (void) open_cur_file(FD_USE_P0_PATH);
368 * Get solaris partition information in the fdisk partition table
370 if (get_solaris_part(cur_file, &cur_disk->fdisk_part) == -1) {
371 err_print("No fdisk solaris partition found\n");
372 cur_disk->fdisk_part.numsect = 0; /* No Solaris */
376 * Restore cur_file with cur_disk->disk_path
378 (void) open_cur_file(FD_USE_CUR_DISK_PATH);
380 return (0);
384 * Read MBR on the disk
385 * if the Solaris partition has changed,
386 * reread the vtoc
388 #ifdef DEADCODE
389 static void
390 update_cur_parts()
393 int i;
394 register struct partition_info *parts;
396 for (i = 0; i < NDKMAP; i++) {
397 #if defined(_SUNOS_VTOC_16)
398 if (cur_parts->vtoc.v_part[i].p_tag &&
399 cur_parts->vtoc.v_part[i].p_tag != V_ALTSCTR) {
400 cur_parts->vtoc.v_part[i].p_start = 0;
401 cur_parts->vtoc.v_part[i].p_size = 0;
403 #endif
404 cur_parts->pinfo_map[i].dkl_nblk = 0;
405 cur_parts->pinfo_map[i].dkl_cylno = 0;
406 cur_parts->vtoc.v_part[i].p_tag =
407 default_vtoc_map[i].p_tag;
408 cur_parts->vtoc.v_part[i].p_flag =
409 default_vtoc_map[i].p_flag;
410 #if defined(_SUNOS_VTOC_16)
412 #endif
414 cur_parts->pinfo_map[C_PARTITION].dkl_nblk = ncyl * spc();
416 #if defined(_SUNOS_VTOC_16)
418 * Adjust for the boot partitions
420 cur_parts->pinfo_map[I_PARTITION].dkl_nblk = spc();
421 cur_parts->pinfo_map[I_PARTITION].dkl_cylno = 0;
422 cur_parts->vtoc.v_part[C_PARTITION].p_start =
423 cur_parts->pinfo_map[C_PARTITION].dkl_cylno * nhead * nsect;
424 cur_parts->vtoc.v_part[C_PARTITION].p_size =
425 cur_parts->pinfo_map[C_PARTITION].dkl_nblk;
427 cur_parts->vtoc.v_part[I_PARTITION].p_start =
428 cur_parts->pinfo_map[I_PARTITION].dkl_cylno;
429 cur_parts->vtoc.v_part[I_PARTITION].p_size =
430 cur_parts->pinfo_map[I_PARTITION].dkl_nblk;
432 #endif /* defined(_SUNOS_VTOC_16) */
433 parts = cur_dtype->dtype_plist;
434 cur_dtype->dtype_ncyl = ncyl;
435 cur_dtype->dtype_plist = cur_parts;
436 parts->pinfo_name = cur_parts->pinfo_name;
437 cur_disk->disk_parts = cur_parts;
438 cur_ctype->ctype_dlist = cur_dtype;
441 #endif /* DEADCODE */
443 static int
444 get_solaris_part(int fd, struct ipart *ipart)
446 int i;
447 struct ipart ip;
448 int status;
449 char *bootptr;
450 struct dk_label update_label;
451 ushort_t found = 0;
452 #ifdef i386
453 uint32_t relsec, numsec;
454 int pno, rval, ext_part_found = 0;
455 ext_part_t *epp;
456 #endif
458 (void) lseek(fd, 0, 0);
459 status = read(fd, (caddr_t)&boot_sec, NBPSCTR);
461 if (status != NBPSCTR) {
462 err_print("Bad read of fdisk partition. Status = %x\n", status);
463 err_print("Cannot read fdisk partition information.\n");
464 return (-1);
467 for (i = 0; i < FD_NUMPART; i++) {
468 int ipc;
470 ipc = i * sizeof (struct ipart);
472 /* Handling the alignment problem of struct ipart */
473 bootptr = &boot_sec.parts[ipc];
474 (void) fill_ipart(bootptr, &ip);
476 #ifdef i386
477 if (fdisk_is_dos_extended(ip.systid) && (ext_part_found == 0)) {
478 /* We support only one extended partition per disk */
479 ext_part_found = 1;
480 (void) extpart_init(&epp);
481 rval = fdisk_get_solaris_part(epp, &pno, &relsec,
482 &numsec);
483 if (rval == FDISK_SUCCESS) {
485 * Found a solaris partition inside the
486 * extended partition. Update the statistics.
488 if (nhead != 0 && nsect != 0) {
489 pcyl = numsec / (nhead * nsect);
490 xstart = relsec / (nhead * nsect);
491 ncyl = pcyl - acyl;
493 solaris_offset = relsec;
494 found = 2;
495 ip.bootid = 0;
496 ip.beghead = ip.begsect = ip.begcyl = 0xff;
497 ip.endhead = ip.endsect = ip.endcyl = 0xff;
498 ip.systid = SUNIXOS2;
499 ip.relsect = relsec;
500 ip.numsect = numsec;
501 ipart->bootid = ip.bootid;
502 status = bcmp(&ip, ipart,
503 sizeof (struct ipart));
504 bcopy(&ip, ipart, sizeof (struct ipart));
506 libfdisk_fini(&epp);
507 continue;
509 #endif
512 * we are interested in Solaris and EFI partition types
514 if (ip.systid == SUNIXOS ||
515 ip.systid == SUNIXOS2 ||
516 ip.systid == EFI_PMBR) {
518 * if the disk has an EFI label, nhead and nsect may
519 * be zero. This test protects us from FPE's, and
520 * format still seems to work fine
522 if (nhead != 0 && nsect != 0) {
523 pcyl = lel(ip.numsect) / (nhead * nsect);
524 xstart = lel(ip.relsect) / (nhead * nsect);
525 ncyl = pcyl - acyl;
527 #ifdef DEBUG
528 else {
529 err_print("Critical geometry values are zero:\n"
530 "\tnhead = %d; nsect = %d\n", nhead, nsect);
532 #endif /* DEBUG */
534 solaris_offset = (uint_t)lel(ip.relsect);
535 found = 1;
536 break;
540 if (!found) {
541 err_print("Solaris fdisk partition not found\n");
542 return (-1);
543 } else if (found == 1) {
545 * Found a primary solaris partition.
546 * compare the previous and current Solaris partition
547 * but don't use bootid in determination of Solaris partition
548 * changes
550 ipart->bootid = ip.bootid;
551 status = bcmp(&ip, ipart, sizeof (struct ipart));
553 bcopy(&ip, ipart, sizeof (struct ipart));
556 /* if the disk partitioning has changed - get the VTOC */
557 if (status) {
558 struct extvtoc exvtoc;
559 struct vtoc vtoc;
561 status = ioctl(fd, DKIOCGEXTVTOC, &exvtoc);
562 if (status == -1) {
563 i = errno;
564 /* Try the old ioctl DKIOCGVTOC */
565 status = ioctl(fd, DKIOCGVTOC, &vtoc);
566 if (status == -1) {
567 err_print("Bad ioctl DKIOCGEXTVTOC.\n");
568 err_print("errno=%d %s\n", i, strerror(i));
569 err_print("Cannot read vtoc information.\n");
570 return (-1);
574 status = read_label(fd, &update_label);
575 if (status == -1) {
576 err_print("Cannot read label information.\n");
577 return (-1);
580 /* copy vtoc information */
581 cur_parts->vtoc = update_label.dkl_vtoc;
583 #if defined(_SUNOS_VTOC_16)
585 * this is to update the slice table on x86
586 * we don't care about VTOC8 here
588 for (i = 0; i < NDKMAP; i ++) {
589 cur_parts->pinfo_map[i].dkl_cylno =
590 update_label.dkl_vtoc.v_part[i].p_start /
591 ((int)(update_label.dkl_nhead *
592 update_label.dkl_nsect));
593 cur_parts->pinfo_map[i].dkl_nblk =
594 update_label.dkl_vtoc.v_part[i].p_size;
596 #endif /* defined(_SUNOS_VTOC_16) */
598 cur_dtype->dtype_ncyl = update_label.dkl_ncyl;
599 cur_dtype->dtype_pcyl = update_label.dkl_pcyl;
600 cur_dtype->dtype_acyl = update_label.dkl_acyl;
601 cur_dtype->dtype_nhead = update_label.dkl_nhead;
602 cur_dtype->dtype_nsect = update_label.dkl_nsect;
603 ncyl = cur_dtype->dtype_ncyl;
604 acyl = cur_dtype->dtype_acyl;
605 pcyl = cur_dtype->dtype_pcyl;
606 nsect = cur_dtype->dtype_nsect;
607 nhead = cur_dtype->dtype_nhead;
609 return (0);
614 copy_solaris_part(struct ipart *ipart)
617 int status, i, fd;
618 struct mboot mboot;
619 struct ipart ip;
620 char buf[MAXPATHLEN];
621 char *bootptr;
622 struct stat statbuf;
623 #ifdef i386
624 uint32_t relsec, numsec;
625 int pno, rval, ext_part_found = 0;
626 ext_part_t *epp;
627 #endif
629 (void) get_pname(&buf[0]);
630 if (stat(buf, &statbuf) == -1 ||
631 !S_ISCHR(statbuf.st_mode) ||
632 ((cur_label == L_TYPE_EFI) &&
633 (cur_disk->disk_flags & DSK_LABEL_DIRTY))) {
635 * Make sure to reset solaris_offset to zero if it is
636 * previously set by a selected disk that
637 * supports the fdisk table.
639 solaris_offset = 0;
641 * Return if this disk does not support fdisk table or
642 * if it uses an EFI label but has not yet been labelled.
643 * If the EFI label has not been written then the open
644 * on the partition will fail.
646 return (0);
649 if ((fd = open(buf, O_RDONLY)) < 0) {
650 err_print("Error: can't open disk '%s'.\n", buf);
651 return (-1);
654 status = read(fd, (caddr_t)&mboot, sizeof (struct mboot));
656 if (status != sizeof (struct mboot)) {
657 err_print("Bad read of fdisk partition.\n");
658 (void) close(fd);
659 return (-1);
662 for (i = 0; i < FD_NUMPART; i++) {
663 int ipc;
665 ipc = i * sizeof (struct ipart);
667 /* Handling the alignment problem of struct ipart */
668 bootptr = &mboot.parts[ipc];
669 (void) fill_ipart(bootptr, &ip);
671 #ifdef i386
672 if (fdisk_is_dos_extended(ip.systid) && (ext_part_found == 0)) {
673 /* We support only one extended partition per disk */
674 ext_part_found = 1;
675 (void) extpart_init(&epp);
676 rval = fdisk_get_solaris_part(epp, &pno, &relsec,
677 &numsec);
678 if (rval == FDISK_SUCCESS) {
680 * Found a solaris partition inside the
681 * extended partition. Update the statistics.
683 if (nhead != 0 && nsect != 0) {
684 pcyl = numsec / (nhead * nsect);
685 ncyl = pcyl - acyl;
687 solaris_offset = relsec;
688 ip.bootid = 0;
689 ip.beghead = ip.begsect = ip.begcyl = 0xff;
690 ip.endhead = ip.endsect = ip.endcyl = 0xff;
691 ip.systid = SUNIXOS2;
692 ip.relsect = relsec;
693 ip.numsect = numsec;
694 bcopy(&ip, ipart, sizeof (struct ipart));
696 libfdisk_fini(&epp);
697 continue;
699 #endif
701 if (ip.systid == SUNIXOS ||
702 ip.systid == SUNIXOS2 ||
703 ip.systid == EFI_PMBR) {
704 solaris_offset = lel(ip.relsect);
705 bcopy(&ip, ipart, sizeof (struct ipart));
708 * if the disk has an EFI label, we typically won't
709 * have values for nhead and nsect. format seems to
710 * work without them, and we need to protect ourselves
711 * from FPE's
713 if (nhead != 0 && nsect != 0) {
714 pcyl = lel(ip.numsect) / (nhead * nsect);
715 ncyl = pcyl - acyl;
717 #ifdef DEBUG
718 else {
719 err_print("Critical geometry values are zero:\n"
720 "\tnhead = %d; nsect = %d\n", nhead, nsect);
722 #endif /* DEBUG */
724 break;
728 (void) close(fd);
729 return (0);
733 #if defined(_FIRMWARE_NEEDS_FDISK)
735 auto_solaris_part(struct dk_label *label)
738 int status, i, fd;
739 struct mboot mboot;
740 struct ipart ip;
741 char *bootptr;
742 char pbuf[MAXPATHLEN];
743 #ifdef i386
744 uint32_t relsec, numsec;
745 int pno, rval, ext_part_found = 0;
746 ext_part_t *epp;
747 #endif
749 (void) get_pname(&pbuf[0]);
750 if ((fd = open_disk(pbuf, O_RDONLY)) < 0) {
751 err_print("Error: can't open selected disk '%s'.\n", pbuf);
752 return (-1);
755 status = read(fd, (caddr_t)&mboot, sizeof (struct mboot));
757 if (status != sizeof (struct mboot)) {
758 err_print("Bad read of fdisk partition.\n");
759 return (-1);
762 for (i = 0; i < FD_NUMPART; i++) {
763 int ipc;
765 ipc = i * sizeof (struct ipart);
767 /* Handling the alignment problem of struct ipart */
768 bootptr = &mboot.parts[ipc];
769 (void) fill_ipart(bootptr, &ip);
771 #ifdef i386
772 if (fdisk_is_dos_extended(ip.systid) && (ext_part_found == 0)) {
773 /* We support only one extended partition per disk */
774 ext_part_found = 1;
775 (void) extpart_init(&epp);
776 rval = fdisk_get_solaris_part(epp, &pno, &relsec,
777 &numsec);
778 if (rval == FDISK_SUCCESS) {
780 * Found a solaris partition inside the
781 * extended partition. Update the statistics.
783 if ((label->dkl_nhead != 0) &&
784 (label->dkl_nsect != 0)) {
785 label->dkl_pcyl =
786 numsec / (label->dkl_nhead *
787 label->dkl_nsect);
788 label->dkl_ncyl = label->dkl_pcyl -
789 label->dkl_acyl;
791 solaris_offset = relsec;
793 libfdisk_fini(&epp);
794 continue;
796 #endif
799 * if the disk has an EFI label, the nhead and nsect fields
800 * the label may be zero. This protects us from FPE's, and
801 * format still seems to work happily
803 if (ip.systid == SUNIXOS ||
804 ip.systid == SUNIXOS2 ||
805 ip.systid == EFI_PMBR) {
806 if ((label->dkl_nhead != 0) &&
807 (label->dkl_nsect != 0)) {
808 label->dkl_pcyl = lel(ip.numsect) /
809 (label->dkl_nhead * label->dkl_nsect);
810 label->dkl_ncyl = label->dkl_pcyl -
811 label->dkl_acyl;
813 #ifdef DEBUG
814 else {
815 err_print("Critical label fields aren't "
816 "non-zero:\n"
817 "\tlabel->dkl_nhead = %d; "
818 "label->dkl_nsect = "
819 "%d\n", label->dkl_nhead,
820 label->dkl_nsect);
822 #endif /* DEBUG */
824 solaris_offset = lel(ip.relsect);
825 break;
829 (void) close(fd);
831 return (0);
833 #endif /* defined(_FIRMWARE_NEEDS_FDISK) */
837 good_fdisk()
839 char buf[MAXPATHLEN];
840 struct stat statbuf;
842 (void) get_pname(&buf[0]);
843 if (stat(buf, &statbuf) == -1 ||
844 !S_ISCHR(statbuf.st_mode) ||
845 cur_label == L_TYPE_EFI) {
847 * Return if this disk does not support fdisk table or
848 * if the disk is labeled with EFI.
850 return (1);
853 if (lel(cur_disk->fdisk_part.numsect) > 0) {
854 return (1);
855 } else {
856 err_print("WARNING - ");
857 err_print("This disk may be in use by an application "
858 "that has\n\t modified the fdisk table. Ensure "
859 "that this disk is\n\t not currently in use "
860 "before proceeding to use fdisk.\n");
861 return (0);
866 #ifdef i386
868 extpart_init(ext_part_t **epp)
870 int rval, lf_op_flag = 0;
871 char p0_path[MAXPATHLEN];
873 get_pname(&p0_path[0]);
874 lf_op_flag |= FDISK_READ_DISK;
875 if ((rval = libfdisk_init(epp, p0_path, NULL, lf_op_flag)) !=
876 FDISK_SUCCESS) {
877 switch (rval) {
879 * FDISK_EBADLOGDRIVE and FDISK_ENOLOGDRIVE can
880 * be considered as soft errors and hence
881 * we do not exit
883 case FDISK_EBADLOGDRIVE:
884 break;
885 case FDISK_ENOLOGDRIVE:
886 break;
887 case FDISK_ENOVGEOM:
888 err_print("Could not get virtual geometry for"
889 " this device\n");
890 fullabort();
891 break;
892 case FDISK_ENOPGEOM:
893 err_print("Could not get physical geometry for"
894 " this device\n");
895 fullabort();
896 break;
897 case FDISK_ENOLGEOM:
898 err_print("Could not get label geometry for "
899 " this device\n");
900 fullabort();
901 break;
902 default:
903 err_print("Failed to initialise libfdisk.\n");
904 fullabort();
905 break;
908 return (0);
910 #endif