aboutsummaryrefslogtreecommitdiff
path: root/util-linux
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-06-28 07:46:32 +0100
committerRon Yorston <rmy@pobox.com>2021-06-28 07:46:32 +0100
commite1ad66c0b8fd58a7158d40771175a7dab224202d (patch)
tree959d687eee9637151ad5798322586174de331141 /util-linux
parent0fdf99bee07b6c38795eb5415b5e337ab82cfba8 (diff)
parent5dbbd0a6f52befe6bc57baf97d39168e595197f1 (diff)
downloadbusybox-w32-e1ad66c0b8fd58a7158d40771175a7dab224202d.tar.gz
busybox-w32-e1ad66c0b8fd58a7158d40771175a7dab224202d.tar.bz2
busybox-w32-e1ad66c0b8fd58a7158d40771175a7dab224202d.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'util-linux')
-rw-r--r--util-linux/blockdev.c28
-rw-r--r--util-linux/dmesg.c2
-rw-r--r--util-linux/fdisk.c4
-rw-r--r--util-linux/flock.c2
-rw-r--r--util-linux/hexdump_xxd.c63
-rw-r--r--util-linux/ionice.c18
-rw-r--r--util-linux/mountpoint.c9
-rw-r--r--util-linux/readprofile.c4
-rw-r--r--util-linux/renice.c2
-rw-r--r--util-linux/switch_root.c35
-rw-r--r--util-linux/taskset.c108
11 files changed, 180 insertions, 95 deletions
diff --git a/util-linux/blockdev.c b/util-linux/blockdev.c
index 20a031377..3b550220a 100644
--- a/util-linux/blockdev.c
+++ b/util-linux/blockdev.c
@@ -25,8 +25,11 @@
25//usage: "\n --getbsz Get block size" 25//usage: "\n --getbsz Get block size"
26//usage: "\n --setbsz BYTES Set block size" 26//usage: "\n --setbsz BYTES Set block size"
27//usage: "\n --getsz Get device size in 512-byte sectors" 27//usage: "\n --getsz Get device size in 512-byte sectors"
28/*//usage: "\n --getsize Get device size in sectors (deprecated)"*/ 28///////: "\n --getsize Get device size in sectors (deprecated)"
29///////^^^^^ supported, but not shown in help ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
29//usage: "\n --getsize64 Get device size in bytes" 30//usage: "\n --getsize64 Get device size in bytes"
31//usage: "\n --getra Get readahead in 512-byte sectors"
32//usage: "\n --setra SECTORS Set readahead"
30//usage: "\n --flushbufs Flush buffers" 33//usage: "\n --flushbufs Flush buffers"
31//usage: "\n --rereadpt Reread partition table" 34//usage: "\n --rereadpt Reread partition table"
32// util-linux 2.31 also has: 35// util-linux 2.31 also has:
@@ -57,6 +60,9 @@ static const char bdcmd_names[] ALIGN1 =
57 "getsz" "\0" 60 "getsz" "\0"
58 "getsize" "\0" 61 "getsize" "\0"
59 "getsize64" "\0" 62 "getsize64" "\0"
63 "getra" "\0"
64 "setra" "\0"
65#define CMD_SETRA 10
60 "flushbufs" "\0" 66 "flushbufs" "\0"
61 "rereadpt" "\0" 67 "rereadpt" "\0"
62; 68;
@@ -70,6 +76,8 @@ static const uint32_t bdcmd_ioctl[] ALIGN4 = {
70 BLKGETSIZE64, //getsz 76 BLKGETSIZE64, //getsz
71 BLKGETSIZE, //getsize 77 BLKGETSIZE, //getsize
72 BLKGETSIZE64, //getsize64 78 BLKGETSIZE64, //getsize64
79 BLKRAGET, //getra
80 BLKRASET, //setra
73 BLKFLSBUF, //flushbufs 81 BLKFLSBUF, //flushbufs
74 BLKRRPART, //rereadpt 82 BLKRRPART, //rereadpt
75}; 83};
@@ -95,6 +103,8 @@ static const uint8_t bdcmd_flags[] ALIGN1 = {
95 ARG_U64 + FL_SCALE512, //getsz 103 ARG_U64 + FL_SCALE512, //getsz
96 ARG_ULONG, //getsize 104 ARG_ULONG, //getsize
97 ARG_U64, //getsize64 105 ARG_U64, //getsize64
106 ARG_ULONG, //getra
107 ARG_ULONG + FL_NORESULT, //setra
98 ARG_NONE + FL_NORESULT, //flushbufs 108 ARG_NONE + FL_NORESULT, //flushbufs
99 ARG_NONE + FL_NORESULT, //rereadpt 109 ARG_NONE + FL_NORESULT, //rereadpt
100}; 110};
@@ -130,8 +140,9 @@ int blockdev_main(int argc UNUSED_PARAM, char **argv)
130 /* setrw translates to BLKROSET(0), most other ioctls don't care... */ 140 /* setrw translates to BLKROSET(0), most other ioctls don't care... */
131 /* ...setro will do BLKROSET(1) */ 141 /* ...setro will do BLKROSET(1) */
132 u64 = (bdcmd == CMD_SETRO); 142 u64 = (bdcmd == CMD_SETRO);
133 if (bdcmd == CMD_SETBSZ) { 143 if (bdcmd == CMD_SETBSZ || bdcmd == CMD_SETRA) {
134 /* ...setbsz is BLKBSZSET(bytes) */ 144 /* ...setbsz is BLKBSZSET(bytes) */
145 /* ...setra is BLKRASET(512 bytes) */
135 u64 = xatoi_positive(*++argv); 146 u64 = xatoi_positive(*++argv);
136 } 147 }
137 148
@@ -145,8 +156,11 @@ int blockdev_main(int argc UNUSED_PARAM, char **argv)
145#if BB_BIG_ENDIAN 156#if BB_BIG_ENDIAN
146 /* Store data properly wrt data size. 157 /* Store data properly wrt data size.
147 * (1) It's no-op for little-endian. 158 * (1) It's no-op for little-endian.
148 * (2) it's no-op for 0 and -1. Only --setro uses arg != 0 and != -1, 159 * (2) it's no-op for 0 and -1.
149 * and it is ARG_INT. --setbsz USER_VAL is also ARG_INT. 160 * --setro uses arg != 0 and != -1, and it is ARG_INT
161 * --setbsz USER_VAL is also ARG_INT
162 * --setra USER_VAL is ARG_ULONG, but it is passed by value,
163 * not reference (see below in ioctl call).
150 * Thus, we don't need to handle ARG_ULONG. 164 * Thus, we don't need to handle ARG_ULONG.
151 */ 165 */
152 switch (flags & ARG_MASK) { 166 switch (flags & ARG_MASK) {
@@ -161,7 +175,11 @@ int blockdev_main(int argc UNUSED_PARAM, char **argv)
161 } 175 }
162#endif 176#endif
163 177
164 if (ioctl(fd, bdcmd_ioctl[bdcmd], &ioctl_val_on_stack.u64) == -1) 178 if (ioctl(fd, bdcmd_ioctl[bdcmd],
179 bdcmd == CMD_SETRA
180 ? (void*)(uintptr_t)u64 /* BLKRASET passes _value_, not pointer to it */
181 : &ioctl_val_on_stack.u64
182 ) == -1)
165 bb_simple_perror_msg_and_die(*argv); 183 bb_simple_perror_msg_and_die(*argv);
166 184
167 /* Fetch it into register(s) */ 185 /* Fetch it into register(s) */
diff --git a/util-linux/dmesg.c b/util-linux/dmesg.c
index dc4e57169..6670b84de 100644
--- a/util-linux/dmesg.c
+++ b/util-linux/dmesg.c
@@ -46,7 +46,7 @@
46//kbuild:lib-$(CONFIG_DMESG) += dmesg.o 46//kbuild:lib-$(CONFIG_DMESG) += dmesg.o
47 47
48//usage:#define dmesg_trivial_usage 48//usage:#define dmesg_trivial_usage
49//usage: "[-c] [-n LEVEL] [-s SIZE]" 49//usage: "[-cr] [-n LEVEL] [-s SIZE]"
50//usage:#define dmesg_full_usage "\n\n" 50//usage:#define dmesg_full_usage "\n\n"
51//usage: "Print or control the kernel ring buffer\n" 51//usage: "Print or control the kernel ring buffer\n"
52//usage: "\n -c Clear ring buffer after printing" 52//usage: "\n -c Clear ring buffer after printing"
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index c50ceead1..1c2a7d683 100644
--- a/util-linux/fdisk.c
+++ b/util-linux/fdisk.c
@@ -232,8 +232,8 @@ struct pte {
232}; 232};
233 233
234#define unable_to_open "can't open '%s'" 234#define unable_to_open "can't open '%s'"
235#define unable_to_read "can't read from %s" 235#define unable_to_read "can't read '%s'"
236#define unable_to_seek "can't seek on %s" 236#define unable_to_seek "can't seek '%s'"
237 237
238enum label_type { 238enum label_type {
239 LABEL_DOS, LABEL_SUN, LABEL_SGI, LABEL_AIX, LABEL_OSF, LABEL_GPT 239 LABEL_DOS, LABEL_SUN, LABEL_SGI, LABEL_AIX, LABEL_OSF, LABEL_GPT
diff --git a/util-linux/flock.c b/util-linux/flock.c
index 12c16013c..1ed752a80 100644
--- a/util-linux/flock.c
+++ b/util-linux/flock.c
@@ -14,7 +14,7 @@
14//kbuild:lib-$(CONFIG_FLOCK) += flock.o 14//kbuild:lib-$(CONFIG_FLOCK) += flock.o
15 15
16//usage:#define flock_trivial_usage 16//usage:#define flock_trivial_usage
17//usage: "[-sxun] FD|{FILE [-c] PROG ARGS}" 17//usage: "[-sxun] FD | { FILE [-c] PROG ARGS }"
18//usage:#define flock_full_usage "\n\n" 18//usage:#define flock_full_usage "\n\n"
19//usage: "[Un]lock file descriptor, or lock FILE, run PROG\n" 19//usage: "[Un]lock file descriptor, or lock FILE, run PROG\n"
20//usage: "\n -s Shared lock" 20//usage: "\n -s Shared lock"
diff --git a/util-linux/hexdump_xxd.c b/util-linux/hexdump_xxd.c
index 29bbc6633..fe78f6242 100644
--- a/util-linux/hexdump_xxd.c
+++ b/util-linux/hexdump_xxd.c
@@ -41,15 +41,17 @@
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: "[-pr] [-g N] [-c N] [-n LEN] [-s OFS] [FILE]" 44//usage: "[-pri] [-g N] [-c N] [-n LEN] [-s OFS] [-o 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"
48//usage: "\n -c N Bytes per line" 48//usage: "\n -c N Bytes per line"
49//usage: "\n -p Show only hex bytes, assumes -c30" 49//usage: "\n -p Show only hex bytes, assumes -c30"
50//usage: "\n -i C include file style"
50// exactly the same help text lines in hexdump and xxd: 51// exactly the same help text lines in hexdump and xxd:
51//usage: "\n -l LENGTH Show only first LENGTH bytes" 52//usage: "\n -l LENGTH Show only first LENGTH bytes"
52//usage: "\n -s OFFSET Skip OFFSET bytes" 53//usage: "\n -s OFFSET Skip OFFSET bytes"
54//usage: "\n -o OFFSET Add OFFSET to displayed offset"
53//usage: "\n -r Reverse (with -p, assumes no offsets in input)" 55//usage: "\n -r Reverse (with -p, assumes no offsets in input)"
54 56
55#include "libbb.h" 57#include "libbb.h"
@@ -61,7 +63,11 @@
61#define OPT_s (1 << 1) 63#define OPT_s (1 << 1)
62#define OPT_a (1 << 2) 64#define OPT_a (1 << 2)
63#define OPT_p (1 << 3) 65#define OPT_p (1 << 3)
64#define OPT_r (1 << 4) 66#define OPT_i (1 << 4)
67#define OPT_r (1 << 5)
68#define OPT_g (1 << 6)
69#define OPT_c (1 << 7)
70#define OPT_o (1 << 8)
65 71
66static void reverse(unsigned opt, unsigned cols, const char *filename) 72static void reverse(unsigned opt, unsigned cols, const char *filename)
67{ 73{
@@ -122,20 +128,30 @@ static void reverse(unsigned opt, unsigned cols, const char *filename)
122 fflush_stdout_and_exit(EXIT_SUCCESS); 128 fflush_stdout_and_exit(EXIT_SUCCESS);
123} 129}
124 130
131static void print_C_style(const char *p, const char *hdr)
132{
133 printf(hdr, isdigit(p[0]) ? "__" : "");
134 while (*p) {
135 bb_putchar(isalnum(*p) ? *p : '_');
136 p++;
137 }
138}
139
125int xxd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 140int xxd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
126int xxd_main(int argc UNUSED_PARAM, char **argv) 141int xxd_main(int argc UNUSED_PARAM, char **argv)
127{ 142{
128 char buf[80]; 143 char buf[80];
129 dumper_t *dumper; 144 dumper_t *dumper;
130 char *opt_l, *opt_s; 145 char *opt_l, *opt_s, *opt_o;
131 unsigned bytes = 2; 146 unsigned bytes = 2;
132 unsigned cols = 0; 147 unsigned cols = 0;
133 unsigned opt; 148 unsigned opt;
149 int r;
134 150
135 dumper = alloc_dumper(); 151 dumper = alloc_dumper();
136 152
137 opt = getopt32(argv, "^" "l:s:aprg:+c:+" "\0" "?1" /* 1 argument max */, 153 opt = getopt32(argv, "^" "l:s:apirg:+c:+o:" "\0" "?1" /* 1 argument max */,
138 &opt_l, &opt_s, &bytes, &cols 154 &opt_l, &opt_s, &bytes, &cols, &opt_o
139 ); 155 );
140 argv += optind; 156 argv += optind;
141 157
@@ -158,14 +174,24 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
158 //BUGGY for /proc/version (unseekable?) 174 //BUGGY for /proc/version (unseekable?)
159 } 175 }
160 176
177 if (opt & OPT_o) {
178 /* -o accepts negative numbers too */
179 dumper->xxd_displayoff = xstrtoll(opt_o, /*base:*/ 0);
180 }
181
161 if (opt & OPT_p) { 182 if (opt & OPT_p) {
162 if (cols == 0) 183 if (cols == 0)
163 cols = 30; 184 cols = 30;
164 bytes = cols; /* -p ignores -gN */ 185 bytes = cols; /* -p ignores -gN */
165 } else { 186 } else {
166 if (cols == 0) 187 if (cols == 0)
167 cols = 16; 188 cols = (opt & OPT_i) ? 12 : 16;
168 bb_dump_add(dumper, "\"%08.8_ax: \""); // "address: " 189 if (opt & OPT_i) {
190 bytes = 1; // -i ignores -gN
191 // output is " 0xXX, 0xXX, 0xXX...", add leading space
192 bb_dump_add(dumper, "\" \"");
193 } else
194 bb_dump_add(dumper, "\"%08.8_ax: \""); // "address: "
169 } 195 }
170 196
171 if (opt & OPT_r) { 197 if (opt & OPT_r) {
@@ -173,11 +199,15 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
173 } 199 }
174 200
175 if (bytes < 1 || bytes >= cols) { 201 if (bytes < 1 || bytes >= cols) {
176 sprintf(buf, "%u/1 \"%%02x\"", cols); // cols * "xx" 202 sprintf(buf, "%u/1 \"%%02x\"", cols); // cols * "XX"
177 bb_dump_add(dumper, buf); 203 bb_dump_add(dumper, buf);
178 } 204 }
179 else if (bytes == 1) { 205 else if (bytes == 1) {
180 sprintf(buf, "%u/1 \"%%02x \"", cols); // cols * "xx " 206 if (opt & OPT_i)
207 sprintf(buf, "%u/1 \" 0x%%02x,\"", cols); // cols * " 0xXX,"
208//TODO: compat: omit the last comma after the very last byte
209 else
210 sprintf(buf, "%u/1 \"%%02x \"", cols); // cols * "XX "
181 bb_dump_add(dumper, buf); 211 bb_dump_add(dumper, buf);
182 } 212 }
183 else { 213 else {
@@ -201,13 +231,22 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
201 free(bigbuf); 231 free(bigbuf);
202 } 232 }
203 233
204 if (!(opt & OPT_p)) { 234 if (!(opt & (OPT_p|OPT_i))) {
205 sprintf(buf, "\" \"%u/1 \"%%_p\"\"\n\"", cols); // " ASCII\n" 235 sprintf(buf, "\" \"%u/1 \"%%_p\"\"\n\"", cols); // " ASCII\n"
206 bb_dump_add(dumper, buf); 236 bb_dump_add(dumper, buf);
207 } else { 237 } else {
208 bb_dump_add(dumper, "\"\n\""); 238 bb_dump_add(dumper, "\"\n\"");
209 dumper->eofstring = "\n"; 239 dumper->xxd_eofstring = "\n";
210 } 240 }
211 241
212 return bb_dump_dump(dumper, argv); 242 if ((opt & OPT_i) && argv[0]) {
243 print_C_style(argv[0], "unsigned char %s");
244 printf("[] = {\n");
245 }
246 r = bb_dump_dump(dumper, argv);
247 if (r == 0 && (opt & OPT_i) && argv[0]) {
248 print_C_style(argv[0], "};\nunsigned int %s");
249 printf("_len = %"OFF_FMT"u;\n", dumper->address);
250 }
251 return r;
213} 252}
diff --git a/util-linux/ionice.c b/util-linux/ionice.c
index c8fb1a777..82bd309d1 100644
--- a/util-linux/ionice.c
+++ b/util-linux/ionice.c
@@ -18,11 +18,13 @@
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 ARGS]" 21//usage: "[-c 1-3] [-n 0-7] [-t] { -p PID | PROG ARGS }"
22//TODO: | -P PGID | -u UID; also -pPu can take _list of_ IDs
22//usage:#define ionice_full_usage "\n\n" 23//usage:#define ionice_full_usage "\n\n"
23//usage: "Change I/O priority and class\n" 24//usage: "Change I/O priority and class\n"
24//usage: "\n -c N Class. 1:realtime 2:best-effort 3:idle" 25//usage: "\n -c N Class. 1:realtime 2:best-effort 3:idle"
25//usage: "\n -n N Priority" 26//usage: "\n -n N Priority"
27//usage: "\n -t Ignore errors"
26 28
27#include <sys/syscall.h> 29#include <sys/syscall.h>
28#include <asm/unistd.h> 30#include <asm/unistd.h>
@@ -64,14 +66,15 @@ int ionice_main(int argc UNUSED_PARAM, char **argv)
64 int pid = 0; /* affect own process */ 66 int pid = 0; /* affect own process */
65 int opt; 67 int opt;
66 enum { 68 enum {
67 OPT_n = 1, 69 OPT_n = 1 << 0,
68 OPT_c = 2, 70 OPT_c = 1 << 1,
69 OPT_p = 4, 71 OPT_p = 1 << 2,
72 OPT_t = 1 << 3,
70 }; 73 };
71 74
72 /* Numeric params */
73 /* '+': stop at first non-option */ 75 /* '+': stop at first non-option */
74 opt = getopt32(argv, "+n:+c:+p:+", &pri, &ioclass, &pid); 76 /* numeric params for -n -c -p */
77 opt = getopt32(argv, "+""n:+c:+p:+t", &pri, &ioclass, &pid);
75 argv += optind; 78 argv += optind;
76 79
77 if (opt & OPT_c) { 80 if (opt & OPT_c) {
@@ -104,7 +107,8 @@ int ionice_main(int argc UNUSED_PARAM, char **argv)
104//pri, ioclass, pri | (ioclass << IOPRIO_CLASS_SHIFT)); 107//pri, ioclass, pri | (ioclass << IOPRIO_CLASS_SHIFT));
105 pri |= (ioclass << IOPRIO_CLASS_SHIFT); 108 pri |= (ioclass << IOPRIO_CLASS_SHIFT);
106 if (ioprio_set(IOPRIO_WHO_PROCESS, pid, pri) == -1) 109 if (ioprio_set(IOPRIO_WHO_PROCESS, pid, pri) == -1)
107 bb_perror_msg_and_die("ioprio_%cet", 's'); 110 if (!(opt & OPT_t))
111 bb_perror_msg_and_die("ioprio_%cet", 's');
108 if (argv[0]) { 112 if (argv[0]) {
109 BB_EXECVP_or_die(argv); 113 BB_EXECVP_or_die(argv);
110 } 114 }
diff --git a/util-linux/mountpoint.c b/util-linux/mountpoint.c
index a44cf6013..28b1e7a54 100644
--- a/util-linux/mountpoint.c
+++ b/util-linux/mountpoint.c
@@ -19,13 +19,14 @@
19//kbuild:lib-$(CONFIG_MOUNTPOINT) += mountpoint.o 19//kbuild:lib-$(CONFIG_MOUNTPOINT) += mountpoint.o
20 20
21//usage:#define mountpoint_trivial_usage 21//usage:#define mountpoint_trivial_usage
22//usage: "[-q] <[-dn] DIR | -x DEVICE>" 22//usage: "[-q] { [-dn] DIR | -x DEVICE }"
23//usage:#define mountpoint_full_usage "\n\n" 23//usage:#define mountpoint_full_usage "\n\n"
24//usage: "Check if the directory is a mountpoint\n" 24//usage: "Check if DIR is a mountpoint\n"
25//usage: "\n -q Quiet" 25//usage: "\n -q Quiet"
26//usage: "\n -d Print major/minor device number of the filesystem" 26//usage: "\n -d Print major:minor of the filesystem"
27//usage: "\n -n Print device name of the filesystem" 27//usage: "\n -n Print device name of the filesystem"
28//usage: "\n -x Print major/minor device number of the blockdevice" 28//////// -n is not supported by util-linux-2.36.1 ^^^^^^^^^^^^^^^^^^
29//usage: "\n -x Print major:minor of DEVICE"
29//usage: 30//usage:
30//usage:#define mountpoint_example_usage 31//usage:#define mountpoint_example_usage
31//usage: "$ mountpoint /proc\n" 32//usage: "$ mountpoint /proc\n"
diff --git a/util-linux/readprofile.c b/util-linux/readprofile.c
index 32d9987e7..f11c62292 100644
--- a/util-linux/readprofile.c
+++ b/util-linux/readprofile.c
@@ -44,8 +44,8 @@
44//usage:#define readprofile_trivial_usage 44//usage:#define readprofile_trivial_usage
45//usage: "[OPTIONS]" 45//usage: "[OPTIONS]"
46//usage:#define readprofile_full_usage "\n\n" 46//usage:#define readprofile_full_usage "\n\n"
47//usage: " -m mapfile (Default: /boot/System.map)" 47//usage: " -m MAPFILE (Default: /boot/System.map)"
48//usage: "\n -p profile (Default: /proc/profile)" 48//usage: "\n -p PROFILE (Default: /proc/profile)"
49//usage: "\n -M NUM Set the profiling multiplier to NUM" 49//usage: "\n -M NUM Set the profiling multiplier to NUM"
50//usage: "\n -i Print only info about the sampling step" 50//usage: "\n -i Print only info about the sampling step"
51//usage: "\n -v Verbose" 51//usage: "\n -v Verbose"
diff --git a/util-linux/renice.c b/util-linux/renice.c
index a318ffce0..fc72550f4 100644
--- a/util-linux/renice.c
+++ b/util-linux/renice.c
@@ -29,7 +29,7 @@
29//kbuild:lib-$(CONFIG_RENICE) += renice.o 29//kbuild:lib-$(CONFIG_RENICE) += renice.o
30 30
31//usage:#define renice_trivial_usage 31//usage:#define renice_trivial_usage
32//usage: "[-n] PRIORITY [[-p | -g | -u] ID...]..." 32//usage: "[-n] PRIORITY [[-p|g|u] ID...]..."
33//usage:#define renice_full_usage "\n\n" 33//usage:#define renice_full_usage "\n\n"
34//usage: "Change scheduling priority of a running process\n" 34//usage: "Change scheduling priority of a running process\n"
35//usage: "\n -n Add PRIORITY to current nice value" 35//usage: "\n -n Add PRIORITY to current nice value"
diff --git a/util-linux/switch_root.c b/util-linux/switch_root.c
index f2674b5ac..901c0b8db 100644
--- a/util-linux/switch_root.c
+++ b/util-linux/switch_root.c
@@ -68,11 +68,22 @@ extern int capget(cap_user_header_t header, const cap_user_data_t data);
68# define MS_MOVE 8192 68# define MS_MOVE 8192
69#endif 69#endif
70 70
71static void delete_contents(const char *directory, dev_t rootdev);
72
73static int FAST_FUNC rmrf(const char *directory, struct dirent *d, void *rootdevp)
74{
75 char *newdir = concat_subpath_file(directory, d->d_name);
76 if (newdir) { // not . or ..
77 // Recurse to delete contents
78 delete_contents(newdir, *(dev_t*)rootdevp);
79 free(newdir);
80 }
81 return 0;
82}
83
71// Recursively delete contents of rootfs 84// Recursively delete contents of rootfs
72static void delete_contents(const char *directory, dev_t rootdev) 85static void delete_contents(const char *directory, dev_t rootdev)
73{ 86{
74 DIR *dir;
75 struct dirent *d;
76 struct stat st; 87 struct stat st;
77 88
78 // Don't descend into other filesystems 89 // Don't descend into other filesystems
@@ -81,25 +92,7 @@ static void delete_contents(const char *directory, dev_t rootdev)
81 92
82 // Recursively delete the contents of directories 93 // Recursively delete the contents of directories
83 if (S_ISDIR(st.st_mode)) { 94 if (S_ISDIR(st.st_mode)) {
84 dir = opendir(directory); 95 iterate_on_dir(directory, rmrf, &rootdev);
85 if (dir) {
86 while ((d = readdir(dir))) {
87 char *newdir = d->d_name;
88
89 // Skip . and ..
90 if (DOT_OR_DOTDOT(newdir))
91 continue;
92
93 // Recurse to delete contents
94 newdir = concat_path_file(directory, newdir);
95 delete_contents(newdir, rootdev);
96 free(newdir);
97 }
98 closedir(dir);
99
100 // Directory should now be empty, zap it
101 rmdir(directory);
102 }
103 } else { 96 } else {
104 // It wasn't a directory, zap it 97 // It wasn't a directory, zap it
105 unlink(directory); 98 unlink(directory);
diff --git a/util-linux/taskset.c b/util-linux/taskset.c
index b542f8c83..afe2f04d2 100644
--- a/util-linux/taskset.c
+++ b/util-linux/taskset.c
@@ -34,10 +34,12 @@
34//kbuild:lib-$(CONFIG_TASKSET) += taskset.o 34//kbuild:lib-$(CONFIG_TASKSET) += taskset.o
35 35
36//usage:#define taskset_trivial_usage 36//usage:#define taskset_trivial_usage
37//usage: "[-p] [HEXMASK] PID | PROG ARGS" 37//usage: "[-ap] [HEXMASK"IF_FEATURE_TASKSET_CPULIST(" | -c LIST")"] { PID | PROG ARGS }"
38//usage:#define taskset_full_usage "\n\n" 38//usage:#define taskset_full_usage "\n\n"
39//usage: "Set or get CPU affinity\n" 39//usage: "Set or get CPU affinity\n"
40//usage: "\n -p Operate on an existing PID" 40//usage: "\n -p Operate on PID"
41//usage: "\n -a Operate on all threads"
42//usage: "\n -c Affinity is a list, not mask"
41//usage: 43//usage:
42//usage:#define taskset_example_usage 44//usage:#define taskset_example_usage
43//usage: "$ taskset 0x7 ./dgemm_test&\n" 45//usage: "$ taskset 0x7 ./dgemm_test&\n"
@@ -205,42 +207,18 @@ static void print_cpulist(const ul *mask, unsigned mask_size_in_bytes)
205} 207}
206#endif 208#endif
207 209
208int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 210enum {
209int taskset_main(int argc UNUSED_PARAM, char **argv) 211 OPT_p = 1 << 0,
212 OPT_a = 1 << 1,
213 OPT_c = (1 << 2) * ENABLE_FEATURE_TASKSET_CPULIST,
214};
215
216static int process_pid_str(const char *pid_str, unsigned opts, char *aff)
210{ 217{
211 ul *mask; 218 ul *mask;
212 unsigned mask_size_in_bytes; 219 unsigned mask_size_in_bytes;
213 pid_t pid = 0;
214 const char *current_new; 220 const char *current_new;
215 char *aff; 221 pid_t pid = xatoi_positive(pid_str);
216 unsigned opts;
217 enum {
218 OPT_p = 1 << 0,
219 OPT_c = (1 << 1) * ENABLE_FEATURE_TASKSET_CPULIST,
220 };
221
222 /* NB: we mimic util-linux's taskset: -p does not take
223 * an argument, i.e., "-pN" is NOT valid, only "-p N"!
224 * Indeed, util-linux-2.13-pre7 uses:
225 * getopt_long(argc, argv, "+pchV", ...), not "...p:..." */
226
227 opts = getopt32(argv, "^+" "p"IF_FEATURE_TASKSET_CPULIST("c")
228 "\0" "-1" /* at least 1 arg */);
229 argv += optind;
230
231 aff = *argv++;
232 if (opts & OPT_p) {
233 char *pid_str = aff;
234 if (*argv) { /* "-p <aff> <pid> ...rest.is.ignored..." */
235 pid_str = *argv; /* NB: *argv != NULL in this case */
236 }
237 /* else it was just "-p <pid>", and *argv == NULL */
238 pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1);
239 } else {
240 /* <aff> <cmd...> */
241 if (!*argv)
242 bb_show_usage();
243 }
244 222
245 mask_size_in_bytes = SZOF_UL; 223 mask_size_in_bytes = SZOF_UL;
246 current_new = "current"; 224 current_new = "current";
@@ -255,13 +233,12 @@ int taskset_main(int argc UNUSED_PARAM, char **argv)
255#endif 233#endif
256 printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n", 234 printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n",
257 pid, current_new, from_mask(mask, mask_size_in_bytes)); 235 pid, current_new, from_mask(mask, mask_size_in_bytes));
258 if (*argv == NULL) { 236 if (!aff) {
259 /* Either it was just "-p <pid>", 237 /* Either it was just "-p <pid>",
260 * or it was "-p <aff> <pid>" and we came here 238 * or it was "-p <aff> <pid>" and we came here
261 * for the second time (see goto below) */ 239 * for the second time (see goto below) */
262 return EXIT_SUCCESS; 240 return 0;
263 } 241 }
264 *argv = NULL;
265 current_new = "new"; 242 current_new = "new";
266 } 243 }
267 memset(mask, 0, mask_size_in_bytes); 244 memset(mask, 0, mask_size_in_bytes);
@@ -331,8 +308,61 @@ int taskset_main(int argc UNUSED_PARAM, char **argv)
331 bb_perror_msg_and_die("can't %cet pid %d's affinity", 's', pid); 308 bb_perror_msg_and_die("can't %cet pid %d's affinity", 's', pid);
332 //bb_error_msg("set mask[0]:%lx", mask[0]); 309 //bb_error_msg("set mask[0]:%lx", mask[0]);
333 310
334 if (!argv[0]) /* "-p <aff> <pid> [...ignored...]" */ 311 if ((opts & OPT_p) && aff) { /* "-p <aff> <pid> [...ignored...]" */
312 aff = NULL;
335 goto print_aff; /* print new affinity and exit */ 313 goto print_aff; /* print new affinity and exit */
314 }
315 return 0;
316}
317
318static int FAST_FUNC iter(const char *dn UNUSED_PARAM, struct dirent *ent, void *aff)
319{
320 if (isdigit(ent->d_name[0]))
321 return process_pid_str(ent->d_name, option_mask32, aff);
322 return 0;
323}
324
325int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
326int taskset_main(int argc UNUSED_PARAM, char **argv)
327{
328 const char *pid_str;
329 char *aff;
330 unsigned opts;
336 331
337 BB_EXECVP_or_die(argv); 332 /* NB: we mimic util-linux's taskset: -p does not take
333 * an argument, i.e., "-pN" is NOT valid, only "-p N"!
334 * Indeed, util-linux-2.13-pre7 uses:
335 * getopt_long(argc, argv, "+pchV", ...), not "...p:..." */
336
337 opts = getopt32(argv, "^+" "pa"IF_FEATURE_TASKSET_CPULIST("c")
338 "\0" "-1" /* at least 1 arg */);
339 argv += optind;
340
341 aff = *argv++;
342 if (!(opts & OPT_p)) {
343 /* <aff> <cmd...> */
344 if (!*argv)
345 bb_show_usage();
346 process_pid_str("0", opts, aff);
347 BB_EXECVP_or_die(argv);
348 }
349
350 pid_str = aff;
351 if (*argv) /* "-p <aff> <pid> ...rest.is.ignored..." */
352 pid_str = *argv;
353 else
354 aff = NULL;
355
356 if (opts & OPT_a) {
357 char *dn;
358 int r;
359
360 dn = xasprintf("/proc/%s/task", pid_str);
361 r = iterate_on_dir(dn, iter, aff);
362 IF_FEATURE_CLEAN_UP(free(dn);)
363 if (r == 0)
364 return r; /* EXIT_SUCCESS */
365 /* else: no /proc/PID/task, act as if no -a was given */
366 }
367 return process_pid_str(pid_str, opts, aff);
338} 368}