]> git.ipfire.org Git - thirdparty/util-linux.git/blame - disk-utils/blockdev.c
blkid: add pretty output, document -L incompatibility with e2fsprogs
[thirdparty/util-linux.git] / disk-utils / blockdev.c
CommitLineData
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>
eb63b9b8 13
eb63b9b8 14#include "nls.h"
bc8b6383 15#include "blkdev.h"
612721db 16
eb63b9b8
KZ
17const char *progname;
18
19struct bdc {
20 char *name;
21 char *iocname;
22 long ioc;
23 int argtype;
24#define ARGNONE 0
25#define ARGINTA 1
e8f26419
KZ
26#define ARGINTAP 2
27#define ARGINTP 3
28#define ARGINTG 4
29#define ARGLINTG 5
c129767e 30#define ARGLLINTG 6
1dea05a8
KZ
31#define ARGLU 7
32#define ARGLLU 8
eb63b9b8
KZ
33 long argval;
34 char *argname;
35 char *help;
36} bdcms[] = {
eb63b9b8
KZ
37 { "--setro", "BLKROSET", BLKROSET, ARGINTP, 1, NULL, N_("set read-only") },
38 { "--setrw", "BLKROSET", BLKROSET, ARGINTP, 0, NULL, N_("set read-write") },
eb63b9b8 39 { "--getro", "BLKROGET", BLKROGET, ARGINTG, -1, NULL, N_("get read-only") },
eb63b9b8 40 { "--getss", "BLKSSZGET", BLKSSZGET, ARGINTG, -1, NULL, N_("get sectorsize") },
e8f26419 41 { "--getbsz", "BLKBSZGET", BLKBSZGET, ARGINTG, -1, NULL, N_("get blocksize") },
e8f26419 42 { "--setbsz", "BLKBSZSET", BLKBSZSET, ARGINTAP, 0, "BLOCKSIZE", N_("set blocksize") },
1dea05a8 43 { "--getsize", "BLKGETSIZE", BLKGETSIZE, ARGLU, -1, NULL, N_("get 32-bit sector count") },
1dea05a8 44 { "--getsize64", "BLKGETSIZE64", BLKGETSIZE64, ARGLLU, -1, NULL, N_("get size in bytes") },
eb63b9b8 45 { "--setra", "BLKRASET", BLKRASET, ARGINTA, 0, "READAHEAD", N_("set readahead") },
eb63b9b8 46 { "--getra", "BLKRAGET", BLKRAGET, ARGLINTG, -1, NULL, N_("get readahead") },
c2a1e788 47 { "--setfra", "BLKFRASET", BLKFRASET, ARGINTA, 0, "FSREADAHEAD", N_("set filesystem readahead") },
c2a1e788 48 { "--getfra", "BLKFRAGET", BLKFRAGET, ARGLINTG, -1, NULL, N_("get filesystem readahead") },
eb63b9b8 49 { "--flushbufs", "BLKFLSBUF", BLKFLSBUF, ARGNONE, 0, NULL, N_("flush buffers") },
eb63b9b8
KZ
50 { "--rereadpt", "BLKRRPART", BLKRRPART, ARGNONE, 0, NULL,
51 N_("reread partition table") },
eb63b9b8
KZ
52};
53
54#define SIZE(a) (sizeof(a)/sizeof((a)[0]))
55
56static void
57usage(void) {
58 int i;
a424171c 59 fputc('\n', stderr);
612721db
KZ
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);
a424171c
KZ
64 fputc('\n', stderr);
65
eb63b9b8 66 fprintf(stderr, _("Available commands:\n"));
a424171c 67 fprintf(stderr, "\t%-30s %s\n", "--getsz",
65b27d36 68 _("get size in 512-byte sectors"));
eb63b9b8 69 for (i = 0; i < SIZE(bdcms); i++) {
eb63b9b8 70 if (bdcms[i].argname)
a424171c
KZ
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));
74 else
75 fprintf(stderr, "\t%-30s %s\n", bdcms[i].name,
76 _(bdcms[i].help));
eb63b9b8 77 }
a424171c 78 fputc('\n', stderr);
eb63b9b8
KZ
79 exit(1);
80}
81
22853e4a 82static int
eb63b9b8
KZ
83find_cmd(char *s) {
84 int j;
85
86 for (j = 0; j < SIZE(bdcms); j++)
87 if (!strcmp(s, bdcms[j].name))
88 return j;
89 return -1;
90}
91
92void do_commands(int fd, char **argv, int d);
612721db
KZ
93void report_header(void);
94void report_device(char *device, int quiet);
95void report_all_devices(void);
eb63b9b8
KZ
96
97int
98main(int argc, char **argv) {
99 int fd, d, j, k;
100 char *p;
101
102 /* egcs-2.91.66 is buggy and says:
103 blockdev.c:93: warning: `d' might be used uninitialized */
104 d = 0;
105
106 progname = argv[0];
107 if ((p = strrchr(progname, '/')) != NULL)
108 progname = p+1;
109
110 setlocale(LC_ALL, "");
111 bindtextdomain(PACKAGE, LOCALEDIR);
112 textdomain(PACKAGE);
113
114 if (argc < 2)
115 usage();
116
117 /* -V not together with commands */
118 if (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")) {
baf39af1 119 printf("%s (%s)\n", progname, PACKAGE_STRING);
eb63b9b8
KZ
120 exit(0);
121 }
122
612721db
KZ
123 /* --report not together with other commands */
124 if (!strcmp(argv[1], "--report")) {
125 report_header();
126 if (argc > 2) {
127 for (d = 2; d < argc; d++)
128 report_device(argv[d], 0);
129 } else {
130 report_all_devices();
131 }
132 exit(0);
133 }
134
eb63b9b8
KZ
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]);
139 if (j >= 0) {
e8f26419
KZ
140 if (bdcms[j].argtype == ARGINTA ||
141 bdcms[j].argtype == ARGINTAP)
eb63b9b8
KZ
142 d++;
143 continue;
144 }
c129767e
KZ
145 if (!strcmp(argv[d], "--getsz"))
146 continue;
eb63b9b8
KZ
147 if (!strcmp(argv[d], "--")) {
148 d++;
149 break;
150 }
151 if (argv[d][0] != '-')
152 break;
153 }
154
155 if (d >= argc)
156 usage();
157
158 for (k = d; k < argc; k++) {
159 fd = open(argv[k], O_RDONLY, 0);
160 if (fd < 0) {
161 perror(argv[k]);
162 exit(1);
163 }
164 do_commands(fd, argv, d);
e8f26419 165 close(fd);
eb63b9b8
KZ
166 }
167 return 0;
168}
169
170void
171do_commands(int fd, char **argv, int d) {
172 int res, i, j;
173 int iarg;
174 long larg;
c129767e 175 long long llarg;
1dea05a8
KZ
176 unsigned long lu;
177 unsigned long long llu;
eb63b9b8
KZ
178 int verbose = 0;
179
180 for (i = 1; i < d; i++) {
181 if (!strcmp(argv[i], "-v")) {
182 verbose = 1;
183 continue;
184 }
185 if (!strcmp(argv[i], "-q")) {
186 verbose = 0;
187 continue;
188 }
189
c129767e 190 if (!strcmp(argv[i], "--getsz")) {
bc8b6383 191 res = blkdev_get_sectors(fd, &llu);
c129767e 192 if (res == 0)
bc8b6383 193 printf("%lld\n", llu);
c129767e
KZ
194 else
195 exit(1);
196 continue;
197 }
198
eb63b9b8
KZ
199 j = find_cmd(argv[i]);
200 if (j == -1) {
612721db
KZ
201 fprintf(stderr, _("%s: Unknown command: %s\n"),
202 progname, argv[i]);
eb63b9b8
KZ
203 usage();
204 }
205
206 switch(bdcms[j].argtype) {
207 default:
208 case ARGNONE:
209 res = ioctl(fd, bdcms[j].ioc, 0);
210 break;
211 case ARGINTA:
212 if (i == d-1) {
213 fprintf(stderr, _("%s requires an argument\n"),
214 bdcms[j].name);
215 usage();
216 }
217 iarg = atoi(argv[++i]);
218 res = ioctl(fd, bdcms[j].ioc, iarg);
219 break;
e8f26419
KZ
220 case ARGINTAP:
221 if (i == d-1) {
222 fprintf(stderr, _("%s requires an argument\n"),
223 bdcms[j].name);
224 usage();
225 }
226 iarg = atoi(argv[++i]);
227 res = ioctl(fd, bdcms[j].ioc, &iarg);
228 break;
eb63b9b8
KZ
229 case ARGINTP:
230 case ARGINTG:
231 iarg = bdcms[j].argval;
232 res = ioctl(fd, bdcms[j].ioc, &iarg);
233 break;
234 case ARGLINTG:
235 larg = bdcms[j].argval;
236 res = ioctl(fd, bdcms[j].ioc, &larg);
237 break;
c129767e
KZ
238 case ARGLLINTG:
239 llarg = bdcms[j].argval;
240 res = ioctl(fd, bdcms[j].ioc, &llarg);
241 break;
1dea05a8
KZ
242 case ARGLU:
243 lu = bdcms[j].argval;
244 res = ioctl(fd, bdcms[j].ioc, &lu);
245 break;
246 case ARGLLU:
247 llu = bdcms[j].argval;
248 res = ioctl(fd, bdcms[j].ioc, &llu);
249 break;
250
eb63b9b8
KZ
251 }
252 if (res == -1) {
253 perror(bdcms[j].iocname);
254 if (verbose)
65b27d36 255 printf(_("%s failed.\n"), _(bdcms[j].help));
eb63b9b8
KZ
256 exit(1);
257 }
258 switch(bdcms[j].argtype) {
259 case ARGINTG:
260 if (verbose)
261 printf("%s: %d\n", _(bdcms[j].help), iarg);
262 else
263 printf("%d\n", iarg);
264 break;
265 case ARGLINTG:
266 if (verbose)
267 printf("%s: %ld\n", _(bdcms[j].help), larg);
268 else
269 printf("%ld\n", larg);
270 break;
c129767e
KZ
271 case ARGLLINTG:
272 if (verbose)
273 printf("%s: %lld\n", _(bdcms[j].help), llarg);
274 else
275 printf("%lld\n", llarg);
276 break;
1dea05a8
KZ
277 case ARGLU:
278 if (verbose)
279 printf("%s: %lu\n", _(bdcms[j].help), lu);
280 else
281 printf("%lu\n", lu);
282 break;
283 case ARGLLU:
284 if (verbose)
285 printf("%s: %llu\n", _(bdcms[j].help), llu);
286 else
287 printf("%llu\n", llu);
288 break;
289
eb63b9b8
KZ
290 default:
291 if (verbose)
612721db 292 printf(_("%s succeeded.\n"), _(bdcms[j].help));
eb63b9b8
KZ
293 break;
294 }
295 }
296}
612721db
KZ
297
298#define PROC_PARTITIONS "/proc/partitions"
299
300void
301report_all_devices(void) {
302 FILE *procpt;
303 char line[200];
304 char ptname[200];
305 char device[210];
306 int ma, mi, sz;
307
308 procpt = fopen(PROC_PARTITIONS, "r");
309 if (!procpt) {
310 fprintf(stderr, _("%s: cannot open %s\n"),
311 progname, PROC_PARTITIONS);
312 exit(1);
313 }
314
315 while (fgets(line, sizeof(line), procpt)) {
18c3e243 316 if (sscanf (line, " %d %d %d %200[^\n ]",
612721db
KZ
317 &ma, &mi, &sz, ptname) != 4)
318 continue;
319
320 sprintf(device, "/dev/%s", ptname);
321 report_device(device, 1);
322 }
122db55d 323
324 fclose(procpt);
612721db
KZ
325}
326
327void
328report_device(char *device, int quiet) {
329 int fd;
330 int ro, ssz, bsz;
bc8b6383
KZ
331 long ra;
332 unsigned long long bytes;
612721db
KZ
333 struct hd_geometry g;
334
335 fd = open(device, O_RDONLY | O_NONBLOCK);
336 if (fd < 0) {
337 if (!quiet)
338 fprintf(stderr, _("%s: cannot open %s\n"),
339 progname, device);
340 return;
341 }
342
343 ro = ssz = bsz = 0;
bc8b6383 344 g.start = ra = 0;
612721db
KZ
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 &&
c129767e 349 ioctl (fd, HDIO_GETGEO, &g) == 0 &&
bc8b6383
KZ
350 blkdev_get_size (fd, &bytes) == 0) {
351 printf("%s %5ld %5d %5d %10ld %15lld %s\n",
c129767e 352 ro ? "ro" : "rw", ra, ssz, bsz, g.start, bytes, device);
612721db
KZ
353 } else {
354 if (!quiet)
355 fprintf(stderr, _("%s: ioctl error on %s\n"),
356 progname, device);
357 }
122db55d 358
359 close(fd);
612721db
KZ
360}
361
362void
363report_header() {
bc8b6383 364 printf(_("RO RA SSZ BSZ StartSec Size Device\n"));
612721db 365}