"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "Assemble.c" between
mdadm-4.1.tar.gz and mdadm-4.2.tar.gz

About: mdadm is a tool for creating, managing and monitoring device arrays using the "md" driver in Linux, also known as Software RAID arrays.

Assemble.c  (mdadm-4.1):Assemble.c  (mdadm-4.2)
skipping to change at line 28 skipping to change at line 28
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Author: Neil Brown * Author: Neil Brown
* Email: <neilb@suse.de> * Email: <neilb@suse.de>
*/ */
#include "mdadm.h" #include "mdadm.h"
#include <ctype.h> #include <ctype.h>
mapping_t assemble_statuses[] = {
{ "but cannot be started", INCR_NO },
{ "but not safe to start", INCR_UNSAFE },
{ "and started", INCR_YES },
{ NULL, INCR_ALREADY }
};
/**
* struct assembly_array_info - General, meaningful information for assembly.
* @name: Array name.
* @new_cnt: Count of drives known to be members, recently added.
* @preexist_cnt: Count of member drives in pre-assembled array.
* @exp_cnt: Count of known expansion targets.
*
* FIXME: @exp_new_cnt for recently added expansion targets.
*/
struct assembly_array_info {
char *name;
int new_cnt;
int preexist_cnt;
int exp_cnt;
};
/**
* set_array_assembly_status() - generate status of assembly for an array.
* @c: Global settings.
* @result: Pointer to status mask.
* @status: Status to be set/printed.
* @arr: Array information.
*
* Print status message to user or set it in @result if it is not NULL.
*/
static void set_array_assembly_status(struct context *c,
int *result, int status,
struct assembly_array_info *arr)
{
int raid_disks = arr->preexist_cnt + arr->new_cnt;
char *status_msg = map_num(assemble_statuses, status);
if (c->export && result)
*result |= status;
if (c->export || c->verbose < 0)
return;
pr_err("%s has been assembled with %d device%s", arr->name,
raid_disks, raid_disks == 1 ? "":"s");
if (arr->preexist_cnt > 0)
fprintf(stderr, " (%d new)", arr->new_cnt);
if (arr->exp_cnt)
fprintf(stderr, " ( + %d for expansion)", arr->exp_cnt);
if (status_msg)
fprintf(stderr, " %s", status_msg);
fprintf(stderr, ".\n");
}
static int name_matches(char *found, char *required, char *homehost, int require _homehost) static int name_matches(char *found, char *required, char *homehost, int require _homehost)
{ {
/* See if the name found matches the required name, possibly /* See if the name found matches the required name, possibly
* prefixed with 'homehost' * prefixed with 'homehost'
*/ */
char *sep; char *sep;
unsigned int l; unsigned int l;
if (strcmp(found, required)==0) if (strcmp(found, required)==0)
return 1; return 1;
skipping to change at line 272 skipping to change at line 328
pr_err("%s has metadata type %s for which auto-assembly is disabled\n", pr_err("%s has metadata type %s for which auto-assembly is disabled\n",
devname, tst->ss->name); devname, tst->ss->name);
tmpdev->used = 2; tmpdev->used = 2;
} }
} }
if (dfd >= 0) close(dfd); if (dfd >= 0) close(dfd);
if (tmpdev->used == 2) { if (tmpdev->used == 2) {
if (auto_assem || !inargv) if (auto_assem || !inargv)
/* Ignore unrecognised devices during auto-assemb ly */ /* Ignore unrecognised devices during auto-assemb ly */
goto loop; goto loop;
if (ident->uuid_set || ident->name[0] || if (ident->name[0] ||
ident->super_minor != UnSet) ident->super_minor != UnSet)
/* Ignore unrecognised device if looking for /* Ignore unrecognised device if looking for
* specific array */ * specific array */
goto loop; goto loop;
if (ident->uuid_set)
/* ignore unrecognized device if looking for
* specific uuid
*/
goto loop;
pr_err("%s has no superblock - assembly aborted\n", pr_err("%s has no superblock - assembly aborted\n",
devname); devname);
if (st) if (st)
st->ss->free_super(st); st->ss->free_super(st);
dev_policy_free(pol); dev_policy_free(pol);
domain_free(domains); domain_free(domains);
if (tst) if (tst)
tst->ss->free_super(tst); tst->ss->free_super(tst);
return -1; return -1;
skipping to change at line 438 skipping to change at line 499
* an array unless there are no more arrays of * an array unless there are no more arrays of
* this type to be found. It can be included * this type to be found. It can be included
* in an array of this type though. * in an array of this type though.
*/ */
tmpdev->used = 3; tmpdev->used = 3;
goto loop; goto loop;
} }
if (st->ss != tst->ss || if (st->ss != tst->ss ||
st->minor_version != tst->minor_version || st->minor_version != tst->minor_version ||
st->ss->compare_super(st, tst) != 0) { st->ss->compare_super(st, tst, 1) != 0) {
/* Some mismatch. If exactly one array matches th is host, /* Some mismatch. If exactly one array matches th is host,
* we can resolve on that one. * we can resolve on that one.
* Or, if we are auto assembling, we just ignore the second * Or, if we are auto assembling, we just ignore the second
* for now. * for now.
*/ */
if (auto_assem) if (auto_assem)
goto loop; goto loop;
if (c->homehost) { if (c->homehost) {
int first = st->ss->match_home(st, c->hom ehost); int first = st->ss->match_home(st, c->hom ehost);
int last = tst->ss->match_home(tst, c->ho mehost); int last = tst->ss->match_home(tst, c->ho mehost);
skipping to change at line 510 skipping to change at line 571
continue; continue;
tmpdev->used = 1; tmpdev->used = 1;
content = *contentp; content = *contentp;
if (!st->sb) { if (!st->sb) {
/* we need sb from one of the spares */ /* we need sb from one of the spares */
int dfd = dev_open(tmpdev->devname, O_RDONLY); int dfd = dev_open(tmpdev->devname, O_RDONLY);
if (dfd < 0 || if (dfd < 0 ||
st->ss->load_super(st, dfd, NULL)) st->ss->load_super(st, dfd, NULL))
tmpdev->used = 2; tmpdev->used = 2;
if (dfd > 0) close_fd(&dfd);
close(dfd);
} }
} }
/* Now reject spares that don't match domains of identified members */ /* Now reject spares that don't match domains of identified members */
for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) { for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
if (tmpdev->used != 3) if (tmpdev->used != 3)
continue; continue;
if (!stat_is_blkdev(tmpdev->devname, &rdev)) { if (!stat_is_blkdev(tmpdev->devname, &rdev)) {
tmpdev->used = 2; tmpdev->used = 2;
} else { } else {
skipping to change at line 581 skipping to change at line 641
int bestcnt = 0; int bestcnt = 0;
int *best = *bestp; int *best = *bestp;
struct supertype *st = *stp; struct supertype *st = *stp;
for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) { for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) {
char *devname = tmpdev->devname; char *devname = tmpdev->devname;
struct stat stb; struct stat stb;
struct supertype *tst; struct supertype *tst;
int i; int i;
int dfd; int dfd;
int disk_state;
if (tmpdev->used != 1) if (tmpdev->used != 1)
continue; continue;
/* looks like a good enough match to update the super block if ne eded */ /* looks like a good enough match to update the super block if ne eded */
if (c->update) { if (c->update) {
/* prepare useful information in info structures */ /* prepare useful information in info structures */
struct stat stb2; struct stat stb2;
int err; int err;
fstat(mdfd, &stb2); fstat(mdfd, &stb2);
skipping to change at line 714 skipping to change at line 775
pr_err("%s is identified as a member of %s, slot %d%s.\n" , pr_err("%s is identified as a member of %s, slot %d%s.\n" ,
devname, mddev, content->disk.raid_disk, devname, mddev, content->disk.raid_disk,
(content->disk.state & (1<<MD_DISK_REPLACEMENT)) ? " replacement":""); (content->disk.state & (1<<MD_DISK_REPLACEMENT)) ? " replacement":"");
devices[devcnt].devname = devname; devices[devcnt].devname = devname;
devices[devcnt].uptodate = 0; devices[devcnt].uptodate = 0;
devices[devcnt].included = (tmpdev->disposition == 'I'); devices[devcnt].included = (tmpdev->disposition == 'I');
devices[devcnt].i = *content; devices[devcnt].i = *content;
devices[devcnt].i.disk.major = major(stb.st_rdev); devices[devcnt].i.disk.major = major(stb.st_rdev);
devices[devcnt].i.disk.minor = minor(stb.st_rdev); devices[devcnt].i.disk.minor = minor(stb.st_rdev);
if (devices[devcnt].i.disk.state == 6) { disk_state = devices[devcnt].i.disk.state & ~((1<<MD_DISK_FAILFAS
T) |
(1<<MD_DISK_WRITEMO
STLY));
if (disk_state == ((1<<MD_DISK_ACTIVE) | (1<<MD_DISK_SYNC))) {
if (most_recent < 0 || if (most_recent < 0 ||
devices[devcnt].i.events devices[devcnt].i.events
> devices[most_recent].i.events) { > devices[most_recent].i.events) {
struct supertype *tmp = tst; struct supertype *tmp = tst;
tst = st; tst = st;
st = tmp; st = tmp;
most_recent = devcnt; most_recent = devcnt;
} }
} }
tst->ss->free_super(tst); tst->ss->free_super(tst);
skipping to change at line 879 skipping to change at line 942
if (chosen_drive < 0 || if (chosen_drive < 0 ||
devices[j].i.events devices[j].i.events
> devices[chosen_drive].i.events) > devices[chosen_drive].i.events)
chosen_drive = j; chosen_drive = j;
} }
if (chosen_drive < 0) if (chosen_drive < 0)
break; break;
current_events = devices[chosen_drive].i.events; current_events = devices[chosen_drive].i.events;
add_another: add_another:
if (c->verbose >= 0) if (c->verbose >= 0)
pr_err("forcing event count in %s(%d) from %d upto %d\n", pr_err("forcing event count in %s(%d) from %d up to %d\n" ,
devices[chosen_drive].devname, devices[chosen_drive].devname,
devices[chosen_drive].i.disk.raid_disk, devices[chosen_drive].i.disk.raid_disk,
(int)(devices[chosen_drive].i.events), (int)(devices[chosen_drive].i.events),
(int)(devices[most_recent].i.events)); (int)(devices[most_recent].i.events));
fd = dev_open(devices[chosen_drive].devname, fd = dev_open(devices[chosen_drive].devname,
devices[chosen_drive].included ? O_RDWR devices[chosen_drive].included ? O_RDWR
: (O_RDWR|O_EXCL)); : (O_RDWR|O_EXCL));
if (fd < 0) { if (fd < 0) {
pr_err("Couldn't open %s for write - not updating\n", pr_err("Couldn't open %s for write - not updating\n",
devices[chosen_drive].devname); devices[chosen_drive].devname);
skipping to change at line 1031 skipping to change at line 1094
if (dfd >= 0) { if (dfd >= 0) {
remove_partitions(dfd); remove_partitions(dfd);
close(dfd); close(dfd);
} }
rv = add_disk(mdfd, st, content, &devices[j].i); rv = add_disk(mdfd, st, content, &devices[j].i);
if (rv) { if (rv) {
pr_err("failed to add %s to %s: %s\n", pr_err("failed to add %s to %s: %s\n",
devices[j].devname, mddev, devices[j].devname, mddev,
strerror(errno)); strerror(errno));
if (errno == EINVAL && content->array.level == 0
&&
content->array.layout != 0) {
cont_err("Possibly your kernel doesn't su
pport RAID0 layouts.\n");
cont_err("Please upgrade.\n");
}
if (i < content->array.raid_disks * 2 || if (i < content->array.raid_disks * 2 ||
i == bestcnt) i == bestcnt)
okcnt--; okcnt--;
else else
sparecnt--; sparecnt--;
} else if (c->verbose > 0) { } else if (c->verbose > 0) {
pr_err("added %s to %s as %d%s%s\n", pr_err("added %s to %s as %d%s%s\n",
devices[j].devname, mddev, devices[j].devname, mddev,
devices[j].i.disk.raid_disk, devices[j].i.disk.raid_disk,
devices[j].uptodate?"": devices[j].uptodate?"":
skipping to change at line 1058 skipping to change at line 1126
pr_err("%s is already in %s as %d\n", pr_err("%s is already in %s as %d\n",
devices[j].devname, mddev, devices[j].devname, mddev,
devices[j].i.disk.raid_disk); devices[j].i.disk.raid_disk);
} else if (c->verbose > 0 && } else if (c->verbose > 0 &&
i < content->array.raid_disks * 2 && (i & 1) == 0) i < content->array.raid_disks * 2 && (i & 1) == 0)
pr_err("no uptodate device for slot %d of %s\n", pr_err("no uptodate device for slot %d of %s\n",
i/2, mddev); i/2, mddev);
} }
if (content->array.level == LEVEL_CONTAINER) { if (content->array.level == LEVEL_CONTAINER) {
sysfs_rules_apply(mddev, content);
if (c->verbose >= 0) { if (c->verbose >= 0) {
pr_err("Container %s has been assembled with %d drive%s", pr_err("Container %s has been assembled with %d drive%s",
mddev, okcnt + sparecnt + journalcnt, mddev, okcnt + sparecnt + journalcnt,
okcnt + sparecnt + journalcnt == 1 ? "" : "s"); okcnt + sparecnt + journalcnt == 1 ? "" : "s");
if (okcnt < (unsigned)content->array.raid_disks) if (okcnt < (unsigned)content->array.raid_disks)
fprintf(stderr, " (out of %d)", fprintf(stderr, " (out of %d)\n",
content->array.raid_disks); content->array.raid_disks);
fprintf(stderr, "\n"); else
fprintf(stderr, "\n");
} }
if (st->ss->validate_container) { if (st->ss->validate_container) {
struct mdinfo *devices_list; struct mdinfo *devices_list;
struct mdinfo *info_devices; struct mdinfo *info_devices;
unsigned int count; unsigned int count;
devices_list = NULL; devices_list = NULL;
info_devices = xmalloc(sizeof(struct mdinfo) * info_devices = xmalloc(sizeof(struct mdinfo) *
(okcnt + sparecnt)); (okcnt + sparecnt));
skipping to change at line 1139 skipping to change at line 1209
c->freeze_reshape); c->freeze_reshape);
} else if (c->readonly && } else if (c->readonly &&
sysfs_attribute_available(content, NULL, sysfs_attribute_available(content, NULL,
"array_state")) { "array_state")) {
rv = sysfs_set_str(content, NULL, rv = sysfs_set_str(content, NULL,
"array_state", "readonly"); "array_state", "readonly");
} else } else
rv = ioctl(mdfd, RUN_ARRAY, NULL); rv = ioctl(mdfd, RUN_ARRAY, NULL);
reopen_mddev(mdfd); /* drop O_EXCL */ reopen_mddev(mdfd); /* drop O_EXCL */
if (rv == 0) { if (rv == 0) {
sysfs_rules_apply(mddev, content);
if (c->verbose >= 0) { if (c->verbose >= 0) {
pr_err("%s has been started with %d drive%s", pr_err("%s has been started with %d drive%s",
mddev, okcnt, okcnt==1?"":"s"); mddev, okcnt, okcnt==1?"":"s");
if (okcnt < (unsigned)content->array.raid_disks) if (okcnt < (unsigned)content->array.raid_disks)
fprintf(stderr, " (out of %d)", fprintf(stderr, " (out of %d)",
content->array.raid_disks); content->array.raid_disks);
if (rebuilding_cnt) if (rebuilding_cnt)
fprintf(stderr, "%s %d rebuilding", fprintf(stderr, "%s %d rebuilding",
sparecnt?",":" and", sparecnt?",":" and",
rebuilding_cnt); rebuilding_cnt);
skipping to change at line 1216 skipping to change at line 1287
sra = sysfs_read(mdfd, NULL, 0); sra = sysfs_read(mdfd, NULL, 0);
if (sra) if (sra)
sysfs_set_str(sra, NULL, sysfs_set_str(sra, NULL,
"sync_action", "repair"); "sync_action", "repair");
sysfs_free(sra); sysfs_free(sra);
} }
return 0; return 0;
} }
pr_err("failed to RUN_ARRAY %s: %s\n", mddev, strerror(errno)); pr_err("failed to RUN_ARRAY %s: %s\n", mddev, strerror(errno));
if (errno == 524 /* ENOTSUP */ &&
content->array.level == 0 && content->array.layout == 0)
cont_err("Please use --update=layout-original or --update
=layout-alternate\n");
if (!enough(content->array.level, content->array.raid_disks, if (!enough(content->array.level, content->array.raid_disks,
content->array.layout, 1, avail)) content->array.layout, 1, avail))
pr_err("Not enough devices to start the array.\n"); pr_err("Not enough devices to start the array.\n");
else if (!enough(content->array.level, else if (!enough(content->array.level,
content->array.raid_disks, content->array.raid_disks,
content->array.layout, clean, avail)) content->array.layout, clean, avail))
pr_err("Not enough devices to start the array while not c lean - consider --force.\n"); pr_err("Not enough devices to start the array while not c lean - consider --force.\n");
return 1; return 1;
skipping to change at line 1470 skipping to change at line 1544
?: st->ss->match_home(st, "any")) { ?: st->ss->match_home(st, "any")) {
case 1: case 1:
trustworthy = LOCAL; trustworthy = LOCAL;
name = strchr(content->name, ':'); name = strchr(content->name, ':');
if (name) if (name)
name++; name++;
else else
name = content->name; name = content->name;
break; break;
} }
if (mddev && map_by_name(&map, mddev) != NULL) {
pr_err("Cannot create device with %s because is in use\n"
, mddev);
goto out;
}
if (!auto_assem) if (!auto_assem)
/* If the array is listed in mdadm.conf or on /* If the array is listed in mdadm.conf or on
* command line, then we trust the name * command line, then we trust the name
* even if the array doesn't look local * even if the array doesn't look local
*/ */
trustworthy = LOCAL; trustworthy = LOCAL;
if (name[0] == 0 && if (name[0] == 0 &&
content->array.level == LEVEL_CONTAINER) { content->array.level == LEVEL_CONTAINER) {
name = content->text_version; name = content->text_version;
skipping to change at line 1707 skipping to change at line 1785
continue; continue;
if (devices[j].i.disk.raid_disk == MD_DISK_ROLE_JOURNAL) if (devices[j].i.disk.raid_disk == MD_DISK_ROLE_JOURNAL)
desired_state = (1<<MD_DISK_JOURNAL); desired_state = (1<<MD_DISK_JOURNAL);
else if (i >= content->array.raid_disks * 2) else if (i >= content->array.raid_disks * 2)
desired_state = 0; desired_state = 0;
else if (i & 1) else if (i & 1)
desired_state = (1<<MD_DISK_ACTIVE) | (1<<MD_DISK_REPLACE MENT); desired_state = (1<<MD_DISK_ACTIVE) | (1<<MD_DISK_REPLACE MENT);
else else
desired_state = (1<<MD_DISK_ACTIVE) | (1<<MD_DISK_SYNC); desired_state = (1<<MD_DISK_ACTIVE) | (1<<MD_DISK_SYNC);
desired_state |= devices[j].i.disk.state & ((1<<MD_DISK_FAILFAST)
|
(1<<MD_DISK_WRITEMOST
LY));
if (!devices[j].uptodate) if (!devices[j].uptodate)
continue; continue;
devices[j].i.disk.state = desired_state; devices[j].i.disk.state = desired_state;
if (!(devices[j].i.array.state & 1)) if (!(devices[j].i.array.state & 1))
clean = 0; clean = 0;
if (st->ss->update_super(st, &devices[j].i, "assemble", NULL, if (st->ss->update_super(st, &devices[j].i, "assemble", NULL,
c->verbose, 0, NULL)) { c->verbose, 0, NULL)) {
if (c->force) { if (c->force) {
skipping to change at line 1892 skipping to change at line 1973
return 1; return 1;
} }
return rv == 2 ? 0 : rv; return rv == 2 ? 0 : rv;
} }
int assemble_container_content(struct supertype *st, int mdfd, int assemble_container_content(struct supertype *st, int mdfd,
struct mdinfo *content, struct context *c, struct mdinfo *content, struct context *c,
char *chosen_name, int *result) char *chosen_name, int *result)
{ {
struct mdinfo *dev, *sra, *dev2; struct mdinfo *dev, *sra, *dev2;
int working = 0, preexist = 0; struct assembly_array_info array = {chosen_name, 0, 0, 0};
int expansion = 0;
int old_raid_disks; int old_raid_disks;
int start_reshape; int start_reshape;
char *avail; char *avail;
int err; int err;
int is_raid456, is_clean, all_disks;
if (sysfs_init(content, mdfd, NULL)) { if (sysfs_init(content, mdfd, NULL)) {
pr_err("Unable to initialize sysfs\n"); pr_err("Unable to initialize sysfs\n");
return 1; return 1;
} }
sra = sysfs_read(mdfd, NULL, GET_VERSION|GET_DEVS); sra = sysfs_read(mdfd, NULL, GET_VERSION|GET_DEVS);
if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0) { if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0) {
if (content->array.major_version == -1 && if (content->array.major_version == -1 &&
content->array.minor_version == -2 && content->array.minor_version == -2 &&
skipping to change at line 1954 skipping to change at line 2035
sysfs_set_str(sra, dev2, "state", "remove"); sysfs_set_str(sra, dev2, "state", "remove");
} }
old_raid_disks = content->array.raid_disks - content->delta_disks; old_raid_disks = content->array.raid_disks - content->delta_disks;
avail = xcalloc(content->array.raid_disks, 1); avail = xcalloc(content->array.raid_disks, 1);
for (dev = content->devs; dev; dev = dev->next) { for (dev = content->devs; dev; dev = dev->next) {
if (dev->disk.raid_disk >= 0) if (dev->disk.raid_disk >= 0)
avail[dev->disk.raid_disk] = 1; avail[dev->disk.raid_disk] = 1;
if (sysfs_add_disk(content, dev, 1) == 0) { if (sysfs_add_disk(content, dev, 1) == 0) {
if (dev->disk.raid_disk >= old_raid_disks && if (dev->disk.raid_disk >= old_raid_disks &&
content->reshape_active) content->reshape_active)
expansion++; array.exp_cnt++;
else else
working++; array.new_cnt++;
} else if (errno == EEXIST) } else if (errno == EEXIST)
preexist++; array.preexist_cnt++;
} }
sysfs_free(sra); sysfs_free(sra);
if (working + expansion == 0 && c->runstop <= 0) {
free(avail); all_disks = array.new_cnt + array.exp_cnt + array.preexist_cnt;
return 1;/* Nothing new, don't try to start */
}
map_update(NULL, fd2devnm(mdfd), content->text_version, map_update(NULL, fd2devnm(mdfd), content->text_version,
content->uuid, chosen_name); content->uuid, chosen_name);
if (content->consistency_policy == CONSISTENCY_POLICY_PPL && if (content->consistency_policy == CONSISTENCY_POLICY_PPL &&
st->ss->validate_ppl) { st->ss->validate_ppl) {
content->array.state |= 1; content->array.state |= 1;
err = 0; err = 0;
for (dev = content->devs; dev; dev = dev->next) { for (dev = content->devs; dev; dev = dev->next) {
int dfd; int dfd;
skipping to change at line 2015 skipping to change at line 2095
close(dfd); close(dfd);
if (err) if (err)
break; break;
} }
if (err) { if (err) {
free(avail); free(avail);
return err; return err;
} }
} else if (c->force) {
/* Set the array as 'clean' so that we can proceed with starting
* it even if we don't have all devices. Mdmon doesn't care
* if the dirty flag is set in metadata, it will start managing
* it anyway.
* This is really important for raid456 (RWH case), other levels
* are started anyway.
*/
content->array.state |= 1;
} }
is_raid456 = (content->array.level >= 4 && content->array.level <= 6);
is_clean = content->array.state & 1;
if (enough(content->array.level, content->array.raid_disks, if (enough(content->array.level, content->array.raid_disks,
content->array.layout, content->array.state & 1, avail) == 0) content->array.layout, is_clean, avail) == 0) {
{ set_array_assembly_status(c, result, INCR_NO, &array);
if (c->export && result)
*result |= INCR_NO; if (c->verbose >= 0 && is_raid456 && !is_clean)
else if (c->verbose >= 0) { pr_err("Consider --force to start dirty degraded array\n"
pr_err("%s assembled with %d device%s", );
chosen_name, preexist + working,
preexist + working == 1 ? "":"s");
if (preexist)
fprintf(stderr, " (%d new)", working);
fprintf(stderr, " but not started\n");
}
free(avail); free(avail);
return 1; return 1;
} }
free(avail); free(avail);
if (c->runstop <= 0 && if (c->runstop <= 0 && all_disks < content->array.working_disks) {
(working + preexist + expansion) <
content->array.working_disks) { set_array_assembly_status(c, result, INCR_UNSAFE, &array);
if (c->export && result)
*result |= INCR_UNSAFE; if (c->verbose >= 0 && c->force)
else if (c->verbose >= 0) { pr_err("Consider --run to start array as degraded.\n");
pr_err("%s assembled with %d device%s",
chosen_name, preexist + working,
preexist + working == 1 ? "":"s");
if (preexist)
fprintf(stderr, " (%d new)", working);
fprintf(stderr, " but not safe to start\n");
}
return 1; return 1;
} }
if (is_raid456 && content->resync_start != MaxSector && c->force &&
all_disks < content->array.raid_disks) {
content->resync_start = MaxSector;
err = sysfs_set_num(content, NULL, "resync_start", MaxSector);
if (err)
return 1;
pr_err("%s array state forced to clean. It may cause data corrupt
ion.\n",
chosen_name);
}
/*
* Before activating the array, perform extra steps required
* to configure the internal write-intent bitmap.
*/
if (content->consistency_policy == CONSISTENCY_POLICY_BITMAP &&
st->ss->set_bitmap)
st->ss->set_bitmap(st, content);
if (start_reshape) { if (start_reshape) {
int spare = content->array.raid_disks + expansion; int spare = content->array.raid_disks + array.exp_cnt;
if (restore_backup(st, content, if (restore_backup(st, content,
working, array.new_cnt,
spare, &c->backup_file, c->verbose) == 1) spare, &c->backup_file, c->verbose) == 1)
return 1; return 1;
err = sysfs_set_str(content, NULL, if (content->reshape_progress == 0) {
"array_state", "readonly"); /* If reshape progress is 0 - we are assembling the
* array that was stopped, before reshape has started.
* Array needs to be started as active, Grow_continue()
* will start the reshape.
*/
sysfs_set_num(content, NULL, "reshape_position",
MaxSector);
err = sysfs_set_str(content, NULL,
"array_state", "active");
sysfs_set_num(content, NULL, "reshape_position", 0);
} else {
err = sysfs_set_str(content, NULL,
"array_state", "readonly");
}
if (err) if (err)
return 1; return 1;
if (st->ss->external) { if (st->ss->external) {
if (!mdmon_running(st->container_devnm)) if (!mdmon_running(st->container_devnm))
start_mdmon(st->container_devnm); start_mdmon(st->container_devnm);
ping_monitor(st->container_devnm); ping_monitor(st->container_devnm);
if (mdmon_running(st->container_devnm) && if (mdmon_running(st->container_devnm) &&
st->update_tail == NULL) st->update_tail == NULL)
st->update_tail = &st->updates; st->update_tail = &st->updates;
skipping to change at line 2102 skipping to change at line 2216
sysfs_set_safemode(content, content->safe_mode_delay); sysfs_set_safemode(content, content->safe_mode_delay);
/* Block subarray here if it is not reshaped now /* Block subarray here if it is not reshaped now
* It has be blocked a little later to allow mdmon to switch in * It has be blocked a little later to allow mdmon to switch in
* in to R/W state * in to R/W state
*/ */
if (st->ss->external && content->recovery_blocked && if (st->ss->external && content->recovery_blocked &&
!start_reshape) !start_reshape)
block_subarray(content); block_subarray(content);
if (c->export && result) { if (err)
if (err) set_array_assembly_status(c, result, INCR_NO, &array);
*result |= INCR_NO; else {
else set_array_assembly_status(c, result, INCR_YES, &array);
*result |= INCR_YES;
} else if (c->verbose >= 0) {
if (err)
pr_err("array %s now has %d device%s",
chosen_name, working + preexist,
working + preexist == 1 ? "":"s");
else
pr_err("Started %s with %d device%s",
chosen_name, working + preexist,
working + preexist == 1 ? "":"s");
if (preexist)
fprintf(stderr, " (%d new)", working);
if (expansion)
fprintf(stderr, " ( + %d for expansion)",
expansion);
fprintf(stderr, "\n");
}
if (!err)
wait_for(chosen_name, mdfd); wait_for(chosen_name, mdfd);
sysfs_rules_apply(chosen_name, content);
}
return err; return err;
/* FIXME should have an O_EXCL and wait for read-auto */ /* FIXME should have an O_EXCL and wait for read-auto */
} }
 End of changes. 32 change blocks. 
68 lines changed or deleted 176 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)