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