X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=util-linux%2Ffdisk.c;h=6391f9bd92dbd558ee5e0e0b077951ba168917f9;hb=237bedd499c58034a1355484d6d4d906f0180308;hp=0b93c22cc786c29c31be88f8f201ecdb42686e1f;hpb=66c5b12dbf85142eea257ba6047191d7c0ee43f3;p=oweals%2Fbusybox.git diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index 0b93c22cc..6391f9bd9 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c @@ -7,6 +7,27 @@ * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +/* Looks like someone forgot to add this to config system */ +//usage:#ifndef ENABLE_FEATURE_FDISK_BLKSIZE +//usage:# define ENABLE_FEATURE_FDISK_BLKSIZE 0 +//usage:# define IF_FEATURE_FDISK_BLKSIZE(a) +//usage:#endif +//usage: +//usage:#define fdisk_trivial_usage +//usage: "[-ul" IF_FEATURE_FDISK_BLKSIZE("s") "] " +//usage: "[-C CYLINDERS] [-H HEADS] [-S SECTORS] [-b SSZ] DISK" +//usage:#define fdisk_full_usage "\n\n" +//usage: "Change partition table\n" +//usage: "\n -u Start and End are in sectors (instead of cylinders)" +//usage: "\n -l Show partition table for each DISK, then exit" +//usage: IF_FEATURE_FDISK_BLKSIZE( +//usage: "\n -s Show partition sizes in kb for each DISK, then exit" +//usage: ) +//usage: "\n -b 2048 (for certain MO disks) use 2048-byte sectors" +//usage: "\n -C CYLINDERS Set number of cylinders/heads/sectors" +//usage: "\n -H HEADS" +//usage: "\n -S SECTORS" + #ifndef _LARGEFILE64_SOURCE /* For lseek64 */ # define _LARGEFILE64_SOURCE @@ -1081,11 +1102,11 @@ warn_geometry(void) printf(" sectors"); if (!g_cylinders) printf(" cylinders"); - printf( #if ENABLE_FEATURE_FDISK_WRITABLE - " (settable in the extra functions menu)" + puts(" (settable in the extra functions menu)"); +#else + bb_putchar('\n'); #endif - "\n"); return 1; } @@ -1129,7 +1150,7 @@ read_extended(int ext) p = pex->part_table; if (!get_start_sect(p)) { - printf("Bad offset in primary extended partition\n"); + puts("Bad offset in primary extended partition"); return; } @@ -1429,8 +1450,8 @@ static int get_boot(void) current_label_type = LABEL_OSF; return 0; } - printf("This disk has both DOS and BSD magic.\n" - "Give the 'b' command to go to BSD mode.\n"); + puts("This disk has both DOS and BSD magic.\n" + "Give the 'b' command to go to BSD mode."); } #endif @@ -1440,9 +1461,9 @@ static int get_boot(void) #else if (!valid_part_table_flag(MBRbuffer)) { if (what == OPEN_MAIN) { - printf("Device contains neither a valid DOS " - "partition table, nor Sun, SGI, OSF or GPT " - "disklabel\n"); + puts("Device contains neither a valid DOS " + "partition table, nor Sun, SGI, OSF or GPT " + "disklabel"); #ifdef __sparc__ IF_FEATURE_SUN_LABEL(create_sunlabel();) #else @@ -1575,7 +1596,7 @@ read_int(sector_t low, sector_t dflt, sector_t high, sector_t base, const char * } if (value >= low && value <= high) break; - printf("Value is out of range\n"); + puts("Value is out of range"); } return value; } @@ -1620,7 +1641,7 @@ get_existing_partition(int warn, unsigned max) printf("Selected partition %u\n", pno+1); return pno; } - printf("No partition is defined yet!\n"); + puts("No partition is defined yet!"); return -1; not_unique: @@ -1647,7 +1668,7 @@ get_nonexisting_partition(int warn, unsigned max) printf("Selected partition %u\n", pno+1); return pno; } - printf("All primary partitions have been defined already!\n"); + puts("All primary partitions have been defined already!"); return -1; not_unique: @@ -1682,10 +1703,10 @@ toggle_dos_compatibility_flag(void) dos_compatible_flag = 1 - dos_compatible_flag; if (dos_compatible_flag) { sector_offset = g_sectors; - printf("DOS Compatibility flag is set\n"); + printf("DOS Compatibility flag is %sset\n", ""); } else { sector_offset = 1; - printf("DOS Compatibility flag is not set\n"); + printf("DOS Compatibility flag is %sset\n", "not "); } } @@ -1792,16 +1813,16 @@ change_sysid(void) sys = read_hex(get_sys_types()); if (!sys && !LABEL_IS_SGI && !LABEL_IS_SUN) { - printf("Type 0 means free space to many systems\n" - "(but not to Linux). Having partitions of\n" - "type 0 is probably unwise.\n"); + puts("Type 0 means free space to many systems\n" + "(but not to Linux). Having partitions of\n" + "type 0 is probably unwise."); /* break; */ } if (!LABEL_IS_SUN && !LABEL_IS_SGI) { if (IS_EXTENDED(sys) != IS_EXTENDED(p->sys_ind)) { - printf("You cannot change a partition into" - " an extended one or vice versa\n"); + puts("You cannot change a partition into" + " an extended one or vice versa"); break; } } @@ -1809,10 +1830,10 @@ change_sysid(void) if (sys < 256) { #if ENABLE_FEATURE_SUN_LABEL if (LABEL_IS_SUN && i == 2 && sys != SUN_WHOLE_DISK) - printf("Consider leaving partition 3 " - "as Whole disk (5),\n" - "as SunOS/Solaris expects it and " - "even Linux likes it\n\n"); + puts("Consider leaving partition 3 " + "as Whole disk (5),\n" + "as SunOS/Solaris expects it and " + "even Linux likes it\n"); #endif #if ENABLE_FEATURE_SGI_LABEL if (LABEL_IS_SGI && @@ -1821,10 +1842,10 @@ change_sysid(void) (i == 8 && sys != 0) ) ) { - printf("Consider leaving partition 9 " - "as volume header (0),\nand " - "partition 11 as entire volume (6)" - "as IRIX expects it\n\n"); + puts("Consider leaving partition 9 " + "as volume header (0),\nand " + "partition 11 as entire volume (6)" + "as IRIX expects it\n"); } #endif if (sys == origsys) @@ -2046,7 +2067,7 @@ fix_partition_table_order(void) int i,k; if (!wrong_p_order(NULL)) { - printf("Ordering is already correct\n\n"); + puts("Ordering is already correct\n"); return; } @@ -2074,7 +2095,7 @@ fix_partition_table_order(void) if (i) fix_chain_of_logicals(); - printf("Done.\n"); + puts("Done"); } #endif @@ -2157,7 +2178,7 @@ list_table(int xtra) * if this is a sgi, sun or aix labeled disk... */ if (LABEL_IS_DOS && wrong_p_order(NULL)) { /* FIXME */ - printf("\nPartition table entries are not in disk order\n"); + puts("\nPartition table entries are not in disk order"); } } @@ -2171,7 +2192,7 @@ x_list_table(int extend) printf("\nDisk %s: %u heads, %u sectors, %u cylinders\n\n", disk_device, g_heads, g_sectors, g_cylinders); - printf("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID\n"); + puts("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID"); for (i = 0; i < g_partitions; i++) { pe = &ptes[i]; p = (extend ? pe->ext_pointer : pe->part_table); @@ -2398,7 +2419,7 @@ add_partition(int n, int sys) limit = first[i] - 1; } if (start > limit) { - printf("No free sectors available\n"); + puts("No free sectors available"); if (n > 4) g_partitions--; return; @@ -2469,9 +2490,9 @@ new_partition(void) return; } if (LABEL_IS_AIX) { - printf("Sorry - this fdisk cannot handle AIX disk labels.\n" + puts("Sorry - this fdisk cannot handle AIX disk labels.\n" "If you want to add DOS-type partitions, create a new empty DOS partition\n" -"table first (use 'o'). This will destroy the present disk contents.\n"); +"table first (use 'o'). This will destroy the present disk contents."); return; } @@ -2479,7 +2500,7 @@ new_partition(void) free_primary += !ptes[i].part_table->sys_ind; if (!free_primary && g_partitions >= MAXIMUM_PARTS) { - printf("The maximum number of partitions has been created\n"); + puts("The maximum number of partitions has been created"); return; } @@ -2487,8 +2508,8 @@ new_partition(void) if (extended_offset) add_logical(); else - printf("You must delete some partition and add " - "an extended partition first\n"); + puts("You must delete some partition and add " + "an extended partition first"); } else { char c, line[80]; snprintf(line, sizeof(line), @@ -2521,6 +2542,35 @@ new_partition(void) } } +static void +reread_partition_table(int leave) +{ + int i; + + puts("Calling ioctl() to re-read partition table"); + sync(); + /* Users with slow external USB disks on a 320MHz ARM system (year 2011) + * report that sleep is needed, otherwise BLKRRPART may fail with -EIO: + */ + sleep(1); + i = ioctl_or_perror(dev_fd, BLKRRPART, NULL, + "WARNING: rereading partition table " + "failed, kernel still uses old table"); +#if 0 + if (dos_changed) + puts( + "\nWARNING: If you have created or modified any DOS 6.x\n" + "partitions, please see the fdisk manual page for additional\n" + "information"); +#endif + + if (leave) { + if (ENABLE_FEATURE_CLEAN_UP) + close_dev_fd(); + exit(i != 0); + } +} + static void write_table(void) { @@ -2532,7 +2582,6 @@ write_table(void) ptes[3].changed = 1; for (i = 3; i < g_partitions; i++) { struct pte *pe = &ptes[i]; - if (pe->changed) { write_part_table_flag(pe->sectorbuffer); write_sector(pe->offset_from_dev_start, pe->sectorbuffer); @@ -2540,48 +2589,21 @@ write_table(void) } } else if (LABEL_IS_SGI) { - /* no test on change? the printf below might be mistaken */ + /* no test on change? the "altered" msg below might be mistaken */ sgi_write_table(); } else if (LABEL_IS_SUN) { - int needw = 0; - - for (i = 0; i < 8; i++) - if (ptes[i].changed) - needw = 1; - if (needw) - sun_write_table(); + for (i = 0; i < 8; i++) { + if (ptes[i].changed) { + sun_write_table(); + break; + } + } } - printf("The partition table has been altered!\n\n"); + puts("The partition table has been altered."); reread_partition_table(1); } - -static void -reread_partition_table(int leave) -{ - int i; - - printf("Calling ioctl() to re-read partition table\n"); - sync(); - /* sleep(2); Huh? */ - i = ioctl_or_perror(dev_fd, BLKRRPART, NULL, - "WARNING: rereading partition table " - "failed, kernel still uses old table"); -#if 0 - 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" - "information\n"); -#endif - - if (leave) { - if (ENABLE_FEATURE_CLEAN_UP) - close_dev_fd(); - exit(i != 0); - } -} #endif /* FEATURE_FDISK_WRITABLE */ #if ENABLE_FEATURE_FDISK_ADVANCED @@ -2722,8 +2744,8 @@ xselect(void) user_sectors = g_sectors = read_int(1, g_sectors, 63, 0, "Number of sectors"); if (dos_compatible_flag) { sector_offset = g_sectors; - printf("Warning: setting sector offset for DOS " - "compatiblity\n"); + puts("Warning: setting sector offset for DOS " + "compatiblity"); } update_units(); break; @@ -2759,14 +2781,14 @@ is_ide_cdrom_or_tape(const char *device) 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)) + if (!is_prefixed_with(device, "/dev/hd")) return 0; snprintf(buf, sizeof(buf), "/proc/ide/%s/media", device+5); procf = fopen_for_read(buf); if (procf != NULL && fgets(buf, sizeof(buf), procf)) - is_ide = (!strncmp(buf, "cdrom", 5) || - !strncmp(buf, "tape", 4)); + is_ide = (is_prefixed_with(buf, "cdrom") || + is_prefixed_with(buf, "tape")); else /* Now when this proc file does not exist, skip the device when it is read-only. */ @@ -2824,13 +2846,37 @@ open_list_and_close(const char *device, int user_specified) close_dev_fd(); } +/* Is it a whole disk? The digit check is still useful + for Xen devices for example. */ +static int is_whole_disk(const char *disk) +{ + unsigned len; + int fd = open(disk, O_RDONLY); + + if (fd != -1) { + struct hd_geometry geometry; + int err = ioctl(fd, HDIO_GETGEO, &geometry); + close(fd); + if (!err) + return (geometry.start == 0); + } + + /* Treat "nameN" as a partition name, not whole disk */ + /* note: mmcblk0 should work from the geometry check above */ + len = strlen(disk); + if (len != 0 && isdigit(disk[len - 1])) + return 0; + + return 1; +} + /* for fdisk -l: try all things in /proc/partitions that look like a partition name (do not end in a digit) */ static void list_devs_in_proc_partititons(void) { FILE *procpt; - char line[100], ptname[100], devname[120], *s; + char line[100], ptname[100], devname[120]; int ma, mi, sz; procpt = fopen_or_warn("/proc/partitions", "r"); @@ -2839,13 +2885,10 @@ list_devs_in_proc_partititons(void) if (sscanf(line, " %u %u %u %[^\n ]", &ma, &mi, &sz, ptname) != 4) continue; - for (s = ptname; *s; s++) - continue; - /* note: excluding '0': e.g. mmcblk0 is not a partition name! */ - if (s[-1] >= '1' && s[-1] <= '9') - continue; + sprintf(devname, "/dev/%s", ptname); - open_list_and_close(devname, 0); + if (is_whole_disk(devname)) + open_list_and_close(devname, 0); } #if ENABLE_FEATURE_CLEAN_UP fclose(procpt); @@ -2876,8 +2919,7 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv) close_dev_fd(); /* needed: fd 3 must not stay closed */ - opt_complementary = "b+:C+:H+:S+"; /* numeric params */ - opt = getopt32(argv, "b:C:H:lS:u" IF_FEATURE_FDISK_BLKSIZE("s"), + opt = getopt32(argv, "b:+C:+H:+lS:+u" IF_FEATURE_FDISK_BLKSIZE("s"), §or_size, &user_cylinders, &user_heads, &user_sectors); argv += optind; if (opt & OPT_b) { @@ -2980,8 +3022,8 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv) printf("\nThe current boot file is: %s\n", sgi_get_bootfile()); if (read_maybe_empty("Please enter the name of the " - "new boot file: ") == '\n') - printf("Boot file unchanged\n"); + "new boot file: ") == '\n') + puts("Boot file unchanged"); else sgi_set_bootfile(line_ptr); } @@ -3058,13 +3100,13 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv) verify(); break; case 'w': - write_table(); /* does not return */ + write_table(); /* does not return */ break; #if ENABLE_FEATURE_FDISK_ADVANCED case 'x': if (LABEL_IS_SGI) { - printf("\n\tSorry, no experts menu for SGI " - "partition tables available\n\n"); + puts("\n\tSorry, no experts menu for SGI " + "partition tables available\n"); } else xselect(); break;