X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=Assemble.c;h=23d0b826f4304db1c5453cf09795b4ecf75579fe;hp=c5d28edc8da7f850562f27ab4ac9aedc50946ed0;hb=0f22b998fb9cf8478810b89cd50fa5b4fbf11d38;hpb=1538aca5cbbd99be47657e0ca0b7e2186426a1b1 diff --git a/Assemble.c b/Assemble.c index c5d28edc..23d0b826 100644 --- a/Assemble.c +++ b/Assemble.c @@ -146,11 +146,11 @@ int Assemble(struct supertype *st, char *mddev, struct mdinfo i; } *devices; int *best = NULL; /* indexed by raid_disk */ - unsigned int bestcnt = 0; + int bestcnt = 0; int devcnt = 0; unsigned int okcnt, sparecnt, rebuilding_cnt; unsigned int req_cnt; - unsigned int i; + int i; int most_recent = 0; int chosen_drive; int change = 0; @@ -182,7 +182,7 @@ int Assemble(struct supertype *st, char *mddev, if (!devlist && ident->uuid_set == 0 && - ident->super_minor < 0 && + (ident->super_minor < 0 || ident->super_minor == UnSet) && ident->name[0] == 0 && (ident->container == NULL || ident->member == NULL) && ident->devices == NULL) { @@ -262,8 +262,14 @@ int Assemble(struct supertype *st, char *mddev, tmpdev->used = 2; } else if (tst->ss->load_super(tst,dfd, NULL)) { if (report_missmatch) - fprintf( stderr, Name ": no RAID superblock on %s\n", - devname); + fprintf(stderr, Name ": no RAID superblock on %s\n", + devname); + } else if (tst->ss->compare_super == NULL) { + if (report_missmatch) + fprintf(stderr, Name ": Cannot assemble %s metadata on %s\n", + tst->ss->name, devname); + tst->ss->free_super(tst); + tmpdev->used = 2; } else if (auto_assem && st == NULL && !conf_test_metadata(tst->ss->name, tst->ss->match_home(tst, homehost) == 1)) { @@ -715,9 +721,9 @@ int Assemble(struct supertype *st, char *mddev, } if (i < 10000) { if (i >= bestcnt) { - unsigned int newbestcnt = i+10; + int newbestcnt = i+10; int *newbest = malloc(sizeof(int)*newbestcnt); - unsigned int c; + int c; for (c=0; c < newbestcnt; c++) if (c < bestcnt) newbest[c] = best[c]; @@ -784,7 +790,7 @@ int Assemble(struct supertype *st, char *mddev, okcnt = 0; sparecnt=0; rebuilding_cnt=0; - for (i=0; i< bestcnt ;i++) { + for (i=0; i< bestcnt; i++) { int j = best[i]; int event_margin = 1; /* always allow a difference of '1' * like the kernel does @@ -822,9 +828,9 @@ int Assemble(struct supertype *st, char *mddev, */ int fd; struct supertype *tst; - long long current_events; + unsigned long long current_events; chosen_drive = -1; - for (i=0; iarray.raid_disks && i < bestcnt; i++) { + for (i = 0; i < content->array.raid_disks && i < bestcnt; i++) { int j = best[i]; if (j>=0 && !devices[j].uptodate && @@ -882,7 +888,7 @@ int Assemble(struct supertype *st, char *mddev, /* If there are any other drives of the same vintage, * add them in as well. We can't lose and we might gain */ - for (i=0; iarray.raid_disks && i < bestcnt ; i++) { + for (i = 0; i < content->array.raid_disks && i < bestcnt ; i++) { int j = best[i]; if (j >= 0 && !devices[j].uptodate && @@ -1133,7 +1139,7 @@ int Assemble(struct supertype *st, char *mddev, fprintf(stderr, Name ": Container %s has been " "assembled with %d drive%s", mddev, okcnt+sparecnt, okcnt+sparecnt==1?"":"s"); - if (okcnt < content->array.raid_disks) + if (okcnt < (unsigned)content->array.raid_disks) fprintf(stderr, " (out of %d)", content->array.raid_disks); fprintf(stderr, "\n"); @@ -1167,7 +1173,7 @@ int Assemble(struct supertype *st, char *mddev, if (verbose >= 0) { fprintf(stderr, Name ": %s has been started with %d drive%s", mddev, okcnt, okcnt==1?"":"s"); - if (okcnt < content->array.raid_disks) + if (okcnt < (unsigned)content->array.raid_disks) fprintf(stderr, " (out of %d)", content->array.raid_disks); if (rebuilding_cnt) fprintf(stderr, "%s %d rebuilding", sparecnt?",":" and", rebuilding_cnt); @@ -1189,6 +1195,29 @@ int Assemble(struct supertype *st, char *mddev, (4 * content->array.chunk_size / 4096) + 1); } } + if (okcnt < (unsigned)content->array.raid_disks) { + /* If any devices did not get added + * because the kernel rejected them based + * on event count, try adding them + * again providing the action policy is + * 're-add' or greater. The bitmap + * might allow them to be included, or + * they will become spares. + */ + for (i = 0; i <= bestcnt; i++) { + int j = best[i]; + if (j >= 0 && !devices[j].uptodate) { + if (!disk_action_allows(&devices[j].i, st->ss->name, act_re_add)) + continue; + rv = add_disk(mdfd, st, content, + &devices[j].i); + if (rv == 0 && verbose >= 0) + fprintf(stderr, + Name ": %s has been re-added.\n", + devices[j].devname); + } + } + } wait_for(mddev, mdfd); close(mdfd); if (auto_assem) { @@ -1242,7 +1271,7 @@ int Assemble(struct supertype *st, char *mddev, if (runstop == -1) { fprintf(stderr, Name ": %s assembled from %d drive%s", mddev, okcnt, okcnt==1?"":"s"); - if (okcnt != content->array.raid_disks) + if (okcnt != (unsigned)content->array.raid_disks) fprintf(stderr, " (out of %d)", content->array.raid_disks); fprintf(stderr, ", but not started.\n"); close(mdfd); @@ -1265,7 +1294,7 @@ int Assemble(struct supertype *st, char *mddev, "array while not clean - consider " "--force.\n"); else { - if (req_cnt == content->array.raid_disks) + if (req_cnt == (unsigned)content->array.raid_disks) fprintf(stderr, " - need all %d to start it", req_cnt); else fprintf(stderr, " - need %d of %d to start", req_cnt, content->array.raid_disks);