2 * blockdev.c --- Do various simple block device ioctls from the command line
11 #include <sys/ioctl.h>
37 { "--setro", "BLKROSET", BLKROSET, ARGINTP, 1, NULL, N_("set read-only") },
38 { "--setrw", "BLKROSET", BLKROSET, ARGINTP, 0, NULL, N_("set read-write") },
39 { "--getro", "BLKROGET", BLKROGET, ARGINTG, -1, NULL, N_("get read-only") },
40 { "--getss", "BLKSSZGET", BLKSSZGET, ARGINTG, -1, NULL, N_("get sectorsize") },
41 { "--getbsz", "BLKBSZGET", BLKBSZGET, ARGINTG, -1, NULL, N_("get blocksize") },
42 { "--setbsz", "BLKBSZSET", BLKBSZSET, ARGINTAP, 0, "BLOCKSIZE", N_("set blocksize") },
43 { "--getsize", "BLKGETSIZE", BLKGETSIZE, ARGLU, -1, NULL, N_("get 32-bit sector count") },
44 { "--getsize64", "BLKGETSIZE64", BLKGETSIZE64, ARGLLU, -1, NULL, N_("get size in bytes") },
45 { "--setra", "BLKRASET", BLKRASET, ARGINTA, 0, "READAHEAD", N_("set readahead") },
46 { "--getra", "BLKRAGET", BLKRAGET, ARGLINTG, -1, NULL, N_("get readahead") },
47 { "--setfra", "BLKFRASET", BLKFRASET, ARGINTA, 0, "FSREADAHEAD", N_("set filesystem readahead") },
48 { "--getfra", "BLKFRAGET", BLKFRAGET, ARGLINTG, -1, NULL, N_("get filesystem readahead") },
49 { "--flushbufs", "BLKFLSBUF", BLKFLSBUF, ARGNONE, 0, NULL, N_("flush buffers") },
50 { "--rereadpt", "BLKRRPART", BLKRRPART, ARGNONE, 0, NULL,
51 N_("reread partition table") },
54 #define SIZE(a) (sizeof(a)/sizeof((a)[0]))
60 fprintf(stderr, _("Usage:\n"));
61 fprintf(stderr, " %s -V\n", progname);
62 fprintf(stderr, _(" %s --report [devices]\n"), progname);
63 fprintf(stderr, _(" %s [-v|-q] commands devices\n"), progname);
66 fprintf(stderr, _("Available commands:\n"));
67 fprintf(stderr, "\t%-30s %s\n", "--getsz",
68 _("get size in 512-byte sectors"));
69 for (i = 0; i < SIZE(bdcms); i++) {
71 fprintf(stderr, "\t%s %-*s %s\n", bdcms[i].name,
72 (int) (29 - strlen(bdcms[i].name)),
73 bdcms[i].argname, _(bdcms[i].help));
75 fprintf(stderr, "\t%-30s %s\n", bdcms[i].name,
86 for (j = 0; j < SIZE(bdcms); j++)
87 if (!strcmp(s, bdcms[j].name))
92 void do_commands(int fd, char **argv, int d);
93 void report_header(void);
94 void report_device(char *device, int quiet);
95 void report_all_devices(void);
98 main(int argc, char **argv) {
102 /* egcs-2.91.66 is buggy and says:
103 blockdev.c:93: warning: `d' might be used uninitialized */
107 if ((p = strrchr(progname, '/')) != NULL)
110 setlocale(LC_ALL, "");
111 bindtextdomain(PACKAGE, LOCALEDIR);
117 /* -V not together with commands */
118 if (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")) {
119 printf("%s (%s)\n", progname, PACKAGE_STRING);
123 /* --report not together with other commands */
124 if (!strcmp(argv[1], "--report")) {
127 for (d = 2; d < argc; d++)
128 report_device(argv[d], 0);
130 report_all_devices();
135 /* do each of the commands on each of the devices */
136 /* devices start after last command */
137 for (d = 1; d < argc; d++) {
138 j = find_cmd(argv[d]);
140 if (bdcms[j].argtype == ARGINTA ||
141 bdcms[j].argtype == ARGINTAP)
145 if (!strcmp(argv[d], "--getsz"))
147 if (!strcmp(argv[d], "--")) {
151 if (argv[d][0] != '-')
158 for (k = d; k < argc; k++) {
159 fd = open(argv[k], O_RDONLY, 0);
164 do_commands(fd, argv, d);
171 do_commands(int fd, char **argv, int d) {
177 unsigned long long llu;
180 for (i = 1; i < d; i++) {
181 if (!strcmp(argv[i], "-v")) {
185 if (!strcmp(argv[i], "-q")) {
190 if (!strcmp(argv[i], "--getsz")) {
191 res = blkdev_get_sectors(fd, &llu);
193 printf("%lld\n", llu);
199 j = find_cmd(argv[i]);
201 fprintf(stderr, _("%s: Unknown command: %s\n"),
206 switch(bdcms[j].argtype) {
209 res = ioctl(fd, bdcms[j].ioc, 0);
213 fprintf(stderr, _("%s requires an argument\n"),
217 iarg = atoi(argv[++i]);
218 res = ioctl(fd, bdcms[j].ioc, iarg);
222 fprintf(stderr, _("%s requires an argument\n"),
226 iarg = atoi(argv[++i]);
227 res = ioctl(fd, bdcms[j].ioc, &iarg);
231 iarg = bdcms[j].argval;
232 res = ioctl(fd, bdcms[j].ioc, &iarg);
235 larg = bdcms[j].argval;
236 res = ioctl(fd, bdcms[j].ioc, &larg);
239 llarg = bdcms[j].argval;
240 res = ioctl(fd, bdcms[j].ioc, &llarg);
243 lu = bdcms[j].argval;
244 res = ioctl(fd, bdcms[j].ioc, &lu);
247 llu = bdcms[j].argval;
248 res = ioctl(fd, bdcms[j].ioc, &llu);
253 perror(bdcms[j].iocname);
255 printf(_("%s failed.\n"), _(bdcms[j].help));
258 switch(bdcms[j].argtype) {
261 printf("%s: %d\n", _(bdcms[j].help), iarg);
263 printf("%d\n", iarg);
267 printf("%s: %ld\n", _(bdcms[j].help), larg);
269 printf("%ld\n", larg);
273 printf("%s: %lld\n", _(bdcms[j].help), llarg);
275 printf("%lld\n", llarg);
279 printf("%s: %lu\n", _(bdcms[j].help), lu);
285 printf("%s: %llu\n", _(bdcms[j].help), llu);
287 printf("%llu\n", llu);
292 printf(_("%s succeeded.\n"), _(bdcms[j].help));
298 #define PROC_PARTITIONS "/proc/partitions"
301 report_all_devices(void) {
308 procpt = fopen(PROC_PARTITIONS, "r");
310 fprintf(stderr, _("%s: cannot open %s\n"),
311 progname, PROC_PARTITIONS);
315 while (fgets(line, sizeof(line), procpt)) {
316 if (sscanf (line, " %d %d %d %200[^\n ]",
317 &ma, &mi, &sz, ptname) != 4)
320 sprintf(device, "/dev/%s", ptname);
321 report_device(device, 1);
328 report_device(char *device, int quiet) {
332 unsigned long long bytes;
333 struct hd_geometry g;
335 fd = open(device, O_RDONLY | O_NONBLOCK);
338 fprintf(stderr, _("%s: cannot open %s\n"),
345 if (ioctl (fd, BLKROGET, &ro) == 0 &&
346 ioctl (fd, BLKRAGET, &ra) == 0 &&
347 ioctl (fd, BLKSSZGET, &ssz) == 0 &&
348 ioctl (fd, BLKBSZGET, &bsz) == 0 &&
349 ioctl (fd, HDIO_GETGEO, &g) == 0 &&
350 blkdev_get_size (fd, &bytes) == 0) {
351 printf("%s %5ld %5d %5d %10ld %15lld %s\n",
352 ro ? "ro" : "rw", ra, ssz, bsz, g.start, bytes, device);
355 fprintf(stderr, _("%s: ioctl error on %s\n"),
364 printf(_("RO RA SSZ BSZ StartSec Size Device\n"));