In several cases, two different long options map to the same short
option. So e.g. you could give '--brief' and it would be interpreted
as '--bitmap'. That isn't really good.
So for every shared short option, define an option number and return
that for the long option instead. Then always check for both the
short and long options.
Also give some bugs like " mode == 'G'" which should be '== GROW'.
Signed-off-by: NeilBrown <neilb@suse.de>
"-ABCDEFGIQhVXWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sa:rfRSow1tye:";
struct option long_options[] = {
"-ABCDEFGIQhVXWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sa:rfRSow1tye:";
struct option long_options[] = {
- {"manage", 0, 0, '@'},
- {"misc", 0, 0, '#'},
+ {"manage", 0, 0, ManageOpt},
+ {"misc", 0, 0, MiscOpt},
{"assemble", 0, 0, 'A'},
{"build", 0, 0, 'B'},
{"create", 0, 0, 'C'},
{"assemble", 0, 0, 'A'},
{"build", 0, 0, 'B'},
{"create", 0, 0, 'C'},
/* after those will normally come the name of the md device */
{"help", 0, 0, 'h'},
/* after those will normally come the name of the md device */
{"help", 0, 0, 'h'},
- {"help-options",0,0,'h'},
+ {"help-options",0,0, HelpOptions},
{"version", 0, 0, 'V'},
{"verbose", 0, 0, 'v'},
{"quiet", 0, 0, 'q'},
/* For create or build: */
{"version", 0, 0, 'V'},
{"verbose", 0, 0, 'v'},
{"quiet", 0, 0, 'q'},
/* For create or build: */
- {"chunk", 1, 0, 'c'},
- {"rounding", 1, 0, 'c'}, /* for linear, chunk is really a rounding number */
+ {"chunk", 1, 0, ChunkSize},
+ {"rounding", 1, 0, ChunkSize}, /* for linear, chunk is really a
+ * rounding number */
{"level", 1, 0, 'l'}, /* 0,1,4,5,6,linear */
{"level", 1, 0, 'l'}, /* 0,1,4,5,6,linear */
- {"parity", 1, 0, 'p'}, /* {left,right}-{a,}symmetric */
- {"layout", 1, 0, 'p'},
+ {"parity", 1, 0, Layout}, /* {left,right}-{a,}symmetric */
+ {"layout", 1, 0, Layout},
{"raid-disks",1, 0, 'n'},
{"raid-devices",1, 0, 'n'},
{"spare-disks",1,0, 'x'},
{"spare-devices",1,0, 'x'},
{"size", 1, 0, 'z'},
{"raid-disks",1, 0, 'n'},
{"raid-devices",1, 0, 'n'},
{"spare-disks",1,0, 'x'},
{"spare-devices",1,0, 'x'},
{"size", 1, 0, 'z'},
- {"auto", 1, 0, 'a'}, /* also for --assemble */
+ {"auto", 1, 0, Auto}, /* also for --assemble */
{"assume-clean",0,0, AssumeClean },
{"metadata", 1, 0, 'e'}, /* superblock format */
{"assume-clean",0,0, AssumeClean },
{"metadata", 1, 0, 'e'}, /* superblock format */
+ {"bitmap", 1, 0, Bitmap},
{"bitmap-chunk", 1, 0, BitmapChunk},
{"write-behind", 2, 0, WriteBehind},
{"bitmap-chunk", 1, 0, BitmapChunk},
{"write-behind", 2, 0, WriteBehind},
- {"write-mostly",0, 0, 'W'},
+ {"write-mostly",0, 0, WriteMostly},
{"re-add", 0, 0, ReAdd},
{"homehost", 1, 0, HomeHost},
#if 0
{"re-add", 0, 0, ReAdd},
{"homehost", 1, 0, HomeHost},
#if 0
/* For assemble */
{"uuid", 1, 0, 'u'},
/* For assemble */
{"uuid", 1, 0, 'u'},
- {"super-minor",1,0, 'm'},
+ {"super-minor",1,0, SuperMinor},
+ {"config", 1, 0, ConfigFile},
+ {"force", 0, 0, Force},
{"update", 1, 0, 'U'},
/* Management */
{"update", 1, 0, 'U'},
/* Management */
- {"add", 0, 0, 'a'},
- {"remove", 0, 0, 'r'},
- {"fail", 0, 0, 'f'},
- {"set-faulty",0, 0, 'f'},
+ {"add", 0, 0, Add},
+ {"remove", 0, 0, Remove},
+ {"fail", 0, 0, Fail},
+ {"set-faulty",0, 0, Fail},
{"run", 0, 0, 'R'},
{"stop", 0, 0, 'S'},
{"readonly", 0, 0, 'o'},
{"readwrite", 0, 0, 'w'},
{"no-degraded",0,0, NoDegraded },
{"run", 0, 0, 'R'},
{"stop", 0, 0, 'S'},
{"readonly", 0, 0, 'o'},
{"readwrite", 0, 0, 'w'},
{"no-degraded",0,0, NoDegraded },
+ {"wait", 0, 0, WaitOpt},
{"wait-clean", 0, 0, Waitclean },
/* For Detail/Examine */
{"wait-clean", 0, 0, Waitclean },
/* For Detail/Examine */
+ {"brief", 0, 0, Brief},
{"export", 0, 0, 'Y'},
{"sparc2.2", 0, 0, Sparc22},
{"test", 0, 0, 't'},
/* For Follow/monitor */
{"export", 0, 0, 'Y'},
{"sparc2.2", 0, 0, Sparc22},
{"test", 0, 0, 't'},
/* For Follow/monitor */
- {"mail", 1, 0, 'm'},
- {"program", 1, 0, 'p'},
- {"alert", 1, 0, 'p'},
- {"increment", 1, 0, 'r'},
+ {"mail", 1, 0, EMail},
+ {"program", 1, 0, ProgramOpt},
+ {"alert", 1, 0, ProgramOpt},
+ {"increment", 1, 0, Increment},
- {"daemonise", 0, 0, 'f'},
- {"daemonize", 0, 0, 'f'},
+ {"daemonise", 0, 0, Fork},
+ {"daemonize", 0, 0, Fork},
{"oneshot", 0, 0, '1'},
{"pid-file", 1, 0, 'i'},
{"syslog", 0, 0, 'y'},
{"oneshot", 0, 0, '1'},
{"pid-file", 1, 0, 'i'},
{"syslog", 0, 0, 'y'},
{"array-size", 1, 0, 'Z'},
/* For Incremental */
{"array-size", 1, 0, 'Z'},
/* For Incremental */
- {"rebuild-map", 0, 0, 'r'},
+ {"rebuild-map", 0, 0, RebuildMapOpt},
{"path", 1, 0, IncrementalPath},
{0, 0, 0, 0}
{"path", 1, 0, IncrementalPath},
{0, 0, 0, 0}
char *cp;
char *update = NULL;
int scan = 0;
char *cp;
char *update = NULL;
int scan = 0;
int runstop = 0;
int readonly = 0;
int write_behind = 0;
int runstop = 0;
int readonly = 0;
int write_behind = 0;
int newmode = mode;
/* firstly, some mode-independent options */
switch(opt) {
int newmode = mode;
/* firstly, some mode-independent options */
switch(opt) {
+ case HelpOptions:
+ print_help = 2;
+ continue;
- if (option_index > 0 &&
- strcmp(long_options[option_index].name, "help-options")==0)
- print_help = 2;
- else
- print_help = 1;
- if (mode == ASSEMBLE || mode == BUILD || mode == CREATE || mode == GROW ||
- mode == INCREMENTAL || mode == MANAGE)
+ if (mode == ASSEMBLE || mode == BUILD || mode == CREATE
+ || mode == GROW || mode == INCREMENTAL
+ || mode == MANAGE)
break; /* b means bitmap */
break; /* b means bitmap */
- case '@': /* just incase they say --manage */
newmode = MANAGE;
shortopt = short_bitmap_options;
break;
case 'a':
newmode = MANAGE;
shortopt = short_bitmap_options;
break;
case 'a':
case ReAdd: /* re-add */
if (!mode) {
newmode = MANAGE;
case ReAdd: /* re-add */
if (!mode) {
newmode = MANAGE;
case AutoDetect:
newmode = AUTODETECT; break;
case AutoDetect:
newmode = AUTODETECT; break;
case 'D':
case 'E':
case 'X':
case 'D':
case 'E':
case 'X':
case 'o':
case 'w':
case 'W':
case 'o':
case 'w':
case 'W':
case Waitclean:
case DetailPlatform:
case KillSubarray:
case UpdateSubarray:
if (opt == KillSubarray || opt == UpdateSubarray) {
if (subarray) {
case Waitclean:
case DetailPlatform:
case KillSubarray:
case UpdateSubarray:
if (opt == KillSubarray || opt == UpdateSubarray) {
if (subarray) {
- fprintf(stderr, Name ": subarray can only be specified once\n");
+ fprintf(stderr, Name ": subarray can only"
+ " be specified once\n");
exit(2);
}
subarray = optarg;
exit(2);
}
subarray = optarg;
mode = newmode;
} else {
/* special case of -c --help */
mode = newmode;
} else {
/* special case of -c --help */
+ if ((opt == 'c' || opt == ConfigFile) &&
( strncmp(optarg, "--h", 3)==0 ||
strncmp(optarg, "-h", 2)==0)) {
fputs(Help_config, stdout);
( strncmp(optarg, "--h", 3)==0 ||
strncmp(optarg, "-h", 2)==0)) {
fputs(Help_config, stdout);
/* if we just set the mode, then done */
switch(opt) {
/* if we just set the mode, then done */
switch(opt) {
+ case ManageOpt:
+ case MiscOpt:
case 'A':
case 'B':
case 'C':
case 'A':
case 'B':
case 'C':
if (opt == 1) {
/* an undecorated option - must be a device name.
*/
if (opt == 1) {
/* an undecorated option - must be a device name.
*/
- if (devs_found > 0 && mode == '@' && !devmode) {
- fprintf(stderr, Name ": Must give one of -a/-r/-f for subsequent devices at %s\n", optarg);
+ if (devs_found > 0 && mode == MANAGE && !devmode) {
+ fprintf(stderr, Name ": Must give one of -a/-r/-f"
+ " for subsequent devices at %s\n", optarg);
- if (devs_found > 0 && mode == 'G' && !devmode) {
- fprintf(stderr, Name ": Must give one of -a for devices do add: %s\n", optarg);
+ if (devs_found > 0 && mode == GROW && !devmode) {
+ fprintf(stderr, Name ": Must give -a/--add for"
+ " devices to add: %s\n", optarg);
exit(2);
}
dv = malloc(sizeof(*dv));
exit(2);
}
dv = malloc(sizeof(*dv));
/* We've got a mode, and opt is now something else which
* could depend on the mode */
/* We've got a mode, and opt is now something else which
* could depend on the mode */
-#define O(a,b) ((a<<8)|b)
+#define O(a,b) ((a<<16)|b)
switch (O(mode,opt)) {
case O(GROW,'c'):
switch (O(mode,opt)) {
case O(GROW,'c'):
+ case O(GROW,ChunkSize):
+ case O(CREATE,ChunkSize):
case O(BUILD,'c'): /* chunk or rounding */
case O(BUILD,'c'): /* chunk or rounding */
+ case O(BUILD,ChunkSize): /* chunk or rounding */
if (chunk) {
fprintf(stderr, Name ": chunk/rounding may only be specified once. "
"Second value is %s.\n", optarg);
if (chunk) {
fprintf(stderr, Name ": chunk/rounding may only be specified once. "
"Second value is %s.\n", optarg);
continue;
case O(MANAGE,'W'):
continue;
case O(MANAGE,'W'):
+ case O(MANAGE,WriteMostly):
+ case O(BUILD,WriteMostly):
+ case O(CREATE,WriteMostly):
/* set write-mostly for following devices */
writemostly = 1;
continue;
/* set write-mostly for following devices */
writemostly = 1;
continue;
continue;
case O(GROW, 'p'): /* new layout */
continue;
case O(GROW, 'p'): /* new layout */
if (layout_str) {
fprintf(stderr,Name ": layout may only be sent once. "
"Second value was %s\n", optarg);
if (layout_str) {
fprintf(stderr,Name ": layout may only be sent once. "
"Second value was %s\n", optarg);
continue;
case O(CREATE,'p'): /* raid5 layout */
continue;
case O(CREATE,'p'): /* raid5 layout */
case O(BUILD,'p'): /* faulty layout */
case O(BUILD,'p'): /* faulty layout */
if (layout != UnSet) {
fprintf(stderr,Name ": layout may only be sent once. "
"Second value was %s\n", optarg);
if (layout != UnSet) {
fprintf(stderr,Name ": layout may only be sent once. "
"Second value was %s\n", optarg);
continue;
case O(CREATE,'a'):
continue;
case O(CREATE,'a'):
- case O(ASSEMBLE,'a'): /* auto-creation of device node */
+ case O(INCREMENTAL,Auto):
+ case O(ASSEMBLE,'a'):
+ case O(ASSEMBLE,Auto): /* auto-creation of device node */
autof = parse_auto(optarg, "--auto flag", 0);
continue;
autof = parse_auto(optarg, "--auto flag", 0);
continue;
continue;
case O(BUILD,'f'): /* force honouring '-n 1' */
continue;
case O(BUILD,'f'): /* force honouring '-n 1' */
+ case O(BUILD,Force): /* force honouring '-n 1' */
case O(GROW,'f'): /* ditto */
case O(GROW,'f'): /* ditto */
+ case O(GROW,Force): /* ditto */
case O(CREATE,'f'): /* force honouring of device list */
case O(CREATE,'f'): /* force honouring of device list */
+ case O(CREATE,Force): /* force honouring of device list */
case O(ASSEMBLE,'f'): /* force assembly */
case O(ASSEMBLE,'f'): /* force assembly */
+ case O(ASSEMBLE,Force): /* force assembly */
case O(MISC,'f'): /* force zero */
case O(MISC,'f'): /* force zero */
+ case O(MISC,Force): /* force zero */
continue;
case O(ASSEMBLE,'m'): /* super-minor for array */
continue;
case O(ASSEMBLE,'m'): /* super-minor for array */
+ case O(ASSEMBLE,SuperMinor):
if (ident.super_minor != UnSet) {
fprintf(stderr, Name ": super-minor cannot be set twice. "
"Second value: %s.\n", optarg);
if (ident.super_minor != UnSet) {
fprintf(stderr, Name ": super-minor cannot be set twice. "
"Second value: %s.\n", optarg);
* so we overload slightly */
continue;
* so we overload slightly */
continue;
- case O(ASSEMBLE,'c'): /* config file */
+ case O(ASSEMBLE,'c'):
+ case O(ASSEMBLE,ConfigFile):
case O(INCREMENTAL, 'c'):
case O(INCREMENTAL, 'c'):
+ case O(INCREMENTAL, ConfigFile):
+ case O(MISC, ConfigFile):
+ case O(MONITOR,ConfigFile):
if (configfile) {
fprintf(stderr, Name ": configfile cannot be set twice. "
"Second value is %s.\n", optarg);
if (configfile) {
fprintf(stderr, Name ": configfile cannot be set twice. "
"Second value is %s.\n", optarg);
continue;
case O(MONITOR,'m'): /* mail address */
continue;
case O(MONITOR,'m'): /* mail address */
if (mailaddr)
fprintf(stderr, Name ": only specify one mailaddress. %s ignored.\n",
optarg);
if (mailaddr)
fprintf(stderr, Name ": only specify one mailaddress. %s ignored.\n",
optarg);
continue;
case O(MONITOR,'p'): /* alert program */
continue;
case O(MONITOR,'p'): /* alert program */
+ case O(MONITOR,ProgramOpt): /* alert program */
if (program)
fprintf(stderr, Name ": only specify one alter program. %s ignored.\n",
optarg);
if (program)
fprintf(stderr, Name ": only specify one alter program. %s ignored.\n",
optarg);
continue;
case O(MONITOR,'r'): /* rebuild increments */
continue;
case O(MONITOR,'r'): /* rebuild increments */
+ case O(MONITOR,Increment):
increments = atoi(optarg);
if (increments>99 || increments<1) {
fprintf(stderr, Name ": please specify positive integer between 1 and 99 as rebuild increments.\n");
increments = atoi(optarg);
if (increments>99 || increments<1) {
fprintf(stderr, Name ": please specify positive integer between 1 and 99 as rebuild increments.\n");
}
continue;
case O(MONITOR,'f'): /* daemonise */
}
continue;
case O(MONITOR,'f'): /* daemonise */
daemonise = 1;
continue;
case O(MONITOR,'i'): /* pid */
daemonise = 1;
continue;
case O(MONITOR,'i'): /* pid */
* to other modes. None have arguments.
*/
case O(GROW,'a'):
* to other modes. None have arguments.
*/
case O(GROW,'a'):
- case O(MANAGE,'a'): /* add a drive */
+ case O(GROW,Add):
+ case O(MANAGE,'a'):
+ case O(MANAGE,Add): /* add a drive */
devmode = 'a';
re_add = 0;
continue;
devmode = 'a';
re_add = 0;
continue;
re_add = 1;
continue;
case O(MANAGE,'r'): /* remove a drive */
re_add = 1;
continue;
case O(MANAGE,'r'): /* remove a drive */
devmode = 'r';
continue;
case O(MANAGE,'f'): /* set faulty */
devmode = 'r';
continue;
case O(MANAGE,'f'): /* set faulty */
- case O(INCREMENTAL,'f'): /* r for incremental is taken, use f
+ case O(MANAGE,Fail):
+ case O(INCREMENTAL,'f'):
+ case O(INCREMENTAL,Remove):
+ case O(INCREMENTAL,Fail): /* r for incremental is taken, use f
* even though we will both fail and
* remove the device */
devmode = 'f';
* even though we will both fail and
* remove the device */
devmode = 'f';
case O(MISC,'o'):
case O(MISC,'w'):
case O(MISC,'W'):
case O(MISC,'o'):
case O(MISC,'w'):
case O(MISC,'W'):
case O(MISC, Waitclean):
case O(MISC, DetailPlatform):
case O(MISC, KillSubarray):
case O(MISC, Waitclean):
case O(MISC, DetailPlatform):
case O(MISC, KillSubarray):
continue;
case O(ASSEMBLE,'b'): /* here we simply set the bitmap file */
continue;
case O(ASSEMBLE,'b'): /* here we simply set the bitmap file */
+ case O(ASSEMBLE,Bitmap):
if (!optarg) {
fprintf(stderr, Name ": bitmap file needed with -b in --assemble mode\n");
exit(2);
if (!optarg) {
fprintf(stderr, Name ": bitmap file needed with -b in --assemble mode\n");
exit(2);
continue;
case O(BUILD,'b'):
continue;
case O(BUILD,'b'):
- case O(CREATE,'b'): /* here we create the bitmap */
+ case O(BUILD,Bitmap):
+ case O(CREATE,'b'):
+ case O(CREATE,Bitmap): /* here we create the bitmap */
if (strcmp(optarg, "none") == 0) {
fprintf(stderr, Name ": '--bitmap none' only"
" support for --grow\n");
if (strcmp(optarg, "none") == 0) {
fprintf(stderr, Name ": '--bitmap none' only"
" support for --grow\n");
}
/* FALL THROUGH */
case O(GROW,'b'):
}
/* FALL THROUGH */
case O(GROW,'b'):
if (strcmp(optarg, "internal")== 0 ||
strcmp(optarg, "none")== 0 ||
strchr(optarg, '/') != NULL) {
if (strcmp(optarg, "internal")== 0 ||
strcmp(optarg, "none")== 0 ||
strchr(optarg, '/') != NULL) {
continue;
case O(INCREMENTAL, 'r'):
continue;
case O(INCREMENTAL, 'r'):
+ case O(INCREMENTAL, RebuildMapOpt):
rebuild_map = 1;
continue;
case O(INCREMENTAL, IncrementalPath):
rebuild_map = 1;
continue;
case O(INCREMENTAL, IncrementalPath):
case 'X':
rv |= ExamineBitmap(dv->devname, brief, ss); continue;
case 'W':
case 'X':
rv |= ExamineBitmap(dv->devname, brief, ss); continue;
case 'W':
rv |= Wait(dv->devname); continue;
case Waitclean:
rv |= WaitClean(dv->devname, -1, verbose-quiet); continue;
rv |= Wait(dv->devname); continue;
case Waitclean:
rv |= WaitClean(dv->devname, -1, verbose-quiet); continue;
Help_manage[], Help_misc[], Help_monitor[], Help_config[];
/* for option that don't have short equivilents, we assign arbitrary
Help_manage[], Help_misc[], Help_monitor[], Help_config[];
/* for option that don't have short equivilents, we assign arbitrary
- * small numbers. '1' means an undecorated option, so we start at '2'.
- * (note we must stop before we get to 65 i.e. 'A')
+ * numbers later than any 'short' character option.
*/
enum special_options {
*/
enum special_options {
BitmapChunk,
WriteBehind,
ReAdd,
NoDegraded,
Sparc22,
BitmapChunk,
WriteBehind,
ReAdd,
NoDegraded,
Sparc22,
HomeHost,
AutoHomeHost,
Symlinks,
HomeHost,
AutoHomeHost,
Symlinks,
Waitclean,
DetailPlatform,
KillSubarray,
Waitclean,
DetailPlatform,
KillSubarray,
- UpdateSubarray, /* 16 */
+ NoSharing,
+ HelpOptions,
+ Brief,
+ ManageOpt,
+ Add,
+ Remove,
+ Fail,
+ MiscOpt,
+ WaitOpt,
+ ConfigFile,
+ ChunkSize,
+ WriteMostly,
+ Layout,
+ Auto,
+ Force,
+ SuperMinor,
+ EMail,
+ ProgramOpt,
+ Increment,
+ Fork,
+ Bitmap,
+ RebuildMapOpt,
};
/* structures read from config file */
};
/* structures read from config file */
/* List of device names - wildcards expanded */
struct mddev_dev {
char *devname;
/* List of device names - wildcards expanded */
struct mddev_dev {
char *devname;
- char disposition; /* 'a' for add, 'r' for remove, 'f' for fail.
+ int disposition; /* 'a' for add, 'r' for remove, 'f' for fail.
* Not set for names read from .config
*/
char writemostly; /* 1 for 'set writemostly', 2 for 'clear writemostly' */
* Not set for names read from .config
*/
char writemostly; /* 1 for 'set writemostly', 2 for 'clear writemostly' */