summaryrefslogtreecommitdiffstats
path: root/fdisk/fdisk.c
diff options
context:
space:
mode:
Diffstat (limited to 'fdisk/fdisk.c')
-rw-r--r--fdisk/fdisk.c164
1 files changed, 106 insertions, 58 deletions
diff --git a/fdisk/fdisk.c b/fdisk/fdisk.c
index 0c57ed22e..4e709b7bc 100644
--- a/fdisk/fdisk.c
+++ b/fdisk/fdisk.c
@@ -8,26 +8,13 @@
* (at your option) any later version.
*
* For detailed old history, see older versions.
- * Contributions before 2000 by faith@cs.unc.edu, Michael Bischoff,
+ * Contributions before 2001 by faith@cs.unc.edu, Michael Bischoff,
* LeBlanc@mcc.ac.uk, martin@cs.unc.edu, leisner@sdsp.mc.xerox.com,
* esr@snark.thyrsus.com, aeb@cwi.nl, quinlan@yggdrasil.com,
* fasten@cs.bonn.edu, orschaer@cip.informatik.uni-erlangen.de,
* jj@sunsite.mff.cuni.cz, fasten@shw.com, ANeuper@GUUG.de,
- * kgw@suse.de.
- *
- * Modified, Sun Feb 20 2000, kalium@gmx.de
- * Added fix operation allowing to reorder primary/extended partition
- * entries within the partition table. Some programs or OSes have
- * problems using a partition table with entries not ordered
- * according to their positions on disk.
- * Munged this patch to also make it work for logical partitions.
- * aeb, 2000-02-20.
- *
- * Wed Mar 1 14:34:53 EST 2000 David Huggins-Daines <dhuggins@linuxcare.com>
- * Better support for OSF/1 disklabels on Alpha.
- *
- * 2000-04-06, Michal Jaegermann (michal@ellpspace.math.ualberta.ca)
- * fixed and added some alpha stuff.
+ * kgw@suse.de, kalium@gmx.de, dhuggins@linuxcare.com,
+ * michal@ellpspace.math.ualberta.ca and probably others.
*/
@@ -170,6 +157,7 @@ int fd, /* the disk */
listing = 0, /* no aborts for fdisk -l */
nowarn = 0, /* no warnings for fdisk -l/-s */
dos_compatible_flag = ~0,
+ dos_changed = 0,
partitions = 4; /* maximum partition + 1 */
uint user_cylinders, user_heads, user_sectors;
@@ -209,7 +197,7 @@ void fatal(enum failure why) {
"Here DISK is something like /dev/hdb or /dev/sda\n"
"and PARTITION is something like /dev/hda7\n"
"-u: give Start and End in sector (instead of cylinder) units\n"
-"-b 2048: (for certain MO drives) use 2048-byte sectors\n");
+"-b 2048: (for certain MO disks) use 2048-byte sectors\n");
break;
case usage2:
/* msg in cases where fdisk used to probe */
@@ -312,6 +300,21 @@ set_changed(int i) {
ptes[i].changed = 1;
}
+/*
+ * Avoid warning about DOS partitions when no DOS partition was changed.
+ * Here a heuristic "is probably dos partition".
+ * We might also do the opposite and warn in all cases except
+ * for "is probably nondos partition".
+ */
+static int
+is_dos_partition(int t) {
+ return (t == 1 || t == 4 || t == 6 ||
+ t == 0x0b || t == 0x0c || t == 0x0e ||
+ t == 0x11 || t == 0x12 || t == 0x14 || t == 0x16 ||
+ t == 0x1b || t == 0x1c || t == 0x1e || t == 0x24 ||
+ t == 0xc1 || t == 0xc4 || t == 0xc6);
+}
+
static void
menu(void) {
if (sun_label) {
@@ -405,7 +408,7 @@ xmenu(void) {
puts(_(" c change number of cylinders"));
puts(_(" d print the raw data in the partition table"));
puts(_(" e list extended partitions")); /* !sun */
- puts(_(" g create an IRIX partition table")); /* sgi */
+ puts(_(" g create an IRIX (SGI) partition table"));/* sgi */
puts(_(" h change number of heads"));
puts(_(" m print this menu"));
puts(_(" p print the partition table"));
@@ -421,7 +424,7 @@ xmenu(void) {
puts(_(" c change number of cylinders"));
puts(_(" d print the raw data in the partition table"));
puts(_(" e list extended partitions")); /* !sun */
- puts(_(" g create an IRIX partition table")); /* sgi */
+ puts(_(" g create an IRIX (SGI) partition table"));/* sgi */
puts(_(" h change number of heads"));
puts(_(" m print this menu"));
puts(_(" p print the partition table"));
@@ -438,7 +441,7 @@ xmenu(void) {
puts(_(" d print the raw data in the partition table"));
puts(_(" e list extended partitions")); /* !sun */
puts(_(" f fix partition order")); /* !sun, !aix, !sgi */
- puts(_(" g create an IRIX partition table")); /* sgi */
+ puts(_(" g create an IRIX (SGI) partition table"));/* sgi */
puts(_(" h change number of heads"));
puts(_(" m print this menu"));
puts(_(" p print the partition table"));
@@ -500,6 +503,13 @@ void list_types(struct systypes *sys)
putchar('\n');
}
+static int
+is_cleared_partition(struct partition *p) {
+ return !(!p || p->boot_ind || p->head || p->sector || p->cyl ||
+ p->sys_ind || p->end_head || p->end_sector || p->end_cyl ||
+ get_start_sect(p) || get_nr_sects(p));
+}
+
static void
clear_partition(struct partition *p) {
if (!p)
@@ -698,6 +708,8 @@ create_doslabel(void) {
sun_nolabel(); /* otherwise always recognised as sun */
sgi_nolabel(); /* otherwise always recognised as sgi */
+ aix_label = osf_label = 0;
+ partitions = 4;
for (i = 510-64; i < 510; i++)
MBRbuffer[i] = 0;
@@ -705,7 +717,7 @@ create_doslabel(void) {
extended_offset = 0;
set_all_unchanged();
set_changed(0);
- get_boot(create_empty);
+ get_boot(create_empty_dos);
}
#include <sys/utsname.h>
@@ -804,6 +816,7 @@ get_geometry(int fd, struct geom *g) {
* Read MBR. Returns:
* -1: no 0xaa55 flag present (possibly entire disk BSD)
* 0: found or created label
+ * 1: I/O error
*/
int
get_boot(enum action what) {
@@ -811,13 +824,17 @@ get_boot(enum action what) {
partitions = 4;
- if (what == create_empty)
- goto got_table; /* skip reading disk */
+ if (what == create_empty_dos)
+ goto got_dos_table; /* skip reading disk */
+ if (what == create_empty_sun)
+ goto got_table;
if ((fd = open(disk_device, type_open)) < 0) {
- if ((fd = open(disk_device, O_RDONLY)) < 0)
+ if ((fd = open(disk_device, O_RDONLY)) < 0) {
+ if (what == try_only)
+ return 1;
fatal(unable_to_open);
- else
+ } else
printf(_("You will not be able to write the partition table.\n"));
}
@@ -825,8 +842,11 @@ get_boot(enum action what) {
update_units();
- if (sector_size != read(fd, MBRbuffer, sector_size))
+ if (sector_size != read(fd, MBRbuffer, sector_size)) {
+ if (what == try_only)
+ return 1;
fatal(unable_to_read);
+ }
got_table:
@@ -842,6 +862,8 @@ got_table:
if (check_osf_label())
return 0;
+got_dos_table:
+
if (!valid_part_table_flag(MBRbuffer)) {
switch(what) {
case fdisk:
@@ -858,7 +880,8 @@ got_table:
return -1;
case try_only:
return -1;
- case create_empty:
+ case create_empty_dos:
+ case create_empty_sun:
break;
}
@@ -876,7 +899,7 @@ got_table:
pe->ext_pointer = NULL;
pe->offset = 0;
pe->sectorbuffer = MBRbuffer;
- pe->changed = (what == create_empty);
+ pe->changed = (what == create_empty_dos);
}
for (i = 0; i < 4; i++) {
@@ -1132,7 +1155,7 @@ delete_partition(int i) {
*/
if (warn_geometry())
- return;
+ return; /* C/H/S not set */
pe->changed = 1;
if (sun_label) {
@@ -1251,6 +1274,9 @@ change_sysid(void) {
(temp = partition_type(sys)) ? temp :
_("Unknown"));
ptes[i].changed = 1;
+ if (is_dos_partition(origsys) ||
+ is_dos_partition(sys))
+ dos_changed = 1;
break;
}
}
@@ -1512,7 +1538,7 @@ list_table(int xtra) {
struct pte *pe = &ptes[i];
p = pe->part_table;
- if (p && p->sys_ind) {
+ if (p && !is_cleared_partition(p)) {
unsigned int psects = get_nr_sects(p);
unsigned int pblocks = psects;
unsigned int podd = 0;
@@ -1844,6 +1870,15 @@ new_partition(void) {
return;
}
+ if (aix_label) {
+ printf(_("\tSorry - this fdisk cannot handle AIX disk labels."
+ "\n\tIf you want to add DOS-type partitions, create"
+ "\n\ta new empty DOS partition table first. (Use o.)"
+ "\n\tWARNING: "
+ "This will destroy the present disk contents.\n"));
+ return;
+ }
+
if (partitions >= MAXIMUM_PARTS) {
printf(_("The maximum number of partitions has been created\n"));
return;
@@ -1938,12 +1973,16 @@ reread_partition_table(int leave) {
error = errno;
}
- if (i < 0)
- printf(_("Re-read table failed with error %d: %s.\nReboot your "
- "system to ensure the partition table is updated.\n"),
+ if (i) {
+ printf(_("\nWARNING: Re-reading the partition table "
+ "failed with error %d: %s.\n"
+ "The kernel still uses the old table.\n"
+ "The new table will be used "
+ "at the next reboot.\n"),
error, strerror(error));
+ }
- if (!sun_label && !sgi_label)
+ if (dos_changed)
printf(
_("\nWARNING: If you have created or modified any DOS 6.x\n"
"partitions, please see the fdisk manual page for additional\n"
@@ -2110,43 +2149,53 @@ xselect(void) {
}
static int
-is_ide_cdrom(char *device) {
+is_ide_cdrom_or_tape(char *device) {
+ FILE *procf;
+ char buf[100];
+ struct stat statbuf;
+ int is_ide = 0;
+
/* No device was given explicitly, and we are trying some
- likely things. But opening /dev/hdc may produce errors like
+ likely things. But opening /dev/hdc may produce errors like
"hdc: tray open or drive not ready"
- if it happens to be a CD-ROM drive. It even happens that
- the process hangs on the attempt to read a music CD.
- So try to be careful. This only works since 2.1.73. */
-
- FILE *procf;
- char buf[100];
- struct stat statbuf;
+ if it happens to be a CD-ROM drive. It even happens that
+ the process hangs on the attempt to read a music CD.
+ So try to be careful. This only works since 2.1.73. */
- if (strncmp("/dev/hd", device, 7))
- return 0;
- snprintf(buf, sizeof(buf), "/proc/ide/%s/media", device+5);
- procf = fopen(buf, "r");
- if (procf != NULL && fgets(buf, sizeof(buf), procf))
- return !strncmp(buf, "cdrom", 5);
+ if (strncmp("/dev/hd", device, 7))
+ return 0;
- /* Now when this proc file does not exist, skip the
- device when it is read-only. */
- if (stat(device, &statbuf) == 0)
- return (statbuf.st_mode & 0222) == 0;
+ snprintf(buf, sizeof(buf), "/proc/ide/%s/media", device+5);
+ procf = fopen(buf, "r");
+ if (procf != NULL && fgets(buf, sizeof(buf), procf))
+ is_ide = (!strncmp(buf, "cdrom", 5) ||
+ !strncmp(buf, "tape", 4));
+ else
+ /* Now when this proc file does not exist, skip the
+ device when it is read-only. */
+ if (stat(device, &statbuf) == 0)
+ is_ide = ((statbuf.st_mode & 0222) == 0);
- return 0;
+ if (procf)
+ fclose(procf);
+ return is_ide;
}
static void
try(char *device, int user_specified) {
+ int gb;
+
disk_device = device;
if (setjmp(listingbuf))
return;
if (!user_specified)
- if (is_ide_cdrom(device))
+ if (is_ide_cdrom_or_tape(device))
return;
if ((fd = open(disk_device, type_open)) >= 0) {
- if (get_boot(try_only) < 0) {
+ gb = get_boot(try_only);
+ if (gb > 0) { /* I/O error */
+ close(fd);
+ } else if (gb < 0) { /* no DOS signature */
list_disk_geometry();
if (aix_label)
return;
@@ -2196,6 +2245,7 @@ tryprocpt(void) {
snprintf(devname, sizeof(devname), "/dev/%s", ptname);
try(devname, 0);
}
+ fclose(procpt);
}
static void
@@ -2312,8 +2362,6 @@ main(int argc, char **argv) {
fatal(usage2);
get_boot(fdisk);
- if (aix_label)
- exit(0);
#ifdef __alpha__
/* On alpha, if we detect a disklabel, go directly to