struct mddev_dev *devlist = NULL;
struct mddev_dev **devlistend = & devlist;
struct mddev_dev *dv;
+ mdu_array_info_t array;
int devs_found = 0;
char *symlinks = NULL;
int grow_continue = 0;
.level = UnSet,
.layout = UnSet,
.bitmap_chunk = UnSet,
- .consistency_policy = UnSet,
+ .consistency_policy = CONSISTENCY_POLICY_UNKNOWN,
};
char sys_hostname[256];
FILE *outf;
int mdfd = -1;
+ int locked = 0;
srandom(time(0) ^ getpid());
- ident.uuid_set=0;
+ ident.uuid_set = 0;
ident.level = UnSet;
ident.raid_disks = UnSet;
- ident.super_minor= UnSet;
- ident.devices=0;
+ ident.super_minor = UnSet;
+ ident.devices = 0;
ident.spare_group = NULL;
ident.autof = 0;
ident.st = NULL;
ident.container = NULL;
ident.member = NULL;
- while ((option_index = -1) ,
- (opt=getopt_long(argc, argv,
- shortopt, long_options,
- &option_index)) != -1) {
+ if (get_linux_version() < 2006015) {
+ pr_err("This version of mdadm does not support kernels older than 2.6.15\n");
+ exit(1);
+ }
+
+ while ((option_index = -1),
+ (opt = getopt_long(argc, argv, shortopt, long_options,
+ &option_index)) != -1) {
int newmode = mode;
/* firstly, some mode-independent options */
switch(opt) {
pr_err("metadata information already given\n");
exit(2);
}
- for(i=0; !ss && superlist[i]; i++)
+ for(i = 0; !ss && superlist[i]; i++)
ss = superlist[i]->match_metadata_desc(optarg);
if (!ss) {
case 5:
s.layout = map_name(r5layout, optarg);
- if (s.layout==UnSet) {
+ if (s.layout == UnSet) {
pr_err("layout %s not understood for raid5.\n",
optarg);
exit(2);
break;
case 6:
s.layout = map_name(r6layout, optarg);
- if (s.layout==UnSet) {
+ if (s.layout == UnSet) {
pr_err("layout %s not understood for raid6.\n",
optarg);
exit(2);
c.homecluster = optarg;
if (strlen(c.homecluster) > 64) {
pr_err("Cluster name too big.\n");
- exit(ERANGE);
+ exit(2);
}
continue;
case O(CREATE,'x'): /* number of spare (eXtra) disks */
case O(MISC,'f'): /* force zero */
case O(MISC,Force): /* force zero */
case O(MANAGE,Force): /* add device which is too large */
- c.force=1;
+ c.force = 1;
continue;
/* now for the Assemble options */
case O(ASSEMBLE, FreezeReshape): /* Freeze reshape during
continue;
if (strcmp(c.update, "revert-reshape") == 0)
continue;
- if (strcmp(c.update, "byteorder")==0) {
+ if (strcmp(c.update, "byteorder") == 0) {
if (ss) {
pr_err("must not set metadata type with --update=byteorder.\n");
exit(2);
}
- for(i=0; !ss && superlist[i]; i++)
+ for(i = 0; !ss && superlist[i]; i++)
ss = superlist[i]->match_metadata_desc(
"0.swap");
if (!ss) {
case O(GROW, 'k'):
s.consistency_policy = map_name(consistency_policies,
optarg);
- if (s.consistency_policy == UnSet ||
- s.consistency_policy < CONSISTENCY_POLICY_RESYNC) {
+ if (s.consistency_policy < CONSISTENCY_POLICY_RESYNC) {
pr_err("Invalid consistency policy: %s\n",
optarg);
exit(2);
pr_err("--write-journal is only supported for RAID level 4/5/6.\n");
exit(2);
}
- if (s.consistency_policy != UnSet &&
+ if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN &&
s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) {
pr_err("--write-journal is not supported with consistency policy: %s\n",
map_num(consistency_policies, s.consistency_policy));
}
}
- if (mode == CREATE && s.consistency_policy != UnSet) {
+ if (mode == CREATE &&
+ s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) {
if (s.level <= 0) {
pr_err("--consistency-policy not meaningful with level %s.\n",
map_num(pers, s.level));
/* --scan implied --brief unless -vv */
c.brief = 1;
+ if (mode == CREATE) {
+ if (s.bitmap_file && strcmp(s.bitmap_file, "clustered") == 0) {
+ locked = cluster_get_dlmlock();
+ if (locked != 1)
+ exit(1);
+ }
+ } else if (mode == MANAGE || mode == GROW || mode == INCREMENTAL) {
+ if (!md_get_array_info(mdfd, &array) && (devmode != 'c')) {
+ if (array.state & (1 << MD_SB_CLUSTERED)) {
+ locked = cluster_get_dlmlock();
+ if (locked != 1)
+ exit(1);
+ }
+ }
+ }
+
switch(mode) {
case MANAGE:
/* readonly, add/remove, readwrite, runstop */
pr_err("can only assemble a single array when providing a backup file.\n");
exit(1);
}
- for (dv = devlist ; dv ; dv=dv->next) {
+ for (dv = devlist; dv; dv = dv->next) {
struct mddev_ident *array_ident = conf_get_ident(dv->devname);
if (array_ident == NULL) {
pr_err("%s not identified in config file.\n",
break;
}
- if (s.level != 1) {
- pr_err("--bitmap=clustered is currently supported with RAID mirror only\n");
+ if (s.level != 1 && s.level != 10) {
+ pr_err("--bitmap=clustered is currently supported with raid1/10 only\n");
+ rv = 1;
+ break;
+ }
+ if (s.level == 10 && !(is_near_layout_10(s.layout) || s.layout == UnSet)) {
+ pr_err("only near layout is supported with clustered raid10\n");
rv = 1;
break;
}
else
c.delay = 60;
}
- rv= Monitor(devlist, mailaddr, program,
- &c, daemonise, oneshot,
- dosyslog, pidfile, increments,
- spare_sharing);
+ rv = Monitor(devlist, mailaddr, program,
+ &c, daemonise, oneshot,
+ dosyslog, pidfile, increments,
+ spare_sharing);
break;
case GROW:
rv = 1;
break;
}
- sysfs_init(&sra, mdfd, NULL);
+ if (sysfs_init(&sra, mdfd, NULL)) {
+ rv = 1;
+ break;
+ }
if (array_size == MAX_SIZE)
err = sysfs_set_str(&sra, NULL, "array_size", "default");
else
rv = 1;
break;
}
- for (dv=devlist->next; dv ; dv=dv->next) {
+ for (dv = devlist->next; dv; dv = dv->next) {
rv = Grow_Add_device(devlist->devname, mdfd,
dv->devname);
if (rv)
rv = Grow_reshape(devlist->devname, mdfd,
devlist->next,
data_offset, &c, &s);
- } else if (s.consistency_policy != UnSet) {
+ } else if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) {
rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s);
} else if (array_size == 0)
pr_err("no changes to --grow\n");
autodetect();
break;
}
+ if (locked)
+ cluster_release_dlmlock();
+ if (mdfd > 0)
+ close(mdfd);
exit(rv);
}
pr_err("No devices listed in conf file were found.\n");
return 1;
}
- for (a = array_list; a ; a = a->next) {
+ for (a = array_list; a; a = a->next) {
a->assembled = 0;
if (a->autof == 0)
a->autof = c->autof;
failures = 0;
successes = 0;
rv = 0;
- for (a = array_list; a ; a = a->next) {
+ for (a = array_list; a; a = a->next) {
int r;
if (a->assembled)
continue;
int rv = 0;
for (members = 0; members <= 1; members++) {
- for (e=ms ; e ; e=e->next) {
+ for (e = ms; e; e = e->next) {
char *name = NULL;
struct map_ent *me;
struct stat stb;
if (members != member)
continue;
me = map_by_devnm(&map, e->devnm);
- if (me && me->path
- && strcmp(me->path, "/unknown") != 0)
+ if (me && me->path && strcmp(me->path, "/unknown") != 0)
name = me->path;
if (name == NULL || stat(name, &stb) != 0)
name = get_md_name(e->devnm);
if (devmode == 'D')
rv |= Detail(name, c);
else
- rv |= WaitClean(name, -1, c->verbose);
+ rv |= WaitClean(name, c->verbose);
put_md_name(name);
}
}
/* Due to possible stacking of devices, repeat until
* nothing more can be stopped
*/
- int progress=1, err;
+ int progress = 1, err;
int last = 0;
int rv = 0;
do {
if (!progress) last = 1;
progress = 0; err = 0;
- for (e=ms ; e ; e=e->next) {
+ for (e = ms; e; e = e->next) {
char *name = get_md_name(e->devnm);
int mdfd;
struct mddev_dev *dv;
int rv = 0;
- for (dv=devlist ; dv; dv=(rv & 16) ? NULL : dv->next) {
- int mdfd;
+ for (dv = devlist; dv; dv = (rv & 16) ? NULL : dv->next) {
+ int mdfd = -1;
switch(dv->disposition) {
case 'D':
}
continue;
case 'Q':
- rv |= Query(dv->devname); continue;
+ rv |= Query(dv->devname);
+ continue;
case 'X':
- rv |= ExamineBitmap(dv->devname, c->brief, ss); continue;
+ rv |= ExamineBitmap(dv->devname, c->brief, ss);
+ continue;
case ExamineBB:
- rv |= ExamineBadblocks(dv->devname, c->brief, ss); continue;
+ rv |= ExamineBadblocks(dv->devname, c->brief, ss);
+ continue;
case 'W':
case WaitOpt:
- rv |= Wait(dv->devname); continue;
+ rv |= Wait(dv->devname);
+ continue;
case Waitclean:
- rv |= WaitClean(dv->devname, -1, c->verbose); continue;
+ rv |= WaitClean(dv->devname, c->verbose);
+ continue;
case KillSubarray:
rv |= Kill_subarray(dv->devname, c->subarray, c->verbose);
continue;
rv |= SetAction(dv->devname, c->action);
continue;
}
- switch(dv->devname[0] == '/') {
- case 0:
- mdfd = open_dev(dv->devname);
- if (mdfd >= 0) break;
- case 1:
- mdfd = open_mddev(dv->devname, 1);
- }
- if (mdfd>=0) {
+
+ if (dv->devname[0] != '/')
+ mdfd = open_dev(dv->devname);
+ if (dv->devname[0] == '/' || mdfd < 0)
+ mdfd = open_mddev(dv->devname, 1);
+
+ if (mdfd >= 0) {
switch(dv->disposition) {
case 'R':
c->runstop = 1;
- rv |= Manage_run(dv->devname, mdfd, c); break;
+ rv |= Manage_run(dv->devname, mdfd, c);
+ break;
case 'S':
- rv |= Manage_stop(dv->devname, mdfd, c->verbose, 0); break;
+ rv |= Manage_stop(dv->devname, mdfd, c->verbose, 0);
+ break;
case 'o':
- rv |= Manage_ro(dv->devname, mdfd, 1); break;
+ rv |= Manage_ro(dv->devname, mdfd, 1);
+ break;
case 'w':
- rv |= Manage_ro(dv->devname, mdfd, -1); break;
+ rv |= Manage_ro(dv->devname, mdfd, -1);
+ break;
}
close(mdfd);
} else
{
int fd = open(dev, O_RDONLY);
struct mdinfo mdi;
+ int retval;
+
if (fd < 0) {
pr_err("Couldn't open %s: %s\n", dev, strerror(errno));
return 1;
}
- sysfs_init(&mdi, fd, NULL);
+ retval = sysfs_init(&mdi, fd, NULL);
close(fd);
- if (!mdi.sys_name[0]) {
+ if (retval) {
pr_err("%s is no an md array\n", dev);
return 1;
}