diff options
Diffstat (limited to 'util-linux/fdisk.c')
-rw-r--r-- | util-linux/fdisk.c | 167 |
1 files changed, 94 insertions, 73 deletions
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index 6391f9bd9..32a66d03d 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c | |||
@@ -363,7 +363,6 @@ struct globals { | |||
363 | 363 | ||
364 | jmp_buf listingbuf; | 364 | jmp_buf listingbuf; |
365 | char line_buffer[80]; | 365 | char line_buffer[80]; |
366 | char partname_buffer[80]; | ||
367 | /* Raw disk label. For DOS-type partition tables the MBR, | 366 | /* Raw disk label. For DOS-type partition tables the MBR, |
368 | * with descriptions of the primary partitions. */ | 367 | * with descriptions of the primary partitions. */ |
369 | char MBRbuffer[MAX_SECTOR_SIZE]; | 368 | char MBRbuffer[MAX_SECTOR_SIZE]; |
@@ -399,7 +398,6 @@ struct globals { | |||
399 | #define total_number_of_sectors (G.total_number_of_sectors) | 398 | #define total_number_of_sectors (G.total_number_of_sectors) |
400 | #define listingbuf (G.listingbuf ) | 399 | #define listingbuf (G.listingbuf ) |
401 | #define line_buffer (G.line_buffer ) | 400 | #define line_buffer (G.line_buffer ) |
402 | #define partname_buffer (G.partname_buffer) | ||
403 | #define MBRbuffer (G.MBRbuffer ) | 401 | #define MBRbuffer (G.MBRbuffer ) |
404 | #define ptes (G.ptes ) | 402 | #define ptes (G.ptes ) |
405 | #define INIT_G() do { \ | 403 | #define INIT_G() do { \ |
@@ -468,9 +466,6 @@ static sector_t bb_BLKGETSIZE_sectors(int fd) | |||
468 | 466 | ||
469 | #define cylinder(s, c) ((c) | (((s) & 0xc0) << 2)) | 467 | #define cylinder(s, c) ((c) | (((s) & 0xc0) << 2)) |
470 | 468 | ||
471 | #define hsc2sector(h,s,c) \ | ||
472 | (sector(s) - 1 + sectors * ((h) + heads * cylinder(s,c))) | ||
473 | |||
474 | static void | 469 | static void |
475 | close_dev_fd(void) | 470 | close_dev_fd(void) |
476 | { | 471 | { |
@@ -478,9 +473,7 @@ close_dev_fd(void) | |||
478 | xmove_fd(xopen(bb_dev_null, O_RDONLY), dev_fd); | 473 | xmove_fd(xopen(bb_dev_null, O_RDONLY), dev_fd); |
479 | } | 474 | } |
480 | 475 | ||
481 | /* | 476 | /* Return partition name */ |
482 | * Return partition name - uses static storage | ||
483 | */ | ||
484 | static const char * | 477 | static const char * |
485 | partname(const char *dev, int pno, int lth) | 478 | partname(const char *dev, int pno, int lth) |
486 | { | 479 | { |
@@ -489,8 +482,8 @@ partname(const char *dev, int pno, int lth) | |||
489 | int bufsiz; | 482 | int bufsiz; |
490 | char *bufp; | 483 | char *bufp; |
491 | 484 | ||
492 | bufp = partname_buffer; | 485 | bufp = auto_string(xzalloc(80)); |
493 | bufsiz = sizeof(partname_buffer); | 486 | bufsiz = 80; |
494 | 487 | ||
495 | w = strlen(dev); | 488 | w = strlen(dev); |
496 | p = ""; | 489 | p = ""; |
@@ -1898,14 +1891,14 @@ check_consistency(const struct partition *p, int partition) | |||
1898 | return; /* do not check extended partitions */ | 1891 | return; /* do not check extended partitions */ |
1899 | 1892 | ||
1900 | /* physical beginning c, h, s */ | 1893 | /* physical beginning c, h, s */ |
1901 | pbc = (p->cyl & 0xff) | ((p->sector << 2) & 0x300); | 1894 | pbc = cylinder(p->sector, p->cyl); |
1902 | pbh = p->head; | 1895 | pbh = p->head; |
1903 | pbs = p->sector & 0x3f; | 1896 | pbs = sector(p->sector); |
1904 | 1897 | ||
1905 | /* physical ending c, h, s */ | 1898 | /* physical ending c, h, s */ |
1906 | pec = (p->end_cyl & 0xff) | ((p->end_sector << 2) & 0x300); | 1899 | pec = cylinder(p->end_sector, p->end_cyl); |
1907 | peh = p->end_head; | 1900 | peh = p->end_head; |
1908 | pes = p->end_sector & 0x3f; | 1901 | pes = sector(p->end_sector); |
1909 | 1902 | ||
1910 | /* compute logical beginning (c, h, s) */ | 1903 | /* compute logical beginning (c, h, s) */ |
1911 | linear2chs(get_start_sect(p), &lbc, &lbh, &lbs); | 1904 | linear2chs(get_start_sect(p), &lbc, &lbh, &lbs); |
@@ -1916,17 +1909,17 @@ check_consistency(const struct partition *p, int partition) | |||
1916 | /* Same physical / logical beginning? */ | 1909 | /* Same physical / logical beginning? */ |
1917 | if (g_cylinders <= 1024 && (pbc != lbc || pbh != lbh || pbs != lbs)) { | 1910 | if (g_cylinders <= 1024 && (pbc != lbc || pbh != lbh || pbs != lbs)) { |
1918 | printf("Partition %u has different physical/logical " | 1911 | printf("Partition %u has different physical/logical " |
1919 | "beginnings (non-Linux?):\n", partition + 1); | 1912 | "start (non-Linux?):\n", partition + 1); |
1920 | printf(" phys=(%u, %u, %u) ", pbc, pbh, pbs); | 1913 | printf(" phys=(%u,%u,%u) ", pbc, pbh, pbs); |
1921 | printf("logical=(%u, %u, %u)\n", lbc, lbh, lbs); | 1914 | printf("logical=(%u,%u,%u)\n", lbc, lbh, lbs); |
1922 | } | 1915 | } |
1923 | 1916 | ||
1924 | /* Same physical / logical ending? */ | 1917 | /* Same physical / logical ending? */ |
1925 | if (g_cylinders <= 1024 && (pec != lec || peh != leh || pes != les)) { | 1918 | if (g_cylinders <= 1024 && (pec != lec || peh != leh || pes != les)) { |
1926 | printf("Partition %u has different physical/logical " | 1919 | printf("Partition %u has different physical/logical " |
1927 | "endings:\n", partition + 1); | 1920 | "end:\n", partition + 1); |
1928 | printf(" phys=(%u, %u, %u) ", pec, peh, pes); | 1921 | printf(" phys=(%u,%u,%u) ", pec, peh, pes); |
1929 | printf("logical=(%u, %u, %u)\n", lec, leh, les); | 1922 | printf("logical=(%u,%u,%u)\n", lec, leh, les); |
1930 | } | 1923 | } |
1931 | 1924 | ||
1932 | /* Ending on cylinder boundary? */ | 1925 | /* Ending on cylinder boundary? */ |
@@ -1940,22 +1933,23 @@ static void | |||
1940 | list_disk_geometry(void) | 1933 | list_disk_geometry(void) |
1941 | { | 1934 | { |
1942 | ullong bytes = ((ullong)total_number_of_sectors << 9); | 1935 | ullong bytes = ((ullong)total_number_of_sectors << 9); |
1943 | long megabytes = bytes / 1000000; | 1936 | ullong xbytes = bytes / (1024*1024); |
1944 | 1937 | char x = 'M'; | |
1945 | if (megabytes < 10000) | 1938 | |
1946 | printf("\nDisk %s: %lu MB, %llu bytes\n", | 1939 | if (xbytes >= 10000) { |
1947 | disk_device, megabytes, bytes); | 1940 | xbytes += 512; /* fdisk util-linux 2.28 does this */ |
1948 | else | 1941 | xbytes /= 1024; |
1949 | printf("\nDisk %s: %lu.%lu GB, %llu bytes\n", | 1942 | x = 'G'; |
1950 | disk_device, megabytes/1000, (megabytes/100)%10, bytes); | 1943 | } |
1951 | printf("%u heads, %u sectors/track, %u cylinders", | 1944 | printf("Disk %s: %llu %cB, %llu bytes, %"SECT_FMT"u sectors\n" |
1952 | g_heads, g_sectors, g_cylinders); | 1945 | "%u cylinders, %u heads, %u sectors/track\n" |
1953 | if (units_per_sector == 1) | 1946 | "Units: %s of %u * %u = %u bytes\n\n", |
1954 | printf(", total %"SECT_FMT"u sectors", | 1947 | disk_device, xbytes, x, |
1955 | total_number_of_sectors / (sector_size/512)); | 1948 | bytes, total_number_of_sectors, |
1956 | printf("\nUnits = %s of %u * %u = %u bytes\n\n", | 1949 | g_cylinders, g_heads, g_sectors, |
1957 | str_units(PLURAL), | 1950 | str_units(PLURAL), |
1958 | units_per_sector, sector_size, units_per_sector * sector_size); | 1951 | units_per_sector, sector_size, units_per_sector * sector_size |
1952 | ); | ||
1959 | } | 1953 | } |
1960 | 1954 | ||
1961 | /* | 1955 | /* |
@@ -2099,10 +2093,17 @@ fix_partition_table_order(void) | |||
2099 | } | 2093 | } |
2100 | #endif | 2094 | #endif |
2101 | 2095 | ||
2096 | static const char * | ||
2097 | chs_string11(unsigned cyl, unsigned head, unsigned sect) | ||
2098 | { | ||
2099 | char *buf = auto_string(xzalloc(sizeof(int)*3 * 3)); | ||
2100 | sprintf(buf, "%u,%u,%u", cylinder(sect,cyl), head, sector(sect)); | ||
2101 | return buf; | ||
2102 | } | ||
2103 | |||
2102 | static void | 2104 | static void |
2103 | list_table(int xtra) | 2105 | list_table(int xtra) |
2104 | { | 2106 | { |
2105 | const struct partition *p; | ||
2106 | int i, w; | 2107 | int i, w; |
2107 | 2108 | ||
2108 | if (LABEL_IS_SUN) { | 2109 | if (LABEL_IS_SUN) { |
@@ -2126,50 +2127,62 @@ list_table(int xtra) | |||
2126 | } | 2127 | } |
2127 | 2128 | ||
2128 | /* Heuristic: we list partition 3 of /dev/foo as /dev/foo3, | 2129 | /* Heuristic: we list partition 3 of /dev/foo as /dev/foo3, |
2129 | but if the device name ends in a digit, say /dev/foo1, | 2130 | * but if the device name ends in a digit, say /dev/foo1, |
2130 | then the partition is called /dev/foo1p3. */ | 2131 | * then the partition is called /dev/foo1p3. |
2132 | */ | ||
2131 | w = strlen(disk_device); | 2133 | w = strlen(disk_device); |
2132 | if (w && isdigit(disk_device[w-1])) | 2134 | if (w && isdigit(disk_device[w-1])) |
2133 | w++; | 2135 | w++; |
2134 | if (w < 5) | 2136 | if (w < 7) |
2135 | w = 5; | 2137 | w = 7; |
2136 | 2138 | ||
2137 | // 1 12345678901 12345678901 12345678901 12 | 2139 | printf("%-*s Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type\n", |
2138 | printf("%*s Boot Start End Blocks Id System\n", | 2140 | w-1, "Device"); |
2139 | w+1, "Device"); | ||
2140 | 2141 | ||
2141 | for (i = 0; i < g_partitions; i++) { | 2142 | for (i = 0; i < g_partitions; i++) { |
2143 | const struct partition *p; | ||
2142 | const struct pte *pe = &ptes[i]; | 2144 | const struct pte *pe = &ptes[i]; |
2143 | sector_t psects; | 2145 | char boot4[4]; |
2144 | sector_t pblocks; | 2146 | char numstr6[6]; |
2145 | unsigned podd; | 2147 | sector_t start_sect; |
2148 | sector_t end_sect; | ||
2149 | sector_t nr_sects; | ||
2146 | 2150 | ||
2147 | p = pe->part_table; | 2151 | p = pe->part_table; |
2148 | if (!p || is_cleared_partition(p)) | 2152 | if (!p || is_cleared_partition(p)) |
2149 | continue; | 2153 | continue; |
2150 | 2154 | ||
2151 | psects = get_nr_sects(p); | 2155 | sprintf(boot4, "%02x", p->boot_ind); |
2152 | pblocks = psects; | 2156 | if ((p->boot_ind & 0x7f) == 0) { |
2153 | podd = 0; | 2157 | /* 0x80 shown as '*', 0x00 is ' ' */ |
2154 | 2158 | boot4[0] = p->boot_ind ? '*' : ' '; | |
2155 | if (sector_size < 1024) { | 2159 | boot4[1] = ' '; |
2156 | pblocks /= (1024 / sector_size); | ||
2157 | podd = psects % (1024 / sector_size); | ||
2158 | } | 2160 | } |
2159 | if (sector_size > 1024) | ||
2160 | pblocks *= (sector_size / 1024); | ||
2161 | 2161 | ||
2162 | printf("%s %c %11"SECT_FMT"u %11"SECT_FMT"u %11"SECT_FMT"u%c %2x %s\n", | 2162 | start_sect = get_partition_start_from_dev_start(pe); |
2163 | partname(disk_device, i+1, w+2), | 2163 | end_sect = start_sect; |
2164 | !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG /* boot flag */ | 2164 | nr_sects = get_nr_sects(p); |
2165 | ? '*' : '?', | 2165 | if (nr_sects != 0) |
2166 | cround(get_partition_start_from_dev_start(pe)), /* start */ | 2166 | end_sect += nr_sects - 1; |
2167 | cround(get_partition_start_from_dev_start(pe) + psects /* end */ | 2167 | |
2168 | - (psects ? 1 : 0)), | 2168 | smart_ulltoa5((ullong)nr_sects * sector_size, |
2169 | pblocks, podd ? '+' : ' ', /* odd flag on end */ | 2169 | numstr6, " KMGTPEZY")[0] = '\0'; |
2170 | p->sys_ind, /* type id */ | ||
2171 | partition_type(p->sys_ind)); /* type name */ | ||
2172 | 2170 | ||
2171 | #define SFMT SECT_FMT | ||
2172 | // Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type | ||
2173 | printf("%s%s %-11s"/**/" %-11s"/**/" %10"SFMT"u %10"SFMT"u %10"SFMT"u %s %2x %s\n", | ||
2174 | partname(disk_device, i+1, w+2), | ||
2175 | boot4, | ||
2176 | chs_string11(p->cyl, p->head, p->sector), | ||
2177 | chs_string11(p->end_cyl, p->end_head, p->end_sector), | ||
2178 | start_sect, | ||
2179 | end_sect, | ||
2180 | nr_sects, | ||
2181 | numstr6, | ||
2182 | p->sys_ind, | ||
2183 | partition_type(p->sys_ind) | ||
2184 | ); | ||
2185 | #undef SFMT | ||
2173 | check_consistency(p, i); | 2186 | check_consistency(p, i); |
2174 | } | 2187 | } |
2175 | 2188 | ||
@@ -2198,13 +2211,17 @@ x_list_table(int extend) | |||
2198 | p = (extend ? pe->ext_pointer : pe->part_table); | 2211 | p = (extend ? pe->ext_pointer : pe->part_table); |
2199 | if (p != NULL) { | 2212 | if (p != NULL) { |
2200 | printf("%2u %02x%4u%4u%5u%4u%4u%5u%11"SECT_FMT"u%11"SECT_FMT"u %02x\n", | 2213 | printf("%2u %02x%4u%4u%5u%4u%4u%5u%11"SECT_FMT"u%11"SECT_FMT"u %02x\n", |
2201 | i + 1, p->boot_ind, p->head, | 2214 | i + 1, p->boot_ind, |
2215 | p->head, | ||
2202 | sector(p->sector), | 2216 | sector(p->sector), |
2203 | cylinder(p->sector, p->cyl), p->end_head, | 2217 | cylinder(p->sector, p->cyl), |
2218 | p->end_head, | ||
2204 | sector(p->end_sector), | 2219 | sector(p->end_sector), |
2205 | cylinder(p->end_sector, p->end_cyl), | 2220 | cylinder(p->end_sector, p->end_cyl), |
2206 | get_start_sect(p), get_nr_sects(p), | 2221 | get_start_sect(p), |
2207 | p->sys_ind); | 2222 | get_nr_sects(p), |
2223 | p->sys_ind | ||
2224 | ); | ||
2208 | if (p->sys_ind) | 2225 | if (p->sys_ind) |
2209 | check_consistency(p, i); | 2226 | check_consistency(p, i); |
2210 | } | 2227 | } |
@@ -2261,6 +2278,7 @@ verify(void) | |||
2261 | { | 2278 | { |
2262 | int i, j; | 2279 | int i, j; |
2263 | sector_t total = 1; | 2280 | sector_t total = 1; |
2281 | sector_t chs_size; | ||
2264 | sector_t first[g_partitions], last[g_partitions]; | 2282 | sector_t first[g_partitions], last[g_partitions]; |
2265 | struct partition *p; | 2283 | struct partition *p; |
2266 | 2284 | ||
@@ -2322,11 +2340,14 @@ verify(void) | |||
2322 | } | 2340 | } |
2323 | } | 2341 | } |
2324 | 2342 | ||
2325 | if (total > g_heads * g_sectors * g_cylinders) | 2343 | chs_size = (sector_t)g_heads * g_sectors * g_cylinders; |
2326 | printf("Total allocated sectors %u greater than the maximum " | 2344 | if (total > chs_size) |
2327 | "%u\n", total, g_heads * g_sectors * g_cylinders); | 2345 | printf("Total allocated sectors %u" |
2346 | " greater than CHS size %"SECT_FMT"u\n", | ||
2347 | total, chs_size | ||
2348 | ); | ||
2328 | else { | 2349 | else { |
2329 | total = g_heads * g_sectors * g_cylinders - total; | 2350 | total = chs_size - total; |
2330 | if (total != 0) | 2351 | if (total != 0) |
2331 | printf("%"SECT_FMT"u unallocated sectors\n", total); | 2352 | printf("%"SECT_FMT"u unallocated sectors\n", total); |
2332 | } | 2353 | } |