summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Assemble.c6
-rw-r--r--Grow.c75
-rw-r--r--mdadm.h2
3 files changed, 63 insertions, 20 deletions
diff --git a/Assemble.c b/Assemble.c
index 7c3a249..8423a81 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -963,6 +963,10 @@ int Assemble(struct supertype *st, char *mddev,
if (content->reshape_active) {
int err = 0;
int *fdlist = malloc(sizeof(int)* bestcnt);
+ if (verbose)
+ fprintf(stderr, Name ":%s has an active reshape - checking "
+ "if critical section needs to be restored\n",
+ chosen_name);
for (i=0; i<bestcnt; i++) {
int j = best[i];
if (j >= 0) {
@@ -977,7 +981,7 @@ int Assemble(struct supertype *st, char *mddev,
fdlist[i] = -1;
}
if (!err)
- err = Grow_restart(st, content, fdlist, bestcnt, backup_file);
+ err = Grow_restart(st, content, fdlist, bestcnt, backup_file, verbose);
while (i>0) {
i--;
if (fdlist[i]>=0) close(fdlist[i]);
diff --git a/Grow.c b/Grow.c
index 554649a..4bd77d9 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1538,7 +1538,8 @@ static int child_same_size(int afd, struct mdinfo *sra, unsigned long stripes,
* write that data into the array and update the super blocks with
* the new reshape_progress
*/
-int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt, char *backup_file)
+int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt,
+ char *backup_file, int verbose)
{
int i, j;
int old_disks;
@@ -1566,6 +1567,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
char buf[4096];
int fd;
int bsbsize;
+ char *devname, namebuf[20];
/* This was a spare and may have some saved data on it.
* Load the superblock, find and load the
@@ -1581,6 +1583,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
backup_file, strerror(errno));
continue;
}
+ devname = backup_file;
} else {
fd = fdlist[i];
if (fd < 0)
@@ -1593,37 +1596,63 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
if (lseek64(fd,
(dinfo.data_offset + dinfo.component_size - 8) <<9,
- 0) < 0)
+ 0) < 0) {
+ fprintf(stderr, Name ": Cannot seek on device %d\n", i);
continue; /* Cannot seek */
+ }
+ sprintf(namebuf, "device-%d", i);
+ devname = namebuf;
}
- if (read(fd, &bsb, sizeof(bsb)) != sizeof(bsb))
+ if (read(fd, &bsb, sizeof(bsb)) != sizeof(bsb)) {
+ if (verbose)
+ fprintf(stderr, Name ": Cannot read from %s\n", devname);
continue; /* Cannot read */
+ }
if (memcmp(bsb.magic, "md_backup_data-1", 16) != 0 &&
- memcmp(bsb.magic, "md_backup_data-2", 16) != 0)
+ memcmp(bsb.magic, "md_backup_data-2", 16) != 0) {
+ if (verbose)
+ fprintf(stderr, Name ": No backup metadata on %s\n", devname);
continue;
- if (bsb.sb_csum != bsb_csum((char*)&bsb, ((char*)&bsb.sb_csum)-((char*)&bsb)))
+ }
+ if (bsb.sb_csum != bsb_csum((char*)&bsb, ((char*)&bsb.sb_csum)-((char*)&bsb))) {
+ if (verbose)
+ fprintf(stderr, Name ": Bad backup-metadata checksum on %s\n", devname);
continue; /* bad checksum */
+ }
if (memcmp(bsb.magic, "md_backup_data-2", 16) == 0 &&
- bsb.sb_csum2 != bsb_csum((char*)&bsb, ((char*)&bsb.sb_csum2)-((char*)&bsb)))
+ bsb.sb_csum2 != bsb_csum((char*)&bsb, ((char*)&bsb.sb_csum2)-((char*)&bsb))) {
+ if (verbose)
+ fprintf(stderr, Name ": Bad backup-metadata checksum2 on %s\n", devname);
continue; /* Bad second checksum */
- if (memcmp(bsb.set_uuid,info->uuid, 16) != 0)
+ }
+ if (memcmp(bsb.set_uuid,info->uuid, 16) != 0) {
+ if (verbose)
+ fprintf(stderr, Name ": Wrong uuid on backup-metadata on %s\n", devname);
continue; /* Wrong uuid */
+ }
if (info->array.utime > __le64_to_cpu(bsb.mtime) + 3600 ||
- info->array.utime < __le64_to_cpu(bsb.mtime))
+ info->array.utime < __le64_to_cpu(bsb.mtime)) {
+ if (verbose)
+ fprintf(stderr, Name ": too-old timestamp on backup-metadata on %s\n", devname);
continue; /* time stamp is too bad */
+ }
if (bsb.magic[15] == '1') {
if (info->delta_disks >= 0) {
/* reshape_progress is increasing */
if (__le64_to_cpu(bsb.arraystart) + __le64_to_cpu(bsb.length) <
- info->reshape_progress)
+ info->reshape_progress) {
+ nonew:
+ if (verbose)
+ fprintf(stderr, Name ": backup-metadata found on %s but is not needed\n", devname);
continue; /* No new data here */
+ }
} else {
/* reshape_progress is decreasing */
if (__le64_to_cpu(bsb.arraystart) >=
info->reshape_progress)
- continue; /* No new data here */
+ goto nonew; /* No new data here */
}
} else {
if (info->delta_disks >= 0) {
@@ -1632,28 +1661,33 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
info->reshape_progress &&
__le64_to_cpu(bsb.arraystart2) + __le64_to_cpu(bsb.length2) <
info->reshape_progress)
- continue; /* No new data here */
+ goto nonew; /* No new data here */
} else {
/* reshape_progress is decreasing */
if (__le64_to_cpu(bsb.arraystart) >=
info->reshape_progress &&
__le64_to_cpu(bsb.arraystart2) >=
info->reshape_progress)
- continue; /* No new data here */
+ goto nonew; /* No new data here */
}
}
- if (lseek64(fd, __le64_to_cpu(bsb.devstart)*512, 0)< 0)
+ if (lseek64(fd, __le64_to_cpu(bsb.devstart)*512, 0)< 0) {
+ second_fail:
+ if (verbose)
+ fprintf(stderr, Name ": Failed to verify secondary backup-metadata block on %s\n",
+ devname);
continue; /* Cannot seek */
+ }
/* There should be a duplicate backup superblock 4k before here */
if (lseek64(fd, -4096, 1) < 0 ||
read(fd, buf, 4096) != 4096)
- continue; /* Cannot find leading superblock */
+ goto second_fail; /* Cannot find leading superblock */
if (bsb.magic[15] == '1')
bsbsize = offsetof(struct mdp_backup_super, pad1);
else
bsbsize = offsetof(struct mdp_backup_super, pad);
if (memcmp(buf, &bsb, bsbsize) != 0)
- continue; /* Cannot find leading superblock */
+ goto second_fail; /* Cannot find leading superblock */
/* Now need the data offsets for all devices. */
offsets = malloc(sizeof(*offsets)*info->array.raid_disks);
@@ -1678,6 +1712,9 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
__le64_to_cpu(bsb.arraystart),
__le64_to_cpu(bsb.length)*512)) {
/* didn't succeed, so giveup */
+ if (verbose)
+ fprintf(stderr, Name ": Error restoring backup from %s\n",
+ devname);
return 1;
}
@@ -1692,6 +1729,9 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
__le64_to_cpu(bsb.arraystart2),
__le64_to_cpu(bsb.length2)*512)) {
/* didn't succeed, so giveup */
+ if (verbose)
+ fprintf(stderr, Name ": Error restoring second backup from %s\n",
+ devname);
return 1;
}
@@ -1732,9 +1772,6 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
/* Didn't find any backup data, try to see if any
* was needed.
*/
- if (info->delta_disks == 0)
- /* Alway need backup data when size doesn't change */
- return 1;
if (info->delta_disks < 0) {
/* When shrinking, the critical section is at the end.
* So see if we are before the critical section.
@@ -1768,6 +1805,8 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
return 0;
}
/* needed to recover critical section! */
+ if (verbose)
+ fprintf(stderr, Name ": Failed to find backup of critical section\n");
return 1;
}
diff --git a/mdadm.h b/mdadm.h
index 74a1b71..2b8370c 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -717,7 +717,7 @@ extern int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
long long size,
int level, char *layout_str, int chunksize, int raid_disks);
extern int Grow_restart(struct supertype *st, struct mdinfo *info,
- int *fdlist, int cnt, char *backup_file);
+ int *fdlist, int cnt, char *backup_file, int verbose);
extern int Grow_continue(int mdfd, struct supertype *st,
struct mdinfo *info, char *backup_file);