* Incremental.c - support --incremental. Part of:
* mdadm - manage Linux "md" devices aka RAID arrays.
*
- * Copyright (C) 2006-2009 Neil Brown <neilb@suse.de>
+ * Copyright (C) 2006-2012 Neil Brown <neilb@suse.de>
*
*
* This program is free software; you can redistribute it and/or modify
devname);
return rv;
}
- dfd = dev_open(devname, O_RDONLY|O_EXCL);
+ dfd = dev_open(devname, O_RDONLY);
if (dfd < 0) {
if (c->verbose >= 0)
pr_err("cannot open %s: %s.\n",
if (must_be_container(dfd)) {
if (!st)
st = super_by_fd(dfd, NULL);
+ if (st)
+ st->ignore_hw_compat = 1;
if (st && st->ss->load_container)
rv = st->ss->load_container(st, dfd, NULL);
st, c->verbose);
goto out;
}
+ st->ignore_hw_compat = 1;
if (st->ss->compare_super == NULL ||
st->ss->load_super(st, dfd, NULL)) {
if (c->verbose >= 0)
else
trustworthy = FOREIGN;
-
if (!match && !conf_test_metadata(st->ss->name, policy,
(trustworthy == LOCAL))) {
if (c->verbose >= 1)
if (map_lock(&map))
pr_err("failed to get exclusive lock on "
"mapfile\n");
+ /* Now check we can get O_EXCL. If not, probably "mdadm -A" has
+ * taken over
+ */
+ dfd = dev_open(devname, O_RDONLY|O_EXCL);
+ if (dfd < 0) {
+ if (c->verbose >= 0)
+ pr_err("cannot reopen %s: %s.\n",
+ devname, strerror(errno));
+ goto out_unlock;
+ }
+ /* Cannot hold it open while we add the device to the array,
+ * so we must release the O_EXCL and depend on the map_lock()
+ */
+ close(dfd);
+ dfd = -1;
+
mp = map_by_uuid(&map, info.uuid);
if (mp)
mdfd = open_dev(mp->devnum);
}
sra = sysfs_read(mdfd, -1, (GET_DEVS | GET_STATE |
GET_OFFSET | GET_SIZE));
-
+
if (!sra || !sra->devs || sra->devs->disk.raid_disk >= 0) {
/* It really should be 'none' - must be old buggy
* kernel, and mdadm -I may not be able to complete.
sra = sysfs_read(mdfd, -1, (GET_DEVS | GET_STATE |
GET_OFFSET | GET_SIZE));
-
+
if (mp->path)
strcpy(chosen_name, mp->path);
else
info.array.working_disks = 0;
for (d = sra->devs; d; d=d->next)
info.array.working_disks ++;
-
+
}
/* 7/ Is there enough devices to possibly start the array? */
if (c->verbose >= 0)
pr_err("container %s now has %d device%s\n",
chosen_name, info.array.working_disks,
- info.array.working_disks==1?"":"s");
+ info.array.working_disks == 1?"":"s");
wait_for(chosen_name, mdfd);
if (st->ss->external)
devnum = fd2devnum(mdfd);
if (c->runstop > 0 || active_disks >= info.array.working_disks) {
struct mdinfo *dsk;
/* Let's try to start it */
+
+ if (info.reshape_active && !(info.reshape_active & RESHAPE_NO_BACKUP)) {
+ fprintf(stderr, Name
+ ": %s: This array is being reshaped and cannot be started\n"
+ " by --incremental. Please use --assemble\n",
+ chosen_name);
+ goto out;
+ }
if (match && match->bitmap_file) {
int bmfd = open(match->bitmap_file, O_RDWR);
if (bmfd < 0) {
/* count how many devices in sra think they are active */
struct mdinfo *d;
int cnt = 0;
+ int replcnt = 0;
__u64 max_events = 0;
char *avail = NULL;
int *best = NULL;
for (d = sra->devs ; d ; d = d->next)
numdevs++;
- for (d = sra->devs, devnum=0 ; d ; d = d->next, devnum++) {
+ for (d = sra->devs, devnum = 0 ; d ; d = d->next, devnum++) {
char dn[30];
int dfd;
int ok;
else if (info.events == max_events+1) {
int i;
max_events = info.events;
- for (i=0; i < raid_disks; i++)
+ for (i = 0; i < raid_disks; i++)
if (avail[i])
avail[i]--;
avail[info.disk.raid_disk] = 2;
best[info.disk.raid_disk] = devnum;
st->ss->getinfo_super(st, bestinfo, NULL);
}
- }
+ } else if (info.disk.state & (1<<MD_DISK_REPLACEMENT))
+ replcnt++;
st->ss->free_super(st);
}
if (!avail)
}
free(best);
free(devmap);
- return cnt;
+ return cnt + replcnt;
}
/* test if container has degraded member(s) */
if (st == NULL) {
int i;
st2 = NULL;
- for(i=0; !st2 && superlist[i]; i++)
+ for(i = 0; !st2 && superlist[i]; i++)
st2 = superlist[i]->match_metadata_desc(
sra->text_version);
if (!st2) {
close(mdfd);
}
if ((sra->component_size > 0 &&
- st2->ss->avail_size(st2, devsize) < sra->component_size)
+ st2->ss->avail_size(st2, devsize,
+ sra->devs
+ ? sra->devs->data_offset
+ : INVALID_SECTORS)
+ < sra->component_size)
||
(sra->component_size == 0 && devsize < component_size)) {
if (verbose > 1)
me->path, strerror(errno));
}
}
+ /* FIXME check for reshape_active and consider not
+ * starting array.
+ */
sra = sysfs_read(mdfd, 0, 0);
if (sra) {
if (sysfs_set_str(sra, NULL,
} else {
int uuid[4];
struct map_ent *mp, *map = NULL;
-
+
if (!parse_uuid(devname, uuid))
return mdname;
mp = map_by_uuid(&map, uuid);