Index: sbin/dkctl/dkctl.c =================================================================== RCS file: /cvsroot/src/sbin/dkctl/dkctl.c,v retrieving revision 1.16 diff -u -r1.16 dkctl.c --- sbin/dkctl/dkctl.c 17 Jun 2006 02:16:19 -0000 1.16 +++ sbin/dkctl/dkctl.c 5 Dec 2007 03:28:38 -0000 @@ -78,13 +78,15 @@ int open_flags; }; +struct command *lookup(const char *); void usage(void); +void run(int, char *[]); +void showall(void); int fd; /* file descriptor for device */ const char *dvname; /* device name */ char dvname_store[MAXPATHLEN]; /* for opendisk(3) */ const char *cmdname; /* command user issued */ -const char *argnames; /* helpstring; expected arguments */ int yesno(const char *); @@ -100,6 +102,10 @@ void disk_listwedges(int, char *[]); void disk_strategy(int, char *[]); +void disk_foreachwedges(int, char *[], void (*)(struct dkwedge_list *)); +void disk_listwedges_cb(struct dkwedge_list *); +void disk_getwedgeinfo_cb(struct dkwedge_info *); + struct command commands[] = { { "getcache", "", @@ -160,37 +166,58 @@ int main(int argc, char *argv[]) { - int i; /* Must have at least: device command */ - if (argc < 3) + if (argc < 2) usage(); - /* Skip program name, get and skip device name and command. */ dvname = argv[1]; - cmdname = argv[2]; - argv += 3; - argc -= 3; + if (argc == 2) + showall(); + else { + /* Skip program name, get and skip device name and command. */ + cmdname = argv[2]; + argv += 3; + argc -= 3; + run(argc, argv); + } - /* Look up and call the command. */ - for (i = 0; commands[i].cmd_name != NULL; i++) - if (strcmp(cmdname, commands[i].cmd_name) == 0) - break; - if (commands[i].cmd_name == NULL) - errx(1, "unknown command: %s", cmdname); + exit(0); +} - argnames = commands[i].arg_names; +void +run(int argc, char *argv[]) +{ + struct command *command; + + command = lookup(cmdname); /* Open the device. */ - fd = opendisk(dvname, commands[i].open_flags, dvname_store, + fd = opendisk(dvname, command->open_flags, dvname_store, sizeof(dvname_store), 0); if (fd == -1) err(1, "%s", dvname); - dvname = dvname_store; - (*commands[i].cmd_func)(argc, argv); - exit(0); + (*command->cmd_func)(argc, argv); + + /* Close the device. */ + (void)close(fd); +} + +struct command * +lookup(const char *name) +{ + int i; + + /* Look up and call the command. */ + for (i = 0; commands[i].cmd_name != NULL; i++) + if (strcmp(name, commands[i].cmd_name) == 0) + break; + if (commands[i].cmd_name == NULL) + errx(1, "unknown command: %s", name); + + return &commands[i]; } void @@ -210,6 +237,26 @@ } void +showall(void) +{ + printf("strategy:\n"); + cmdname = "strategy"; + run(0, NULL); + + putchar('\n'); + + printf("cache:\n"); + cmdname = "getcache"; + run(0, NULL); + + putchar('\n'); + + printf("wedges:\n"); + cmdname = "listwedges"; + run(0, NULL); +} + +void disk_strategy(int argc, char *argv[]) { struct disk_strategy odks; @@ -563,19 +610,25 @@ if (ioctl(fd, DIOCGWEDGEINFO, &dkw) == -1) err(1, "%s: getwedgeinfo", dvname); - printf("%s at %s: %s\n", dkw.dkw_devname, dkw.dkw_parent, - dkw.dkw_wname); /* XXX Unicode */ + disk_getwedgeinfo_cb(&dkw); +} + +void +disk_getwedgeinfo_cb(struct dkwedge_info *dkw) +{ + + printf("%s at %s: %s\n", dkw->dkw_devname, dkw->dkw_parent, + dkw->dkw_wname); /* XXX Unicode */ printf("%s: %"PRIu64" blocks at %"PRId64", type: %s\n", - dkw.dkw_devname, dkw.dkw_size, dkw.dkw_offset, dkw.dkw_ptype); + dkw->dkw_devname, dkw->dkw_size, dkw->dkw_offset, dkw->dkw_ptype); } void -disk_listwedges(int argc, char *argv[]) +disk_foreachwedges(int argc, char *argv[], void (*func)(struct dkwedge_list *)) { struct dkwedge_info *dkw; struct dkwedge_list dkwl; size_t bufsize; - u_int i; if (argc != 0) usage(); @@ -586,15 +639,15 @@ for (;;) { if (ioctl(fd, DIOCLWEDGES, &dkwl) == -1) - err(1, "%s: listwedges", dvname); + err(1, "%s: %s", dvname, cmdname); if (dkwl.dkwl_nwedges == dkwl.dkwl_ncopied) break; bufsize = dkwl.dkwl_nwedges * sizeof(*dkw); if (dkwl.dkwl_bufsize < bufsize) { dkw = realloc(dkwl.dkwl_buf, bufsize); if (dkw == NULL) - errx(1, "%s: listwedges: unable to " - "allocate wedge info buffer", dvname); + errx(1, "%s: %s: unable to " + "allocate wedge info buffer", dvname, cmdname); dkwl.dkwl_buf = dkw; dkwl.dkwl_bufsize = bufsize; } @@ -605,13 +658,30 @@ return; } - printf("%s: %u wedge%s:\n", dvname, dkwl.dkwl_nwedges, - dkwl.dkwl_nwedges == 1 ? "" : "s"); - for (i = 0; i < dkwl.dkwl_nwedges; i++) { + (*func)(&dkwl); +} + +void +disk_listwedges(int argc, char *argv[]) +{ + + disk_foreachwedges(argc, argv, disk_listwedges_cb); +} + +void +disk_listwedges_cb(struct dkwedge_list *dkwl) +{ + struct dkwedge_info *dkw = dkwl->dkwl_buf; + u_int i; + + printf("%s: %u wedge%s:\n", dvname, dkwl->dkwl_nwedges, + dkwl->dkwl_nwedges == 1 ? "" : "s"); + for (i = 0; i < dkwl->dkwl_nwedges; i++) { printf("%s: %s, %"PRIu64" blocks at %"PRId64", type: %s\n", dkw[i].dkw_devname, dkw[i].dkw_wname, /* XXX Unicode */ dkw[i].dkw_size, dkw[i].dkw_offset, dkw[i].dkw_ptype); + disk_getwedgeinfo_cb(&dkw[i]); } }