aboutsummaryrefslogtreecommitdiff
path: root/util-linux
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2016-10-19 17:01:55 +0100
committerRon Yorston <rmy@pobox.com>2016-10-19 17:01:55 +0100
commit075814c60a316cfd088c88f26f75ab21b5850b98 (patch)
treef6e33ac693630827deb309faa5fa4931588db57d /util-linux
parent977d65c1bbc57f5cdd0c8bfd67c8b5bb1cd390dd (diff)
parentf37e1155aabde6bd95d267a8aec347cedccb8bc3 (diff)
downloadbusybox-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.c167
-rw-r--r--util-linux/mdev.c88
-rw-r--r--util-linux/mount.c28
-rw-r--r--util-linux/unshare.c4
-rw-r--r--util-linux/volume_id/get_devname.c6
-rw-r--r--util-linux/volume_id/ubifs.c125
-rw-r--r--util-linux/volume_id/volume_id.c3
-rw-r--r--util-linux/volume_id/volume_id_internal.h2
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
474static void 469static void
475close_dev_fd(void) 470close_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 */
484static const char * 477static const char *
485partname(const char *dev, int pno, int lth) 478partname(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
1940list_disk_geometry(void) 1933list_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
2096static const char *
2097chs_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
2102static void 2104static void
2103list_table(int xtra) 2105list_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 */
814static int FAST_FUNC fileAction(const char *fileName, 815static 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");
834static 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 */
858static 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 */
38struct 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 */
77struct 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
108int 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
173int FAST_FUNC volume_id_probe_all(struct volume_id *id, /*uint64_t off,*/ uint64_t size) 176int 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
222int FAST_FUNC volume_id_probe_xfs(struct volume_id *id /*,uint64_t off*/); 222int FAST_FUNC volume_id_probe_xfs(struct volume_id *id /*,uint64_t off*/);
223 223
224int FAST_FUNC volume_id_probe_ubifs(struct volume_id *id /*,uint64_t off*/);
225
224POP_SAVED_FUNCTION_VISIBILITY 226POP_SAVED_FUNCTION_VISIBILITY