diff options
Diffstat (limited to 'sbin/gvinum/gvinum.c')
-rw-r--r-- | sbin/gvinum/gvinum.c | 252 |
1 files changed, 131 insertions, 121 deletions
diff --git a/sbin/gvinum/gvinum.c b/sbin/gvinum/gvinum.c index 5760d2b8bb28..4feaa811f2d8 100644 --- a/sbin/gvinum/gvinum.c +++ b/sbin/gvinum/gvinum.c @@ -58,35 +58,36 @@ #include "gvinum.h" -void gvinum_attach(int, char **); -void gvinum_concat(int, char **); -void gvinum_create(int, char **); -void gvinum_detach(int, char **); -void gvinum_grow(int, char **); -void gvinum_help(void); -void gvinum_list(int, char **); -void gvinum_move(int, char **); -void gvinum_mirror(int, char **); -void gvinum_parityop(int, char **, int); -void gvinum_printconfig(int, char **); -void gvinum_raid5(int, char **); -void gvinum_rename(int, char **); -void gvinum_resetconfig(void); -void gvinum_rm(int, char **); -void gvinum_saveconfig(void); -void gvinum_setstate(int, char **); -void gvinum_start(int, char **); -void gvinum_stop(int, char **); -void gvinum_stripe(int, char **); -void parseline(int, char **); -void printconfig(FILE *, char *); - -char *create_drive(char *); -void create_volume(int, char **, char *); -char *find_name(const char *, int, int); -char *find_pattern(char *, char *); -void copy_device(struct gv_drive *, const char *); -#define find_drive() find_name("gvinumdrive", GV_TYPE_DRIVE, GV_MAXDRIVENAME) +static void gvinum_attach(int, char * const *); +static void gvinum_concat(int, char * const *); +static void gvinum_create(int, char * const *); +static void gvinum_detach(int, char * const *); +static void gvinum_grow(int, char * const *); +static void gvinum_help(void); +static void gvinum_list(int, char * const *); +static void gvinum_move(int, char * const *); +static void gvinum_mirror(int, char * const *); +static void gvinum_parityop(int, char * const * , int); +static void gvinum_printconfig(int, char * const *); +static void gvinum_raid5(int, char * const *); +static void gvinum_rename(int, char * const *); +static void gvinum_resetconfig(int, char * const *); +static void gvinum_rm(int, char * const *); +static void gvinum_saveconfig(void); +static void gvinum_setstate(int, char * const *); +static void gvinum_start(int, char * const *); +static void gvinum_stop(int, char * const *); +static void gvinum_stripe(int, char * const *); +static void parseline(int, char * const *); +static void printconfig(FILE *, const char *); + +static char *create_drive(const char *); +static void create_volume(int, char * const * , const char *); +static char *find_name(const char *, int, int); +static const char *find_pattern(char *, const char *); +static void copy_device(struct gv_drive *, const char *); +#define find_drive() \ + find_name("gvinumdrive", GV_TYPE_DRIVE, GV_MAXDRIVENAME) int main(int argc, char **argv) @@ -95,8 +96,10 @@ main(int argc, char **argv) char buffer[BUFSIZ], *inputline, *token[GV_MAXARGS]; /* Load the module if necessary. */ - if (kldfind(GVINUMMOD) < 0 && kldload(GVINUMMOD) < 0) - err(1, GVINUMMOD ": Kernel module not available"); + if (modfind(GVINUMMOD) < 0) { + if (kldload(GVINUMKLD) < 0 && modfind(GVINUMMOD) < 0) + err(1, GVINUMKLD ": Kernel module not available"); + } /* Arguments given on the command line. */ if (argc > 1) { @@ -130,8 +133,8 @@ main(int argc, char **argv) } /* Attach a plex to a volume or a subdisk to a plex. */ -void -gvinum_attach(int argc, char **argv) +static void +gvinum_attach(int argc, char * const *argv) { struct gctl_req *req; const char *errstr; @@ -167,8 +170,8 @@ gvinum_attach(int argc, char **argv) gctl_free(req); } -void -gvinum_create(int argc, char **argv) +static void +gvinum_create(int argc, char * const *argv) { struct gctl_req *req; struct gv_drive *d; @@ -191,8 +194,8 @@ gvinum_create(int argc, char **argv) flags |= GV_FLAG_F; /* Else it must be a file. */ } else { - if ((tmp = fopen(argv[1], "r")) == NULL) { - warn("can't open '%s' for reading", argv[1]); + if ((tmp = fopen(argv[i], "r")) == NULL) { + warn("can't open '%s' for reading", argv[i]); return; } } @@ -400,8 +403,8 @@ gvinum_create(int argc, char **argv) } /* Create a concatenated volume. */ -void -gvinum_concat(int argc, char **argv) +static void +gvinum_concat(int argc, char * const *argv) { if (argc < 2) { @@ -411,10 +414,9 @@ gvinum_concat(int argc, char **argv) create_volume(argc, argv, "concat"); } - /* Create a drive quick and dirty. */ -char * -create_drive(char *device) +static char * +create_drive(const char *device) { struct gv_drive *d; struct gctl_req *req; @@ -477,12 +479,12 @@ create_drive(char *device) return (drivename); } -/* +/* * General routine for creating a volume. Mainly for use by concat, mirror, * raid5 and stripe commands. */ -void -create_volume(int argc, char **argv, char *verb) +static void +create_volume(int argc, char * const *argv, const char *verb) { struct gctl_req *req; const char *errstr; @@ -516,7 +518,7 @@ create_volume(int argc, char **argv, char *verb) snprintf(buf, sizeof(buf), "drive%d", drives++); /* First we create the drive. */ - drivename = create_drive(argv[i]); + drivename = create_drive(argv[i]); if (drivename == NULL) goto bad; /* Then we add it to the request. */ @@ -532,7 +534,7 @@ create_volume(int argc, char **argv, char *verb) /* Then we send a request to actually create the volumes. */ gctl_ro_param(req, "verb", -1, verb); - gctl_ro_param(req, "flags", sizeof(int), &flags); + gctl_ro_param(req, "flags", sizeof(int), &flags); gctl_ro_param(req, "drives", sizeof(int), &drives); gctl_ro_param(req, "name", -1, volname); errstr = gctl_issue(req); @@ -543,8 +545,8 @@ bad: } /* Parse a line of the config, return the word after <pattern>. */ -char * -find_pattern(char *line, char *pattern) +static const char * +find_pattern(char *line, const char *pattern) { char *ptr; @@ -561,12 +563,12 @@ find_pattern(char *line, char *pattern) } /* Find a free name for an object given a prefix. */ -char * +static char * find_name(const char *prefix, int type, int namelen) { struct gctl_req *req; - char comment[1], buf[GV_CFG_LEN - 1], *name, *sname, *ptr; - const char *errstr; + char comment[1], buf[GV_CFG_LEN - 1], *sname, *ptr; + const char *errstr, *name; int i, n, begin, len, conflict; char line[1024]; @@ -631,9 +633,10 @@ find_name(const char *prefix, int type, int namelen) return (NULL); } -void +static void copy_device(struct gv_drive *d, const char *device) { + if (strncmp(device, "/dev/", 5) == 0) strlcpy(d->device, (device + 5), sizeof(d->device)); else @@ -641,8 +644,8 @@ copy_device(struct gv_drive *d, const char *device) } /* Detach a plex or subdisk from its parent. */ -void -gvinum_detach(int argc, char **argv) +static void +gvinum_detach(int argc, char * const *argv) { const char *errstr; struct gctl_req *req; @@ -652,7 +655,7 @@ gvinum_detach(int argc, char **argv) optreset = 1; optind = 1; while ((i = getopt(argc, argv, "f")) != -1) { - switch(i) { + switch (i) { case 'f': flags |= GV_FLAG_F; break; @@ -680,9 +683,10 @@ gvinum_detach(int argc, char **argv) gctl_free(req); } -void +static void gvinum_help(void) { + printf("COMMANDS\n" "checkparity [-f] plex\n" " Check the parity blocks of a RAID-5 plex.\n" @@ -721,7 +725,7 @@ gvinum_help(void) " Change the name of the specified object.\n" "rebuildparity plex [-f]\n" " Rebuild the parity blocks of a RAID-5 plex.\n" - "resetconfig\n" + "resetconfig [-f]\n" " Reset the complete gvinum configuration\n" "rm [-r] [-f] volume | plex | subdisk | drive\n" " Remove an object.\n" @@ -737,12 +741,10 @@ gvinum_help(void) "stripe [-fv] [-n name] drives\n" " Create a striped volume from the specified drives.\n" ); - - return; } -void -gvinum_setstate(int argc, char **argv) +static void +gvinum_setstate(int argc, char * const *argv) { struct gctl_req *req; int flags, i; @@ -796,8 +798,8 @@ gvinum_setstate(int argc, char **argv) gctl_free(req); } -void -gvinum_list(int argc, char **argv) +static void +gvinum_list(int argc, char * const *argv) { struct gctl_req *req; int flags, i, j; @@ -858,12 +860,11 @@ gvinum_list(int argc, char **argv) printf("%s", config); gctl_free(req); - return; } /* Create a mirrored volume. */ -void -gvinum_mirror(int argc, char **argv) +static void +gvinum_mirror(int argc, char * const *argv) { if (argc < 2) { @@ -874,8 +875,8 @@ gvinum_mirror(int argc, char **argv) } /* Note that move is currently of form '[-r] target object [...]' */ -void -gvinum_move(int argc, char **argv) +static void +gvinum_move(int argc, char * const *argv) { struct gctl_req *req; const char *errstr; @@ -925,17 +926,17 @@ gvinum_move(int argc, char **argv) if (errstr != NULL) warnx("can't move object(s): %s", errstr); gctl_free(req); - return; } -void -gvinum_printconfig(int argc, char **argv) +static void +gvinum_printconfig(int argc, char * const *argv) { + printconfig(stdout, ""); } -void -gvinum_parityop(int argc, char **argv, int rebuild) +static void +gvinum_parityop(int argc, char * const *argv, int rebuild) { struct gctl_req *req; int flags, i; @@ -959,7 +960,6 @@ gvinum_parityop(int argc, char **argv, int rebuild) case 'v': flags |= GV_FLAG_V; break; - case '?': default: warnx("invalid flag '%c'", i); return; @@ -987,8 +987,8 @@ gvinum_parityop(int argc, char **argv, int rebuild) } /* Create a RAID-5 volume. */ -void -gvinum_raid5(int argc, char **argv) +static void +gvinum_raid5(int argc, char * const *argv) { if (argc < 2) { @@ -998,9 +998,8 @@ gvinum_raid5(int argc, char **argv) create_volume(argc, argv, "raid5"); } - -void -gvinum_rename(int argc, char **argv) +static void +gvinum_rename(int argc, char * const *argv) { struct gctl_req *req; const char *errstr; @@ -1016,7 +1015,6 @@ gvinum_rename(int argc, char **argv) case 'r': flags |= GV_FLAG_R; break; - case '?': default: return; } @@ -1049,11 +1047,10 @@ gvinum_rename(int argc, char **argv) if (errstr != NULL) warnx("can't rename object: %s", errstr); gctl_free(req); - return; } -void -gvinum_rm(int argc, char **argv) +static void +gvinum_rm(int argc, char * const *argv) { struct gctl_req *req; int flags, i, j; @@ -1071,7 +1068,6 @@ gvinum_rm(int argc, char **argv) case 'r': flags |= GV_FLAG_R; break; - case '?': default: return; } @@ -1099,27 +1095,41 @@ gvinum_rm(int argc, char **argv) gctl_free(req); } -void -gvinum_resetconfig(void) +static void +gvinum_resetconfig(int argc, char * const *argv) { struct gctl_req *req; const char *errstr; char reply[32]; + int flags, i; - if (!isatty(STDIN_FILENO)) { - warn("Please enter this command from a tty device\n"); - return; + flags = 0; + while ((i = getopt(argc, argv, "f")) != -1) { + switch (i) { + case 'f': + flags |= GV_FLAG_F; + break; + default: + warn("invalid flag: %c", i); + return; + } } - printf(" WARNING! This command will completely wipe out your gvinum" - "configuration.\n" - " All data will be lost. If you really want to do this," - " enter the text\n\n" - " NO FUTURE\n" - " Enter text -> "); - fgets(reply, sizeof(reply), stdin); - if (strcmp(reply, "NO FUTURE\n")) { - printf("\n No change\n"); - return; + if ((flags & GV_FLAG_F) == 0) { + if (!isatty(STDIN_FILENO)) { + warn("Please enter this command from a tty device\n"); + return; + } + printf(" WARNING! This command will completely wipe out" + " your gvinum configuration.\n" + " All data will be lost. If you really want to do this," + " enter the text\n\n" + " NO FUTURE\n" + " Enter text -> "); + fgets(reply, sizeof(reply), stdin); + if (strcmp(reply, "NO FUTURE\n")) { + printf("\n No change\n"); + return; + } } req = gctl_get_handle(); gctl_ro_param(req, "class", -1, "VINUM"); @@ -1134,7 +1144,7 @@ gvinum_resetconfig(void) printf("gvinum configuration obliterated\n"); } -void +static void gvinum_saveconfig(void) { struct gctl_req *req; @@ -1149,8 +1159,8 @@ gvinum_saveconfig(void) gctl_free(req); } -void -gvinum_start(int argc, char **argv) +static void +gvinum_start(int argc, char * const *argv) { struct gctl_req *req; int i, initsize, j; @@ -1170,7 +1180,6 @@ gvinum_start(int argc, char **argv) case 'S': initsize = atoi(optarg); break; - case '?': default: return; } @@ -1202,14 +1211,15 @@ gvinum_start(int argc, char **argv) gctl_free(req); } -void -gvinum_stop(int argc, char **argv) +static void +gvinum_stop(int argc, char * const *argv) { int err, fileid; - fileid = kldfind(GVINUMMOD); + fileid = kldfind(GVINUMKLD); if (fileid == -1) { - warn("cannot find " GVINUMMOD); + if (modfind(GVINUMMOD) < 0) + warn("cannot find " GVINUMKLD); return; } @@ -1219,7 +1229,7 @@ gvinum_stop(int argc, char **argv) * event thread will be free for the g_wither_geom() call from * gv_unload(). It's silly, but it works. */ - printf("unloading " GVINUMMOD " kernel module... "); + printf("unloading " GVINUMKLD " kernel module... "); fflush(stdout); if ((err = kldunload(fileid)) != 0 && (errno == EAGAIN)) { sleep(1); @@ -1227,7 +1237,7 @@ gvinum_stop(int argc, char **argv) } if (err != 0) { printf(" failed!\n"); - warn("cannot unload " GVINUMMOD); + warn("cannot unload " GVINUMKLD); return; } @@ -1236,8 +1246,8 @@ gvinum_stop(int argc, char **argv) } /* Create a striped volume. */ -void -gvinum_stripe(int argc, char **argv) +static void +gvinum_stripe(int argc, char * const *argv) { if (argc < 2) { @@ -1248,8 +1258,8 @@ gvinum_stripe(int argc, char **argv) } /* Grow a subdisk by adding disk backed by provider. */ -void -gvinum_grow(int argc, char **argv) +static void +gvinum_grow(int argc, char * const *argv) { struct gctl_req *req; char *drive, *sdname; @@ -1259,6 +1269,7 @@ gvinum_grow(int argc, char **argv) const char *errstr; int drives, volumes, plexes, subdisks, flags; + flags = 0; drives = volumes = plexes = subdisks = 0; if (argc < 3) { warnx("usage:\tgrow plex drive\n"); @@ -1326,9 +1337,10 @@ gvinum_grow(int argc, char **argv) gctl_free(req); } -void -parseline(int argc, char **argv) +static void +parseline(int argc, char * const *argv) { + if (argc <= 0) return; @@ -1369,7 +1381,7 @@ parseline(int argc, char **argv) else if (!strcmp(argv[0], "rename")) gvinum_rename(argc, argv); else if (!strcmp(argv[0], "resetconfig")) - gvinum_resetconfig(); + gvinum_resetconfig(argc, argv); else if (!strcmp(argv[0], "rm")) gvinum_rm(argc, argv); else if (!strcmp(argv[0], "saveconfig")) @@ -1388,8 +1400,6 @@ parseline(int argc, char **argv) gvinum_parityop(argc, argv, 1); else printf("unknown command '%s'\n", argv[0]); - - return; } /* @@ -1397,8 +1407,8 @@ parseline(int argc, char **argv) * gvinum_create when called without an argument, in order to give the user * something to edit. */ -void -printconfig(FILE *of, char *comment) +static void +printconfig(FILE *of, const char *comment) { struct gctl_req *req; struct utsname uname_s; |