aboutsummaryrefslogtreecommitdiff
path: root/util-linux
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-01-14 13:28:49 +0000
committerRon Yorston <rmy@pobox.com>2021-01-14 13:28:49 +0000
commit89963b524d211e1aec12b72b3725be05ee95c8cf (patch)
tree48590aef62b7ee7686b7898256f29def8d9c50b9 /util-linux
parent9aa5a829070392c2ac6494d0c4e674c0c2bc7dab (diff)
parent2b7c1aa92c68524559a2067609d09309d5c09adc (diff)
downloadbusybox-w32-89963b524d211e1aec12b72b3725be05ee95c8cf.tar.gz
busybox-w32-89963b524d211e1aec12b72b3725be05ee95c8cf.tar.bz2
busybox-w32-89963b524d211e1aec12b72b3725be05ee95c8cf.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'util-linux')
-rw-r--r--util-linux/acpid.c4
-rw-r--r--util-linux/blockdev.c2
-rw-r--r--util-linux/chrt.c36
-rw-r--r--util-linux/fbset.c2
-rw-r--r--util-linux/fdisk.c11
-rw-r--r--util-linux/fdisk_osf.c4
-rw-r--r--util-linux/fdisk_sgi.c2
-rw-r--r--util-linux/fdisk_sun.c4
-rw-r--r--util-linux/fstrim.c8
-rw-r--r--util-linux/hexdump.c2
-rw-r--r--util-linux/hexdump_xxd.c3
-rw-r--r--util-linux/hwclock.c193
-rw-r--r--util-linux/ionice.c8
-rw-r--r--util-linux/mdev.c119
-rw-r--r--util-linux/mkfs_ext2.c2
-rw-r--r--util-linux/mkswap.c2
-rw-r--r--util-linux/mount.c91
-rw-r--r--util-linux/nsenter.c5
-rw-r--r--util-linux/rdate.c7
-rw-r--r--util-linux/rtcwake.c13
-rw-r--r--util-linux/script.c2
-rw-r--r--util-linux/setpriv.c2
-rw-r--r--util-linux/uevent.c50
-rw-r--r--util-linux/umount.c8
-rw-r--r--util-linux/unshare.c6
-rw-r--r--util-linux/volume_id/erofs.c67
-rw-r--r--util-linux/volume_id/volume_id.c11
-rw-r--r--util-linux/volume_id/volume_id_internal.h8
28 files changed, 434 insertions, 238 deletions
diff --git a/util-linux/acpid.c b/util-linux/acpid.c
index d473e24fc..00613f8e3 100644
--- a/util-linux/acpid.c
+++ b/util-linux/acpid.c
@@ -99,7 +99,7 @@ struct acpi_event {
99 const char *desc; 99 const char *desc;
100}; 100};
101 101
102static const struct acpi_event f_evt_tab[] = { 102static const struct acpi_event f_evt_tab[] ALIGN_PTR = {
103 { "EV_KEY", 0x01, "KEY_POWER", 116, 1, "button/power PWRF 00000080" }, 103 { "EV_KEY", 0x01, "KEY_POWER", 116, 1, "button/power PWRF 00000080" },
104 { "EV_KEY", 0x01, "KEY_POWER", 116, 1, "button/power PWRB 00000080" }, 104 { "EV_KEY", 0x01, "KEY_POWER", 116, 1, "button/power PWRB 00000080" },
105 { "EV_SW", 0x05, "SW_LID", 0x00, 1, "button/lid LID0 00000080" }, 105 { "EV_SW", 0x05, "SW_LID", 0x00, 1, "button/lid LID0 00000080" },
@@ -110,7 +110,7 @@ struct acpi_action {
110 const char *action; 110 const char *action;
111}; 111};
112 112
113static const struct acpi_action f_act_tab[] = { 113static const struct acpi_action f_act_tab[] ALIGN_PTR = {
114 { "PWRF", "PWRF/00000080" }, 114 { "PWRF", "PWRF/00000080" },
115 { "LID0", "LID/00000080" }, 115 { "LID0", "LID/00000080" },
116}; 116};
diff --git a/util-linux/blockdev.c b/util-linux/blockdev.c
index e60bbe609..20a031377 100644
--- a/util-linux/blockdev.c
+++ b/util-linux/blockdev.c
@@ -60,7 +60,7 @@ static const char bdcmd_names[] ALIGN1 =
60 "flushbufs" "\0" 60 "flushbufs" "\0"
61 "rereadpt" "\0" 61 "rereadpt" "\0"
62; 62;
63static const uint32_t bdcmd_ioctl[] = { 63static const uint32_t bdcmd_ioctl[] ALIGN4 = {
64 BLKROSET, //setro 64 BLKROSET, //setro
65 BLKROSET, //setrw 65 BLKROSET, //setrw
66 BLKROGET, //getro 66 BLKROGET, //getro
diff --git a/util-linux/chrt.c b/util-linux/chrt.c
index 4dd78dabf..a8701b55f 100644
--- a/util-linux/chrt.c
+++ b/util-linux/chrt.c
@@ -17,7 +17,7 @@
17//kbuild:lib-$(CONFIG_CHRT) += chrt.o 17//kbuild:lib-$(CONFIG_CHRT) += chrt.o
18 18
19//usage:#define chrt_trivial_usage 19//usage:#define chrt_trivial_usage
20//usage: "-m | -p [PRIO] PID | [-rfobi] PRIO PROG [ARGS]" 20//usage: "-m | -p [PRIO] PID | [-rfobi] PRIO PROG ARGS"
21//usage:#define chrt_full_usage "\n\n" 21//usage:#define chrt_full_usage "\n\n"
22//usage: "Change scheduling priority and class for a process\n" 22//usage: "Change scheduling priority and class for a process\n"
23//usage: "\n -m Show min/max priorities" 23//usage: "\n -m Show min/max priorities"
@@ -39,6 +39,17 @@
39# define SCHED_IDLE 5 39# define SCHED_IDLE 5
40#endif 40#endif
41 41
42//musl has no __MUSL__ or similar define to check for,
43//but its <sys/types.h> has these lines:
44// #define __NEED_fsblkcnt_t
45// #define __NEED_fsfilcnt_t
46#if defined(__linux__) && defined(__NEED_fsblkcnt_t) && defined(__NEED_fsfilcnt_t)
47# define LIBC_IS_MUSL 1
48# include <sys/syscall.h>
49#else
50# define LIBC_IS_MUSL 0
51#endif
52
42static const char *policy_name(int pol) 53static const char *policy_name(int pol)
43{ 54{
44 if (pol > 6) 55 if (pol > 6)
@@ -85,6 +96,7 @@ int chrt_main(int argc UNUSED_PARAM, char **argv)
85 char *priority = priority; /* for compiler */ 96 char *priority = priority; /* for compiler */
86 const char *current_new; 97 const char *current_new;
87 int policy = SCHED_RR; 98 int policy = SCHED_RR;
99 int ret;
88 100
89 opt = getopt32(argv, "^" 101 opt = getopt32(argv, "^"
90 "+" "mprfobi" 102 "+" "mprfobi"
@@ -132,7 +144,15 @@ int chrt_main(int argc UNUSED_PARAM, char **argv)
132 if (opt & OPT_p) { 144 if (opt & OPT_p) {
133 int pol; 145 int pol;
134 print_rt_info: 146 print_rt_info:
147#if LIBC_IS_MUSL
148 /* musl libc returns ENOSYS for its sched_getscheduler library
149 * function, because the sched_getscheduler Linux kernel system call
150 * does not conform to Posix; so we use the system call directly
151 */
152 pol = syscall(SYS_sched_getscheduler, pid);
153#else
135 pol = sched_getscheduler(pid); 154 pol = sched_getscheduler(pid);
155#endif
136 if (pol < 0) 156 if (pol < 0)
137 bb_perror_msg_and_die("can't %cet pid %u's policy", 'g', (int)pid); 157 bb_perror_msg_and_die("can't %cet pid %u's policy", 'g', (int)pid);
138#ifdef SCHED_RESET_ON_FORK 158#ifdef SCHED_RESET_ON_FORK
@@ -149,7 +169,12 @@ int chrt_main(int argc UNUSED_PARAM, char **argv)
149 printf("pid %u's %s scheduling policy: SCHED_%s\n", 169 printf("pid %u's %s scheduling policy: SCHED_%s\n",
150 pid, current_new, policy_name(pol) 170 pid, current_new, policy_name(pol)
151 ); 171 );
152 if (sched_getparam(pid, &sp)) 172#if LIBC_IS_MUSL
173 ret = syscall(SYS_sched_getparam, pid, &sp);
174#else
175 ret = sched_getparam(pid, &sp);
176#endif
177 if (ret)
153 bb_perror_msg_and_die("can't get pid %u's attributes", (int)pid); 178 bb_perror_msg_and_die("can't get pid %u's attributes", (int)pid);
154 printf("pid %u's %s scheduling priority: %d\n", 179 printf("pid %u's %s scheduling priority: %d\n",
155 (int)pid, current_new, sp.sched_priority 180 (int)pid, current_new, sp.sched_priority
@@ -168,7 +193,12 @@ int chrt_main(int argc UNUSED_PARAM, char **argv)
168 sched_get_priority_min(policy), sched_get_priority_max(policy) 193 sched_get_priority_min(policy), sched_get_priority_max(policy)
169 ); 194 );
170 195
171 if (sched_setscheduler(pid, policy, &sp) < 0) 196#if LIBC_IS_MUSL
197 ret = syscall(SYS_sched_setscheduler, pid, policy, &sp);
198#else
199 ret = sched_setscheduler(pid, policy, &sp);
200#endif
201 if (ret)
172 bb_perror_msg_and_die("can't %cet pid %u's policy", 's', (int)pid); 202 bb_perror_msg_and_die("can't %cet pid %u's policy", 's', (int)pid);
173 203
174 if (!argv[0]) /* "-p PRIO PID [...]" */ 204 if (!argv[0]) /* "-p PRIO PID [...]" */
diff --git a/util-linux/fbset.c b/util-linux/fbset.c
index 0b9a9a6bc..cc5413b40 100644
--- a/util-linux/fbset.c
+++ b/util-linux/fbset.c
@@ -193,7 +193,7 @@ static const struct cmdoptions_t {
193 const char name[9]; 193 const char name[9];
194 const unsigned char param_count; 194 const unsigned char param_count;
195 const unsigned char code; 195 const unsigned char code;
196} g_cmdoptions[] = { 196} g_cmdoptions[] ALIGN1 = {
197 /*"12345678" + NUL */ 197 /*"12345678" + NUL */
198//TODO: convert to index_in_strings() 198//TODO: convert to index_in_strings()
199 { "fb" , 1, CMD_FB }, 199 { "fb" , 1, CMD_FB },
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index 0fb2e3e17..c50ceead1 100644
--- a/util-linux/fdisk.c
+++ b/util-linux/fdisk.c
@@ -185,8 +185,11 @@ struct hd_geometry {
185 185
186#define HDIO_GETGEO 0x0301 /* get device geometry */ 186#define HDIO_GETGEO 0x0301 /* get device geometry */
187 187
188/* TODO: #if ENABLE_FEATURE_FDISK_WRITABLE */ 188/* TODO: just #if ENABLE_FEATURE_FDISK_WRITABLE */
189/* (currently fdisk_sun/sgi.c do not have proper WRITABLE #ifs) */ 189/* (currently fdisk_sun/sgi.c do not have proper WRITABLE #ifs) */
190#if ENABLE_FEATURE_FDISK_WRITABLE \
191 || ENABLE_FEATURE_SGI_LABEL \
192 || ENABLE_FEATURE_SUN_LABEL
190static const char msg_building_new_label[] ALIGN1 = 193static const char msg_building_new_label[] ALIGN1 =
191"Building a new %s. Changes will remain in memory only,\n" 194"Building a new %s. Changes will remain in memory only,\n"
192"until you decide to write them. After that the previous content\n" 195"until you decide to write them. After that the previous content\n"
@@ -194,7 +197,7 @@ static const char msg_building_new_label[] ALIGN1 =
194 197
195static const char msg_part_already_defined[] ALIGN1 = 198static const char msg_part_already_defined[] ALIGN1 =
196"Partition %u is already defined, delete it before re-adding\n"; 199"Partition %u is already defined, delete it before re-adding\n";
197/* #endif */ 200#endif
198 201
199 202
200struct partition { 203struct partition {
@@ -303,7 +306,7 @@ static sector_t get_nr_sects(const struct partition *p);
303 306
304/* DOS partition types */ 307/* DOS partition types */
305 308
306static const char *const i386_sys_types[] = { 309static const char *const i386_sys_types[] ALIGN_PTR = {
307 "\x00" "Empty", 310 "\x00" "Empty",
308 "\x01" "FAT12", 311 "\x01" "FAT12",
309 "\x04" "FAT16 <32M", 312 "\x04" "FAT16 <32M",
@@ -2667,7 +2670,7 @@ reread_partition_table(int leave)
2667 /* Users with slow external USB disks on a 320MHz ARM system (year 2011) 2670 /* Users with slow external USB disks on a 320MHz ARM system (year 2011)
2668 * report that sleep is needed, otherwise BLKRRPART may fail with -EIO: 2671 * report that sleep is needed, otherwise BLKRRPART may fail with -EIO:
2669 */ 2672 */
2670 sleep(1); 2673 sleep1();
2671 i = ioctl_or_perror(dev_fd, BLKRRPART, NULL, 2674 i = ioctl_or_perror(dev_fd, BLKRRPART, NULL,
2672 "WARNING: rereading partition table " 2675 "WARNING: rereading partition table "
2673 "failed, kernel still uses old table"); 2676 "failed, kernel still uses old table");
diff --git a/util-linux/fdisk_osf.c b/util-linux/fdisk_osf.c
index 92180b2bc..765740ff1 100644
--- a/util-linux/fdisk_osf.c
+++ b/util-linux/fdisk_osf.c
@@ -144,7 +144,7 @@ struct xbsd_disklabel {
144#define BSD_DSTYPE_DOSPART(s) ((s) & 3) /* dos partition number */ 144#define BSD_DSTYPE_DOSPART(s) ((s) & 3) /* dos partition number */
145#define BSD_DSTYPE_GEOMETRY 0x10 /* drive params in label */ 145#define BSD_DSTYPE_GEOMETRY 0x10 /* drive params in label */
146 146
147static const char *const xbsd_dktypenames[] = { 147static const char *const xbsd_dktypenames[] ALIGN_PTR = {
148 "unknown", 148 "unknown",
149 "SMD", 149 "SMD",
150 "MSCP", 150 "MSCP",
@@ -190,7 +190,7 @@ static const char *const xbsd_dktypenames[] = {
190#define BSD_FS_MSDOS 8 /* MS-DOS file system */ 190#define BSD_FS_MSDOS 8 /* MS-DOS file system */
191#endif 191#endif
192 192
193static const char *const xbsd_fstypes[] = { 193static const char *const xbsd_fstypes[] ALIGN_PTR = {
194 "\x00" "unused", /* BSD_FS_UNUSED */ 194 "\x00" "unused", /* BSD_FS_UNUSED */
195 "\x01" "swap", /* BSD_FS_SWAP */ 195 "\x01" "swap", /* BSD_FS_SWAP */
196 "\x02" "Version 6", /* BSD_FS_V6 */ 196 "\x02" "Version 6", /* BSD_FS_V6 */
diff --git a/util-linux/fdisk_sgi.c b/util-linux/fdisk_sgi.c
index c90c801e2..acb438ac0 100644
--- a/util-linux/fdisk_sgi.c
+++ b/util-linux/fdisk_sgi.c
@@ -174,7 +174,7 @@ isinfreelist(unsigned int b)
174 * end of free blocks section 174 * end of free blocks section
175 */ 175 */
176 176
177static const char *const sgi_sys_types[] = { 177static const char *const sgi_sys_types[] ALIGN_PTR = {
178/* SGI_VOLHDR */ "\x00" "SGI volhdr" , 178/* SGI_VOLHDR */ "\x00" "SGI volhdr" ,
179/* 0x01 */ "\x01" "SGI trkrepl" , 179/* 0x01 */ "\x01" "SGI trkrepl" ,
180/* 0x02 */ "\x02" "SGI secrepl" , 180/* 0x02 */ "\x02" "SGI secrepl" ,
diff --git a/util-linux/fdisk_sun.c b/util-linux/fdisk_sun.c
index 29d7c283a..427b9487b 100644
--- a/util-linux/fdisk_sun.c
+++ b/util-linux/fdisk_sun.c
@@ -61,7 +61,7 @@ guess_device_type(void)
61 } 61 }
62} 62}
63 63
64static const char *const sun_sys_types[] = { 64static const char *const sun_sys_types[] ALIGN_PTR = {
65 "\x00" "Empty" , /* 0 */ 65 "\x00" "Empty" , /* 0 */
66 "\x01" "Boot" , /* 1 */ 66 "\x01" "Boot" , /* 1 */
67 "\x02" "SunOS root" , /* 2 */ 67 "\x02" "SunOS root" , /* 2 */
@@ -133,7 +133,7 @@ static const struct sun_predefined_drives {
133 unsigned short ntrks; 133 unsigned short ntrks;
134 unsigned short nsect; 134 unsigned short nsect;
135 unsigned short rspeed; 135 unsigned short rspeed;
136} sun_drives[] = { 136} sun_drives[] ALIGN_PTR = {
137 { "Quantum","ProDrive 80S",1,832,2,834,6,34,3662}, 137 { "Quantum","ProDrive 80S",1,832,2,834,6,34,3662},
138 { "Quantum","ProDrive 105S",1,974,2,1019,6,35,3662}, 138 { "Quantum","ProDrive 105S",1,974,2,1019,6,35,3662},
139 { "CDC","Wren IV 94171-344",3,1545,2,1549,9,46,3600}, 139 { "CDC","Wren IV 94171-344",3,1545,2,1549,9,46,3600},
diff --git a/util-linux/fstrim.c b/util-linux/fstrim.c
index 8d29a6d54..6d673002f 100644
--- a/util-linux/fstrim.c
+++ b/util-linux/fstrim.c
@@ -20,18 +20,10 @@
20//usage:#define fstrim_trivial_usage 20//usage:#define fstrim_trivial_usage
21//usage: "[OPTIONS] MOUNTPOINT" 21//usage: "[OPTIONS] MOUNTPOINT"
22//usage:#define fstrim_full_usage "\n\n" 22//usage:#define fstrim_full_usage "\n\n"
23//usage: IF_LONG_OPTS(
24//usage: " -o,--offset OFFSET Offset in bytes to discard from"
25//usage: "\n -l,--length LEN Bytes to discard"
26//usage: "\n -m,--minimum MIN Minimum extent length"
27//usage: "\n -v,--verbose Print number of discarded bytes"
28//usage: )
29//usage: IF_NOT_LONG_OPTS(
30//usage: " -o OFFSET Offset in bytes to discard from" 23//usage: " -o OFFSET Offset in bytes to discard from"
31//usage: "\n -l LEN Bytes to discard" 24//usage: "\n -l LEN Bytes to discard"
32//usage: "\n -m MIN Minimum extent length" 25//usage: "\n -m MIN Minimum extent length"
33//usage: "\n -v Print number of discarded bytes" 26//usage: "\n -v Print number of discarded bytes"
34//usage: )
35 27
36#include "libbb.h" 28#include "libbb.h"
37#include <linux/fs.h> 29#include <linux/fs.h>
diff --git a/util-linux/hexdump.c b/util-linux/hexdump.c
index 2174c3008..57e7e8db7 100644
--- a/util-linux/hexdump.c
+++ b/util-linux/hexdump.c
@@ -28,7 +28,7 @@
28//kbuild:lib-$(CONFIG_HD) += hexdump.o 28//kbuild:lib-$(CONFIG_HD) += hexdump.o
29 29
30//usage:#define hexdump_trivial_usage 30//usage:#define hexdump_trivial_usage
31//usage: "[-bcCdefnosvx] [FILE]..." 31//usage: "[-bcdoxCv] [-e FMT] [-f FMT_FILE] [-n LEN] [-s OFS] [FILE]..."
32//usage:#define hexdump_full_usage "\n\n" 32//usage:#define hexdump_full_usage "\n\n"
33//usage: "Display FILEs (or stdin) in a user specified format\n" 33//usage: "Display FILEs (or stdin) in a user specified format\n"
34//usage: "\n -b 1-byte octal display" 34//usage: "\n -b 1-byte octal display"
diff --git a/util-linux/hexdump_xxd.c b/util-linux/hexdump_xxd.c
index d2f4b6ed8..29bbc6633 100644
--- a/util-linux/hexdump_xxd.c
+++ b/util-linux/hexdump_xxd.c
@@ -41,7 +41,7 @@
41// -u use upper case hex letters. 41// -u use upper case hex letters.
42 42
43//usage:#define xxd_trivial_usage 43//usage:#define xxd_trivial_usage
44//usage: "[OPTIONS] [FILE]" 44//usage: "[-pr] [-g N] [-c N] [-n LEN] [-s OFS] [FILE]"
45//usage:#define xxd_full_usage "\n\n" 45//usage:#define xxd_full_usage "\n\n"
46//usage: "Hex dump FILE (or stdin)\n" 46//usage: "Hex dump FILE (or stdin)\n"
47//usage: "\n -g N Bytes per group" 47//usage: "\n -g N Bytes per group"
@@ -51,7 +51,6 @@
51//usage: "\n -l LENGTH Show only first LENGTH bytes" 51//usage: "\n -l LENGTH Show only first LENGTH bytes"
52//usage: "\n -s OFFSET Skip OFFSET bytes" 52//usage: "\n -s OFFSET Skip OFFSET bytes"
53//usage: "\n -r Reverse (with -p, assumes no offsets in input)" 53//usage: "\n -r Reverse (with -p, assumes no offsets in input)"
54// TODO: implement -r (see hexdump -R)
55 54
56#include "libbb.h" 55#include "libbb.h"
57#include "dump.h" 56#include "dump.h"
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c
index e85bca2b2..723b09589 100644
--- a/util-linux/hwclock.c
+++ b/util-linux/hwclock.c
@@ -36,6 +36,19 @@
36#include <sys/utsname.h> 36#include <sys/utsname.h>
37#include "rtc_.h" 37#include "rtc_.h"
38 38
39
40//musl has no __MUSL__ or similar define to check for,
41//but its <sys/types.h> has these lines:
42// #define __NEED_fsblkcnt_t
43// #define __NEED_fsfilcnt_t
44#if defined(__linux__) && defined(__NEED_fsblkcnt_t) && defined(__NEED_fsfilcnt_t)
45# define LIBC_IS_MUSL 1
46# include <sys/syscall.h>
47#else
48# define LIBC_IS_MUSL 0
49#endif
50
51
39/* diff code is disabled: it's not sys/hw clock diff, it's some useless 52/* diff code is disabled: it's not sys/hw clock diff, it's some useless
40 * "time between hwclock was started and we saw CMOS tick" quantity. 53 * "time between hwclock was started and we saw CMOS tick" quantity.
41 * It's useless since hwclock is started at a random moment, 54 * It's useless since hwclock is started at a random moment,
@@ -66,7 +79,7 @@ static time_t read_rtc(const char **pp_rtcname, struct timeval *sys_tv, int utc)
66 int before = tm_time.tm_sec; 79 int before = tm_time.tm_sec;
67 while (1) { 80 while (1) {
68 rtc_read_tm(&tm_time, fd); 81 rtc_read_tm(&tm_time, fd);
69 gettimeofday(sys_tv, NULL); 82 xgettimeofday(sys_tv);
70 if (before != (int)tm_time.tm_sec) 83 if (before != (int)tm_time.tm_sec)
71 break; 84 break;
72 } 85 }
@@ -116,26 +129,72 @@ static void show_clock(const char **pp_rtcname, int utc)
116#endif 129#endif
117} 130}
118 131
119static void to_sys_clock(const char **pp_rtcname, int utc) 132static void set_kernel_tz(const struct timezone *tz)
120{ 133{
121 struct timeval tv; 134#if LIBC_IS_MUSL
122 struct timezone tz; 135 /* musl libc does not pass tz argument to syscall
123 136 * because "it's deprecated by POSIX, therefore it's fine
124 tz.tz_minuteswest = timezone / 60; 137 * if we gratuitously break stuff" :(
125 /* ^^^ used to also subtract 60*daylight, but it's wrong:
126 * daylight!=0 means "this timezone has some DST
127 * during the year", not "DST is in effect now".
128 */ 138 */
129 tz.tz_dsttime = 0; 139#if !defined(SYS_settimeofday) && defined(SYS_settimeofday_time32)
130 140# define SYS_settimeofday SYS_settimeofday_time32
131 /* glibc v2.31+ returns an error if both args are non-NULL */ 141#endif
132 if (settimeofday(NULL, &tz)) 142 int ret = syscall(SYS_settimeofday, NULL, tz);
143#else
144 int ret = settimeofday(NULL, tz);
145#endif
146 if (ret)
133 bb_simple_perror_msg_and_die("settimeofday"); 147 bb_simple_perror_msg_and_die("settimeofday");
148}
149
150/*
151 * At system boot, kernel may set system time from RTC,
152 * but it knows nothing about timezones. If RTC is in local time,
153 * then system time is wrong - it is offset by timezone.
154 * --systz option corrects system time if RTC is in local time,
155 * and (always) sets in-kernel timezone.
156 * (Unlike --hctosys, it does not read the RTC).
157 *
158 * util-linux's code has this comment:
159 * RTC | settimeofday calls
160 * ------|-------------------------------------------------
161 * Local | 1st) warps system time*, sets PCIL* and kernel tz
162 * UTC | 1st) locks warp_clock 2nd) sets kernel tz
163 * * only on first call after boot
164 * (PCIL is "persistent_clock_is_local" kernel internal flag,
165 * it makes kernel save RTC in local time, not UTC.)
166 */
167static void set_kernel_timezone_and_clock(int utc, const struct timeval *hctosys)
168{
169 time_t cur;
170 struct tm *broken;
171 struct timezone tz = { 0 };
172
173 /* if --utc, prevent kernel's warp_clock() with a dummy call */
174 if (utc)
175 set_kernel_tz(&tz);
176
177 /* Set kernel's timezone offset based on userspace one */
178//It's tempting to call tzset() and use libc global "timezone" variable
179//...but it does NOT include DST shift (IOW: it's WRONG, usually by one hour,
180//if DST is in effect!) Thus this ridiculous dance:
181 cur = time(NULL);
182 broken = localtime(&cur);
183 tz.tz_minuteswest = -broken->tm_gmtoff / 60;
184 /*tz.tz_dsttime = 0; already is */
185 set_kernel_tz(&tz); /* MIGHT warp_clock() if 1st call since boot */
186
187 if (hctosys) /* it's --hctosys: set time too */
188 xsettimeofday(hctosys);
189}
190
191static void to_sys_clock(const char **pp_rtcname, int utc)
192{
193 struct timeval tv;
134 194
135 tv.tv_sec = read_rtc(pp_rtcname, NULL, utc); 195 tv.tv_sec = read_rtc(pp_rtcname, NULL, utc);
136 tv.tv_usec = 0; 196 tv.tv_usec = 0;
137 if (settimeofday(&tv, NULL)) 197 return set_kernel_timezone_and_clock(utc, &tv);
138 bb_simple_perror_msg_and_die("settimeofday");
139} 198}
140 199
141static void from_sys_clock(const char **pp_rtcname, int utc) 200static void from_sys_clock(const char **pp_rtcname, int utc)
@@ -146,7 +205,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc)
146 int rtc; 205 int rtc;
147 206
148 rtc = rtc_xopen(pp_rtcname, O_WRONLY); 207 rtc = rtc_xopen(pp_rtcname, O_WRONLY);
149 gettimeofday(&tv, NULL); 208 xgettimeofday(&tv);
150 /* Prepare tm_time */ 209 /* Prepare tm_time */
151 if (sizeof(time_t) == sizeof(tv.tv_sec)) { 210 if (sizeof(time_t) == sizeof(tv.tv_sec)) {
152 if (utc) 211 if (utc)
@@ -194,7 +253,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc)
194 unsigned rem_usec; 253 unsigned rem_usec;
195 time_t t; 254 time_t t;
196 255
197 gettimeofday(&tv, NULL); 256 xgettimeofday(&tv);
198 257
199 t = tv.tv_sec; 258 t = tv.tv_sec;
200 rem_usec = 1000000 - tv.tv_usec; 259 rem_usec = 1000000 - tv.tv_usec;
@@ -215,7 +274,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc)
215 } 274 }
216 275
217 /* gmtime/localtime took some time, re-get cur time */ 276 /* gmtime/localtime took some time, re-get cur time */
218 gettimeofday(&tv, NULL); 277 xgettimeofday(&tv);
219 278
220 if (tv.tv_sec < t /* we are still in old second */ 279 if (tv.tv_sec < t /* we are still in old second */
221 || (tv.tv_sec == t && tv.tv_usec < adj) /* not too far into next second */ 280 || (tv.tv_sec == t && tv.tv_usec < adj) /* not too far into next second */
@@ -261,64 +320,53 @@ static void from_sys_clock(const char **pp_rtcname, int utc)
261 close(rtc); 320 close(rtc);
262} 321}
263 322
264/* 323// hwclock from util-linux 2.36.1
265 * At system boot, kernel may set system time from RTC, 324// hwclock [function] [option...]
266 * but it knows nothing about timezones. If RTC is in local time, 325//Functions:
267 * then system time is wrong - it is offset by timezone. 326// -r, --show display the RTC time
268 * This option corrects system time if RTC is in local time, 327// --get display drift corrected RTC time
269 * and (always) sets in-kernel timezone. 328// --set set the RTC according to --date
270 * 329// -s, --hctosys set the system time from the RTC
271 * This is an alternate option to --hctosys that does not read the 330// -w, --systohc set the RTC from the system time
272 * hardware clock. 331// --systz send timescale configurations to the kernel
273 */ 332// -a, --adjust adjust the RTC to account for systematic drift
274static void set_system_clock_timezone(int utc) 333// --predict predict the drifted RTC time according to --date
275{ 334//Options:
276 struct timeval tv; 335// -u, --utc the RTC timescale is UTC
277 struct tm *broken; 336// -l, --localtime the RTC timescale is Local
278 struct timezone tz; 337// -f, --rtc <file> use an alternate file to /dev/rtc0
279 338// --directisa use the ISA bus instead of /dev/rtc0 access
280 gettimeofday(&tv, NULL); 339// --date <time> date/time input for --set and --predict
281 broken = localtime(&tv.tv_sec); 340// --delay <sec> delay used when set new RTC time
282 tz.tz_minuteswest = timezone / 60; 341// --update-drift update the RTC drift factor
283 if (broken->tm_isdst > 0) 342// --noadjfile do not use /etc/adjtime
284 tz.tz_minuteswest -= 60; 343// --adjfile <file> use an alternate file to /etc/adjtime
285 tz.tz_dsttime = 0; 344// --test dry run; implies --verbose
286 gettimeofday(&tv, NULL); 345// -v, --verbose display more details
287 if (!utc)
288 tv.tv_sec += tz.tz_minuteswest * 60;
289
290 /* glibc v2.31+ returns an error if both args are non-NULL */
291 if (settimeofday(NULL, &tz))
292 bb_simple_perror_msg_and_die("settimeofday");
293 if (settimeofday(&tv, NULL))
294 bb_simple_perror_msg_and_die("settimeofday");
295}
296 346
297//usage:#define hwclock_trivial_usage 347//usage:#define hwclock_trivial_usage
298//usage: IF_LONG_OPTS( 348//usage: IF_LONG_OPTS(
299//usage: "[-r|--show] [-s|--hctosys] [-w|--systohc] [--systz]" 349//usage: "[-swul] [--systz] [-f DEV]"
300//usage: " [--localtime] [-u|--utc]"
301//usage: " [-f|--rtc FILE]"
302//usage: ) 350//usage: )
303//usage: IF_NOT_LONG_OPTS( 351//usage: IF_NOT_LONG_OPTS(
304//usage: "[-r] [-s] [-w] [-t] [-l] [-u] [-f FILE]" 352//usage: "[-swult] [-f DEV]"
305//usage: ) 353//usage: )
306//usage:#define hwclock_full_usage "\n\n" 354//usage:#define hwclock_full_usage "\n\n"
307//usage: "Query and set hardware clock (RTC)\n" 355//usage: "Show or set hardware clock (RTC)\n"
308//usage: "\n -r Show hardware clock time" 356///////: "\n -r Show RTC time"
309//usage: "\n -s Set system time from hardware clock" 357///////-r is default, don't bother showing it in help
310//usage: "\n -w Set hardware clock from system time" 358//usage: "\n -s Set system time from RTC"
359//usage: "\n -w Set RTC from system time"
311//usage: IF_LONG_OPTS( 360//usage: IF_LONG_OPTS(
312//usage: "\n --systz Set in-kernel timezone, correct system time" 361//usage: "\n --systz Set in-kernel timezone, correct system time"
362//usage: "\n if RTC is kept in local time"
313//usage: ) 363//usage: )
314//usage: "\n if hardware clock is in local time" 364//usage: "\n -f DEV Use specified device (e.g. /dev/rtc2)"
315//usage: "\n -u Assume hardware clock is kept in UTC" 365//usage: "\n -u Assume RTC is kept in UTC"
316//usage: IF_LONG_OPTS( 366//usage: "\n -l Assume RTC is kept in local time"
317//usage: "\n --localtime Assume hardware clock is kept in local time" 367//usage: "\n (if neither is given, read from "ADJTIME_PATH")"
318//usage: )
319//usage: "\n -f FILE Use specified device (e.g. /dev/rtc2)"
320 368
321//TODO: get rid of incompatible -t and -l aliases to --systz and --localtime 369//TODO: get rid of incompatible -t alias to --systz?
322 370
323#define HWCLOCK_OPT_LOCALTIME 0x01 371#define HWCLOCK_OPT_LOCALTIME 0x01
324#define HWCLOCK_OPT_UTC 0x02 372#define HWCLOCK_OPT_UTC 0x02
@@ -334,10 +382,9 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv)
334 const char *rtcname = NULL; 382 const char *rtcname = NULL;
335 unsigned opt; 383 unsigned opt;
336 int utc; 384 int utc;
337
338#if ENABLE_LONG_OPTS 385#if ENABLE_LONG_OPTS
339 static const char hwclock_longopts[] ALIGN1 = 386 static const char hwclock_longopts[] ALIGN1 =
340 "localtime\0" No_argument "l" /* short opt is non-standard */ 387 "localtime\0" No_argument "l"
341 "utc\0" No_argument "u" 388 "utc\0" No_argument "u"
342 "show\0" No_argument "r" 389 "show\0" No_argument "r"
343 "hctosys\0" No_argument "s" 390 "hctosys\0" No_argument "s"
@@ -346,17 +393,15 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv)
346 "rtc\0" Required_argument "f" 393 "rtc\0" Required_argument "f"
347 ; 394 ;
348#endif 395#endif
349
350 /* Initialize "timezone" (libc global variable) */
351 tzset();
352
353 opt = getopt32long(argv, 396 opt = getopt32long(argv,
354 "^lurswtf:" "\0" "r--wst:w--rst:s--wrt:t--rsw:l--u:u--l", 397 "^""lurswtf:v" /* -v is accepted and ignored */
398 "\0"
399 "r--wst:w--rst:s--wrt:t--rsw:l--u:u--l",
355 hwclock_longopts, 400 hwclock_longopts,
356 &rtcname 401 &rtcname
357 ); 402 );
358 403
359 /* If -u or -l wasn't given check if we are using utc */ 404 /* If -u or -l wasn't given, check if we are using utc */
360 if (opt & (HWCLOCK_OPT_UTC | HWCLOCK_OPT_LOCALTIME)) 405 if (opt & (HWCLOCK_OPT_UTC | HWCLOCK_OPT_LOCALTIME))
361 utc = (opt & HWCLOCK_OPT_UTC); 406 utc = (opt & HWCLOCK_OPT_UTC);
362 else 407 else
@@ -367,7 +412,7 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv)
367 else if (opt & HWCLOCK_OPT_SYSTOHC) 412 else if (opt & HWCLOCK_OPT_SYSTOHC)
368 from_sys_clock(&rtcname, utc); 413 from_sys_clock(&rtcname, utc);
369 else if (opt & HWCLOCK_OPT_SYSTZ) 414 else if (opt & HWCLOCK_OPT_SYSTZ)
370 set_system_clock_timezone(utc); 415 set_kernel_timezone_and_clock(utc, NULL);
371 else 416 else
372 /* default HWCLOCK_OPT_SHOW */ 417 /* default HWCLOCK_OPT_SHOW */
373 show_clock(&rtcname, utc); 418 show_clock(&rtcname, utc);
diff --git a/util-linux/ionice.c b/util-linux/ionice.c
index 40c04d5e0..c8fb1a777 100644
--- a/util-linux/ionice.c
+++ b/util-linux/ionice.c
@@ -18,11 +18,11 @@
18//kbuild:lib-$(CONFIG_IONICE) += ionice.o 18//kbuild:lib-$(CONFIG_IONICE) += ionice.o
19 19
20//usage:#define ionice_trivial_usage 20//usage:#define ionice_trivial_usage
21//usage: "[-c 1-3] [-n 0-7] [-p PID] [PROG]" 21//usage: "[-c 1-3] [-n 0-7] [-p PID] [PROG ARGS]"
22//usage:#define ionice_full_usage "\n\n" 22//usage:#define ionice_full_usage "\n\n"
23//usage: "Change I/O priority and class\n" 23//usage: "Change I/O priority and class\n"
24//usage: "\n -c Class. 1:realtime 2:best-effort 3:idle" 24//usage: "\n -c N Class. 1:realtime 2:best-effort 3:idle"
25//usage: "\n -n Priority" 25//usage: "\n -n N Priority"
26 26
27#include <sys/syscall.h> 27#include <sys/syscall.h>
28#include <asm/unistd.h> 28#include <asm/unistd.h>
@@ -61,7 +61,7 @@ int ionice_main(int argc UNUSED_PARAM, char **argv)
61 /* Defaults */ 61 /* Defaults */
62 int ioclass = 0; 62 int ioclass = 0;
63 int pri = 0; 63 int pri = 0;
64 int pid = 0; /* affect own porcess */ 64 int pid = 0; /* affect own process */
65 int opt; 65 int opt;
66 enum { 66 enum {
67 OPT_n = 1, 67 OPT_n = 1,
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index 59dbcf0cd..dbbcbc655 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -80,12 +80,14 @@
80//kbuild:lib-$(CONFIG_MDEV) += mdev.o 80//kbuild:lib-$(CONFIG_MDEV) += mdev.o
81 81
82//usage:#define mdev_trivial_usage 82//usage:#define mdev_trivial_usage
83//usage: "[-s]" IF_FEATURE_MDEV_DAEMON(" | [-df]") 83//usage: "[-vS] " IF_FEATURE_MDEV_DAEMON("{ ") "[-s]" IF_FEATURE_MDEV_DAEMON(" | [-df] }")
84//usage:#define mdev_full_usage "\n\n" 84//usage:#define mdev_full_usage "\n\n"
85//usage: "mdev -s is to be run during boot to scan /sys and populate /dev.\n" 85//usage: " -v verbose\n"
86//usage: " -S log to syslog too\n"
87//usage: " -s scan /sys and populate /dev\n"
86//usage: IF_FEATURE_MDEV_DAEMON( 88//usage: IF_FEATURE_MDEV_DAEMON(
87//usage: "mdev -d[f]: daemon, listen on netlink.\n" 89//usage: " -d daemon, listen on netlink\n"
88//usage: " -f: stay in foreground.\n" 90//usage: " -f stay in foreground\n"
89//usage: ) 91//usage: )
90//usage: "\n" 92//usage: "\n"
91//usage: "Bare mdev is a kernel hotplug helper. To activate it:\n" 93//usage: "Bare mdev is a kernel hotplug helper. To activate it:\n"
@@ -113,6 +115,7 @@
113#include "common_bufsiz.h" 115#include "common_bufsiz.h"
114#include "xregex.h" 116#include "xregex.h"
115#include <linux/netlink.h> 117#include <linux/netlink.h>
118#include <syslog.h>
116 119
117/* "mdev -s" scans /sys/class/xxx, looking for directories which have dev 120/* "mdev -s" scans /sys/class/xxx, looking for directories which have dev
118 * file (it is of the form "M:m\n"). Example: /sys/class/tty/tty0/dev 121 * file (it is of the form "M:m\n"). Example: /sys/class/tty/tty0/dev
@@ -269,10 +272,6 @@
269# define dbg3s(msg) ((void)0) 272# define dbg3s(msg) ((void)0)
270#endif 273#endif
271 274
272
273#ifndef SO_RCVBUFFORCE
274#define SO_RCVBUFFORCE 33
275#endif
276static const char keywords[] ALIGN1 = "add\0remove\0"; // "change\0" 275static const char keywords[] ALIGN1 = "add\0remove\0"; // "change\0"
277enum { OP_add, OP_remove }; 276enum { OP_add, OP_remove };
278 277
@@ -297,7 +296,7 @@ struct rule {
297 296
298struct globals { 297struct globals {
299 int root_major, root_minor; 298 int root_major, root_minor;
300 smallint verbose; 299 int verbose;
301 char *subsystem; 300 char *subsystem;
302 char *subsys_env; /* for putenv("SUBSYSTEM=subsystem") */ 301 char *subsys_env; /* for putenv("SUBSYSTEM=subsystem") */
303#if ENABLE_FEATURE_MDEV_CONF 302#if ENABLE_FEATURE_MDEV_CONF
@@ -921,7 +920,7 @@ static void load_firmware(const char *firmware, const char *sysfs_path)
921 loading_fd = open("loading", O_WRONLY); 920 loading_fd = open("loading", O_WRONLY);
922 if (loading_fd >= 0) 921 if (loading_fd >= 0)
923 goto loading; 922 goto loading;
924 sleep(1); 923 sleep1();
925 } 924 }
926 goto out; 925 goto out;
927 926
@@ -964,7 +963,7 @@ static void load_firmware(const char *firmware, const char *sysfs_path)
964static char *curtime(void) 963static char *curtime(void)
965{ 964{
966 struct timeval tv; 965 struct timeval tv;
967 gettimeofday(&tv, NULL); 966 xgettimeofday(&tv);
968 sprintf( 967 sprintf(
969 strftime_HHMMSS(G.timestr, sizeof(G.timestr), &tv.tv_sec), 968 strftime_HHMMSS(G.timestr, sizeof(G.timestr), &tv.tv_sec),
970 ".%06u", 969 ".%06u",
@@ -1152,15 +1151,50 @@ static void initial_scan(char *temp)
1152 1151
1153#if ENABLE_FEATURE_MDEV_DAEMON 1152#if ENABLE_FEATURE_MDEV_DAEMON
1154 1153
1155/* uevent applet uses 16k buffer, and mmaps it before every read */ 1154/*
1156# define BUFFER_SIZE (2 * 1024) 1155 * The kernel (as of v5.4) will pass up to 32 environment variables with a
1157# define RCVBUF (2 * 1024 * 1024) 1156 * total of 2kiB on each event. On top of that the action string and device
1157 * path are added. Using a 3kiB buffer for the event should suffice in any
1158 * case.
1159 *
1160 * As far as the socket receive buffer size is concerned 2MiB proved to be too
1161 * small (see [1]). Udevd seems to use a whooping 128MiB. The socket receive
1162 * buffer size is just a resource limit. The buffers are allocated lazily so
1163 * the memory is not wasted.
1164 *
1165 * [1] http://lists.busybox.net/pipermail/busybox/2019-December/087665.html
1166 */
1167# define USER_RCVBUF (3 * 1024)
1168# define KERN_RCVBUF (128 * 1024 * 1024)
1158# define MAX_ENV 32 1169# define MAX_ENV 32
1159 1170
1171static int daemon_init(char *temp)
1172{
1173 int fd;
1174
1175 /* Subscribe for UEVENT kernel messages */
1176 /* Without a sufficiently big RCVBUF, a ton of simultaneous events
1177 * can trigger ENOBUFS on read, which is unrecoverable.
1178 * Reproducer:
1179 * mdev -d
1180 * find /sys -name uevent -exec sh -c 'echo add >"{}"' ';'
1181 */
1182 fd = create_and_bind_to_netlink(NETLINK_KOBJECT_UEVENT, 1 << 0, KERN_RCVBUF);
1183
1184 /*
1185 * Make inital scan after the uevent socket is alive and
1186 * _before_ we fork away. Already open mdev.log because we work
1187 * in daemon mode.
1188 */
1189 initial_scan(temp);
1190
1191 return fd;
1192}
1193
1160static void daemon_loop(char *temp, int fd) 1194static void daemon_loop(char *temp, int fd)
1161{ 1195{
1162 for (;;) { 1196 for (;;) {
1163 char netbuf[BUFFER_SIZE]; 1197 char netbuf[USER_RCVBUF];
1164 char *env[MAX_ENV]; 1198 char *env[MAX_ENV];
1165 char *s, *end; 1199 char *s, *end;
1166 ssize_t len; 1200 ssize_t len;
@@ -1168,6 +1202,16 @@ static void daemon_loop(char *temp, int fd)
1168 1202
1169 len = safe_read(fd, netbuf, sizeof(netbuf) - 1); 1203 len = safe_read(fd, netbuf, sizeof(netbuf) - 1);
1170 if (len < 0) { 1204 if (len < 0) {
1205 if (errno == ENOBUFS) {
1206 /*
1207 * We ran out of socket receive buffer space.
1208 * Start from scratch.
1209 */
1210 dbg1s("uevent overrun, rescanning");
1211 close(fd);
1212 fd = daemon_init(temp);
1213 continue;
1214 }
1171 bb_simple_perror_msg_and_die("read"); 1215 bb_simple_perror_msg_and_die("read");
1172 } 1216 }
1173 end = netbuf + len; 1217 end = netbuf + len;
@@ -1196,8 +1240,9 @@ int mdev_main(int argc UNUSED_PARAM, char **argv)
1196{ 1240{
1197 enum { 1241 enum {
1198 MDEV_OPT_SCAN = 1 << 0, 1242 MDEV_OPT_SCAN = 1 << 0,
1199 MDEV_OPT_DAEMON = 1 << 1, 1243 MDEV_OPT_SYSLOG = 1 << 1,
1200 MDEV_OPT_FOREGROUND = 1 << 2, 1244 MDEV_OPT_DAEMON = 1 << 2,
1245 MDEV_OPT_FOREGROUND = 1 << 3,
1201 }; 1246 };
1202 int opt; 1247 int opt;
1203 RESERVE_CONFIG_BUFFER(temp, PATH_MAX + SCRATCH_SIZE); 1248 RESERVE_CONFIG_BUFFER(temp, PATH_MAX + SCRATCH_SIZE);
@@ -1213,7 +1258,11 @@ int mdev_main(int argc UNUSED_PARAM, char **argv)
1213 1258
1214 xchdir("/dev"); 1259 xchdir("/dev");
1215 1260
1216 opt = getopt32(argv, "s" IF_FEATURE_MDEV_DAEMON("df")); 1261 opt = getopt32(argv, "^"
1262 "sS" IF_FEATURE_MDEV_DAEMON("df") "v"
1263 "\0"
1264 "vv",
1265 &G.verbose);
1217 1266
1218#if ENABLE_FEATURE_MDEV_CONF 1267#if ENABLE_FEATURE_MDEV_CONF
1219 G.filename = "/etc/mdev.conf"; 1268 G.filename = "/etc/mdev.conf";
@@ -1223,32 +1272,24 @@ int mdev_main(int argc UNUSED_PARAM, char **argv)
1223 } 1272 }
1224#endif 1273#endif
1225 1274
1275 if (opt & MDEV_OPT_SYSLOG) {
1276 openlog(applet_name, LOG_PID, LOG_DAEMON);
1277 logmode |= LOGMODE_SYSLOG;
1278 }
1279
1226#if ENABLE_FEATURE_MDEV_DAEMON 1280#if ENABLE_FEATURE_MDEV_DAEMON
1227 if (opt & MDEV_OPT_DAEMON) { 1281 if (opt & MDEV_OPT_DAEMON) {
1228 /* 1282 /* Daemon mode listening on uevent netlink socket. Fork away
1229 * Daemon mode listening on uevent netlink socket. 1283 * after initial scan so that caller can be sure everything
1230 */ 1284 * is up-to-date when mdev process returns.
1231 int fd;
1232
1233 /* Subscribe for UEVENT kernel messages */
1234 /* Without a sufficiently big RCVBUF, a ton of simultaneous events
1235 * can trigger ENOBUFS on read, which is unrecoverable.
1236 * Reproducer:
1237 * mdev -d
1238 * find /sys -name uevent -exec sh -c 'echo add >"{}"' ';'
1239 */ 1285 */
1240 fd = create_and_bind_to_netlink(NETLINK_KOBJECT_UEVENT, 1 << 0, RCVBUF); 1286 int fd = daemon_init(temp);
1241 1287
1242 /* 1288 if (!(opt & MDEV_OPT_FOREGROUND)) {
1243 * Make inital scan after the uevent socket is alive and 1289 /* there is no point in logging to /dev/null */
1244 * _before_ we fork away. 1290 logmode &= ~LOGMODE_STDIO;
1245 */
1246 initial_scan(temp);
1247
1248 if (!(opt & MDEV_OPT_FOREGROUND))
1249 bb_daemonize_or_rexec(0, argv); 1291 bb_daemonize_or_rexec(0, argv);
1250 1292 }
1251 open_mdev_log(NULL, getpid());
1252 1293
1253 daemon_loop(temp, fd); 1294 daemon_loop(temp, fd);
1254 } 1295 }
diff --git a/util-linux/mkfs_ext2.c b/util-linux/mkfs_ext2.c
index 1f525d75b..fcf374b2d 100644
--- a/util-linux/mkfs_ext2.c
+++ b/util-linux/mkfs_ext2.c
@@ -131,7 +131,7 @@ static void allocate(uint8_t *bitmap, uint32_t blocksize, uint32_t start, uint32
131static uint32_t has_super(uint32_t x) 131static uint32_t has_super(uint32_t x)
132{ 132{
133 // 0, 1 and powers of 3, 5, 7 up to 2^32 limit 133 // 0, 1 and powers of 3, 5, 7 up to 2^32 limit
134 static const uint32_t supers[] = { 134 static const uint32_t supers[] ALIGN4 = {
135 0, 1, 3, 5, 7, 9, 25, 27, 49, 81, 125, 243, 343, 625, 729, 135 0, 1, 3, 5, 7, 9, 25, 27, 49, 81, 125, 243, 343, 625, 729,
136 2187, 2401, 3125, 6561, 15625, 16807, 19683, 59049, 78125, 136 2187, 2401, 3125, 6561, 15625, 16807, 19683, 59049, 78125,
137 117649, 177147, 390625, 531441, 823543, 1594323, 1953125, 137 117649, 177147, 390625, 531441, 823543, 1594323, 1953125,
diff --git a/util-linux/mkswap.c b/util-linux/mkswap.c
index 9e51a1dcc..8fe5d0293 100644
--- a/util-linux/mkswap.c
+++ b/util-linux/mkswap.c
@@ -128,7 +128,7 @@ int mkswap_main(int argc UNUSED_PARAM, char **argv)
128 128
129 /* Figure out how big the device is */ 129 /* Figure out how big the device is */
130 len = get_volume_size_in_bytes(fd, argv[1], 1024, /*extend:*/ 1); 130 len = get_volume_size_in_bytes(fd, argv[1], 1024, /*extend:*/ 1);
131 pagesize = getpagesize(); 131 pagesize = bb_getpagesize();
132 len -= pagesize; 132 len -= pagesize;
133 133
134 /* Announce our intentions */ 134 /* Announce our intentions */
diff --git a/util-linux/mount.c b/util-linux/mount.c
index fc5161d7f..831dab9e2 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -182,14 +182,16 @@
182//usage: "Returns 0 for success, number of failed mounts for -a, or errno for one mount." 182//usage: "Returns 0 for success, number of failed mounts for -a, or errno for one mount."
183 183
184#include <mntent.h> 184#include <mntent.h>
185#if ENABLE_FEATURE_SYSLOG
185#include <syslog.h> 186#include <syslog.h>
187#endif
186#include <sys/mount.h> 188#include <sys/mount.h>
187// Grab more as needed from util-linux's mount/mount_constants.h 189// Grab more as needed from util-linux's mount/mount_constants.h
188#ifndef MS_DIRSYNC 190#ifndef MS_DIRSYNC
189# define MS_DIRSYNC (1 << 7) // Directory modifications are synchronous 191# define MS_DIRSYNC (1 << 7) // Directory modifications are synchronous
190#endif 192#endif
191#ifndef MS_UNION 193#ifndef MS_NOSYMFOLLOW
192# define MS_UNION (1 << 8) 194# define MS_NOSYMFOLLOW (1 << 8)
193#endif 195#endif
194#ifndef MS_BIND 196#ifndef MS_BIND
195# define MS_BIND (1 << 12) 197# define MS_BIND (1 << 12)
@@ -216,12 +218,16 @@
216#ifndef MS_SHARED 218#ifndef MS_SHARED
217# define MS_SHARED (1 << 20) 219# define MS_SHARED (1 << 20)
218#endif 220#endif
221
219#ifndef MS_RELATIME 222#ifndef MS_RELATIME
220# define MS_RELATIME (1 << 21) 223# define MS_RELATIME (1 << 21)
221#endif 224#endif
222#ifndef MS_STRICTATIME 225#ifndef MS_STRICTATIME
223# define MS_STRICTATIME (1 << 24) 226# define MS_STRICTATIME (1 << 24)
224#endif 227#endif
228#ifndef MS_LAZYTIME
229# define MS_LAZYTIME (1 << 25)
230#endif
225 231
226/* Any ~MS_FOO value has this bit set: */ 232/* Any ~MS_FOO value has this bit set: */
227#define BB_MS_INVERTED_VALUE (1u << 31) 233#define BB_MS_INVERTED_VALUE (1u << 31)
@@ -323,7 +329,7 @@ enum {
323 329
324// Standard mount options (from -o options or --options), 330// Standard mount options (from -o options or --options),
325// with corresponding flags 331// with corresponding flags
326static const int32_t mount_options[] = { 332static const int32_t mount_options[] ALIGN4 = {
327 // MS_FLAGS set a bit. ~MS_FLAGS disable that bit. 0 flags are NOPs. 333 // MS_FLAGS set a bit. ~MS_FLAGS disable that bit. 0 flags are NOPs.
328 334
329 IF_FEATURE_MOUNT_LOOP( 335 IF_FEATURE_MOUNT_LOOP(
@@ -358,16 +364,19 @@ static const int32_t mount_options[] = {
358 /* "noatime" */ MS_NOATIME, 364 /* "noatime" */ MS_NOATIME,
359 /* "diratime" */ ~MS_NODIRATIME, 365 /* "diratime" */ ~MS_NODIRATIME,
360 /* "nodiratime" */ MS_NODIRATIME, 366 /* "nodiratime" */ MS_NODIRATIME,
361 /* "mand" */ MS_MANDLOCK,
362 /* "nomand" */ ~MS_MANDLOCK,
363 /* "relatime" */ MS_RELATIME, 367 /* "relatime" */ MS_RELATIME,
364 /* "norelatime" */ ~MS_RELATIME, 368 /* "norelatime" */ ~MS_RELATIME,
365 /* "strictatime" */ MS_STRICTATIME, 369 /* "strictatime" */ MS_STRICTATIME,
366 /* "loud" */ ~MS_SILENT, 370 /* "nostrictatime"*/ ~MS_STRICTATIME,
367 /* "rbind" */ MS_BIND|MS_RECURSIVE, 371 /* "lazytime" */ MS_LAZYTIME,
372 /* "nolazytime" */ ~MS_LAZYTIME,
373 /* "nosymfollow" */ MS_NOSYMFOLLOW,
374 /* "mand" */ MS_MANDLOCK,
375 /* "nomand" */ ~MS_MANDLOCK,
376 /* "loud" */ ~MS_SILENT,
368 377
369 // action flags 378 // action flags
370 /* "union" */ MS_UNION, 379 /* "rbind" */ MS_BIND|MS_RECURSIVE,
371 /* "bind" */ MS_BIND, 380 /* "bind" */ MS_BIND,
372 /* "move" */ MS_MOVE, 381 /* "move" */ MS_MOVE,
373 /* "shared" */ MS_SHARED, 382 /* "shared" */ MS_SHARED,
@@ -404,29 +413,32 @@ static const char mount_option_str[] ALIGN1 =
404 ) 413 )
405 IF_FEATURE_MOUNT_FLAGS( 414 IF_FEATURE_MOUNT_FLAGS(
406 // vfs flags 415 // vfs flags
407 "nosuid\0" 416 "nosuid" "\0"
408 "suid\0" 417 "suid" "\0"
409 "dev\0" 418 "dev" "\0"
410 "nodev\0" 419 "nodev" "\0"
411 "exec\0" 420 "exec" "\0"
412 "noexec\0" 421 "noexec" "\0"
413 "sync\0" 422 "sync" "\0"
414 "dirsync\0" 423 "dirsync" "\0"
415 "async\0" 424 "async" "\0"
416 "atime\0" 425 "atime" "\0"
417 "noatime\0" 426 "noatime" "\0"
418 "diratime\0" 427 "diratime" "\0"
419 "nodiratime\0" 428 "nodiratime" "\0"
420 "mand\0" 429 "relatime" "\0"
421 "nomand\0" 430 "norelatime" "\0"
422 "relatime\0" 431 "strictatime" "\0"
423 "norelatime\0" 432 "nostrictatime""\0"
424 "strictatime\0" 433 "lazytime" "\0"
425 "loud\0" 434 "nolazytime" "\0"
426 "rbind\0" 435 "nosymfollow" "\0"
436 "mand" "\0"
437 "nomand" "\0"
438 "loud" "\0"
427 439
428 // action flags 440 // action flags
429 "union\0" 441 "rbind\0"
430 "bind\0" 442 "bind\0"
431 "move\0" 443 "move\0"
432 "make-shared\0" 444 "make-shared\0"
@@ -641,7 +653,7 @@ static unsigned long parse_mount_options(char *options, char **unrecognized)
641// Return a list of all block device backed filesystems 653// Return a list of all block device backed filesystems
642static llist_t *get_block_backed_filesystems(void) 654static llist_t *get_block_backed_filesystems(void)
643{ 655{
644 static const char filesystems[2][sizeof("/proc/filesystems")] = { 656 static const char filesystems[2][sizeof("/proc/filesystems")] ALIGN1 = {
645 "/etc/filesystems", 657 "/etc/filesystems",
646 "/proc/filesystems", 658 "/proc/filesystems",
647 }; 659 };
@@ -2064,13 +2076,18 @@ static int singlemount(struct mntent *mp, int ignore_busy)
2064 } 2076 }
2065 2077
2066 // Might this be an NFS filesystem? 2078 // Might this be an NFS filesystem?
2067 if ((!mp->mnt_type || is_prefixed_with(mp->mnt_type, "nfs")) 2079 if (!(vfsflags & (MS_BIND | MS_MOVE))
2068 && strchr(mp->mnt_fsname, ':') != NULL 2080 && (!mp->mnt_type || is_prefixed_with(mp->mnt_type, "nfs"))
2069 ) { 2081 ) {
2070 if (!mp->mnt_type) 2082 char *colon = strchr(mp->mnt_fsname, ':');
2071 mp->mnt_type = (char*)"nfs"; 2083 if (colon // looks like "hostname:..."
2072 rc = nfsmount(mp, vfsflags, filteropts); 2084 && strchrnul(mp->mnt_fsname, '/') > colon // "hostname:" has no slashes
2073 goto report_error; 2085 ) {
2086 if (!mp->mnt_type)
2087 mp->mnt_type = (char*)"nfs";
2088 rc = nfsmount(mp, vfsflags, filteropts);
2089 goto report_error;
2090 }
2074 } 2091 }
2075 2092
2076 // Look at the file. (Not found isn't a failure for remount, or for 2093 // Look at the file. (Not found isn't a failure for remount, or for
@@ -2110,7 +2127,7 @@ static int singlemount(struct mntent *mp, int ignore_busy)
2110 bb_simple_error_msg(bb_msg_perm_denied_are_you_root); 2127 bb_simple_error_msg(bb_msg_perm_denied_are_you_root);
2111 else 2128 else
2112 bb_simple_perror_msg("can't setup loop device"); 2129 bb_simple_perror_msg("can't setup loop device");
2113 return errno; 2130 return loopfd; // was "return errno", but it can be 0 here
2114 } 2131 }
2115 2132
2116 // Autodetect bind mounts 2133 // Autodetect bind mounts
diff --git a/util-linux/nsenter.c b/util-linux/nsenter.c
index c48dcf885..e6339da2f 100644
--- a/util-linux/nsenter.c
+++ b/util-linux/nsenter.c
@@ -17,7 +17,7 @@
17//kbuild:lib-$(CONFIG_NSENTER) += nsenter.o 17//kbuild:lib-$(CONFIG_NSENTER) += nsenter.o
18 18
19//usage:#define nsenter_trivial_usage 19//usage:#define nsenter_trivial_usage
20//usage: "[OPTIONS] [PROG [ARGS]]" 20//usage: "[OPTIONS] [PROG ARGS]"
21//usage:#define nsenter_full_usage "\n" 21//usage:#define nsenter_full_usage "\n"
22//usage: "\n -t PID Target process to get namespaces from" 22//usage: "\n -t PID Target process to get namespaces from"
23//usage: "\n -m[FILE] Enter mount namespace" 23//usage: "\n -m[FILE] Enter mount namespace"
@@ -103,8 +103,9 @@ static const struct namespace_descr ns_list[] = {
103}; 103};
104/* 104/*
105 * Upstream nsenter doesn't support the short option for --preserve-credentials 105 * Upstream nsenter doesn't support the short option for --preserve-credentials
106 * "+": stop on first non-option
106 */ 107 */
107static const char opt_str[] ALIGN1 = "U::i::u::n::p::m::""t:+S:+G:+r::w::F"; 108static const char opt_str[] ALIGN1 = "+""U::i::u::n::p::m::""t:+S:+G:+r::w::F";
108 109
109#if ENABLE_LONG_OPTS 110#if ENABLE_LONG_OPTS
110static const char nsenter_longopts[] ALIGN1 = 111static const char nsenter_longopts[] ALIGN1 =
diff --git a/util-linux/rdate.c b/util-linux/rdate.c
index bb1dc519a..9b80141c9 100644
--- a/util-linux/rdate.c
+++ b/util-linux/rdate.c
@@ -96,11 +96,10 @@ int rdate_main(int argc UNUSED_PARAM, char **argv)
96 if (time(NULL) == remote_time) 96 if (time(NULL) == remote_time)
97 bb_simple_error_msg("current time matches remote time"); 97 bb_simple_error_msg("current time matches remote time");
98 else { 98 else {
99 struct timespec ts; 99 struct timeval ts;
100 ts.tv_sec = remote_time; 100 ts.tv_sec = remote_time;
101 ts.tv_nsec = 0; 101 ts.tv_usec = 0;
102 if (clock_settime(CLOCK_REALTIME, &ts) < 0) 102 xsettimeofday(&ts);
103 bb_simple_perror_msg_and_die("can't set time of day");
104 } 103 }
105 } 104 }
106 105
diff --git a/util-linux/rtcwake.c b/util-linux/rtcwake.c
index 823e55662..eac16077d 100644
--- a/util-linux/rtcwake.c
+++ b/util-linux/rtcwake.c
@@ -36,24 +36,13 @@
36//usage: "[-a | -l | -u] [-d DEV] [-m MODE] [-s SEC | -t TIME]" 36//usage: "[-a | -l | -u] [-d DEV] [-m MODE] [-s SEC | -t TIME]"
37//usage:#define rtcwake_full_usage "\n\n" 37//usage:#define rtcwake_full_usage "\n\n"
38//usage: "Enter a system sleep state until specified wakeup time\n" 38//usage: "Enter a system sleep state until specified wakeup time\n"
39//usage: IF_LONG_OPTS( 39//usage: "\n -a Read clock mode from "ADJTIME_PATH" (default)"
40//usage: "\n -a,--auto Read clock mode from adjtime"
41//usage: "\n -l,--local Clock is set to local time"
42//usage: "\n -u,--utc Clock is set to UTC time"
43//usage: "\n -d,--device DEV Specify the RTC device"
44//usage: "\n -m,--mode MODE Set sleep state (default: standby)"
45//usage: "\n -s,--seconds SEC Set timeout in SEC seconds from now"
46//usage: "\n -t,--time TIME Set timeout to TIME seconds from epoch"
47//usage: )
48//usage: IF_NOT_LONG_OPTS(
49//usage: "\n -a Read clock mode from adjtime"
50//usage: "\n -l Clock is set to local time" 40//usage: "\n -l Clock is set to local time"
51//usage: "\n -u Clock is set to UTC time" 41//usage: "\n -u Clock is set to UTC time"
52//usage: "\n -d DEV Specify the RTC device" 42//usage: "\n -d DEV Specify the RTC device"
53//usage: "\n -m MODE Set sleep state (default: standby)" 43//usage: "\n -m MODE Set sleep state (default: standby)"
54//usage: "\n -s SEC Set timeout in SEC seconds from now" 44//usage: "\n -s SEC Set timeout in SEC seconds from now"
55//usage: "\n -t TIME Set timeout to TIME seconds from epoch" 45//usage: "\n -t TIME Set timeout to TIME seconds from epoch"
56//usage: )
57 46
58#include "libbb.h" 47#include "libbb.h"
59#include "rtc_.h" 48#include "rtc_.h"
diff --git a/util-linux/script.c b/util-linux/script.c
index 4eac5e94f..963435335 100644
--- a/util-linux/script.c
+++ b/util-linux/script.c
@@ -172,7 +172,7 @@ int script_main(int argc UNUSED_PARAM, char **argv)
172 struct timeval tv; 172 struct timeval tv;
173 double newtime; 173 double newtime;
174 174
175 gettimeofday(&tv, NULL); 175 xgettimeofday(&tv);
176 newtime = tv.tv_sec + (double) tv.tv_usec / 1000000; 176 newtime = tv.tv_sec + (double) tv.tv_usec / 1000000;
177 fprintf(timing_fp, "%f %u\n", newtime - oldtime, count); 177 fprintf(timing_fp, "%f %u\n", newtime - oldtime, count);
178 oldtime = newtime; 178 oldtime = newtime;
diff --git a/util-linux/setpriv.c b/util-linux/setpriv.c
index 1e4b201ed..6904cf019 100644
--- a/util-linux/setpriv.c
+++ b/util-linux/setpriv.c
@@ -47,7 +47,7 @@
47//kbuild:lib-$(CONFIG_SETPRIV) += setpriv.o 47//kbuild:lib-$(CONFIG_SETPRIV) += setpriv.o
48 48
49//usage:#define setpriv_trivial_usage 49//usage:#define setpriv_trivial_usage
50//usage: "[OPTIONS] PROG [ARGS]" 50//usage: "[OPTIONS] PROG ARGS"
51//usage:#define setpriv_full_usage "\n\n" 51//usage:#define setpriv_full_usage "\n\n"
52//usage: "Run PROG with different privilege settings\n" 52//usage: "Run PROG with different privilege settings\n"
53//usage: IF_FEATURE_SETPRIV_DUMP( 53//usage: IF_FEATURE_SETPRIV_DUMP(
diff --git a/util-linux/uevent.c b/util-linux/uevent.c
index 57d9328ef..db11746d0 100644
--- a/util-linux/uevent.c
+++ b/util-linux/uevent.c
@@ -15,7 +15,7 @@
15//kbuild:lib-$(CONFIG_UEVENT) += uevent.o 15//kbuild:lib-$(CONFIG_UEVENT) += uevent.o
16 16
17//usage:#define uevent_trivial_usage 17//usage:#define uevent_trivial_usage
18//usage: "[PROG [ARGS]]" 18//usage: "[PROG ARGS]"
19//usage:#define uevent_full_usage "\n\n" 19//usage:#define uevent_full_usage "\n\n"
20//usage: "uevent runs PROG for every netlink notification." 20//usage: "uevent runs PROG for every netlink notification."
21//usage: "\n""PROG's environment contains data passed from the kernel." 21//usage: "\n""PROG's environment contains data passed from the kernel."
@@ -26,22 +26,26 @@
26#include "common_bufsiz.h" 26#include "common_bufsiz.h"
27#include <linux/netlink.h> 27#include <linux/netlink.h>
28 28
29#define BUFFER_SIZE 16*1024
30
31#define env ((char **)bb_common_bufsiz1) 29#define env ((char **)bb_common_bufsiz1)
32#define INIT_G() do { setup_common_bufsiz(); } while (0) 30#define INIT_G() do { setup_common_bufsiz(); } while (0)
33enum { 31enum {
34 MAX_ENV = COMMON_BUFSIZE / sizeof(char*) - 1, 32 MAX_ENV = COMMON_BUFSIZE / sizeof(char*) - 1,
35 /* sizeof(env[0]) instead of sizeof(char*) 33 // ^^^sizeof(env[0]) instead of sizeof(char*)
36 * makes gcc-6.3.0 emit "strict-aliasing" warning. 34 // makes gcc-6.3.0 emit "strict-aliasing" warning.
37 */ 35
36 // socket receive buffer of 2MiB proved to be too small:
37 // http://lists.busybox.net/pipermail/busybox/2019-December/087665.html
38 // udevd seems to use a whooping 128MiB.
39 // The socket receive buffer size is just a resource limit.
40 // The buffers are allocated lazily so the memory is not wasted.
41 KERN_RCVBUF = 128 * 1024 * 1024,
42
43 // Might be made smaller: the kernel v5.4 passes up to 32 environment
44 // variables with a total of 2kb on each event.
45 // On top of that the action string and device path are added.
46 USER_RCVBUF = 16 * 1024,
38}; 47};
39 48
40#ifndef SO_RCVBUFFORCE
41#define SO_RCVBUFFORCE 33
42#endif
43enum { RCVBUF = 2 * 1024 * 1024 };
44
45int uevent_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 49int uevent_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
46int uevent_main(int argc UNUSED_PARAM, char **argv) 50int uevent_main(int argc UNUSED_PARAM, char **argv)
47{ 51{
@@ -57,7 +61,8 @@ int uevent_main(int argc UNUSED_PARAM, char **argv)
57 // Reproducer: 61 // Reproducer:
58 // uevent mdev & 62 // uevent mdev &
59 // find /sys -name uevent -exec sh -c 'echo add >"{}"' ';' 63 // find /sys -name uevent -exec sh -c 'echo add >"{}"' ';'
60 fd = create_and_bind_to_netlink(NETLINK_KOBJECT_UEVENT, /*groups:*/ 1 << 0, RCVBUF); 64 reopen:
65 fd = create_and_bind_to_netlink(NETLINK_KOBJECT_UEVENT, /*groups:*/ 1 << 0, KERN_RCVBUF);
61 66
62 for (;;) { 67 for (;;) {
63 char *netbuf; 68 char *netbuf;
@@ -69,17 +74,20 @@ int uevent_main(int argc UNUSED_PARAM, char **argv)
69 // for a new uevent notification to come in. 74 // for a new uevent notification to come in.
70 // We use a fresh mmap so that buffer is not allocated 75 // We use a fresh mmap so that buffer is not allocated
71 // until kernel actually starts filling it. 76 // until kernel actually starts filling it.
72 netbuf = mmap(NULL, BUFFER_SIZE, 77 netbuf = xmmap_anon(USER_RCVBUF);
73 PROT_READ | PROT_WRITE,
74 MAP_PRIVATE | MAP_ANON,
75 /* ignored: */ -1, 0);
76 if (netbuf == MAP_FAILED)
77 bb_simple_perror_msg_and_die("mmap");
78 78
79 // Here we block, possibly for a very long time 79 // Here we block, possibly for a very long time
80 len = safe_read(fd, netbuf, BUFFER_SIZE - 1); 80 len = safe_read(fd, netbuf, USER_RCVBUF - 1);
81 if (len < 0) 81 if (len < 0) {
82 if (errno == ENOBUFS) {
83 // Ran out of socket receive buffer
84 bb_simple_error_msg("uevent overrun");
85 close(fd);
86 munmap(netbuf, USER_RCVBUF);
87 goto reopen;
88 }
82 bb_simple_perror_msg_and_die("read"); 89 bb_simple_perror_msg_and_die("read");
90 }
83 end = netbuf + len; 91 end = netbuf + len;
84 *end = '\0'; 92 *end = '\0';
85 93
@@ -108,7 +116,7 @@ int uevent_main(int argc UNUSED_PARAM, char **argv)
108 while (env[idx]) 116 while (env[idx])
109 bb_unsetenv(env[idx++]); 117 bb_unsetenv(env[idx++]);
110 } 118 }
111 munmap(netbuf, BUFFER_SIZE); 119 munmap(netbuf, USER_RCVBUF);
112 } 120 }
113 121
114 return 0; // not reached 122 return 0; // not reached
diff --git a/util-linux/umount.c b/util-linux/umount.c
index 63a3bf504..23da32868 100644
--- a/util-linux/umount.c
+++ b/util-linux/umount.c
@@ -41,16 +41,16 @@
41//kbuild:lib-$(CONFIG_UMOUNT) += umount.o 41//kbuild:lib-$(CONFIG_UMOUNT) += umount.o
42 42
43//usage:#define umount_trivial_usage 43//usage:#define umount_trivial_usage
44//usage: "[OPTIONS] FILESYSTEM|DIRECTORY" 44//usage: "[-rlf"IF_FEATURE_MTAB_SUPPORT("m")IF_FEATURE_MOUNT_LOOP("d")IF_FEATURE_UMOUNT_ALL("a")"] [-t FSTYPE] FILESYSTEM|DIRECTORY"
45//usage:#define umount_full_usage "\n\n" 45//usage:#define umount_full_usage "\n\n"
46//usage: "Unmount file systems\n" 46//usage: "Unmount filesystems\n"
47//usage: IF_FEATURE_UMOUNT_ALL( 47//usage: IF_FEATURE_UMOUNT_ALL(
48//usage: "\n -a Unmount all file systems" IF_FEATURE_MTAB_SUPPORT(" in /etc/mtab") 48//usage: "\n -a Unmount all filesystems" IF_FEATURE_MTAB_SUPPORT(" in /etc/mtab")
49//usage: ) 49//usage: )
50//usage: IF_FEATURE_MTAB_SUPPORT( 50//usage: IF_FEATURE_MTAB_SUPPORT(
51//usage: "\n -n Don't erase /etc/mtab entries" 51//usage: "\n -n Don't erase /etc/mtab entries"
52//usage: ) 52//usage: )
53//usage: "\n -r Try to remount devices as read-only if mount is busy" 53//usage: "\n -r Remount devices read-only if mount is busy"
54//usage: "\n -l Lazy umount (detach filesystem)" 54//usage: "\n -l Lazy umount (detach filesystem)"
55//usage: "\n -f Force umount (i.e., unreachable NFS server)" 55//usage: "\n -f Force umount (i.e., unreachable NFS server)"
56//usage: IF_FEATURE_MOUNT_LOOP( 56//usage: IF_FEATURE_MOUNT_LOOP(
diff --git a/util-linux/unshare.c b/util-linux/unshare.c
index 2087413e8..68ccdd874 100644
--- a/util-linux/unshare.c
+++ b/util-linux/unshare.c
@@ -23,7 +23,7 @@
23//kbuild:lib-$(CONFIG_UNSHARE) += unshare.o 23//kbuild:lib-$(CONFIG_UNSHARE) += unshare.o
24 24
25//usage:#define unshare_trivial_usage 25//usage:#define unshare_trivial_usage
26//usage: "[OPTIONS] [PROG [ARGS]]" 26//usage: "[OPTIONS] [PROG ARGS]"
27//usage:#define unshare_full_usage "\n" 27//usage:#define unshare_full_usage "\n"
28//usage: "\n -m,--mount[=FILE] Unshare mount namespace" 28//usage: "\n -m,--mount[=FILE] Unshare mount namespace"
29//usage: "\n -u,--uts[=FILE] Unshare UTS namespace (hostname etc.)" 29//usage: "\n -u,--uts[=FILE] Unshare UTS namespace (hostname etc.)"
@@ -31,8 +31,8 @@
31//usage: "\n -n,--net[=FILE] Unshare network namespace" 31//usage: "\n -n,--net[=FILE] Unshare network namespace"
32//usage: "\n -p,--pid[=FILE] Unshare PID namespace" 32//usage: "\n -p,--pid[=FILE] Unshare PID namespace"
33//usage: "\n -U,--user[=FILE] Unshare user namespace" 33//usage: "\n -U,--user[=FILE] Unshare user namespace"
34//usage: "\n -f,--fork Fork before execing PROG" 34//usage: "\n -f Fork before execing PROG"
35//usage: "\n -r,--map-root-user Map current user to root (implies -U)" 35//usage: "\n -r Map current user to root (implies -U)"
36//usage: "\n --mount-proc[=DIR] Mount /proc filesystem first (implies -m)" 36//usage: "\n --mount-proc[=DIR] Mount /proc filesystem first (implies -m)"
37//usage: "\n --propagation slave|shared|private|unchanged" 37//usage: "\n --propagation slave|shared|private|unchanged"
38//usage: "\n Modify mount propagation in mount namespace" 38//usage: "\n Modify mount propagation in mount namespace"
diff --git a/util-linux/volume_id/erofs.c b/util-linux/volume_id/erofs.c
new file mode 100644
index 000000000..a163a353d
--- /dev/null
+++ b/util-linux/volume_id/erofs.c
@@ -0,0 +1,67 @@
1/*
2 * volume_id - reads filesystem label and uuid
3 *
4 * Copyright (C) 2020 Norbert Lange <nolange79@gmail.com>
5 *
6 * Licensed under GPLv2, see file LICENSE in this source tree.
7 */
8//config:config FEATURE_VOLUMEID_EROFS
9//config: bool "erofs filesystem"
10//config: default y
11//config: depends on VOLUMEID
12//config: help
13//config: Erofs is a compressed readonly filesystem for Linux.
14
15//kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_EROFS) += erofs.o
16
17#include "volume_id_internal.h"
18
19#define EROFS_SUPER_MAGIC_V1 0xE0F5E1E2
20#define EROFS_SUPER_OFFSET 1024
21#define EROFS_FEATURE_COMPAT_SB_CHKSUM 0x00000001
22
23/* 128-byte erofs on-disk super block */
24struct erofs_super_block {
25 uint32_t magic; /* file system magic number */
26 uint32_t checksum; /* crc32c(super_block) */
27 uint32_t feature_compat;
28 uint8_t blkszbits; /* support block_size == PAGE_SIZE only */
29 uint8_t reserved;
30
31 uint16_t root_nid; /* nid of root directory */
32 uint64_t inos; /* total valid ino # (== f_files - f_favail) */
33
34 uint64_t build_time; /* inode v1 time derivation */
35 uint32_t build_time_nsec; /* inode v1 time derivation in nano scale */
36 uint32_t blocks; /* used for statfs */
37 uint32_t meta_blkaddr; /* start block address of metadata area */
38 uint32_t xattr_blkaddr; /* start block address of shared xattr area */
39 uint8_t uuid[16]; /* 128-bit uuid for volume */
40 uint8_t volume_name[16]; /* volume name */
41 uint32_t feature_incompat;
42 uint8_t reserved2[44];
43} PACKED;
44
45int FAST_FUNC volume_id_probe_erofs(struct volume_id *id /*,uint64_t off*/)
46{
47 struct erofs_super_block *sb;
48
49 BUILD_BUG_ON(sizeof(struct erofs_super_block) != 128);
50
51 dbg("erofs: probing at offset 0x%llx", EROFS_SUPER_OFFSET);
52 sb = volume_id_get_buffer(id, EROFS_SUPER_OFFSET, sizeof(*sb));
53 if (!sb)
54 return -1;
55
56 if (sb->magic != cpu_to_le32(EROFS_SUPER_MAGIC_V1))
57 return -1;
58
59 IF_FEATURE_BLKID_TYPE(id->type = "erofs");
60
61 volume_id_set_label_string(id, sb->volume_name,
62 MIN(sizeof(sb->volume_name), VOLUME_ID_LABEL_SIZE));
63
64 volume_id_set_uuid(id, sb->uuid, UUID_DCE);
65
66 return 0;
67}
diff --git a/util-linux/volume_id/volume_id.c b/util-linux/volume_id/volume_id.c
index c3f07a741..8ceb61bde 100644
--- a/util-linux/volume_id/volume_id.c
+++ b/util-linux/volume_id/volume_id.c
@@ -49,7 +49,7 @@
49typedef int FAST_FUNC (*raid_probe_fptr)(struct volume_id *id, /*uint64_t off,*/ uint64_t size); 49typedef int FAST_FUNC (*raid_probe_fptr)(struct volume_id *id, /*uint64_t off,*/ uint64_t size);
50typedef int FAST_FUNC (*probe_fptr)(struct volume_id *id /*, uint64_t off*/); 50typedef int FAST_FUNC (*probe_fptr)(struct volume_id *id /*, uint64_t off*/);
51 51
52static const raid_probe_fptr raid1[] = { 52static const raid_probe_fptr raid1[] ALIGN_PTR = {
53#if ENABLE_FEATURE_VOLUMEID_LINUXRAID 53#if ENABLE_FEATURE_VOLUMEID_LINUXRAID
54 volume_id_probe_linux_raid, 54 volume_id_probe_linux_raid,
55#endif 55#endif
@@ -76,7 +76,7 @@ static const raid_probe_fptr raid1[] = {
76#endif 76#endif
77}; 77};
78 78
79static const probe_fptr raid2[] = { 79static const probe_fptr raid2[] ALIGN_PTR = {
80#if ENABLE_FEATURE_VOLUMEID_LVM 80#if ENABLE_FEATURE_VOLUMEID_LVM
81 volume_id_probe_lvm1, 81 volume_id_probe_lvm1,
82 volume_id_probe_lvm2, 82 volume_id_probe_lvm2,
@@ -90,7 +90,7 @@ static const probe_fptr raid2[] = {
90}; 90};
91 91
92/* signature in the first block, only small buffer needed */ 92/* signature in the first block, only small buffer needed */
93static const probe_fptr fs1[] = { 93static const probe_fptr fs1[] ALIGN_PTR = {
94#if ENABLE_FEATURE_VOLUMEID_FAT 94#if ENABLE_FEATURE_VOLUMEID_FAT
95 volume_id_probe_vfat, 95 volume_id_probe_vfat,
96#endif 96#endif
@@ -106,6 +106,9 @@ static const probe_fptr fs1[] = {
106#if ENABLE_FEATURE_VOLUMEID_SQUASHFS 106#if ENABLE_FEATURE_VOLUMEID_SQUASHFS
107 volume_id_probe_squashfs, 107 volume_id_probe_squashfs,
108#endif 108#endif
109#if ENABLE_FEATURE_VOLUMEID_EROFS
110 volume_id_probe_erofs,
111#endif
109#if ENABLE_FEATURE_VOLUMEID_XFS 112#if ENABLE_FEATURE_VOLUMEID_XFS
110 volume_id_probe_xfs, 113 volume_id_probe_xfs,
111#endif 114#endif
@@ -115,7 +118,7 @@ static const probe_fptr fs1[] = {
115}; 118};
116 119
117/* fill buffer with maximum */ 120/* fill buffer with maximum */
118static const probe_fptr fs2[] = { 121static const probe_fptr fs2[] ALIGN_PTR = {
119#if ENABLE_FEATURE_VOLUMEID_LINUXSWAP 122#if ENABLE_FEATURE_VOLUMEID_LINUXSWAP
120 volume_id_probe_linux_swap, 123 volume_id_probe_linux_swap,
121#endif 124#endif
diff --git a/util-linux/volume_id/volume_id_internal.h b/util-linux/volume_id/volume_id_internal.h
index ada18339d..b1e44481f 100644
--- a/util-linux/volume_id/volume_id_internal.h
+++ b/util-linux/volume_id/volume_id_internal.h
@@ -66,6 +66,9 @@ struct volume_id {
66 uint8_t *sbbuf; 66 uint8_t *sbbuf;
67 uint8_t *seekbuf; 67 uint8_t *seekbuf;
68 uint64_t seekbuf_off; 68 uint64_t seekbuf_off;
69#if ENABLE_FEATURE_BLKID_TYPE
70 const char *type;
71#endif
69#ifdef UNUSED_PARTITION_CODE 72#ifdef UNUSED_PARTITION_CODE
70 struct volume_id_partition *partitions; 73 struct volume_id_partition *partitions;
71 size_t partition_count; 74 size_t partition_count;
@@ -80,9 +83,6 @@ struct volume_id {
80// char type_version[VOLUME_ID_FORMAT_SIZE]; 83// char type_version[VOLUME_ID_FORMAT_SIZE];
81// smallint usage_id; 84// smallint usage_id;
82// const char *usage; 85// const char *usage;
83#if ENABLE_FEATURE_BLKID_TYPE
84 const char *type;
85#endif
86}; 86};
87 87
88struct volume_id* FAST_FUNC volume_id_open_node(int fd); 88struct volume_id* FAST_FUNC volume_id_open_node(int fd);
@@ -215,6 +215,8 @@ int FAST_FUNC volume_id_probe_romfs(struct volume_id *id /*,uint64_t off*/);
215 215
216int FAST_FUNC volume_id_probe_squashfs(struct volume_id *id /*,uint64_t off*/); 216int FAST_FUNC volume_id_probe_squashfs(struct volume_id *id /*,uint64_t off*/);
217 217
218int FAST_FUNC volume_id_probe_erofs(struct volume_id *id /*,uint64_t off*/);
219
218int FAST_FUNC volume_id_probe_sysv(struct volume_id *id /*,uint64_t off*/); 220int FAST_FUNC volume_id_probe_sysv(struct volume_id *id /*,uint64_t off*/);
219 221
220int FAST_FUNC volume_id_probe_udf(struct volume_id *id /*,uint64_t off*/); 222int FAST_FUNC volume_id_probe_udf(struct volume_id *id /*,uint64_t off*/);