diff options
author | Ron Yorston <rmy@pobox.com> | 2016-10-19 17:01:55 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2016-10-19 17:01:55 +0100 |
commit | 075814c60a316cfd088c88f26f75ab21b5850b98 (patch) | |
tree | f6e33ac693630827deb309faa5fa4931588db57d /util-linux | |
parent | 977d65c1bbc57f5cdd0c8bfd67c8b5bb1cd390dd (diff) | |
parent | f37e1155aabde6bd95d267a8aec347cedccb8bc3 (diff) | |
download | busybox-w32-075814c60a316cfd088c88f26f75ab21b5850b98.tar.gz busybox-w32-075814c60a316cfd088c88f26f75ab21b5850b98.tar.bz2 busybox-w32-075814c60a316cfd088c88f26f75ab21b5850b98.zip |
Merge branch busybox (up to "ash: comment out free(p) just before...")
Diffstat (limited to 'util-linux')
-rw-r--r-- | util-linux/fdisk.c | 167 | ||||
-rw-r--r-- | util-linux/mdev.c | 88 | ||||
-rw-r--r-- | util-linux/mount.c | 28 | ||||
-rw-r--r-- | util-linux/unshare.c | 4 | ||||
-rw-r--r-- | util-linux/volume_id/get_devname.c | 6 | ||||
-rw-r--r-- | util-linux/volume_id/ubifs.c | 125 | ||||
-rw-r--r-- | util-linux/volume_id/volume_id.c | 3 | ||||
-rw-r--r-- | util-linux/volume_id/volume_id_internal.h | 2 |
8 files changed, 292 insertions, 131 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 | } |
diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 37514eb54..a59115dd4 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c | |||
@@ -543,8 +543,7 @@ static char *build_alias(char *alias, const char *device_name) | |||
543 | 543 | ||
544 | /* mknod in /dev based on a path like "/sys/block/hda/hda1" | 544 | /* mknod in /dev based on a path like "/sys/block/hda/hda1" |
545 | * NB1: path parameter needs to have SCRATCH_SIZE scratch bytes | 545 | * NB1: path parameter needs to have SCRATCH_SIZE scratch bytes |
546 | * after NUL, but we promise to not mangle (IOW: to restore NUL if needed) | 546 | * after NUL, but we promise to not mangle it (IOW: to restore NUL if needed). |
547 | * path string. | ||
548 | * NB2: "mdev -s" may call us many times, do not leak memory/fds! | 547 | * NB2: "mdev -s" may call us many times, do not leak memory/fds! |
549 | * | 548 | * |
550 | * device_name = $DEVNAME (may be NULL) | 549 | * device_name = $DEVNAME (may be NULL) |
@@ -810,41 +809,39 @@ static void make_device(char *device_name, char *path, int operation) | |||
810 | } /* for (;;) */ | 809 | } /* for (;;) */ |
811 | } | 810 | } |
812 | 811 | ||
813 | /* File callback for /sys/ traversal */ | 812 | /* File callback for /sys/ traversal. |
813 | * We act only on "/sys/.../dev" (pseudo)file | ||
814 | */ | ||
814 | static int FAST_FUNC fileAction(const char *fileName, | 815 | static int FAST_FUNC fileAction(const char *fileName, |
815 | struct stat *statbuf UNUSED_PARAM, | 816 | struct stat *statbuf UNUSED_PARAM, |
816 | void *userData, | 817 | void *userData, |
817 | int depth UNUSED_PARAM) | 818 | int depth UNUSED_PARAM) |
818 | { | 819 | { |
819 | size_t len = strlen(fileName) - 4; /* can't underflow */ | 820 | size_t len = strlen(fileName) - 4; /* can't underflow */ |
820 | char *scratch = userData; | 821 | char *path = userData; /* char array[PATH_MAX + SCRATCH_SIZE] */ |
821 | 822 | char subsys[PATH_MAX]; | |
822 | /* len check is for paranoid reasons */ | 823 | int res; |
823 | if (strcmp(fileName + len, "/dev") != 0 || len >= PATH_MAX) | 824 | |
824 | return FALSE; | 825 | /* Is it a ".../dev" file? (len check is for paranoid reasons) */ |
825 | 826 | if (strcmp(fileName + len, "/dev") != 0 || len >= PATH_MAX - 32) | |
826 | strcpy(scratch, fileName); | 827 | return FALSE; /* not .../dev */ |
827 | scratch[len] = '\0'; | 828 | |
828 | make_device(/*DEVNAME:*/ NULL, scratch, OP_add); | 829 | strcpy(path, fileName); |
829 | 830 | path[len] = '\0'; | |
830 | return TRUE; | 831 | |
831 | } | 832 | /* Read ".../subsystem" symlink in the same directory where ".../dev" is */ |
832 | 833 | strcpy(subsys, path); | |
833 | /* Directory callback for /sys/ traversal */ | 834 | strcpy(subsys + len, "/subsystem"); |
834 | static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM, | 835 | res = readlink(subsys, subsys, sizeof(subsys)-1); |
835 | struct stat *statbuf UNUSED_PARAM, | 836 | if (res > 0) { |
836 | void *userData UNUSED_PARAM, | 837 | subsys[res] = '\0'; |
837 | int depth) | ||
838 | { | ||
839 | /* Extract device subsystem -- the name of the directory | ||
840 | * under /sys/class/ */ | ||
841 | if (1 == depth) { | ||
842 | free(G.subsystem); | 838 | free(G.subsystem); |
843 | if (G.subsys_env) { | 839 | if (G.subsys_env) { |
844 | bb_unsetenv_and_free(G.subsys_env); | 840 | bb_unsetenv_and_free(G.subsys_env); |
845 | G.subsys_env = NULL; | 841 | G.subsys_env = NULL; |
846 | } | 842 | } |
847 | G.subsystem = strrchr(fileName, '/'); | 843 | /* Set G.subsystem and $SUBSYSTEM from symlink's last component */ |
844 | G.subsystem = strrchr(subsys, '/'); | ||
848 | if (G.subsystem) { | 845 | if (G.subsystem) { |
849 | G.subsystem = xstrdup(G.subsystem + 1); | 846 | G.subsystem = xstrdup(G.subsystem + 1); |
850 | G.subsys_env = xasprintf("%s=%s", "SUBSYSTEM", G.subsystem); | 847 | G.subsys_env = xasprintf("%s=%s", "SUBSYSTEM", G.subsystem); |
@@ -852,6 +849,17 @@ static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM, | |||
852 | } | 849 | } |
853 | } | 850 | } |
854 | 851 | ||
852 | make_device(/*DEVNAME:*/ NULL, path, OP_add); | ||
853 | |||
854 | return TRUE; | ||
855 | } | ||
856 | |||
857 | /* Directory callback for /sys/ traversal */ | ||
858 | static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM, | ||
859 | struct stat *statbuf UNUSED_PARAM, | ||
860 | void *userData UNUSED_PARAM, | ||
861 | int depth) | ||
862 | { | ||
855 | return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE); | 863 | return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE); |
856 | } | 864 | } |
857 | 865 | ||
@@ -872,8 +880,9 @@ static void load_firmware(const char *firmware, const char *sysfs_path) | |||
872 | int firmware_fd, loading_fd; | 880 | int firmware_fd, loading_fd; |
873 | 881 | ||
874 | /* check for /lib/firmware/$FIRMWARE */ | 882 | /* check for /lib/firmware/$FIRMWARE */ |
875 | xchdir("/lib/firmware"); | 883 | firmware_fd = -1; |
876 | firmware_fd = open(firmware, O_RDONLY); /* can fail */ | 884 | if (chdir("/lib/firmware") == 0) |
885 | firmware_fd = open(firmware, O_RDONLY); /* can fail */ | ||
877 | 886 | ||
878 | /* check for /sys/$DEVPATH/loading ... give 30 seconds to appear */ | 887 | /* check for /sys/$DEVPATH/loading ... give 30 seconds to appear */ |
879 | xchdir(sysfs_path); | 888 | xchdir(sysfs_path); |
@@ -1065,25 +1074,10 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) | |||
1065 | 1074 | ||
1066 | putenv((char*)"ACTION=add"); | 1075 | putenv((char*)"ACTION=add"); |
1067 | 1076 | ||
1068 | /* ACTION_FOLLOWLINKS is needed since in newer kernels | 1077 | /* Create all devices from /sys/dev hierarchy */ |
1069 | * /sys/block/loop* (for example) are symlinks to dirs, | 1078 | recursive_action("/sys/dev", |
1070 | * not real directories. | 1079 | ACTION_RECURSE | ACTION_FOLLOWLINKS, |
1071 | * (kernel's CONFIG_SYSFS_DEPRECATED makes them real dirs, | 1080 | fileAction, dirAction, temp, 0); |
1072 | * but we can't enforce that on users) | ||
1073 | */ | ||
1074 | if (access("/sys/class/block", F_OK) != 0) { | ||
1075 | /* Scan obsolete /sys/block only if /sys/class/block | ||
1076 | * doesn't exist. Otherwise we'll have dupes. | ||
1077 | * Also, do not complain if it doesn't exist. | ||
1078 | * Some people configure kernel to have no blockdevs. | ||
1079 | */ | ||
1080 | recursive_action("/sys/block", | ||
1081 | ACTION_RECURSE | ACTION_FOLLOWLINKS | ACTION_QUIET, | ||
1082 | fileAction, dirAction, temp, 0); | ||
1083 | } | ||
1084 | recursive_action("/sys/class", | ||
1085 | ACTION_RECURSE | ACTION_FOLLOWLINKS, | ||
1086 | fileAction, dirAction, temp, 0); | ||
1087 | } else { | 1081 | } else { |
1088 | char *fw; | 1082 | char *fw; |
1089 | char *seq; | 1083 | char *seq; |
diff --git a/util-linux/mount.c b/util-linux/mount.c index 13590ceb4..eb8b7ba7b 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -1931,7 +1931,6 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
1931 | int len; | 1931 | int len; |
1932 | char c; | 1932 | char c; |
1933 | char *hostname, *share; | 1933 | char *hostname, *share; |
1934 | char *dotted, *ip; | ||
1935 | len_and_sockaddr *lsa; | 1934 | len_and_sockaddr *lsa; |
1936 | 1935 | ||
1937 | // Parse mp->mnt_fsname of the form "//hostname/share[/dir1/dir2]" | 1936 | // Parse mp->mnt_fsname of the form "//hostname/share[/dir1/dir2]" |
@@ -1971,13 +1970,26 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
1971 | if (!lsa) | 1970 | if (!lsa) |
1972 | goto report_error; | 1971 | goto report_error; |
1973 | 1972 | ||
1974 | // Insert "ip=..." option into options | 1973 | // If there is no "ip=..." option yet |
1975 | dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); | 1974 | if (!is_prefixed_with(filteropts, ",ip="+1) |
1976 | if (ENABLE_FEATURE_CLEAN_UP) free(lsa); | 1975 | && !strstr(filteropts, ",ip=") |
1977 | ip = xasprintf("ip=%s", dotted); | 1976 | ) { |
1978 | if (ENABLE_FEATURE_CLEAN_UP) free(dotted); | 1977 | char *dotted, *ip; |
1979 | parse_mount_options(ip, &filteropts); | 1978 | // Insert "ip=..." option into options |
1980 | if (ENABLE_FEATURE_CLEAN_UP) free(ip); | 1979 | dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); |
1980 | if (ENABLE_FEATURE_CLEAN_UP) free(lsa); | ||
1981 | ip = xasprintf("ip=%s", dotted); | ||
1982 | if (ENABLE_FEATURE_CLEAN_UP) free(dotted); | ||
1983 | // Note: IPv6 scoped addresses ("host%iface", see RFC 4007) should be | ||
1984 | // handled by libc in getnameinfo() (inside xmalloc_sockaddr2dotted_noport()). | ||
1985 | // Currently, glibc does not support that (has no NI_NUMERICSCOPE), | ||
1986 | // musl apparently does. This results in "ip=numericIPv6%iface_name" | ||
1987 | // (instead of _numeric_ iface_id) with glibc. | ||
1988 | // This probably should be fixed in glibc, not here. | ||
1989 | // The workaround is to manually specify correct "ip=ADDR%n" option. | ||
1990 | parse_mount_options(ip, &filteropts); | ||
1991 | if (ENABLE_FEATURE_CLEAN_UP) free(ip); | ||
1992 | } | ||
1981 | 1993 | ||
1982 | mp->mnt_type = (char*)"cifs"; | 1994 | mp->mnt_type = (char*)"cifs"; |
1983 | rc = mount_it_now(mp, vfsflags, filteropts); | 1995 | rc = mount_it_now(mp, vfsflags, filteropts); |
diff --git a/util-linux/unshare.c b/util-linux/unshare.c index fa7086add..dcc59559a 100644 --- a/util-linux/unshare.c +++ b/util-linux/unshare.c | |||
@@ -103,7 +103,7 @@ enum { | |||
103 | OPT_mount = 1 << 0, | 103 | OPT_mount = 1 << 0, |
104 | OPT_uts = 1 << 1, | 104 | OPT_uts = 1 << 1, |
105 | OPT_ipc = 1 << 2, | 105 | OPT_ipc = 1 << 2, |
106 | OPT_network = 1 << 3, | 106 | OPT_net = 1 << 3, |
107 | OPT_pid = 1 << 4, | 107 | OPT_pid = 1 << 4, |
108 | OPT_user = 1 << 5, /* OPT_user, NS_USR_POS, and ns_list[] index must match! */ | 108 | OPT_user = 1 << 5, /* OPT_user, NS_USR_POS, and ns_list[] index must match! */ |
109 | OPT_fork = 1 << 6, | 109 | OPT_fork = 1 << 6, |
@@ -142,7 +142,7 @@ static const char unshare_longopts[] ALIGN1 = | |||
142 | "mount\0" Optional_argument "\xf0" | 142 | "mount\0" Optional_argument "\xf0" |
143 | "uts\0" Optional_argument "\xf1" | 143 | "uts\0" Optional_argument "\xf1" |
144 | "ipc\0" Optional_argument "\xf2" | 144 | "ipc\0" Optional_argument "\xf2" |
145 | "network\0" Optional_argument "\xf3" | 145 | "net\0" Optional_argument "\xf3" |
146 | "pid\0" Optional_argument "\xf4" | 146 | "pid\0" Optional_argument "\xf4" |
147 | "user\0" Optional_argument "\xf5" | 147 | "user\0" Optional_argument "\xf5" |
148 | "fork\0" No_argument "f" | 148 | "fork\0" No_argument "f" |
diff --git a/util-linux/volume_id/get_devname.c b/util-linux/volume_id/get_devname.c index 6b97df113..b64d28ceb 100644 --- a/util-linux/volume_id/get_devname.c +++ b/util-linux/volume_id/get_devname.c | |||
@@ -107,7 +107,11 @@ uuidcache_check_device(const char *device, | |||
107 | int depth UNUSED_PARAM) | 107 | int depth UNUSED_PARAM) |
108 | { | 108 | { |
109 | /* note: this check rejects links to devices, among other nodes */ | 109 | /* note: this check rejects links to devices, among other nodes */ |
110 | if (!S_ISBLK(statbuf->st_mode)) | 110 | if (!S_ISBLK(statbuf->st_mode) |
111 | #if ENABLE_FEATURE_VOLUMEID_UBIFS | ||
112 | && !(S_ISCHR(statbuf->st_mode) && strncmp(bb_basename(device), "ubi", 3) == 0) | ||
113 | #endif | ||
114 | ) | ||
111 | return TRUE; | 115 | return TRUE; |
112 | 116 | ||
113 | /* Users report that mucking with floppies (especially non-present | 117 | /* Users report that mucking with floppies (especially non-present |
diff --git a/util-linux/volume_id/ubifs.c b/util-linux/volume_id/ubifs.c new file mode 100644 index 000000000..13604ec35 --- /dev/null +++ b/util-linux/volume_id/ubifs.c | |||
@@ -0,0 +1,125 @@ | |||
1 | /* | ||
2 | * volume_id - reads filesystem label and uuid | ||
3 | * | ||
4 | * Copyright (C) 2012 S-G Bergh <sgb@systemasis.org> | ||
5 | * | ||
6 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
7 | */ | ||
8 | |||
9 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_UBIFS) += ubifs.o | ||
10 | |||
11 | //config: | ||
12 | //config:config FEATURE_VOLUMEID_UBIFS | ||
13 | //config: bool "UBIFS filesystem" | ||
14 | //config: default y | ||
15 | //config: depends on VOLUMEID | ||
16 | //config: help | ||
17 | //config: UBIFS (Unsorted Block Image File System) is a file | ||
18 | //config: system for use with raw flash memory media. | ||
19 | //config: | ||
20 | |||
21 | #include "volume_id_internal.h" | ||
22 | |||
23 | #define UBIFS_NODE_MAGIC 0x06101831 | ||
24 | |||
25 | /* | ||
26 | * struct ubifs_ch - common header node. | ||
27 | * @magic: UBIFS node magic number (%UBIFS_NODE_MAGIC) | ||
28 | * @crc: CRC-32 checksum of the node header | ||
29 | * @sqnum: sequence number | ||
30 | * @len: full node length | ||
31 | * @node_type: node type | ||
32 | * @group_type: node group type | ||
33 | * @padding: reserved for future, zeroes | ||
34 | * | ||
35 | * Every UBIFS node starts with this common part. If the node has a key, the | ||
36 | * key always goes next. | ||
37 | */ | ||
38 | struct ubifs_ch { | ||
39 | uint32_t magic; | ||
40 | uint32_t crc; | ||
41 | uint64_t sqnum; | ||
42 | uint32_t len; | ||
43 | uint8_t node_type; | ||
44 | uint8_t group_type; | ||
45 | uint8_t padding[2]; | ||
46 | } PACKED; | ||
47 | |||
48 | /* | ||
49 | * struct ubifs_sb_node - superblock node. | ||
50 | * @ch: common header | ||
51 | * @padding: reserved for future, zeroes | ||
52 | * @key_hash: type of hash function used in keys | ||
53 | * @key_fmt: format of the key | ||
54 | * @flags: file-system flags (%UBIFS_FLG_BIGLPT, etc) | ||
55 | * @min_io_size: minimal input/output unit size | ||
56 | * @leb_size: logical eraseblock size in bytes | ||
57 | * @leb_cnt: count of LEBs used by file-system | ||
58 | * @max_leb_cnt: maximum count of LEBs used by file-system | ||
59 | * @max_bud_bytes: maximum amount of data stored in buds | ||
60 | * @log_lebs: log size in logical eraseblocks | ||
61 | * @lpt_lebs: number of LEBs used for lprops table | ||
62 | * @orph_lebs: number of LEBs used for recording orphans | ||
63 | * @jhead_cnt: count of journal heads | ||
64 | * @fanout: tree fanout (max. number of links per indexing node) | ||
65 | * @lsave_cnt: number of LEB numbers in LPT's save table | ||
66 | * @fmt_version: UBIFS on-flash format version | ||
67 | * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc) | ||
68 | * @padding1: reserved for future, zeroes | ||
69 | * @rp_uid: reserve pool UID | ||
70 | * @rp_gid: reserve pool GID | ||
71 | * @rp_size: size of the reserved pool in bytes | ||
72 | * @padding2: reserved for future, zeroes | ||
73 | * @time_gran: time granularity in nanoseconds | ||
74 | * @uuid: UUID generated when the file system image was created | ||
75 | * @ro_compat_version: UBIFS R/O compatibility version | ||
76 | */ | ||
77 | struct ubifs_sb_node { | ||
78 | struct ubifs_ch ch; | ||
79 | uint8_t padding[2]; | ||
80 | uint8_t key_hash; | ||
81 | uint8_t key_fmt; | ||
82 | uint32_t flags; | ||
83 | uint32_t min_io_size; | ||
84 | uint32_t leb_size; | ||
85 | uint32_t leb_cnt; | ||
86 | uint32_t max_leb_cnt; | ||
87 | uint64_t max_bud_bytes; | ||
88 | uint32_t log_lebs; | ||
89 | uint32_t lpt_lebs; | ||
90 | uint32_t orph_lebs; | ||
91 | uint32_t jhead_cnt; | ||
92 | uint32_t fanout; | ||
93 | uint32_t lsave_cnt; | ||
94 | uint32_t fmt_version; | ||
95 | uint16_t default_compr; | ||
96 | uint8_t padding1[2]; | ||
97 | uint32_t rp_uid; | ||
98 | uint32_t rp_gid; | ||
99 | uint64_t rp_size; | ||
100 | uint32_t time_gran; | ||
101 | uint8_t uuid[16]; | ||
102 | uint32_t ro_compat_version; | ||
103 | /* | ||
104 | uint8_t padding2[3968]; | ||
105 | */ | ||
106 | } PACKED; | ||
107 | |||
108 | int FAST_FUNC volume_id_probe_ubifs(struct volume_id *id /*,uint64_t off*/) | ||
109 | { | ||
110 | #define off ((uint64_t)0) | ||
111 | struct ubifs_sb_node *sb; | ||
112 | |||
113 | dbg("UBIFS: probing at offset 0x%llx", (unsigned long long) off); | ||
114 | sb = volume_id_get_buffer(id, off, sizeof(struct ubifs_sb_node)); | ||
115 | if (!sb) | ||
116 | return -1; | ||
117 | |||
118 | if (le32_to_cpu(sb->ch.magic) != UBIFS_NODE_MAGIC) | ||
119 | return -1; | ||
120 | |||
121 | IF_FEATURE_BLKID_TYPE(id->type = "ubifs";) | ||
122 | volume_id_set_uuid(id, sb->uuid, UUID_DCE); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
diff --git a/util-linux/volume_id/volume_id.c b/util-linux/volume_id/volume_id.c index 3f71e0084..5bb95994b 100644 --- a/util-linux/volume_id/volume_id.c +++ b/util-linux/volume_id/volume_id.c | |||
@@ -168,6 +168,9 @@ static const probe_fptr fs2[] = { | |||
168 | #if ENABLE_FEATURE_VOLUMEID_OCFS2 | 168 | #if ENABLE_FEATURE_VOLUMEID_OCFS2 |
169 | volume_id_probe_ocfs2, | 169 | volume_id_probe_ocfs2, |
170 | #endif | 170 | #endif |
171 | #if ENABLE_FEATURE_VOLUMEID_UBIFS | ||
172 | volume_id_probe_ubifs, | ||
173 | #endif | ||
171 | }; | 174 | }; |
172 | 175 | ||
173 | int FAST_FUNC volume_id_probe_all(struct volume_id *id, /*uint64_t off,*/ uint64_t size) | 176 | int FAST_FUNC volume_id_probe_all(struct volume_id *id, /*uint64_t off,*/ uint64_t size) |
diff --git a/util-linux/volume_id/volume_id_internal.h b/util-linux/volume_id/volume_id_internal.h index 3061ac4d5..759a832e6 100644 --- a/util-linux/volume_id/volume_id_internal.h +++ b/util-linux/volume_id/volume_id_internal.h | |||
@@ -221,4 +221,6 @@ int FAST_FUNC volume_id_probe_udf(struct volume_id *id /*,uint64_t off*/); | |||
221 | 221 | ||
222 | int FAST_FUNC volume_id_probe_xfs(struct volume_id *id /*,uint64_t off*/); | 222 | int FAST_FUNC volume_id_probe_xfs(struct volume_id *id /*,uint64_t off*/); |
223 | 223 | ||
224 | int FAST_FUNC volume_id_probe_ubifs(struct volume_id *id /*,uint64_t off*/); | ||
225 | |||
224 | POP_SAVED_FUNCTION_VISIBILITY | 226 | POP_SAVED_FUNCTION_VISIBILITY |