]>
Commit | Line | Data |
---|---|---|
eb63b9b8 KZ |
1 | /* |
2 | * blockdev.c --- Do various simple block device ioctls from the command line | |
3 | * aeb, 991028 | |
4 | */ | |
5 | ||
6 | #include <stdio.h> | |
7 | #include <fcntl.h> | |
eb63b9b8 KZ |
8 | #include <stdlib.h> |
9 | #include <string.h> | |
10 | #include <unistd.h> | |
11 | #include <sys/ioctl.h> | |
3281d426 | 12 | #include <errno.h> |
4832fd9f TW |
13 | #ifdef HAVE_LINUX_BLKZONED_H |
14 | #include <linux/blkzoned.h> | |
15 | #endif | |
eb63b9b8 | 16 | |
515422fd | 17 | #include "c.h" |
eb63b9b8 | 18 | #include "nls.h" |
bc8b6383 | 19 | #include "blkdev.h" |
14c76d8b | 20 | #include "pathnames.h" |
45ca68ec | 21 | #include "closestream.h" |
40775268 | 22 | #include "strutils.h" |
569d1dac | 23 | #include "sysfs.h" |
612721db | 24 | |
eb63b9b8 | 25 | struct bdc { |
c3f62be7 KZ |
26 | long ioc; /* ioctl code */ |
27 | const char *iocname; /* ioctl name (e.g. BLKROSET) */ | |
28 | long argval; /* default argument */ | |
29 | ||
30 | const char *name; /* --setfoo */ | |
31 | const char *argname; /* argument name or NULL */ | |
32 | ||
33 | const char *help; | |
34 | ||
35 | int argtype; | |
36 | int flags; | |
37 | }; | |
38 | ||
39 | /* command flags */ | |
40 | enum { | |
41 | FL_NOPTR = (1 << 1), /* does not assume pointer (ARG_INT only)*/ | |
42 | FL_NORESULT = (1 << 2) /* does not return any data */ | |
43 | }; | |
44 | ||
45 | /* ioctl argument types */ | |
46 | enum { | |
47 | ARG_NONE, | |
726fa24e | 48 | ARG_USHRT, |
c3f62be7 | 49 | ARG_INT, |
726fa24e | 50 | ARG_UINT, |
c3f62be7 KZ |
51 | ARG_LONG, |
52 | ARG_ULONG, | |
53 | ARG_LLONG, | |
54 | ARG_ULLONG | |
55 | }; | |
56 | ||
57 | #define IOCTL_ENTRY( io ) .ioc = io, .iocname = # io | |
58 | ||
00239f33 | 59 | static const struct bdc bdcms[] = |
c3f62be7 KZ |
60 | { |
61 | { | |
62 | IOCTL_ENTRY(BLKROSET), | |
63 | .name = "--setro", | |
64 | .argtype = ARG_INT, | |
65 | .argval = 1, | |
66 | .flags = FL_NORESULT, | |
67 | .help = N_("set read-only") | |
68 | },{ | |
69 | IOCTL_ENTRY(BLKROSET), | |
70 | .name = "--setrw", | |
71 | .argtype = ARG_INT, | |
72 | .argval = 0, | |
73 | .flags = FL_NORESULT, | |
74 | .help = N_("set read-write") | |
75 | },{ | |
76 | IOCTL_ENTRY(BLKROGET), | |
77 | .name = "--getro", | |
78 | .argtype = ARG_INT, | |
79 | .argval = -1, | |
80 | .help = N_("get read-only") | |
1519ab5f KZ |
81 | },{ |
82 | IOCTL_ENTRY(BLKDISCARDZEROES), | |
83 | .name = "--getdiscardzeroes", | |
84 | .argtype = ARG_UINT, | |
85 | .argval = -1, | |
86 | .help = N_("get discard zeroes support status") | |
c3f62be7 KZ |
87 | },{ |
88 | IOCTL_ENTRY(BLKSSZGET), | |
89 | .name = "--getss", | |
90 | .argtype = ARG_INT, | |
91 | .argval = -1, | |
d965d63f KZ |
92 | .help = N_("get logical block (sector) size") |
93 | },{ | |
94 | IOCTL_ENTRY(BLKPBSZGET), | |
95 | .name = "--getpbsz", | |
96 | .argtype = ARG_UINT, | |
97 | .argval = -1, | |
98 | .help = N_("get physical block (sector) size") | |
99 | },{ | |
100 | IOCTL_ENTRY(BLKIOMIN), | |
101 | .name = "--getiomin", | |
102 | .argtype = ARG_UINT, | |
103 | .argval = -1, | |
104 | .help = N_("get minimum I/O size") | |
105 | },{ | |
106 | IOCTL_ENTRY(BLKIOOPT), | |
107 | .name = "--getioopt", | |
108 | .argtype = ARG_UINT, | |
109 | .argval = -1, | |
110 | .help = N_("get optimal I/O size") | |
111 | },{ | |
112 | IOCTL_ENTRY(BLKALIGNOFF), | |
113 | .name = "--getalignoff", | |
114 | .argtype = ARG_INT, | |
ed98508a | 115 | .argval = -1, |
455fdf4a | 116 | .help = N_("get alignment offset in bytes") |
d965d63f KZ |
117 | },{ |
118 | IOCTL_ENTRY(BLKSECTGET), | |
119 | .name = "--getmaxsect", | |
120 | .argtype = ARG_USHRT, | |
121 | .argval = -1, | |
122 | .help = N_("get max sectors per request") | |
c3f62be7 KZ |
123 | },{ |
124 | IOCTL_ENTRY(BLKBSZGET), | |
125 | .name = "--getbsz", | |
126 | .argtype = ARG_INT, | |
127 | .argval = -1, | |
128 | .help = N_("get blocksize") | |
39d2e706 KZ |
129 | },{ |
130 | IOCTL_ENTRY(BLKBSZSET), | |
131 | .name = "--setbsz", | |
132 | .argname = "<bytes>", | |
133 | .argtype = ARG_INT, | |
134 | .flags = FL_NORESULT, | |
7ab32ae6 | 135 | .help = N_("set blocksize on file descriptor opening the block device") |
c3f62be7 KZ |
136 | },{ |
137 | IOCTL_ENTRY(BLKGETSIZE), | |
138 | .name = "--getsize", | |
139 | .argtype = ARG_ULONG, | |
140 | .argval = -1, | |
455fdf4a | 141 | .help = N_("get 32-bit sector count (deprecated, use --getsz)") |
c3f62be7 KZ |
142 | },{ |
143 | IOCTL_ENTRY(BLKGETSIZE64), | |
144 | .name = "--getsize64", | |
145 | .argtype = ARG_ULLONG, | |
146 | .argval = -1, | |
147 | .help = N_("get size in bytes") | |
148 | },{ | |
149 | IOCTL_ENTRY(BLKRASET), | |
150 | .name = "--setra", | |
455fdf4a | 151 | .argname = "<sectors>", |
c3f62be7 KZ |
152 | .argtype = ARG_INT, |
153 | .flags = FL_NOPTR | FL_NORESULT, | |
154 | .help = N_("set readahead") | |
155 | },{ | |
156 | IOCTL_ENTRY(BLKRAGET), | |
157 | .name = "--getra", | |
158 | .argtype = ARG_LONG, | |
159 | .argval = -1, | |
160 | .help = N_("get readahead") | |
161 | },{ | |
162 | IOCTL_ENTRY(BLKFRASET), | |
163 | .name = "--setfra", | |
455fdf4a | 164 | .argname = "<sectors>", |
c3f62be7 KZ |
165 | .argtype = ARG_INT, |
166 | .flags = FL_NOPTR | FL_NORESULT, | |
167 | .help = N_("set filesystem readahead") | |
168 | },{ | |
169 | IOCTL_ENTRY(BLKFRAGET), | |
170 | .name = "--getfra", | |
171 | .argtype = ARG_LONG, | |
172 | .argval = -1, | |
173 | .help = N_("get filesystem readahead") | |
c10adc20 TW |
174 | },{ |
175 | IOCTL_ENTRY(BLKGETDISKSEQ), | |
176 | .name = "--getdiskseq", | |
177 | .argtype = ARG_ULLONG, | |
178 | .argval = -1, | |
179 | .help = N_("get disk sequence number") | |
c3f62be7 | 180 | },{ |
ae20b7fb | 181 | #ifdef BLKGETZONESZ |
4832fd9f TW |
182 | IOCTL_ENTRY(BLKGETZONESZ), |
183 | .name = "--getzonesz", | |
184 | .argtype = ARG_UINT, | |
185 | .argval = -1, | |
186 | .help = N_("get zone size") | |
187 | },{ | |
188 | #endif | |
c3f62be7 KZ |
189 | IOCTL_ENTRY(BLKFLSBUF), |
190 | .name = "--flushbufs", | |
191 | .help = N_("flush buffers") | |
192 | },{ | |
193 | IOCTL_ENTRY(BLKRRPART), | |
194 | .name = "--rereadpt", | |
195 | .help = N_("reread partition table") | |
196 | } | |
eb63b9b8 KZ |
197 | }; |
198 | ||
9325dbfd | 199 | static void __attribute__((__noreturn__)) usage(void) |
bded204c | 200 | { |
75737ad6 | 201 | size_t i; |
9325dbfd | 202 | |
a861538c RM |
203 | fputs(USAGE_HEADER, stdout); |
204 | printf(_( | |
205 | " %1$s [-v|-q] commands devices\n" | |
206 | " %1$s --report [devices]\n" | |
207 | " %1$s -h|-V\n" | |
208 | ), program_invocation_short_name); | |
a424171c | 209 | |
a861538c RM |
210 | fputs(USAGE_SEPARATOR, stdout); |
211 | puts( _("Call block device ioctls from the command line.")); | |
212 | ||
213 | fputs(USAGE_OPTIONS, stdout); | |
214 | puts( _(" -q quiet mode")); | |
215 | puts( _(" -v verbose mode")); | |
216 | puts( _(" --report print report for specified (or all) devices")); | |
217 | fputs(USAGE_SEPARATOR, stdout); | |
f45f3ec3 | 218 | printf(USAGE_HELP_OPTIONS(16)); |
a861538c RM |
219 | |
220 | fputs(USAGE_SEPARATOR, stdout); | |
221 | puts( _("Available commands:")); | |
222 | printf(_(" %-25s get size in 512-byte sectors\n"), "--getsz"); | |
515422fd | 223 | for (i = 0; i < ARRAY_SIZE(bdcms); i++) { |
eb63b9b8 | 224 | if (bdcms[i].argname) |
a861538c | 225 | printf(" %s %-*s %s\n", bdcms[i].name, |
bded204c SK |
226 | (int)(24 - strlen(bdcms[i].name)), |
227 | bdcms[i].argname, _(bdcms[i].help)); | |
a424171c | 228 | else |
a861538c | 229 | printf(" %-25s %s\n", bdcms[i].name, |
bded204c | 230 | _(bdcms[i].help)); |
eb63b9b8 | 231 | } |
9325dbfd | 232 | |
43c960c8 | 233 | printf(USAGE_MAN_TAIL("blockdev(8)")); |
9325dbfd | 234 | exit(EXIT_SUCCESS); |
eb63b9b8 KZ |
235 | } |
236 | ||
baaa4479 SK |
237 | static int find_cmd(char *s) |
238 | { | |
75737ad6 | 239 | size_t j; |
eb63b9b8 | 240 | |
515422fd | 241 | for (j = 0; j < ARRAY_SIZE(bdcms); j++) |
eb63b9b8 KZ |
242 | if (!strcmp(s, bdcms[j].name)) |
243 | return j; | |
244 | return -1; | |
245 | } | |
246 | ||
f61a097b WG |
247 | static void do_commands(int fd, char **argv, int d); |
248 | static void report_header(void); | |
249 | static void report_device(char *device, int quiet); | |
250 | static void report_all_devices(void); | |
eb63b9b8 | 251 | |
baaa4479 SK |
252 | int main(int argc, char **argv) |
253 | { | |
eb63b9b8 | 254 | int fd, d, j, k; |
eb63b9b8 | 255 | |
eb63b9b8 KZ |
256 | setlocale(LC_ALL, ""); |
257 | bindtextdomain(PACKAGE, LOCALEDIR); | |
258 | textdomain(PACKAGE); | |
2c308875 | 259 | close_stdout_atexit(); |
eb63b9b8 | 260 | |
9325dbfd RM |
261 | if (argc < 2) { |
262 | warnx(_("not enough arguments")); | |
263 | errtryhelp(EXIT_FAILURE); | |
264 | } | |
eb63b9b8 KZ |
265 | |
266 | /* -V not together with commands */ | |
2c308875 KZ |
267 | if (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")) |
268 | print_version(EXIT_SUCCESS); | |
bded204c | 269 | if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) |
9325dbfd | 270 | usage(); |
eb63b9b8 | 271 | |
612721db KZ |
272 | /* --report not together with other commands */ |
273 | if (!strcmp(argv[1], "--report")) { | |
274 | report_header(); | |
275 | if (argc > 2) { | |
276 | for (d = 2; d < argc; d++) | |
277 | report_device(argv[d], 0); | |
278 | } else { | |
279 | report_all_devices(); | |
280 | } | |
6b515d0b | 281 | return EXIT_SUCCESS; |
612721db KZ |
282 | } |
283 | ||
eb63b9b8 KZ |
284 | /* do each of the commands on each of the devices */ |
285 | /* devices start after last command */ | |
286 | for (d = 1; d < argc; d++) { | |
287 | j = find_cmd(argv[d]); | |
288 | if (j >= 0) { | |
c3f62be7 | 289 | if (bdcms[j].argname) |
eb63b9b8 KZ |
290 | d++; |
291 | continue; | |
292 | } | |
c129767e KZ |
293 | if (!strcmp(argv[d], "--getsz")) |
294 | continue; | |
eb63b9b8 KZ |
295 | if (!strcmp(argv[d], "--")) { |
296 | d++; | |
297 | break; | |
298 | } | |
299 | if (argv[d][0] != '-') | |
300 | break; | |
301 | } | |
302 | ||
9325dbfd RM |
303 | if (d >= argc) { |
304 | warnx(_("no device specified")); | |
305 | errtryhelp(EXIT_FAILURE); | |
306 | } | |
eb63b9b8 KZ |
307 | |
308 | for (k = d; k < argc; k++) { | |
309 | fd = open(argv[k], O_RDONLY, 0); | |
6b515d0b SK |
310 | if (fd < 0) |
311 | err(EXIT_FAILURE, _("cannot open %s"), argv[k]); | |
eb63b9b8 | 312 | do_commands(fd, argv, d); |
e8f26419 | 313 | close(fd); |
eb63b9b8 | 314 | } |
6b515d0b | 315 | return EXIT_SUCCESS; |
eb63b9b8 KZ |
316 | } |
317 | ||
f61a097b | 318 | static void do_commands(int fd, char **argv, int d) |
baaa4479 | 319 | { |
eb63b9b8 | 320 | int res, i, j; |
15705de0 KZ |
321 | int iarg = 0; |
322 | unsigned int uarg = 0; | |
323 | unsigned short huarg = 0; | |
324 | long larg = 0; | |
325 | long long llarg = 0; | |
326 | unsigned long lu = 0; | |
327 | unsigned long long llu = 0; | |
eb63b9b8 KZ |
328 | int verbose = 0; |
329 | ||
330 | for (i = 1; i < d; i++) { | |
331 | if (!strcmp(argv[i], "-v")) { | |
332 | verbose = 1; | |
333 | continue; | |
baaa4479 | 334 | } |
eb63b9b8 KZ |
335 | if (!strcmp(argv[i], "-q")) { |
336 | verbose = 0; | |
337 | continue; | |
338 | } | |
339 | ||
c129767e | 340 | if (!strcmp(argv[i], "--getsz")) { |
bc8b6383 | 341 | res = blkdev_get_sectors(fd, &llu); |
c129767e | 342 | if (res == 0) |
bc8b6383 | 343 | printf("%lld\n", llu); |
c129767e | 344 | else |
baaa4479 SK |
345 | errx(EXIT_FAILURE, |
346 | _("could not get device size")); | |
c129767e KZ |
347 | continue; |
348 | } | |
349 | ||
eb63b9b8 KZ |
350 | j = find_cmd(argv[i]); |
351 | if (j == -1) { | |
cc4d8d72 | 352 | warnx(_("Unknown command: %s"), argv[i]); |
9325dbfd | 353 | errtryhelp(EXIT_FAILURE); |
eb63b9b8 KZ |
354 | } |
355 | ||
baaa4479 | 356 | switch (bdcms[j].argtype) { |
eb63b9b8 | 357 | default: |
c3f62be7 | 358 | case ARG_NONE: |
eb63b9b8 KZ |
359 | res = ioctl(fd, bdcms[j].ioc, 0); |
360 | break; | |
726fa24e KZ |
361 | case ARG_USHRT: |
362 | huarg = bdcms[j].argval; | |
363 | res = ioctl(fd, bdcms[j].ioc, &huarg); | |
364 | break; | |
c3f62be7 KZ |
365 | case ARG_INT: |
366 | if (bdcms[j].argname) { | |
baaa4479 | 367 | if (i == d - 1) { |
cc4d8d72 | 368 | warnx(_("%s requires an argument"), |
baaa4479 | 369 | bdcms[j].name); |
9325dbfd | 370 | errtryhelp(EXIT_FAILURE); |
c3f62be7 | 371 | } |
40775268 | 372 | iarg = strtos32_or_err(argv[++i], _("failed to parse command argument")); |
c3f62be7 KZ |
373 | } else |
374 | iarg = bdcms[j].argval; | |
375 | ||
376 | res = bdcms[j].flags & FL_NOPTR ? | |
baaa4479 SK |
377 | ioctl(fd, bdcms[j].ioc, iarg) : |
378 | ioctl(fd, bdcms[j].ioc, &iarg); | |
eb63b9b8 | 379 | break; |
726fa24e KZ |
380 | case ARG_UINT: |
381 | uarg = bdcms[j].argval; | |
382 | res = ioctl(fd, bdcms[j].ioc, &uarg); | |
383 | break; | |
c3f62be7 | 384 | case ARG_LONG: |
eb63b9b8 KZ |
385 | larg = bdcms[j].argval; |
386 | res = ioctl(fd, bdcms[j].ioc, &larg); | |
387 | break; | |
c3f62be7 | 388 | case ARG_LLONG: |
c129767e KZ |
389 | llarg = bdcms[j].argval; |
390 | res = ioctl(fd, bdcms[j].ioc, &llarg); | |
391 | break; | |
c3f62be7 | 392 | case ARG_ULONG: |
1dea05a8 KZ |
393 | lu = bdcms[j].argval; |
394 | res = ioctl(fd, bdcms[j].ioc, &lu); | |
395 | break; | |
c3f62be7 | 396 | case ARG_ULLONG: |
1dea05a8 KZ |
397 | llu = bdcms[j].argval; |
398 | res = ioctl(fd, bdcms[j].ioc, &llu); | |
399 | break; | |
eb63b9b8 | 400 | } |
c3f62be7 | 401 | |
eb63b9b8 | 402 | if (res == -1) { |
338a6bc5 | 403 | warn(_("ioctl error on %s"), bdcms[j].iocname); |
eb63b9b8 | 404 | if (verbose) |
65b27d36 | 405 | printf(_("%s failed.\n"), _(bdcms[j].help)); |
6b515d0b | 406 | exit(EXIT_FAILURE); |
eb63b9b8 | 407 | } |
c3f62be7 KZ |
408 | |
409 | if (bdcms[j].argtype == ARG_NONE || | |
410 | (bdcms[j].flags & FL_NORESULT)) { | |
eb63b9b8 | 411 | if (verbose) |
c3f62be7 KZ |
412 | printf(_("%s succeeded.\n"), _(bdcms[j].help)); |
413 | continue; | |
414 | } | |
415 | ||
416 | if (verbose) | |
417 | printf("%s: ", _(bdcms[j].help)); | |
418 | ||
baaa4479 | 419 | switch (bdcms[j].argtype) { |
726fa24e KZ |
420 | case ARG_USHRT: |
421 | printf("%hu\n", huarg); | |
422 | break; | |
c3f62be7 KZ |
423 | case ARG_INT: |
424 | printf("%d\n", iarg); | |
eb63b9b8 | 425 | break; |
726fa24e KZ |
426 | case ARG_UINT: |
427 | printf("%u\n", uarg); | |
428 | break; | |
c3f62be7 KZ |
429 | case ARG_LONG: |
430 | printf("%ld\n", larg); | |
c129767e | 431 | break; |
c3f62be7 KZ |
432 | case ARG_LLONG: |
433 | printf("%lld\n", llarg); | |
1dea05a8 | 434 | break; |
c3f62be7 KZ |
435 | case ARG_ULONG: |
436 | printf("%lu\n", lu); | |
1dea05a8 | 437 | break; |
c3f62be7 KZ |
438 | case ARG_ULLONG: |
439 | printf("%llu\n", llu); | |
eb63b9b8 KZ |
440 | break; |
441 | } | |
442 | } | |
443 | } | |
612721db | 444 | |
f61a097b | 445 | static void report_all_devices(void) |
baaa4479 | 446 | { |
612721db KZ |
447 | FILE *procpt; |
448 | char line[200]; | |
657d9adb | 449 | char ptname[200 + 1]; |
612721db KZ |
450 | char device[210]; |
451 | int ma, mi, sz; | |
452 | ||
14c76d8b | 453 | procpt = fopen(_PATH_PROC_PARTITIONS, "r"); |
cc4d8d72 | 454 | if (!procpt) |
14c76d8b | 455 | err(EXIT_FAILURE, _("cannot open %s"), _PATH_PROC_PARTITIONS); |
612721db KZ |
456 | |
457 | while (fgets(line, sizeof(line), procpt)) { | |
baaa4479 SK |
458 | if (sscanf(line, " %d %d %d %200[^\n ]", |
459 | &ma, &mi, &sz, ptname) != 4) | |
612721db KZ |
460 | continue; |
461 | ||
26266436 | 462 | snprintf(device, sizeof(device), "/dev/%s", ptname); |
612721db KZ |
463 | report_device(device, 1); |
464 | } | |
122db55d | 465 | |
466 | fclose(procpt); | |
612721db KZ |
467 | } |
468 | ||
f61a097b | 469 | static void report_device(char *device, int quiet) |
baaa4479 | 470 | { |
612721db KZ |
471 | int fd; |
472 | int ro, ssz, bsz; | |
bc8b6383 KZ |
473 | long ra; |
474 | unsigned long long bytes; | |
569d1dac | 475 | uint64_t start = 0; |
d73a7184 | 476 | char start_str[16] = { "\0" }; |
569d1dac | 477 | struct stat st; |
612721db KZ |
478 | |
479 | fd = open(device, O_RDONLY | O_NONBLOCK); | |
480 | if (fd < 0) { | |
481 | if (!quiet) | |
6b515d0b | 482 | warn(_("cannot open %s"), device); |
612721db KZ |
483 | return; |
484 | } | |
485 | ||
486 | ro = ssz = bsz = 0; | |
569d1dac | 487 | ra = 0; |
345ddd28 KZ |
488 | if (fstat(fd, &st) == 0) { |
489 | dev_t disk; | |
490 | struct path_cxt *pc; | |
491 | ||
492 | pc = ul_new_sysfs_path(st.st_rdev, NULL, NULL); | |
493 | if (pc && | |
494 | sysfs_blkdev_get_wholedisk(pc, NULL, 0, &disk) == 0 && | |
495 | disk != st.st_rdev) { | |
496 | ||
497 | if (ul_path_read_u64(pc, &start, "start") != 0) | |
d73a7184 | 498 | /* TRANSLATORS: Start sector not available. Max. 15 letters. */ |
26266436 | 499 | snprintf(start_str, sizeof(start_str), "%15s", _("N/A")); |
345ddd28 KZ |
500 | } |
501 | ul_unref_path(pc); | |
569d1dac | 502 | } |
9147d2ad | 503 | if (!*start_str) |
26266436 | 504 | snprintf(start_str, sizeof(start_str), "%15ju", start); |
9147d2ad | 505 | |
baaa4479 SK |
506 | if (ioctl(fd, BLKROGET, &ro) == 0 && |
507 | ioctl(fd, BLKRAGET, &ra) == 0 && | |
508 | ioctl(fd, BLKSSZGET, &ssz) == 0 && | |
509 | ioctl(fd, BLKBSZGET, &bsz) == 0 && | |
baaa4479 | 510 | blkdev_get_size(fd, &bytes) == 0) { |
c4a543ff | 511 | printf("%s %5ld %5d %5d %s %15lld %s\n", |
9147d2ad | 512 | ro ? "ro" : "rw", ra, ssz, bsz, start_str, bytes, device); |
612721db KZ |
513 | } else { |
514 | if (!quiet) | |
cc4d8d72 | 515 | warnx(_("ioctl error on %s"), device); |
612721db | 516 | } |
122db55d | 517 | |
518 | close(fd); | |
612721db KZ |
519 | } |
520 | ||
16bd8025 | 521 | static void report_header(void) |
baaa4479 | 522 | { |
d73a7184 | 523 | printf(_("RO RA SSZ BSZ StartSec Size Device\n")); |
612721db | 524 | } |