1 /* fbdctl - FBD control tool - by D.C. van Moolenbroek */
11 #define PATH_DEV_FBD "/dev/fbd"
17 fprintf(stderr
, "usage:\n");
18 fprintf(stderr
, " %s list\n", getprogname());
19 fprintf(stderr
, " %s add [-a start[-end]] [-s skip] [-c count] [-rw] "
20 "<action> [params]\n", getprogname());
21 fprintf(stderr
, " %s del N\n", getprogname());
22 fprintf(stderr
, "\n");
23 fprintf(stderr
, "actions and params:\n");
24 fprintf(stderr
, " corrupt [zero|persist|random]\n");
25 fprintf(stderr
, " error [OK|EIO]\n");
26 fprintf(stderr
, " misdir <start>-<end> <align>\n");
27 fprintf(stderr
, " lost\n");
28 fprintf(stderr
, " torn <lead>\n");
29 fprintf(stderr
, "use %s -d <device> to specify a device other than "
30 "%s\n", getprogname(), PATH_DEV_FBD
);
36 print_rule(struct fbd_rule
* rule
)
38 printf("%-2d %04lX%08lX-%04lX%08lX %-4d %-5d %c%c ",
39 rule
->num
, ex64hi(rule
->start
), ex64lo(rule
->start
),
40 ex64hi(rule
->end
), ex64lo(rule
->end
), rule
->skip
,
41 rule
->count
, (rule
->flags
& FBD_FLAG_READ
) ? 'r' : ' ',
42 (rule
->flags
& FBD_FLAG_WRITE
) ? 'w' : ' ');
44 switch (rule
->action
) {
45 case FBD_ACTION_CORRUPT
:
46 printf("%-7s ", "corrupt");
47 switch (rule
->params
.corrupt
.type
) {
48 case FBD_CORRUPT_ZERO
: printf("zero"); break;
49 case FBD_CORRUPT_PERSIST
: printf("persist"); break;
50 case FBD_CORRUPT_RANDOM
: printf("random"); break;
51 default: printf("<unknown>");
55 case FBD_ACTION_ERROR
:
56 printf("%-7s ", "error");
58 switch (rule
->params
.error
.code
) {
67 printf("%d", rule
->params
.error
.code
);
72 case FBD_ACTION_MISDIR
:
73 printf("%-7s %04lX%08lX-%04lX%08lX %u",
74 "misdir", ex64hi(rule
->params
.misdir
.start
),
75 ex64lo(rule
->params
.misdir
.start
),
76 ex64hi(rule
->params
.misdir
.end
),
77 ex64lo(rule
->params
.misdir
.end
),
78 rule
->params
.misdir
.align
);
81 case FBD_ACTION_LOSTTORN
:
82 if (rule
->params
.losttorn
.lead
> 0)
83 printf("%-7s %u", "torn", rule
->params
.losttorn
.lead
);
85 printf("%-7s", "lost");
97 printf("N Start End Skip Count RW Action Params\n");
102 if (ioctl(fd
, FBDCGETRULE
, &rule
) < 0) {
115 scan_hex64(char * input
, u64_t
* val
)
123 if (len
< 1 || len
> 16) return 0;
126 memcpy(buf
, input
, len
- 8);
130 hi
= strtoul(buf
, NULL
, 16);
134 lo
= strtoul(input
, NULL
, 16);
136 *val
= make64(lo
, hi
);
142 scan_range(char * input
, u64_t
* start
, u64_t
* end
, int need_end
)
146 if ((p
= strchr(input
, '-')) != NULL
) {
149 if (!scan_hex64(p
, end
)) return 0;
151 else if (need_end
) return 0;
153 return scan_hex64(input
, start
);
157 do_add(int fd
, int argc
, char ** argv
, int off
)
159 struct fbd_rule rule
;
162 memset(&rule
, 0, sizeof(rule
));
164 while ((c
= getopt(argc
-off
, argv
+off
, "a:s:c:rw")) != EOF
) {
167 if (!scan_range(optarg
, &rule
.start
, &rule
.end
, 0))
171 rule
.skip
= atoi(optarg
);
174 rule
.count
= atoi(optarg
);
177 rule
.flags
|= FBD_FLAG_READ
;
180 rule
.flags
|= FBD_FLAG_WRITE
;
187 optind
+= off
; /* compensate for the shifted argc/argv */
189 if (optind
>= argc
) usage();
191 /* default to reads and writes */
192 if (!rule
.flags
) rule
.flags
= FBD_FLAG_READ
| FBD_FLAG_WRITE
;
194 if (!strcmp(argv
[optind
], "corrupt")) {
195 if (optind
+1 >= argc
) usage();
197 rule
.action
= FBD_ACTION_CORRUPT
;
199 if (!strcmp(argv
[optind
+1], "zero"))
200 rule
.params
.corrupt
.type
= FBD_CORRUPT_ZERO
;
201 else if (!strcmp(argv
[optind
+1], "persist"))
202 rule
.params
.corrupt
.type
= FBD_CORRUPT_PERSIST
;
203 else if (!strcmp(argv
[optind
+1], "random"))
204 rule
.params
.corrupt
.type
= FBD_CORRUPT_RANDOM
;
207 else if (!strcmp(argv
[optind
], "error")) {
208 if (optind
+1 >= argc
) usage();
210 rule
.action
= FBD_ACTION_ERROR
;
212 if (!strcmp(argv
[optind
+1], "OK"))
213 rule
.params
.error
.code
= 0;
214 else if (!strcmp(argv
[optind
+1], "EIO")) {
216 rule
.params
.error
.code
= -EIO
;
218 rule
.params
.error
.code
= EIO
;
222 else if (!strcmp(argv
[optind
], "misdir")) {
223 if (optind
+2 >= argc
) usage();
225 rule
.action
= FBD_ACTION_MISDIR
;
227 if (!scan_range(argv
[optind
+1], &rule
.params
.misdir
.start
,
228 &rule
.params
.misdir
.end
, 1))
231 rule
.params
.misdir
.align
= atoi(argv
[optind
+2]);
233 if ((int)rule
.params
.misdir
.align
<= 0)
236 else if (!strcmp(argv
[optind
], "lost")) {
237 rule
.action
= FBD_ACTION_LOSTTORN
;
239 rule
.params
.losttorn
.lead
= 0;
241 else if (!strcmp(argv
[optind
], "torn")) {
242 if (optind
+1 >= argc
) usage();
244 rule
.action
= FBD_ACTION_LOSTTORN
;
246 rule
.params
.losttorn
.lead
= atoi(argv
[optind
+1]);
248 if ((int)rule
.params
.losttorn
.lead
<= 0)
257 r
= ioctl(fd
, FBDCADDRULE
, &rule
);
265 printf("Added rule %d\n", r
);
271 do_del(int fd
, int argc
, char ** argv
, int off
)
278 num
= atoi(argv
[off
+ 1]);
280 if (ioctl(fd
, FBDCDELRULE
, &num
)) {
286 printf("Deleted rule %d\n", num
);
292 main(int argc
, char ** argv
)
295 const char *dev
= PATH_DEV_FBD
;
297 setprogname(argv
[0]);
302 if (!strcmp(argv
[1], "-d")) {
311 fd
= open(dev
, O_RDONLY
);
318 if (!strcmp(argv
[off
], "list"))
320 else if (!strcmp(argv
[off
], "add"))
321 r
= do_add(fd
, argc
, argv
, off
);
322 else if (!strcmp(argv
[off
], "del"))
323 r
= do_del(fd
, argc
, argv
, off
);