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]
22 * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2016 Toomas Soome <tsoome@me.com>
27 * This file contains functions that implement the fdisk menu commands.
32 #include <sys/resource.h>
38 #include <sys/dktp/fdisk.h>
40 #include <sys/dklabel.h>
48 #include "menu_command.h"
49 #include "menu_defect.h"
50 #include "menu_partition.h"
51 #include "menu_fdisk.h"
56 #include "partition.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.
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)))
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 */
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
);
102 static int getbyte();
103 static int getlong();
105 #endif /* defined(sparc) */
107 static int get_solaris_part();
109 #endif /* __STDC__ */
112 int extpart_init(ext_part_t
**epp
);
115 * Handling the alignment problem of struct ipart.
118 fill_ipart(char *bootptr
, struct ipart
*partp
)
124 * Packing short/word for struct ipart to resolve
125 * little endian on Sparc since it is not
126 * properly aligned on Sparc.
128 partp
->bootid
= getbyte((uchar_t
**)&bootptr
);
129 partp
->beghead
= getbyte((uchar_t
**)&bootptr
);
130 partp
->begsect
= getbyte((uchar_t
**)&bootptr
);
131 partp
->begcyl
= getbyte((uchar_t
**)&bootptr
);
132 partp
->systid
= getbyte((uchar_t
**)&bootptr
);
133 partp
->endhead
= getbyte((uchar_t
**)&bootptr
);
134 partp
->endsect
= getbyte((uchar_t
**)&bootptr
);
135 partp
->endcyl
= getbyte((uchar_t
**)&bootptr
);
136 partp
->relsect
= getlong((uchar_t
**)&bootptr
);
137 partp
->numsect
= getlong((uchar_t
**)&bootptr
);
142 * The fdisk table does not begin on a 4-byte boundary within
143 * the master boot record; so, we need to recopy its contents
144 * to another data structure to avoid an alignment exception.
146 (void) bcopy(bootptr
, partp
, sizeof (struct ipart
));
148 #error No Platform defined
149 #endif /* defined(sparc) */
153 * Get a correct byte/short/word routines for Sparc platform.
157 getbyte(uchar_t
**bp
)
168 getshort(uchar_t
**bp
)
172 b
= ((**bp
) << 8) | *(*bp
+ 1);
176 #endif /* DEADCODE */
179 getlong(uchar_t
**bp
)
183 bh
= ((**bp
) << 8) | *(*bp
+ 1);
185 bl
= ((**bp
) << 8) | *(*bp
+ 1);
191 #endif /* defined(sparc) */
195 * Convert emcpowerN[a-p,p0,p1,p2,p3,p4] to emcpowerNp0 path,
196 * this is specific for emc powerpath driver.
199 get_emcpower_pname(char *name
, char *devname
)
201 char *emcp
= "emcpower";
204 int i
= strlen(emcp
);
206 (void) strcpy(np
, devname
);
207 npt
= strstr(np
, emcp
);
208 while ((i
< strlen(npt
)) && (isdigit(npt
[i
])))
211 (void) snprintf(name
, MAXNAMELEN
, "/dev/rdsk/%sp0", npt
);
216 * Convert cn[tn]dn to cn[tn]dns2 path
219 get_sname(char *name
)
221 char buf
[MAXPATHLEN
];
222 char *devp
= "/dev/dsk";
223 char *rdevp
= "/dev/rdsk";
228 if (emcpower_name(cur_disk
->disk_name
)) {
229 get_emcpower_pname(name
, cur_disk
->disk_name
);
235 * If it is a full path /dev/[r]dsk/cn[tn]dn, use this path
237 (void) strcpy(np
, cur_disk
->disk_name
);
238 if (strncmp(rdevp
, cur_disk
->disk_name
, strlen(rdevp
)) == 0 ||
239 strncmp(devp
, cur_disk
->disk_name
, strlen(devp
)) == 0) {
241 * Skip if the path is already included with sN
243 if (strchr(np
, 's') == strrchr(np
, 's')) {
244 npt
= strrchr(np
, 'p');
245 /* If pN is found, do not include it */
249 (void) snprintf(buf
, sizeof (buf
), "%ss2", np
);
251 (void) snprintf(buf
, sizeof (buf
), "%s", np
);
254 (void) snprintf(buf
, sizeof (buf
), "/dev/rdsk/%ss2", np
);
256 (void) strcpy(name
, buf
);
260 * Convert cn[tn]dnsn to cn[tn]dnp0 path
263 get_pname(char *name
)
265 char buf
[MAXPATHLEN
];
266 char *devp
= "/dev/dsk";
267 char *rdevp
= "/dev/rdsk";
272 * If it is a full path /dev/[r]dsk/cn[tn]dnsn, use this path
274 if (cur_disk
== NULL
) {
275 (void) strcpy(np
, x86_devname
);
277 (void) strcpy(np
, cur_disk
->disk_name
);
281 if (emcpower_name(np
)) {
282 get_emcpower_pname(name
, np
);
287 if (strncmp(rdevp
, np
, strlen(rdevp
)) == 0 ||
288 strncmp(devp
, np
, strlen(devp
)) == 0) {
290 * Skip if the path is already included with pN
292 if (strchr(np
, 'p') == NULL
) {
293 npt
= strrchr(np
, 's');
294 /* If sN is found, do not include it */
295 if (isdigit(*++npt
)) {
298 (void) snprintf(buf
, sizeof (buf
), "%sp0", np
);
300 (void) snprintf(buf
, sizeof (buf
), "%s", np
);
303 (void) snprintf(buf
, sizeof (buf
), "/dev/rdsk/%sp0", np
);
305 (void) strcpy(name
, buf
);
309 * Open file descriptor for current disk (cur_file)
310 * with "p0" path or cur_disk->disk_path
313 open_cur_file(int mode
)
316 char pbuf
[MAXPATHLEN
];
320 (void) get_pname(&pbuf
[0]);
323 case FD_USE_CUR_DISK_PATH
:
324 if (cur_disk
->fdisk_part
.systid
== SUNIXOS
||
325 cur_disk
->fdisk_part
.systid
== SUNIXOS2
) {
326 (void) get_sname(&pbuf
[0]);
329 dkpath
= cur_disk
->disk_path
;
333 err_print("Error: Invalid mode option for opening "
338 /* Close previous cur_file */
339 (void) close(cur_file
);
340 /* Open cur_file with the required path dkpath */
341 if ((cur_file
= open_disk(dkpath
, O_RDWR
| O_NDELAY
)) < 0) {
343 "Error: can't open selected disk '%s'.\n", dkpath
);
350 * This routine implements the 'fdisk' command. It simply runs
351 * the fdisk command on the current disk.
352 * Use of this is restricted to interactive mode only.
358 char buf
[MAXPATHLEN
];
359 char pbuf
[MAXPATHLEN
];
363 * We must be in interactive mode to use the fdisk command
365 if (option_f
!= (char *)NULL
|| isatty(0) != 1 || isatty(1) != 1) {
366 err_print("Fdisk command is for interactive use only!\n");
371 * There must be a current disk type and a current disk
373 if (cur_dtype
== NULL
) {
374 err_print("Current Disk Type is not set.\n");
379 * Before running the fdisk command, get file status of
380 * /dev/rdsk/cn[tn]dnp0 path to see if this disk
381 * supports fixed disk partition table.
383 (void) get_pname(&pbuf
[0]);
384 if (stat(pbuf
, (struct stat
*)&statbuf
) == -1 ||
385 !S_ISCHR(statbuf
.st_mode
)) {
387 "Disk does not support fixed disk partition table\n");
392 * Run the fdisk program.
394 (void) snprintf(buf
, sizeof (buf
), "fdisk %s\n", pbuf
);
398 * Open cur_file with "p0" path for accessing the fdisk table
400 (void) open_cur_file(FD_USE_P0_PATH
);
403 * Get solaris partition information in the fdisk partition table
405 if (get_solaris_part(cur_file
, &cur_disk
->fdisk_part
) == -1) {
406 err_print("No fdisk solaris partition found\n");
407 cur_disk
->fdisk_part
.numsect
= 0; /* No Solaris */
411 * Restore cur_file with cur_disk->disk_path
413 (void) open_cur_file(FD_USE_CUR_DISK_PATH
);
419 * Read MBR on the disk
420 * if the Solaris partition has changed,
429 register struct partition_info
*parts
;
431 for (i
= 0; i
< NDKMAP
; i
++) {
432 #if defined(_SUNOS_VTOC_16)
433 if (cur_parts
->vtoc
.v_part
[i
].p_tag
&&
434 cur_parts
->vtoc
.v_part
[i
].p_tag
!= V_ALTSCTR
) {
435 cur_parts
->vtoc
.v_part
[i
].p_start
= 0;
436 cur_parts
->vtoc
.v_part
[i
].p_size
= 0;
439 cur_parts
->pinfo_map
[i
].dkl_nblk
= 0;
440 cur_parts
->pinfo_map
[i
].dkl_cylno
= 0;
441 cur_parts
->vtoc
.v_part
[i
].p_tag
=
442 default_vtoc_map
[i
].p_tag
;
443 cur_parts
->vtoc
.v_part
[i
].p_flag
=
444 default_vtoc_map
[i
].p_flag
;
445 #if defined(_SUNOS_VTOC_16)
449 cur_parts
->pinfo_map
[C_PARTITION
].dkl_nblk
= ncyl
* spc();
451 #if defined(_SUNOS_VTOC_16)
453 * Adjust for the boot partitions
455 cur_parts
->pinfo_map
[I_PARTITION
].dkl_nblk
= spc();
456 cur_parts
->pinfo_map
[I_PARTITION
].dkl_cylno
= 0;
457 cur_parts
->vtoc
.v_part
[C_PARTITION
].p_start
=
458 cur_parts
->pinfo_map
[C_PARTITION
].dkl_cylno
* nhead
* nsect
;
459 cur_parts
->vtoc
.v_part
[C_PARTITION
].p_size
=
460 cur_parts
->pinfo_map
[C_PARTITION
].dkl_nblk
;
462 cur_parts
->vtoc
.v_part
[I_PARTITION
].p_start
=
463 cur_parts
->pinfo_map
[I_PARTITION
].dkl_cylno
;
464 cur_parts
->vtoc
.v_part
[I_PARTITION
].p_size
=
465 cur_parts
->pinfo_map
[I_PARTITION
].dkl_nblk
;
467 #endif /* defined(_SUNOS_VTOC_16) */
468 parts
= cur_dtype
->dtype_plist
;
469 cur_dtype
->dtype_ncyl
= ncyl
;
470 cur_dtype
->dtype_plist
= cur_parts
;
471 parts
->pinfo_name
= cur_parts
->pinfo_name
;
472 cur_disk
->disk_parts
= cur_parts
;
473 cur_ctype
->ctype_dlist
= cur_dtype
;
476 #endif /* DEADCODE */
479 get_solaris_part(int fd
, struct ipart
*ipart
)
486 struct dk_label update_label
;
489 uint32_t relsec
, numsec
;
490 int pno
, rval
, ext_part_found
= 0;
494 (void) lseek(fd
, 0, 0);
497 * We may get mbr of different size, but the first 512 bytes
498 * are valid information.
500 mbr
= malloc(cur_blksz
);
502 err_print("No memory available.\n");
505 status
= read(fd
, mbr
, cur_blksz
);
507 if (status
!= cur_blksz
) {
508 err_print("Bad read of fdisk partition. Status = %x\n", status
);
509 err_print("Cannot read fdisk partition information.\n");
514 (void) memcpy(&boot_sec
, mbr
, sizeof (struct mboot
));
518 (void) extpart_init(&epp
);
520 for (i
= 0; i
< FD_NUMPART
; i
++) {
523 ipc
= i
* sizeof (struct ipart
);
525 /* Handling the alignment problem of struct ipart */
526 bootptr
= &boot_sec
.parts
[ipc
];
527 (void) fill_ipart(bootptr
, &ip
);
530 if (fdisk_is_dos_extended(ip
.systid
) && (ext_part_found
== 0)) {
531 /* We support only one extended partition per disk */
533 rval
= fdisk_get_solaris_part(epp
, &pno
, &relsec
,
535 if (rval
== FDISK_SUCCESS
) {
537 * Found a solaris partition inside the
538 * extended partition. Update the statistics.
540 if (nhead
!= 0 && nsect
!= 0) {
541 pcyl
= numsec
/ (nhead
* nsect
);
542 xstart
= relsec
/ (nhead
* nsect
);
545 solaris_offset
= relsec
;
548 ip
.beghead
= ip
.begsect
= ip
.begcyl
= 0xff;
549 ip
.endhead
= ip
.endsect
= ip
.endcyl
= 0xff;
550 ip
.systid
= SUNIXOS2
;
553 ipart
->bootid
= ip
.bootid
;
554 status
= bcmp(&ip
, ipart
,
555 sizeof (struct ipart
));
556 bcopy(&ip
, ipart
, sizeof (struct ipart
));
563 * we are interested in Solaris and EFI partition types
566 if ((ip
.systid
== SUNIXOS
&&
567 (fdisk_is_linux_swap(epp
, lel(ip
.relsect
), NULL
) != 0)) ||
568 ip
.systid
== SUNIXOS2
||
569 ip
.systid
== EFI_PMBR
) {
571 if (ip
.systid
== SUNIXOS
||
572 ip
.systid
== SUNIXOS2
||
573 ip
.systid
== EFI_PMBR
) {
576 * if the disk has an EFI label, nhead and nsect may
577 * be zero. This test protects us from FPE's, and
578 * format still seems to work fine
580 if (nhead
!= 0 && nsect
!= 0) {
581 pcyl
= lel(ip
.numsect
) / (nhead
* nsect
);
582 xstart
= lel(ip
.relsect
) / (nhead
* nsect
);
587 err_print("Critical geometry values are zero:\n"
588 "\tnhead = %d; nsect = %d\n", nhead
, nsect
);
592 solaris_offset
= (uint_t
)lel(ip
.relsect
);
603 err_print("Solaris fdisk partition not found\n");
605 } else if (found
== 1) {
607 * Found a primary solaris partition.
608 * compare the previous and current Solaris partition
609 * but don't use bootid in determination of Solaris partition
612 ipart
->bootid
= ip
.bootid
;
613 status
= bcmp(&ip
, ipart
, sizeof (struct ipart
));
615 bcopy(&ip
, ipart
, sizeof (struct ipart
));
618 /* if the disk partitioning has changed - get the VTOC */
620 struct extvtoc exvtoc
;
623 status
= ioctl(fd
, DKIOCGEXTVTOC
, &exvtoc
);
626 /* Try the old ioctl DKIOCGVTOC */
627 status
= ioctl(fd
, DKIOCGVTOC
, &vtoc
);
629 err_print("Bad ioctl DKIOCGEXTVTOC.\n");
630 err_print("errno=%d %s\n", i
, strerror(i
));
631 err_print("Cannot read vtoc information.\n");
636 status
= read_label(fd
, &update_label
);
638 err_print("Cannot read label information.\n");
642 /* copy vtoc information */
643 cur_parts
->vtoc
= update_label
.dkl_vtoc
;
645 #if defined(_SUNOS_VTOC_16)
647 * this is to update the slice table on x86
648 * we don't care about VTOC8 here
650 for (i
= 0; i
< NDKMAP
; i
++) {
651 cur_parts
->pinfo_map
[i
].dkl_cylno
=
652 update_label
.dkl_vtoc
.v_part
[i
].p_start
/
653 ((int)(update_label
.dkl_nhead
*
654 update_label
.dkl_nsect
));
655 cur_parts
->pinfo_map
[i
].dkl_nblk
=
656 update_label
.dkl_vtoc
.v_part
[i
].p_size
;
658 #endif /* defined(_SUNOS_VTOC_16) */
660 cur_dtype
->dtype_ncyl
= update_label
.dkl_ncyl
;
661 cur_dtype
->dtype_pcyl
= update_label
.dkl_pcyl
;
662 cur_dtype
->dtype_acyl
= update_label
.dkl_acyl
;
663 cur_dtype
->dtype_nhead
= update_label
.dkl_nhead
;
664 cur_dtype
->dtype_nsect
= update_label
.dkl_nsect
;
665 ncyl
= cur_dtype
->dtype_ncyl
;
666 acyl
= cur_dtype
->dtype_acyl
;
667 pcyl
= cur_dtype
->dtype_pcyl
;
668 nsect
= cur_dtype
->dtype_nsect
;
669 nhead
= cur_dtype
->dtype_nhead
;
676 copy_solaris_part(struct ipart
*ipart
)
683 char buf
[MAXPATHLEN
];
687 uint32_t relsec
, numsec
;
688 int pno
, rval
, ext_part_found
= 0;
692 (void) get_pname(&buf
[0]);
693 if (stat(buf
, &statbuf
) == -1 ||
694 !S_ISCHR(statbuf
.st_mode
) ||
695 ((cur_label
== L_TYPE_EFI
) &&
696 (cur_disk
->disk_flags
& DSK_LABEL_DIRTY
))) {
698 * Make sure to reset solaris_offset to zero if it is
699 * previously set by a selected disk that
700 * supports the fdisk table.
704 * Return if this disk does not support fdisk table or
705 * if it uses an EFI label but has not yet been labelled.
706 * If the EFI label has not been written then the open
707 * on the partition will fail.
712 if ((fd
= open(buf
, O_RDONLY
)) < 0) {
714 * Labeled device support in lofi provides p0 partition on
715 * both x86 and sparc. However, sparc does not implement fdisk
716 * partitioning. This workaround will allow format
717 * to ignore fdisk errors in case of lofi devices.
719 if (strcmp(cur_disk
->disk_dkinfo
.dki_cname
, "lofi") == 0) {
723 err_print("Error: can't open disk '%s'.\n", buf
);
728 * We may get mbr of different size, but the first 512 bytes
729 * are valid information.
731 mbr
= malloc(cur_blksz
);
733 err_print("No memory available.\n");
736 status
= read(fd
, mbr
, cur_blksz
);
738 if (status
!= cur_blksz
) {
739 err_print("Bad read of fdisk partition.\n");
745 (void) memcpy(&mboot
, mbr
, sizeof (struct mboot
));
748 (void) extpart_init(&epp
);
750 for (i
= 0; i
< FD_NUMPART
; i
++) {
753 ipc
= i
* sizeof (struct ipart
);
755 /* Handling the alignment problem of struct ipart */
756 bootptr
= &mboot
.parts
[ipc
];
757 (void) fill_ipart(bootptr
, &ip
);
760 if (fdisk_is_dos_extended(ip
.systid
) && (ext_part_found
== 0)) {
761 /* We support only one extended partition per disk */
763 rval
= fdisk_get_solaris_part(epp
, &pno
, &relsec
,
765 if (rval
== FDISK_SUCCESS
) {
767 * Found a solaris partition inside the
768 * extended partition. Update the statistics.
770 if (nhead
!= 0 && nsect
!= 0) {
771 pcyl
= numsec
/ (nhead
* nsect
);
774 solaris_offset
= relsec
;
776 ip
.beghead
= ip
.begsect
= ip
.begcyl
= 0xff;
777 ip
.endhead
= ip
.endsect
= ip
.endcyl
= 0xff;
778 ip
.systid
= SUNIXOS2
;
781 bcopy(&ip
, ipart
, sizeof (struct ipart
));
789 if ((ip
.systid
== SUNIXOS
&&
790 (fdisk_is_linux_swap(epp
, lel(ip
.relsect
), NULL
) != 0)) ||
791 ip
.systid
== SUNIXOS2
||
792 ip
.systid
== EFI_PMBR
) {
794 if (ip
.systid
== SUNIXOS
||
795 ip
.systid
== SUNIXOS2
||
796 ip
.systid
== EFI_PMBR
) {
798 solaris_offset
= lel(ip
.relsect
);
799 bcopy(&ip
, ipart
, sizeof (struct ipart
));
802 * if the disk has an EFI label, we typically won't
803 * have values for nhead and nsect. format seems to
804 * work without them, and we need to protect ourselves
807 if (nhead
!= 0 && nsect
!= 0) {
808 pcyl
= lel(ip
.numsect
) / (nhead
* nsect
);
813 err_print("Critical geometry values are zero:\n"
814 "\tnhead = %d; nsect = %d\n", nhead
, nsect
);
830 #if defined(_FIRMWARE_NEEDS_FDISK)
832 auto_solaris_part(struct dk_label
*label
)
840 char pbuf
[MAXPATHLEN
];
842 uint32_t relsec
, numsec
;
843 int pno
, rval
, ext_part_found
= 0;
847 (void) get_pname(&pbuf
[0]);
848 if ((fd
= open_disk(pbuf
, O_RDONLY
)) < 0) {
849 err_print("Error: can't open selected disk '%s'.\n", pbuf
);
854 * We may get mbr of different size, but the first 512 bytes
855 * are valid information.
857 mbr
= malloc(cur_blksz
);
859 err_print("No memory available.\n");
862 status
= read(fd
, mbr
, cur_blksz
);
864 if (status
!= cur_blksz
) {
865 err_print("Bad read of fdisk partition.\n");
870 (void) memcpy(&mboot
, mbr
, sizeof (struct mboot
));
873 (void) extpart_init(&epp
);
875 for (i
= 0; i
< FD_NUMPART
; i
++) {
878 ipc
= i
* sizeof (struct ipart
);
880 /* Handling the alignment problem of struct ipart */
881 bootptr
= &mboot
.parts
[ipc
];
882 (void) fill_ipart(bootptr
, &ip
);
885 if (fdisk_is_dos_extended(ip
.systid
) && (ext_part_found
== 0)) {
886 /* We support only one extended partition per disk */
888 rval
= fdisk_get_solaris_part(epp
, &pno
, &relsec
,
890 if (rval
== FDISK_SUCCESS
) {
892 * Found a solaris partition inside the
893 * extended partition. Update the statistics.
895 if ((label
->dkl_nhead
!= 0) &&
896 (label
->dkl_nsect
!= 0)) {
898 numsec
/ (label
->dkl_nhead
*
900 label
->dkl_ncyl
= label
->dkl_pcyl
-
903 solaris_offset
= relsec
;
910 * if the disk has an EFI label, the nhead and nsect fields
911 * the label may be zero. This protects us from FPE's, and
912 * format still seems to work happily
917 if ((ip
.systid
== SUNIXOS
&&
918 (fdisk_is_linux_swap(epp
, lel(ip
.relsect
), NULL
) != 0)) ||
919 ip
.systid
== SUNIXOS2
||
920 ip
.systid
== EFI_PMBR
) {
922 if (ip
.systid
== SUNIXOS
||
923 ip
.systid
== SUNIXOS2
||
924 ip
.systid
== EFI_PMBR
) {
926 if ((label
->dkl_nhead
!= 0) &&
927 (label
->dkl_nsect
!= 0)) {
928 label
->dkl_pcyl
= lel(ip
.numsect
) /
929 (label
->dkl_nhead
* label
->dkl_nsect
);
930 label
->dkl_ncyl
= label
->dkl_pcyl
-
935 err_print("Critical label fields aren't "
937 "\tlabel->dkl_nhead = %d; "
938 "label->dkl_nsect = "
939 "%d\n", label
->dkl_nhead
,
944 solaris_offset
= lel(ip
.relsect
);
956 #endif /* defined(_FIRMWARE_NEEDS_FDISK) */
962 char buf
[MAXPATHLEN
];
965 (void) get_pname(&buf
[0]);
966 if (stat(buf
, &statbuf
) == -1 ||
967 !S_ISCHR(statbuf
.st_mode
) ||
968 cur_label
== L_TYPE_EFI
) {
970 * Return if this disk does not support fdisk table or
971 * if the disk is labeled with EFI.
976 if (lel(cur_disk
->fdisk_part
.numsect
) > 0) {
980 * Labeled device support in lofi provides p0 partition on
981 * both x86 and sparc. However, sparc does not implement fdisk
982 * partitioning. This workaround will allow format
983 * to ignore fdisk errors in case of lofi devices.
985 if (strcmp(cur_disk
->disk_dkinfo
.dki_cname
, "lofi") == 0) {
988 err_print("WARNING - ");
989 err_print("This disk may be in use by an application "
990 "that has\n\t modified the fdisk table. Ensure "
991 "that this disk is\n\t not currently in use "
992 "before proceeding to use fdisk.\n");
999 extpart_init(ext_part_t
**epp
)
1001 int rval
, lf_op_flag
= 0;
1002 char p0_path
[MAXPATHLEN
];
1004 get_pname(&p0_path
[0]);
1005 lf_op_flag
|= FDISK_READ_DISK
;
1006 if ((rval
= libfdisk_init(epp
, p0_path
, NULL
, lf_op_flag
)) !=
1010 * FDISK_EBADLOGDRIVE, FDISK_ENOLOGDRIVE
1011 * and FDISK_EBADMAGIC can be considered
1012 * as soft errors and hence we do not exit.
1014 case FDISK_EBADLOGDRIVE
:
1016 case FDISK_ENOLOGDRIVE
:
1018 case FDISK_EBADMAGIC
:
1020 case FDISK_ENOVGEOM
:
1021 err_print("Could not get virtual geometry for"
1025 case FDISK_ENOPGEOM
:
1026 err_print("Could not get physical geometry for"
1030 case FDISK_ENOLGEOM
:
1031 err_print("Could not get label geometry for "
1036 err_print("Failed to initialise libfdisk.\n");