1 /* fbdctl - FBD control tool - by D.C. van Moolenbroek */
5 #include <minix/ioctl.h>
7 #include <sys/ioc_fbd.h>
12 static int usage(char *name
)
15 printf(" %s list\n", name
);
16 printf(" %s add [-a start[-end]] [-s skip] [-c count] [-rw] "
17 "<action> [params]\n", name
);
18 printf(" %s del N\n", name
);
20 printf("actions and params:\n");
21 printf(" corrupt [zero|persist|random]\n");
22 printf(" error [OK|EIO]\n");
23 printf(" misdir <start>-<end> <align>\n");
25 printf(" torn <lead>\n");
26 printf("use %s -d <device> to specify a device other than /dev/fbd\n",
32 static void print_rule(struct fbd_rule
*rule
)
34 printf("%-2d %04lX%08lX-%04lX%08lX %-4d %-5d %c%c ",
35 rule
->num
, ex64hi(rule
->start
), ex64lo(rule
->start
),
36 ex64hi(rule
->end
), ex64lo(rule
->end
), rule
->skip
,
37 rule
->count
, (rule
->flags
& FBD_FLAG_READ
) ? 'r' : ' ',
38 (rule
->flags
& FBD_FLAG_WRITE
) ? 'w' : ' ');
40 switch (rule
->action
) {
41 case FBD_ACTION_CORRUPT
:
42 printf("%-7s ", "corrupt");
43 switch (rule
->params
.corrupt
.type
) {
44 case FBD_CORRUPT_ZERO
: printf("zero"); break;
45 case FBD_CORRUPT_PERSIST
: printf("persist"); break;
46 case FBD_CORRUPT_RANDOM
: printf("random"); break;
47 default: printf("<unknown>");
51 case FBD_ACTION_ERROR
:
52 printf("%-7s ", "error");
54 switch (rule
->params
.error
.code
) {
63 printf("%d", rule
->params
.error
.code
);
68 case FBD_ACTION_MISDIR
:
69 printf("%-7s %04lX%08lX-%04lX%08lX %u",
70 "misdir", ex64hi(rule
->params
.misdir
.start
),
71 ex64lo(rule
->params
.misdir
.start
),
72 ex64hi(rule
->params
.misdir
.end
),
73 ex64lo(rule
->params
.misdir
.end
),
74 rule
->params
.misdir
.align
);
77 case FBD_ACTION_LOSTTORN
:
78 if (rule
->params
.losttorn
.lead
> 0)
79 printf("%-7s %u", "torn",
80 rule
->params
.losttorn
.lead
);
82 printf("%-7s", "lost");
88 static int do_list(int fd
)
93 printf("N Start End Skip Count RW Action Params\n");
98 if (ioctl(fd
, FBDCGETRULE
, &rule
) < 0) {
110 static int scan_hex64(char *input
, u64_t
*val
)
118 if (len
< 1 || len
> 16) return 0;
121 memcpy(buf
, input
, len
- 8);
125 hi
= strtoul(buf
, NULL
, 16);
129 lo
= strtoul(input
, NULL
, 16);
131 *val
= make64(lo
, hi
);
136 static int scan_range(char *input
, u64_t
*start
, u64_t
*end
, int need_end
)
140 if ((p
= strchr(input
, '-')) != NULL
) {
143 if (!scan_hex64(p
, end
)) return 0;
145 else if (need_end
) return 0;
147 return scan_hex64(input
, start
);
150 static int do_add(int fd
, int argc
, char **argv
, int off
)
152 struct fbd_rule rule
;
155 memset(&rule
, 0, sizeof(rule
));
157 while ((c
= getopt(argc
-off
, argv
+off
, "a:s:c:rw")) != EOF
) {
160 if (!scan_range(optarg
, &rule
.start
, &rule
.end
, 0))
161 return usage(argv
[0]);
164 rule
.skip
= atoi(optarg
);
167 rule
.count
= atoi(optarg
);
170 rule
.flags
|= FBD_FLAG_READ
;
173 rule
.flags
|= FBD_FLAG_WRITE
;
176 return usage(argv
[0]);
180 optind
+= off
; /* compensate for the shifted argc/argv */
182 if (optind
>= argc
) return usage(argv
[0]);
184 /* default to reads and writes */
185 if (!rule
.flags
) rule
.flags
= FBD_FLAG_READ
| FBD_FLAG_WRITE
;
187 if (!strcmp(argv
[optind
], "corrupt")) {
188 if (optind
+1 >= argc
) return usage(argv
[0]);
190 rule
.action
= FBD_ACTION_CORRUPT
;
192 if (!strcmp(argv
[optind
+1], "zero"))
193 rule
.params
.corrupt
.type
= FBD_CORRUPT_ZERO
;
194 else if (!strcmp(argv
[optind
+1], "persist"))
195 rule
.params
.corrupt
.type
= FBD_CORRUPT_PERSIST
;
196 else if (!strcmp(argv
[optind
+1], "random"))
197 rule
.params
.corrupt
.type
= FBD_CORRUPT_RANDOM
;
198 else return usage(argv
[0]);
200 else if (!strcmp(argv
[optind
], "error")) {
201 if (optind
+1 >= argc
) return usage(argv
[0]);
203 rule
.action
= FBD_ACTION_ERROR
;
205 if (!strcmp(argv
[optind
+1], "OK"))
206 rule
.params
.error
.code
= 0;
207 else if (!strcmp(argv
[optind
+1], "EIO")) {
209 rule
.params
.error
.code
= -EIO
;
211 rule
.params
.error
.code
= EIO
;
213 else return usage(argv
[0]);
215 else if (!strcmp(argv
[optind
], "misdir")) {
216 if (optind
+2 >= argc
) return usage(argv
[0]);
218 rule
.action
= FBD_ACTION_MISDIR
;
220 if (!scan_range(argv
[optind
+1], &rule
.params
.misdir
.start
,
221 &rule
.params
.misdir
.end
, 1))
222 return usage(argv
[0]);
224 rule
.params
.misdir
.align
= atoi(argv
[optind
+2]);
226 if ((int) rule
.params
.misdir
.align
<= 0)
227 return usage(argv
[0]);
229 else if (!strcmp(argv
[optind
], "lost")) {
230 rule
.action
= FBD_ACTION_LOSTTORN
;
232 rule
.params
.losttorn
.lead
= 0;
234 else if (!strcmp(argv
[optind
], "torn")) {
235 if (optind
+1 >= argc
) return usage(argv
[0]);
237 rule
.action
= FBD_ACTION_LOSTTORN
;
239 rule
.params
.losttorn
.lead
= atoi(argv
[optind
+1]);
241 if ((int) rule
.params
.losttorn
.lead
<= 0)
242 return usage(argv
[0]);
244 else return usage(argv
[0]);
250 r
= ioctl(fd
, FBDCADDRULE
, &rule
);
258 printf("Added rule %d\n", r
);
263 static int do_del(int fd
, int argc
, char **argv
, int off
)
268 return usage(argv
[0]);
270 num
= atoi(argv
[off
+ 1]);
272 if (ioctl(fd
, FBDCDELRULE
, &num
)) {
278 printf("Deleted rule %d\n", num
);
283 int main(int argc
, char **argv
)
286 char *dev
= "/dev/fbd";
289 return usage(argv
[0]);
291 if (!strcmp(argv
[1], "-d")) {
293 return usage(argv
[0]);
300 fd
= open(dev
, O_RDONLY
);
307 else if (!strcmp(argv
[off
], "list"))
309 else if (!strcmp(argv
[off
], "add"))
310 r
= do_add(fd
, argc
, argv
, off
);
311 else if (!strcmp(argv
[off
], "del"))
312 r
= do_del(fd
, argc
, argv
, off
);