menu_fdisk.c revision e998e519114d9176339a9115abd802dfdebde87f
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Common Development and Distribution License (the "License").
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling * Use is subject to license terms.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This file contains functions that implement the fdisk menu commands.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Byte swapping macros for accessing struct ipart
fa9e4066f08beec538e775443c5be79dd423fcabahrens * to resolve little endian on Sparc.
fa9e4066f08beec538e775443c5be79dd423fcabahrens#if defined(sparc)
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define les(val) ((((val)&0xFF)<<8)|(((val)>>8)&0xFF))
f94275ce205810a201404c5f35f4cc96057022b1Adam Leventhal#define lel(val) (((unsigned)(les((val)&0x0000FFFF))<<16) | \
fa9e4066f08beec538e775443c5be79dd423fcabahrens#else /* defined(sparc) */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* defined(sparc) */
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* Function prototypes */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* defined(sparc) */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int get_solaris_part(int fd, struct ipart *ipart);
fa9e4066f08beec538e775443c5be79dd423fcabahrens#else /* __STDC__ */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#if defined(sparc)
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int getbyte();
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int getlong();
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* defined(sparc) */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* __STDC__ */
46a2abf27af40eda17a3f97e79eda1aef4e3c3c8eschrock * Handling the alignment problem of struct ipart.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Sparc platform:
46a2abf27af40eda17a3f97e79eda1aef4e3c3c8eschrock * Packing short/word for struct ipart to resolve
46a2abf27af40eda17a3f97e79eda1aef4e3c3c8eschrock * little endian on Sparc since it is not
fa9e4066f08beec538e775443c5be79dd423fcabahrens * properly aligned on Sparc.
03a818bc5cc6f80c183dfb3334f4d0ff2ab36fccmmusante * i386 platform:
03a818bc5cc6f80c183dfb3334f4d0ff2ab36fccmmusante * The fdisk table does not begin on a 4-byte boundary within
03a818bc5cc6f80c183dfb3334f4d0ff2ab36fccmmusante * the master boot record; so, we need to recopy its contents
03a818bc5cc6f80c183dfb3334f4d0ff2ab36fccmmusante * to another data structure to avoid an alignment exception.
46a2abf27af40eda17a3f97e79eda1aef4e3c3c8eschrock (void) bcopy(bootptr, partp, sizeof (struct ipart));
46657f8d750bdb71753495ce2919170f126b8e34mmusante#endif /* defined(sparc) */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Get a correct byte/short/word routines for Sparc platform.
fa9e4066f08beec538e775443c5be79dd423fcabahrens#if defined(sparc)
181c2f42873ba1b0fdc4d0470593ad30176af1f0mmusante return (b);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (b);
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* DEADCODE */
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (b);
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* defined(sparc) */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Convert cn[tn]dn to cn[tn]dns2 path
46a2abf27af40eda17a3f97e79eda1aef4e3c3c8eschrock * If it is a full path /dev/[r]dsk/cn[tn]dn, use this path
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (strncmp(rdevp, cur_disk->disk_name, strlen(rdevp)) == 0 ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens strncmp(devp, cur_disk->disk_name, strlen(devp)) == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Skip if the path is already included with sN
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* If pN is found, do not include it */
46a2abf27af40eda17a3f97e79eda1aef4e3c3c8eschrock (void) snprintf(buf, sizeof (buf), "/dev/rdsk/%ss2", np);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Convert cn[tn]dnsn to cn[tn]dnp0 path
99653d4ee642c6528e88224f12409a5f23060994eschrock * If it is a full path /dev/[r]dsk/cn[tn]dnsn, use this path
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * Skip if the path is already included with pN
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* If sN is found, do not include it */
46a2abf27af40eda17a3f97e79eda1aef4e3c3c8eschrock (void) snprintf(buf, sizeof (buf), "/dev/rdsk/%sp0", np);
99653d4ee642c6528e88224f12409a5f23060994eschrock * Open file descriptor for current disk (cur_file)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * with "p0" path or cur_disk->disk_path
181c2f42873ba1b0fdc4d0470593ad30176af1f0mmusante err_print("Error: Invalid mode option for opening "
181c2f42873ba1b0fdc4d0470593ad30176af1f0mmusante "cur_file\n");
99653d4ee642c6528e88224f12409a5f23060994eschrock /* Close previous cur_file */
46a2abf27af40eda17a3f97e79eda1aef4e3c3c8eschrock /* Open cur_file with the required path dkpath */
46a2abf27af40eda17a3f97e79eda1aef4e3c3c8eschrock if ((cur_file = open_disk(dkpath, O_RDWR | O_NDELAY)) < 0) {
46a2abf27af40eda17a3f97e79eda1aef4e3c3c8eschrock "Error: can't open selected disk '%s'.\n", dkpath);
46a2abf27af40eda17a3f97e79eda1aef4e3c3c8eschrock * This routine implements the 'fdisk' command. It simply runs
46a2abf27af40eda17a3f97e79eda1aef4e3c3c8eschrock * the fdisk command on the current disk.
46a2abf27af40eda17a3f97e79eda1aef4e3c3c8eschrock * Use of this is restricted to interactive mode only.
99653d4ee642c6528e88224f12409a5f23060994eschrock * We must be in interactive mode to use the fdisk command
99653d4ee642c6528e88224f12409a5f23060994eschrock if (option_f != (char *)NULL || isatty(0) != 1 || isatty(1) != 1) {
99653d4ee642c6528e88224f12409a5f23060994eschrock err_print("Fdisk command is for interactive use only!\n");
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
99653d4ee642c6528e88224f12409a5f23060994eschrock * There must be a current disk type and a current disk
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Before running the fdisk command, get file status of
fa9e4066f08beec538e775443c5be79dd423fcabahrens * /dev/rdsk/cn[tn]dnp0 path to see if this disk
fa9e4066f08beec538e775443c5be79dd423fcabahrens * supports fixed disk partition table.
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor "Disk does not support fixed disk partition table\n");
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor return (0);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * Run the fdisk program.
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor (void) snprintf(buf, sizeof (buf), "fdisk %s\n", pbuf);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Open cur_file with "p0" path for accessing the fdisk table
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * Get solaris partition information in the fdisk partition table
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor if (get_solaris_part(cur_file, &cur_disk->fdisk_part) == -1) {
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * Restore cur_file with cur_disk->disk_path
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Read MBR on the disk
fa9e4066f08beec538e775443c5be79dd423fcabahrens * if the Solaris partition has changed,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * reread the vtoc
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < NDKMAP; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens cur_parts->pinfo_map[C_PARTITION].dkl_nblk = ncyl * spc();
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Adjust for the boot partitions
fa9e4066f08beec538e775443c5be79dd423fcabahrens cur_parts->pinfo_map[C_PARTITION].dkl_cylno * nhead * nsect;
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* defined(_SUNOS_VTOC_16) */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* DEADCODE */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We may get mbr of different size, but the first 512 bytes
fa9e4066f08beec538e775443c5be79dd423fcabahrens * are valid information.
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens err_print("Bad read of fdisk partition. Status = %x\n", status);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin err_print("Cannot read fdisk partition information.\n");
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) memcpy(&boot_sec, mbr, sizeof (struct mboot));
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < FD_NUMPART; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Handling the alignment problem of struct ipart */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (fdisk_is_dos_extended(ip.systid) && (ext_part_found == 0)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* We support only one extended partition per disk */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Found a solaris partition inside the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * extended partition. Update the statistics.
fa9e4066f08beec538e775443c5be79dd423fcabahrens sizeof (struct ipart));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * we are interested in Solaris and EFI partition types
99653d4ee642c6528e88224f12409a5f23060994eschrock (fdisk_is_linux_swap(epp, lel(ip.relsect), NULL) != 0)) ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens * if the disk has an EFI label, nhead and nsect may
fa9e4066f08beec538e775443c5be79dd423fcabahrens * be zero. This test protects us from FPE's, and
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * format still seems to work fine
b327cd3f3b4dab4f29e7140159b1e01ed2ceef2aIgor Kozhukhov err_print("Critical geometry values are zero:\n"
99653d4ee642c6528e88224f12409a5f23060994eschrock#endif /* DEBUG */
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin return (-1);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin * Found a primary solaris partition.
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin * compare the previous and current Solaris partition
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin * but don't use bootid in determination of Solaris partition
99653d4ee642c6528e88224f12409a5f23060994eschrock /* if the disk partitioning has changed - get the VTOC */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Try the old ioctl DKIOCGVTOC */
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
99653d4ee642c6528e88224f12409a5f23060994eschrock /* copy vtoc information */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * this is to update the slice table on x86
fa9e4066f08beec538e775443c5be79dd423fcabahrens * we don't care about VTOC8 here
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < NDKMAP; i ++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* defined(_SUNOS_VTOC_16) */
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Make sure to reset solaris_offset to zero if it is
fa9e4066f08beec538e775443c5be79dd423fcabahrens * previously set by a selected disk that
fa9e4066f08beec538e775443c5be79dd423fcabahrens * supports the fdisk table.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Return if this disk does not support fdisk table or
fa9e4066f08beec538e775443c5be79dd423fcabahrens * if it uses an EFI label but has not yet been labelled.
99653d4ee642c6528e88224f12409a5f23060994eschrock * If the EFI label has not been written then the open
fa9e4066f08beec538e775443c5be79dd423fcabahrens * on the partition will fail.
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We may get mbr of different size, but the first 512 bytes
fa9e4066f08beec538e775443c5be79dd423fcabahrens * are valid information.
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor for (i = 0; i < FD_NUMPART; i++) {
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor /* Handling the alignment problem of struct ipart */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (fdisk_is_dos_extended(ip.systid) && (ext_part_found == 0)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* We support only one extended partition per disk */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Found a solaris partition inside the
99653d4ee642c6528e88224f12409a5f23060994eschrock * extended partition. Update the statistics.
fa9e4066f08beec538e775443c5be79dd423fcabahrens (fdisk_is_linux_swap(epp, lel(ip.relsect), NULL) != 0)) ||
99653d4ee642c6528e88224f12409a5f23060994eschrock * if the disk has an EFI label, we typically won't
99653d4ee642c6528e88224f12409a5f23060994eschrock * have values for nhead and nsect. format seems to
99653d4ee642c6528e88224f12409a5f23060994eschrock * work without them, and we need to protect ourselves
99653d4ee642c6528e88224f12409a5f23060994eschrock * from FPE's
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* DEBUG */
99653d4ee642c6528e88224f12409a5f23060994eschrock return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens err_print("Error: can't open selected disk '%s'.\n", pbuf);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We may get mbr of different size, but the first 512 bytes
fa9e4066f08beec538e775443c5be79dd423fcabahrens * are valid information.
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor return (-1);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor return (-1);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin for (i = 0; i < FD_NUMPART; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Handling the alignment problem of struct ipart */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (fdisk_is_dos_extended(ip.systid) && (ext_part_found == 0)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* We support only one extended partition per disk */
99653d4ee642c6528e88224f12409a5f23060994eschrock * Found a solaris partition inside the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * extended partition. Update the statistics.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * if the disk has an EFI label, the nhead and nsect fields
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the label may be zero. This protects us from FPE's, and
fa9e4066f08beec538e775443c5be79dd423fcabahrens * format still seems to work happily
fa9e4066f08beec538e775443c5be79dd423fcabahrens (fdisk_is_linux_swap(epp, lel(ip.relsect), NULL) != 0)) ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens "non-zero:\n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\tlabel->dkl_nhead = %d; "
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock "label->dkl_nsect = "
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* DEBUG */
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* defined(_FIRMWARE_NEEDS_FDISK) */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Return if this disk does not support fdisk table or
fa9e4066f08beec538e775443c5be79dd423fcabahrens * if the disk is labeled with EFI.
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens err_print("This disk may be in use by an application "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "that has\n\t modified the fdisk table. Ensure "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "that this disk is\n\t not currently in use "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "before proceeding to use fdisk.\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock if ((rval = libfdisk_init(epp, p0_path, NULL, lf_op_flag)) !=
fa9e4066f08beec538e775443c5be79dd423fcabahrens * FDISK_EBADLOGDRIVE and FDISK_ENOLOGDRIVE can
fa9e4066f08beec538e775443c5be79dd423fcabahrens * be considered as soft errors and hence
fa9e4066f08beec538e775443c5be79dd423fcabahrens * we do not exit
99653d4ee642c6528e88224f12409a5f23060994eschrock " this device\n");
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan " this device\n");
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan " this device\n");
99653d4ee642c6528e88224f12409a5f23060994eschrock return (0);