fdisk.c revision d463bb94f213817526ea7f7b2b8219ef1fe801d9
0N/A * The contents of this file are subject to the terms of the 0N/A * Common Development and Distribution License (the "License"). 0N/A * You may not use this file except in compliance with the License. 0N/A * See the License for the specific language governing permissions 0N/A * and limitations under the License. 0N/A * When distributing Covered Code, include this CDDL HEADER in each 0N/A * If applicable, add the following below this CDDL HEADER, with the 0N/A * fields enclosed by brackets "[]" replaced with your own identifying 0N/A * information: Portions Copyright [yyyy] [name of copyright owner] 0N/A * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 0N/A * Use is subject to license terms. 0N/A/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ 2366N/A/* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */ 4134N/A/* Copyright (c) 1987, 1988 Microsoft Corporation */ 4134N/A * This program reads the partition table on the specified device and 4134N/A * also reads the drive parameters. The user can perform various 4134N/A * operations from a supplied menu or from the command line. Diagnostic 0N/A * options are also available. 1689N/A#
define HOME "[1;1H[0K[2;1H[0K[3;1H[0K[4;1H[0K[5;1H[0K" \
0N/A "[6;1H[0K[7;1H[0K[8;1H[0K[9;1H[0K[10;1H[0K[1;1H" 1859N/A#
define M_LINE "[13;1H[0K[14;1H[0K[15;1H[0K[16;1H[0K[17;1H" \
3894N/A "[0K[18;1H[0K[19;1H[0K[13;1H" 4134N/A * the MAX values are the maximum usable values for BIOS chs values 4134N/A * The MAX_CYL value of 1022 is the maximum usable value 1689N/A * the value of 1023 is a fence value, 4134N/A * indicating no CHS geometry exists for the corresponding LBA value. 4134N/A * HEAD range [ 0 .. MAX_HEAD ], so number of heads is (MAX_HEAD + 1) 338N/A * SECT range [ 1 .. MAX_SECT ], so number of sectors is (MAX_SECT) 4134N/A * Support for fdisk(1M) on the SPARC platform 4134N/A * In order to convert little endian values to big endian for SPARC, 4134N/A * These swapping macros will be used to access information in the 4134N/A * mboot and ipart structures. 4134N/A"[ -A id:act:bhead:bsect:bcyl:ehead:esect:ecyl:rsect:numsect ]\n" 4134N/A"[ -D id:act:bhead:bsect:bcyl:ehead:esect:ecyl:rsect:numsect ]\n" 0N/A"[ -F fdisk_file ] [ -h ] [ -o offset ] [ -P fill_patt ] [ -s size ]\n" 0N/A"[ -S geom_file ] [ [ -v ] -W { creat_fdisk_file | - } ]\n" 4134N/A"[ -w | r | d | n | I | B | E | g | G | R | t | T ] rdevice";
0N/A" -A id:act:bhead:bsect:bcyl:ehead:esect:ecyl:rsect:numsect\n" 0N/A" Create a partition with specific attributes:\n" 0N/A" act = active partition flag (0 is off and 128 is on)\n" 3853N/A" bhead = beginning head for start of partition\n" 3853N/A" bsect = beginning sector for start of partition\n" 3853N/A" bcyl = beginning cylinder for start of partition\n" 3853N/A" ehead = ending head for end of partition\n" 3853N/A" esect = ending sector for end of partition\n" 4134N/A" ecyl = ending cylinder for end of partition\n" 0N/A" rsect = sector number from start of disk for\n" 0N/A" start of partition\n" 4134N/A" numsect = partition size in sectors\n" 4134N/A" Use master_boot as the master boot file.\n" 4134N/A" -B Create one Solaris partition that uses the entire disk.\n" 0N/A" -E Create one EFI partition that uses the entire disk.\n" 0N/A" -D id:act:bhead:bsect:bcyl:ehead:esect:ecyl:rsect:numsect\n" 0N/A" Delete a partition. See attribute definitions for -A.\n" 0N/A" Use fdisk_file to initialize on-line fdisk table.\n" 4134N/A" -I Forego device checks. Generate a file image of what would go\n" 4134N/A" on a disk using the geometry specified with the -S option.\n" 4134N/A" -n Do not run in interactive mode.\n" 0N/A" -R Open the disk device as read-only.\n" 0N/A" -t Check and adjust VTOC to be consistent with fdisk table.\n" 0N/A" VTOC slices exceeding the partition size will be truncated.\n" 4134N/A" -T Check and adjust VTOC to be consistent with fdisk table.\n" 0N/A" VTOC slices exceeding the partition size will be removed.\n" 4134N/A" Write on-disk table to fdisk_file.\n" 0N/A" -W - Write on-disk table to standard output.\n" 3999N/A" -v Display virtual geometry. Must be used with the -W option.\n" 3999N/A" -d Activate debug information about progress.\n" 0N/A" -g Write label geometry to standard output:\n" 4134N/A" PCYL number of physical cylinders\n" 0N/A" NCYL number of usable cylinders\n" 4134N/A" ACYL number of alternate cylinders\n" 0N/A" NSECTORS number of sectors per track\n" 4134N/A" SECTSIZ size of a sector in bytes\n" 4134N/A" -G Write physical geometry to standard output (see -g).\n" 4134N/A" -h Issue this verbose help message.\n" 0N/A" Block offset from start of disk (default 0). Ignored if\n" 0N/A" Fill disk with pattern fill_patt. fill_patt can be decimal or\n" 4134N/A" hexadecimal and is used as number for constant long word\n" 0N/A" pattern. If fill_patt is \"#\" then pattern of block #\n" 4134N/A" for each block. Pattern is put in each block as long words\n" 4134N/A" and fills each block (see -o and -s).\n" 4134N/A" -r Read from a disk to stdout (see -o and -s).\n" 4134N/A" -s size Number of blocks on which to perform operation (see -o).\n" 4134N/A" Use geom_file to set the label geometry (see -g).\n" 4134N/A" -w Write to a disk from stdin (see -o and -s).";
0N/A/* All the user options and flags */ 0N/Astatic char *
Dfltdev;
/* name of fixed disk drive */ 4134N/Astatic int io_rd = 0;
/* read disk and write stdout (-r) */ 4134N/Astatic int io_patt = 0;
/* write pattern to disk (-P pattern) */ 0N/Astatic int io_pgeom = 0;
/* get drive physical geometry (-G) */ 0N/Astatic char *
io_sgeom = 0;
/* set label geometry (-S geom_file) */ 0N/A/* The -o offset and -s size options specify the area of the disk on */ 0N/A/* which to perform the particular operation; i.e., -P, -r, or -w. */ 3894N/Astatic int v_flag = 0;
/* virtual geometry-HBA flag (-v) */ 0N/A/* Disk geometry information */ 4142N/A /* used to limit fdisk to 2TB */ 4142N/A/* Physical geometry for the drive */ 4142N/Astatic int acyl;
/* number of alternate sectors */ 0N/A/* HBA (virtual) geometry for the drive */ 0N/A/* Load functions for fdisk table modification */ 4134N/A * Copy the new table back to the sector buffer 0N/A * and write it to disk 0N/A /* If the VTOC table is wrong fix it (truncation only) */ 0N/A * Process command-line options. 0N/A /* Process the options. */ 0N/A * If '-' is the -W argument, then write 0N/A * to standard output, otherwise write 0N/A * to the specified file. 309N/A /* User option checking */ 309N/A /* By default, run in interactive mode */ 4134N/A /* Was any error detected? */ 309N/A "\nDetailed help is available with the -h option.\n");
4134N/A /* Figure out the correct device node to open */ 0N/A "fdisk: Cannot open device %s.\n",
0N/A * not all disk (or disklike) drivers support DKIOCGMEDIAINFO 0N/A * in that case leave the minfo structure zeroed 0N/A /* Get the disk geometry */ 4134N/A /* Get disk's HBA (virtual) geometry */ 0N/A * If ioctl isn't implemented on this platform, then 0N/A * turn off flag to print out virtual geometry (-v), 0N/A * otherwise use the virtual geometry. 0N/A * This means that the ioctl exists, but 0N/A * is invalid for this disk, meaning the 0N/A * disk doesn't have an HBA geometry 0N/A * (like, say, it's larger than 8GB). 4134N/A "%s: Cannot get virtual disk geometry.\n",
4134N/A /* save virtual geometry values obtained by ioctl */ 4134N/A "%s: Cannot get physical disk geometry.\n",
4134N/A * Call DKIOCGGEOM if the ioctls for physical and virtual 4134N/A * geometry fail. Get both from this generic call. 4134N/A "%s: Cannot get disk label geometry.\n",
4134N/A * if hba geometry was not set by DKIOC_VIRTGEOM 4134N/A * or we got an invalid hba geometry 4134N/A * then set hba geometry based on max values 0N/A * turn off flag to print out virtual geometry (-v) 4134N/A " cylinders[%d] heads[%d] sectors[%d]\n" 4134N/A " sector size[%d] blocks[%d] mbytes[%d]\n",
4134N/A " cylinders[%d] heads[%d] sectors[%d]\n" 4134N/A " sector size[%d] blocks[%d] mbytes[%d]\n",
4134N/A /* If user has requested a geometry report just do it and exit */ 0N/A "%s: Cannot get disk label geometry.\n",
0N/A "* PCYL NCYL ACYL BCYL NHEAD NSECT" 0N/A (
void)
printf(
" %-8d %-8d %-8d %-8d %-5d %-5d %-6d\n",
0N/A "%s: Cannot get physical disk geometry.\n",
4134N/A "* PCYL NCYL ACYL BCYL NHEAD NSECT" 0N/A (
void)
printf(
" %-8d %-8d %-8d %-8d %-5d %-5d %-6d\n",
4134N/A * some drivers may not support DKIOCGMEDIAINFO 0N/A /* Allocate memory to hold three complete sectors */ 4134N/A "fdisk: Unable to obtain enough buffer memory" 4134N/A /* Zero out the "NULL" sector */ 4134N/A /* Find out what the user wants done */ 4134N/A /* This is the fdisk edit, the real reason for the program. */ 4134N/A /* Get the new BOOT program in case we write a new fdisk table */ 4134N/A /* Read from disk master boot */ 4134N/A * Verify and copy the device's fdisk table. This will be used 2464N/A * as the prototype mboot if the device's mboot looks invalid. 4134N/A /* save away a copy of Table in Old_Table for sensing changes */ 4134N/A /* Load fdisk table from specified file (-F fdisk_file) */ 4134N/A /* Load and verify user-specified table parameters */ 4134N/A /* Does user want to delete or add an entry? */ 0N/A /* Check if there is no fdisk table */ 4134N/A "No fdisk table exists. The default" 4134N/A " partition for the disk is:\n\n" 4134N/A " a 100%% \"SOLARIS System\" " 4134N/A "Type \"y\" to accept the default " 4134N/A "partition, otherwise type \"n\" to " 4134N/A "edit the\n partition table.\n");
4134N/A " than 2TB. Solaris partition will" 0N/A /* Edit the partition table as directed */ 4134N/A /* now set up UNIX System partition */ 3109N/A /* calculate CHS values for table entry 0 */ 0N/A /* create an EFI partition for the whole disk */ 0N/A "Error creating EFI partition\n");
3679N/A /* Display complete fdisk table entries for debugging purposes */ 4134N/A /* Interactive fdisk mode */ 4134N/A /* If user wants to write the table to a file, do it */ 0N/A * Read geometry from specified file (-S). 4134N/A /* open the prototype file */ 4134N/A /* Read a line from the file */ 0N/A "Syntax error:\n \"%s\".\n",
0N/A }
/* while (fgets(line, sizeof (line) - 1, fp)) */ 4134N/A "fdisk: Cannot set label geometry.\n");
0N/A * Read the master boot sector from the device. 0N/A "fdisk: Error seeking to partition table on %s.\n",
868N/A "fdisk: Error reading partition table from %s.\n",
0N/A * Write the master boot sector to the device. 0N/A * If the new table has any Solaris partitions and the old 0N/A * table does not have an entry that describes it 0N/A * exactly then clear the old vtoc (if any). 4134N/A /* We only care about potential Solaris parts. */ 0N/A /* Does the old table have an exact entry for the new entry? */ 0N/A /* We only care about old Solaris partitions. */ 0N/A /* Is this old one the same as a new one? */ 0N/A /* Did a solaris partition change location or size? */ 0N/A /* Yes clear old vtoc */ 0N/A "Clearing VTOC labels from NEW" 4134N/A /* see if the old table had EFI */ 4134N/A * if EFI partition changed, set the flag to clear 2464N/A /* clear labels if necessary */ 4134N/A "\tError %d clearing EFI labels" 2464N/A " (probably no EFI labels exist)\n",
2464N/A "fdisk: Error in ioctl DKIOCSMBOOT on %s.\n",
2464N/A "fdisk: Error seeking to master boot record on %s.\n",
2464N/A "fdisk: Error writing master boot record to %s.\n",
868N/A * Read the prototype boot records from the files. 4134N/A * If the master boot file hasn't been specified, use the 0N/A * implementation architecture name to generate the default one. 4134N/A * The mboot file must be delivered on all platforms 4134N/A * and installed in a non-platform-dependent 1963N/A /* First read in the master boot record */ 1963N/A /* Open the master boot proto file */ 1963N/A "fdisk: Cannot open master boot file %s.\n",
0N/A /* Read the master boot program */ 0N/A "fdisk: Cannot read master boot file %s.\n",
4134N/A /* Is this really a master boot record? */ 4134N/A "Bad magic number: is %x, but should be %x.\n",
3902N/A /* Zero out the partitions part of this record */ 4134N/A * Fill disk with pattern based on block number. 0N/A * Write to the disk at absolute relative block io_offset 0N/A /* Write the data to disk */ 650N/A * Read from the disk at absolute relative block io_offset for 0N/A * io_size blocks. Write the data to standard ouput (-r). 2464N/A /* Write to standard ouptut */ 0N/A "fdisk: Output warning: %d of %d" 0N/A " characters written.\n",
4134N/A }
/* if ((c = write(1, Bootsect, (unsigned)sectsiz)) */ 0N/A * Read the data from standard input. Write to the disk at 0N/A * absolute relative block io_offset for io_size blocks (-w). 2464N/A /* Read from standard input */ 0N/A "fdisk: WARNING: Incomplete read (%d of" 2464N/A " %d characters read) on input file.\n",
3352N/A /* Fill pattern to mark partial sector in buf */ 650N/A /* Write to disk drive */ 2464N/A * Load will either read the fdisk table from a file or add or 2464N/A * delete an entry (-A, -D, -F). 2366N/A * Zero out the table before loading it, which will 2366N/A * force it to be updated on disk later (-F 2366N/A /* Open the prototype file */ 2366N/A "fdisk: Cannot open prototype partition file %s.\n",
2366N/A /* Read a line from the file */ 2366N/A * Validate the partition. It cannot start at sector 2366N/A * 0 unless it is UNUSED or already exists 4134N/A "fdisk: Error on entry \"%s\".\n",
4134N/A * If we got here it means we copied an 4134N/A * unmodified entry. So there is no need 3853N/A * to insert it in the table or do any 3853N/A * checks against disk size. 3853N/A * This is a work around on the following 3853N/A * situation (for IDE disks, at least): 3853N/A * Different operation systems calculate 4134N/A * disk size different ways, of which there 0N/A * The first, rounds the disk size to modulo 4134N/A * cylinder size (virtual made-up cylinder 0N/A * usually based on maximum number of heads 4134N/A * and sectors in partition table fields). 0N/A * Our OS's (for IDE) and most other "Unix" 4134N/A * The second, uses every single block 868N/A * on the disk (to maximize available space). 4134N/A * Since disk manufactures do not know about 0N/A * "virtual cylinders", there are some number 4134N/A * of blocks that make up a partial cylinder 0N/A * at the end of the disk. 4134N/A * The difference between these two methods 4134N/A * is where the problem is. When one 4134N/A * a disk that has another OS using that 4134N/A * "partial cylinder", install fails. It fails 4134N/A * since fdisk thinks its asked to create a 4134N/A * partition with the -F option that contains 4134N/A * a partition that runs off the end of the 4134N/A * Find an unused entry to use and put the entry 4134N/A "fdisk: Error on entry \"%s\".\n",
4134N/A }
/* while (fgets(line, sizeof (line) - 1, fp)) */ 4134N/A "fdisk: Cannot create partition table\n");
0N/A /* Parse the user-supplied deletion line (-D) */ 4134N/A /* Find the exact entry in the table */ 4134N/A * Found the entry. Now move rest of 4134N/A * entries up toward the top of the 4134N/A * table, leaving available entries at 4134N/A * the end of the fdisk table. 4134N/A * Mark the last entry as unused in case 4134N/A * all table entries were in use prior 0N/A "fdisk: Entry does not match any existing partition:\n" 4134N/A /* Parse the user-supplied addition line (-A) */ 0N/A "fdisk: Syntax error \"%s\"\n",
file);
4134N/A /* Validate the partition. It cannot start at sector 0 */ 4134N/A "fdisk: New partition cannot start at sector 0:\n" 4134N/A * if the user wishes to add an EFI partition, we need 4134N/A * more extensive validation. rsect should be 1, and 4134N/A * numsect should equal the entire disk capacity - 1 4134N/A "fdisk: EFI partitions must start at sector" 4134N/A "fdisk: EFI partitions must " 4134N/A "encompass the entire maximum 2 TB " 4134N/A "(input numsect: %u - max: %llu)\n",
4134N/A "fdisk: EFI partitions must encompass the " 4134N/A "(input numsect: %u - avail: %llu)\n",
4134N/A /* Find unused entry for use and put entry in table */ 4134N/A "fdisk: Invalid entry could not be inserted:\n" 4134N/A /* Make sure new entry does not overlap existing entry */ 4134N/A "fdisk: Cannot create partition \"%s\"\n",
file);
4134N/A * This will calculate the CHS values for beginning and ending CHS 4134N/A * for a single partition table entry (ti) based on the relsect 4134N/A * and numsect values contained in the partion table entry. 4134N/A * hba_heads and hba_sectors contain the number of heads and sectors. 4134N/A * If the number of cylinders exceeds the MAX_CYL, 4134N/A * then maximum values will be placed in the corresponding chs entry. 4134N/A * the lba address cannot be expressed in CHS value 4134N/A * so store the maximum CHS field values in the CHS fields. 4134N/A * This code is identical to the code above 4134N/A * except that it works on ending CHS values 0N/A * Insert entry into fdisk table. Check all user-supplied values 0N/A * for the entry, but not the validity relative to other table 4134N/A /* validate partition size */ 4134N/A "fdisk: Partition table exceeds the size of the disk.\n");
4134N/A /* find UNUSED partition table entry */ 0N/A * If we have been called with a valid geometry, use it 0N/A * valid means non-zero values that fit in the BIOS fields 1755N/A * The specified values are invalid, 1755N/A * so calculate the values based on hba_heads, hba_sectors 0N/A * entry_from_old_table 1689N/A * If the specified entry is in the old table and is not a Solaris entry 4134N/A * then insert same entry into new fdisk table. If we do this then 4134N/A * all checks are skipped for that entry! 0N/A /* find UNUSED partition table entry */ 4134N/A * Verify that no partition entries overlap or exceed the size of 4134N/A /* Make sure new entry does not overlap an existing entry */ 4134N/A * No valid partitions allowed after an UNUSED or 4134N/A * EFI_PMBR partitions must be the only partition 4134N/A * and must be Table entry 0 4134N/A "for EFI_PMBR partition:\n" 0N/A "EFI_PMBR partition must " 0N/A "disk.\n numsect %d - " 4134N/A /* make sure the partition isn't larger than the disk */ 0N/A "Cannot add partition to " 0N/A "table; no more partitions " 4134N/A "current partition overlaps" 0N/A * Parse user-supplied data to set up fdisk partitions 4134N/A * Validate that a new partition does not start at sector 0. Only UNUSED 4134N/A * partitions and previously existing partitions are allowed to start at 0. 4134N/A "New partition cannot start at sector 0\n");
4134N/A * Print out interactive menu and process user input. 0N/A while (!((s[0] >
'0') && (s[0] <
'7') &&
0N/A ((s[
1] ==
'\0') || (s[
1] ==
'\n')))) {
868N/A "Enter a one-digit number between 1 and 6.");
4134N/A /* update disk partition table, if changed */ 0N/A * If the VTOC table is wrong fix it 4134N/A * If the VTOC table is wrong fix it 0N/A * Create partition entry in the table (interactive mode). 4134N/A "The partition table is full!\n" 4134N/A "You must delete a partition before creating" 0N/A "You must delete a partition before creating" 1755N/A * The question here is expanding to more than what is 4134N/A * allocated for question lines (Q_LINE) which garbles 4134N/A * at least warning line. Clearing warning line as workaround 1755N/A "Select the partition type to create:\n" 4134N/A " 1=SOLARIS2 2=UNIX 3=PCIXOS 4=Other\n" 4134N/A " 5=DOS12 6=DOS16 7=DOSEXT 8=DOSBIG\n" 1689N/A " 9=DOS16LBA A=x86 Boot B=Diagnostic C=FAT32\n" 4134N/A " D=FAT32LBA E=DOSEXTLBA F=EFI 0=Exit? ");
0N/A if ((s[
1] !=
'\0') && (s[
1] !=
'\n')) {
0N/A (
void)
printf(
"Invalid selection, try again.");
0N/A case '0':
/* exit */ 868N/A case '1':
/* Solaris partition */ 0N/A case '2':
/* UNIX partition */ 4134N/A case '3':
/* PCIXOS partition */ 4134N/A case '4':
/* OTHEROS System partition */ 4134N/A case 'a':
/* x86 Boot partition */ 0N/A case 'b':
/* Diagnostic boot partition */ 1755N/A case 'd':
/* FAT32 and need extended int13 */ 4134N/A case 'e':
/* Extended partition, need extended int13 */ 0N/A (
void)
printf(
"WARNING: Disk is larger than 2 TB. " 868N/A "Upper limit is 2 TB for non-EFI partition ID\n");
1400N/A /* create the new partition */ 4134N/A /* see if it should be the active partition */ 4134N/A "Should this become the active partition? If " 0N/A "yes, it will be activated\n" 0N/A "each time the computer is reset or turned on.\n" 0N/A "Please type \"y\" or \"n\". ");
0N/A /* set up the return code */ 1755N/A * partitions of type EFI_PMBR must be the only partitions in 4134N/A * First, make sure there were no errors the table is 4134N/A "fdisk: Cannot create EFI partition table; \n" 4134N/A "current partition table is invalid.\n");
4134N/A "An EFI partition must be the only partition on " 4134N/A "disk. You may manually delete existing\n" 4134N/A "partitions, or fdisk can do it.\n" 4134N/A "Do you want fdisk to destroy existing " 0N/A "Please type \"y\" or \"n\". ");
1400N/A /* create the table entry - i should be 0 */ 0N/A /* EFI partitions are currently never active */ 0N/A /* set up the return code */ 4134N/A * Query the user to specify the size of the new partition in 4134N/A * terms of percentage of the disk or by specifying the starting 4134N/A * cylinder and length in cylinders. 0N/A * make a local copy of the partition table 0N/A * and sort it into relsect order 629N/A "Specify the percentage of disk to use for this partition\n" 629N/A "(or type \"c\" to specify the size in cylinders). ");
629N/A if (s[0] !=
'c') {
/* Specify size in percentage of disk */ 629N/A while ((s[i] !=
'\0') && (s[i] !=
'\n')) {
629N/A if (s[i] <
'0' || s[i] >
'9') {
629N/A "specified; retry the operation.");
629N/A "specified; retry the operation.");
629N/A "Percentage value is too large. The value must be" 629N/A " between 1 and 100;\nretry the operation.\n");
4134N/A "Percentage value is too small. The value must be" 0N/A " between 1 and 100;\nretry the operation.\n");
0N/A /* Verify DOS12 partition doesn't exceed max size of 32MB. */ 0N/A (
void)
printf(
"Maximum size for a DOS partition " 0N/A "is %d%%; retry the operation.",
0N/A n <=
100 ? n :
100);
4134N/A * check for free space before partition i 4134N/A * where i varies from 0 to 3 4134N/A * freespace after partition 3 is unusable 0N/A * because there are no free partitions 0N/A * freespace begins at the end of previous partition 0N/A * freespace ends before the current partition 0N/A * or the end of the disk (chs end) 4134N/A * Partition might start before cylinder 1. 4134N/A * Make sure free space is not negative. 4134N/A /* save largest free space */ 0N/A /* We found a place to use */ 0N/A "Maximum percentage available is %lld\n",
824N/A "fdisk: Partition table is full.\n");
4134N/A /* Specifying size in cylinders */ 1963N/A "New partition cannot start at cylinder 0.\n");
3999N/A "Cylinder %d is out of bounds, " 4134N/A "Cylinder %d is already allocated" 4134N/A "Maximum size for partition is %u cylinders" 4134N/A /* Verify partition doesn't exceed disk size or 2 TB */ 4134N/A "Maximum size for partition is %d " 4134N/A "cylinders; \nretry the operation.",
4134N/A "Maximum size for partition is %d " 4134N/A "cylinders; \nretry the operation.",
4134N/A /* Verify DOS12 partition doesn't exceed max size of 32MB. */ 4134N/A "Maximum size for a %s partition is %ld cylinders;" 4134N/A * Display command menu (interactive mode). 4134N/A "SELECT ONE OF THE FOLLOWING:\n" 4134N/A " 2. Specify the active partition\n" 4134N/A " 4. Change between Solaris and Solaris2 Partition IDs\n" 4170N/A " 5. Exit (update disk configuration and exit)\n" 4170N/A " 6. Cancel (exit without updating disk configuration)\n");
4170N/A * Change the ACTIVE designation of a partition. 4134N/A "Specify the partition number to boot from" 4134N/A " (or specify 0 for none): ");
4134N/A if (((s[
1] !=
'\0') && (s[
1] !=
'\n')) ||
4134N/A (s[0] <
'0') || (s[0] >
'4')) {
4170N/A "Invalid response, please specify a number" 4170N/A if (s[0] ==
'0') {
/* No active partitions */ 4170N/A "No partition is currently marked as active.");
4134N/A }
else {
/* User has selected a partition to be active */ 4134N/A /* a DOS-DATA or EXT-DOS partition cannot be active */ 3999N/A "DOS-DATA, EXT_DOS and EXT_DOS_LBA partitions " 0N/A "cannot be made active.\n");
(
void)
printf(
"Select another partition.");
"Partition %d is now active. The system will start up" (
void)
printf(
"partition after the next reboot.");
* Change between SOLARIS and SOLARIS2 partition id (
void)
printf(
"Specify the partition number to change" " (or enter 0 to exit): ");
"Invalid response, retry the operation.\n");
/* exit delete command */ "Partition %d is not a Solaris partition.",
(
void)
printf(
"Partition %d has been changed.", i +
1);
* Remove partition entry from the table (interactive mode). (
void)
printf(
"Specify the partition number to delete" " (or enter 0 to exit): ");
if ((s[0] ==
'0')) {
/* exit delete command */ /* Accept only a single digit between 1 and 4 */ if (((s[
1] !=
'\0') && (s[
1] !=
'\n')) ||
(
void)
printf(
"Invalid response, retry the operation.\n");
}
else {
/* Found a digit between 1 and 4 */ --i;
/* Structure begins with element 0 */ (
void)
printf(
"Partition %d does not exist.", i +
1);
(
void)
printf(
"Are you sure you want to delete partition %d?" " This will make all files and \n", i +
1);
(
void)
printf(
"programs in this partition inaccessible (type" (
void)
printf(
"Partition %d has been deleted.", i +
1);
(
void)
printf(
" This was the active partition.");
* Remove blanks from strings of user responses. if ((s[i] ==
' ') || (s[i] ==
'\t'))
/* Found first non-blank character of the string */ for (j = 0; i <
CBUFLEN; j++, i++) {
if ((s[j] = s[i]) ==
'\0') {
/* Reached end of string */ * Take the user-specified cylinder number and convert it from a * string to a decimal value. for (i =
slen -
1; i >= 0; i--) {
if (s[i] <
'0' || s[i] >
'9') {
cyl += (j * (s[i] -
'0'));
* Display the current fdisk table; determine percentage * of the disk used for each partition. (
void)
printf(
"WARNING: critical disk geometry information" (
void)
printf(
" Total disk size is %d cylinders\n",
Numcyl);
(
void)
printf(
" Cylinder size is %d (%d byte) blocks\n\n",
" Partition Status Type Start End Length" " ========= ====== ============ ===== === ======" /* Else leave the percent as is since it's already */ "\n %d %s %-12.12s %4d %4d %4d" /* Print warning message if table is empty */ (
void)
printf(
"WARNING: no partitions are defined!");
/* Clear the warning line */ /* Print warning if disk > 2TB and is not EFI PMBR */ (
void)
printf(
"WARNING: Disk is larger than 2 TB. " "Upper limit is 2 TB for non-EFI partition ID\n");
* Write the detailed fdisk table to standard error for * the selected disk device. " SYSID ACT BHEAD BSECT BEGCYL EHEAD ESECT ENDCYL RELSECT" * copy_Table_to_Old_Table * Copy Table into Old_Table. The function only copies the systid, * numsect, relsect, and bootid values because they are the only * ones compared when determining if Table has changed. * Zero out the systid, numsect, relsect, and bootid values in the * Copy the bytes from the boot record to an internal "Table". * All unused are padded with zeros starting at offset 446. /* Get an aligned copy of the partition tables */ bootptr = (
char *)
iparts;
/* Points to start of partition table */ /* Signature is missing */ * When the DOS fdisk command deletes a partition, it is not * recognized by the old algorithm. The algorithm that * follows looks at each entry in the Bootrec and copies all /* For now, always replace the bootcode with ours */ * Initialize ipart structure values. /* Packing struct ipart for Sparc */ * Get a byte, a short, or a long (SPARC only). bh = ((**
bp) <<
8) | *(*
bp +
1);
bl = ((**
bp) <<
8) | *(*
bp +
1);
* Copy the table into the boot record. Note that the unused * entries will always be the last ones in the table and they are * marked with 100 in sysind. The the unused portion of the table * is padded with zeros in the bytes after the used entries. * Check for any changes in the partition table. /* Partition table changed, write back to disk */ * Display contents of partition table to standard output or * another file name without writing it to the disk (-W file). * If file isn't standard output, then it's a file name. * Open file and write it. "fdisk: Cannot open output file %s.\n",
* Write the fdisk table information /* Write virtual (HBA) geometry, if required */ (
void)
fprintf(
fp,
"* 101: FDISK_NOVELL3\n");
(
void)
fprintf(
fp,
"* 131: FDISK_LINUXNAT\n");
(
void)
fprintf(
fp,
"* 134: FDISK_NTFSVOL1\n");
(
void)
fprintf(
fp,
"* 135: FDISK_NTFSVOL2\n");
(
void)
fprintf(
fp,
"* 167: FDISK_NEXTSTEP\n");
(
void)
fprintf(
fp,
"* 184: FDISK_BSDISWAP\n");
"\n* Id Act Bhead Bsect Bcyl Ehead Esect Ecyl" " %-5d %-4d %-6d %-6d %-7d %-6d %-6d %-7d %-10u" * Read the VTOC table on the Solaris partition and check that no * slices exist that extend past the end of the Solaris partition. * If no Solaris partition exists, nothing is done. * Only the size matters (not starting point), since * VTOC entries are relative to the start of "fdisk: No Solaris partition found - VTOC not" exit(
1);
/* Failed to read the VTOC */ /* Special case for slice two (entire disk) */ "slice %d starts at %llu, is not at" "slice %d size %llu does not cover" "slice %d tag was %d should be %d",
"slice %d (start %llu, end %llu)" " is larger than the partition",
"slice %d (start %llu) is larger than the " "slice %d (end %llu) is larger" /* Make the VTOC look sane - ha ha */ /* Write the VTOC back to the disk */ * Get yes or no answer. Return 1 for yes and 0 for no. if (((s[
1] !=
'\0') && (s[
1] !=
'\n')) ||
((s[0] !=
'y') && (s[0] !=
'n'))) {
(
void)
printf(
"Please answer with \"y\" or \"n\": ");
* Read the VTOC from the Solaris partition of the device. * Write the VTOC to the Solaris partition on the device. "fdisk: Invalid entry exists in VTOC.\n");
* issues DKIOCSETEFI IOCTL * Clear EFI labels from the EFI_PMBR partition on the device * This function is modeled on the libefi(3LIB) call efi_write() * see if we can read the EFI label * set up the dk_ioc structure for writing * clear the primary label "\tClearing primary EFI label at block %lld\n",
* clear the backup partition table "\tClearing backup partition table at block %lld\n",
"\tUnable to clear backup EFI label at " "block %llu; errno %d\n",
* Clear the VTOC from the current or previous Solaris partition on the "\tClearing primary VTOC at byte %llu (block %llu)\n",
"\tError seeking to primary label at byte %llu\n",
"\tWarning: only %d bytes written to clear primary" "DEBUG: Error seeking to primary label at byte %llu\n",
"DEBUG: Successful lseek() to byte %llu\n",
"DEBUG: Warning: only %d bytes read of label\n",
"DEBUG: Warning: disk_label and read_label differ!!!\n");
"\tError seeking to backup label at byte %llu on " " byte %llu (block %llu)\n",
"\t\tWarning: only %d bytes written to " "clear backup VTOC at block %llu!\n",
bytes,
"DEBUG: Error seeking to backup label at byte %llu\n",
"DEBUG: Successful lseek() to byte %llu\n",
"DEBUG: Warning: only %d bytes read of backup label\n",
"DEBUG: Warning: disk_label and read_label differ!!!\n");
"DEBUG: Good compare of disk_label and backup " "Fdisk is normally used with the device that " \
"represents the entire fixed disk.\n" \
"The device does not appear to include absolute\n" \
"sector 0 of the PHYSICAL disk " \
"(the normal location for an fdisk table).\n" "The device does not appear to encompass the entire PHYSICAL disk.\n" "Unable to find a volume table of contents.\n" \
"Cannot verify the device encompasses the full PHYSICAL disk.\n" "Unable to get geometry from device.\n" \
"Cannot verify the device encompasses the full PHYSICAL disk.\n" "Are you sure you want to continue? (y/n) " * Called when a sanity check fails. This routine gives a warning * specific to the check that fails, followed by a generic lecture * about the "right" device to supply as input. Then, if appropriate, * it will prompt the user on whether or not they want to continue. * Inappropriate times for prompting are when the user has selected * non-interactive mode or read-only mode. * First try the PARTINFO ioctl. If it works, we will be able * to tell if they've specified the full disk partition by checking * to see if they've specified a partition that starts at sector 0. * Called from main to construct the name of the device node to open. * Initially tries to stat the node exactly as provided, if that fails * we prepend the default path (/dev/rdsk/). /* Don't do anything if we are skipping device checks */ /* Try the node as provided first */ * Copy the passed in string to a new buffer, prepend the * default path and try again. /* Copy over the default path and the provided node */ /* Try to stat it again */ /* Failed all options, give up */ "fdisk: Cannot stat device %s.\n",
/* Make sure the device specified is the raw device */ "fdisk: %s must be a raw device.\n",
node);