X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=Grow.c;h=62c67d04fe4881e277c6d3208dd8945e0ff3b922;hb=ecdbb368f8ce8bdb710d124c9b5b5e021474a77d;hp=efa8c47271439743ab53521ec1bb1994f78bb990;hpb=39bbb392022d7d3008a0695755ced84fa49d2231;p=thirdparty%2Fmdadm.git diff --git a/Grow.c b/Grow.c index efa8c472..62c67d04 100644 --- a/Grow.c +++ b/Grow.c @@ -573,7 +573,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file, goto release; } ioctl(fd, GET_ARRAY_INFO, &array); - size = get_component_size(fd); + size = get_component_size(fd)/2; if (size == 0) size = array.size; if (!quiet) @@ -581,7 +581,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file, devname, size); changed = 1; } else { - size = get_component_size(fd); + size = get_component_size(fd)/2; if (size == 0) size = array.size; } @@ -1096,7 +1096,10 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file, /* set them all just in case some old 'new_*' value * persists from some earlier problem */ - int err; + int err = err; /* only used if rv==1, and always set if + * rv==1, so initialisation not needed, + * despite gcc warning + */ if (sysfs_set_num(sra, NULL, "chunk_size", nchunk) < 0) rv = 1, err = errno; if (!rv && sysfs_set_num(sra, NULL, "layout", nlayout) < 0) @@ -1251,6 +1254,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file, * */ +/* FIXME return status is never checked */ int grow_backup(struct mdinfo *sra, unsigned long long offset, /* per device */ unsigned long stripes, /* per device */ @@ -1333,16 +1337,16 @@ int grow_backup(struct mdinfo *sra, bsb.sb_csum2 = bsb_csum((char*)&bsb, ((char*)&bsb.sb_csum2)-((char*)&bsb)); - lseek64(destfd[i], destoffsets[i] - 4096, 0); - write(destfd[i], &bsb, 512); + rv |= lseek64(destfd[i], destoffsets[i] - 4096, 0); + rv = rv ?: write(destfd[i], &bsb, 512); if (destoffsets[i] > 4096) { - lseek64(destfd[i], destoffsets[i]+stripes*chunk*odata, 0); - write(destfd[i], &bsb, 512); + rv |= lseek64(destfd[i], destoffsets[i]+stripes*chunk*odata, 0); + rv = rv ?: write(destfd[i], &bsb, 512); } fsync(destfd[i]); } - return 0; + return rv; } /* in 2.6.30, the value reported by sync_completed can be @@ -1355,6 +1359,7 @@ int grow_backup(struct mdinfo *sra, * The various caller give appropriate values so that * every works. */ +/* FIXME return value is often ignored */ int wait_backup(struct mdinfo *sra, unsigned long long offset, /* per device */ unsigned long long blocks, /* per device */ @@ -1368,6 +1373,7 @@ int wait_backup(struct mdinfo *sra, int fd = sysfs_get_fd(sra, NULL, "sync_completed"); unsigned long long completed; int i; + int rv; if (fd < 0) return -1; @@ -1399,24 +1405,26 @@ int wait_backup(struct mdinfo *sra, bsb.length = __cpu_to_le64(0); } bsb.mtime = __cpu_to_le64(time(0)); + rv = 0; for (i = 0; i < dests; i++) { bsb.devstart = __cpu_to_le64(destoffsets[i]/512); bsb.sb_csum = bsb_csum((char*)&bsb, ((char*)&bsb.sb_csum)-((char*)&bsb)); if (memcmp(bsb.magic, "md_backup_data-2", 16) == 0) bsb.sb_csum2 = bsb_csum((char*)&bsb, ((char*)&bsb.sb_csum2)-((char*)&bsb)); - lseek64(destfd[i], destoffsets[i]-4096, 0); - write(destfd[i], &bsb, 512); + rv |= lseek64(destfd[i], destoffsets[i]-4096, 0); + rv = rv ?: write(destfd[i], &bsb, 512); fsync(destfd[i]); } - return 0; + return rv; } static void fail(char *msg) { - write(2, msg, strlen(msg)); - write(2, "\n", 1); - exit(1); + int rv; + rv = write(2, msg, strlen(msg)); + rv |= write(2, "\n", 1); + exit(rv ? 1 : 2); } static char *abuf, *bbuf; @@ -1452,8 +1460,12 @@ static void validate(int afd, int bfd, unsigned long long offset) free(abuf); free(bbuf); abuflen = len; - posix_memalign((void**)&abuf, 4096, abuflen); - posix_memalign((void**)&bbuf, 4096, abuflen); + if (posix_memalign((void**)&abuf, 4096, abuflen) || + posix_memalign((void**)&bbuf, 4096, abuflen)) { + abuflen = 0; + /* just stop validating on mem-alloc failure */ + return; + } } lseek64(bfd, offset, 0); @@ -1508,7 +1520,9 @@ static int child_grow(int afd, struct mdinfo *sra, unsigned long stripes, char *buf; int degraded = 0; - posix_memalign((void**)&buf, 4096, disks * chunk); + if (posix_memalign((void**)&buf, 4096, disks * chunk)) + /* Don't start the 'reshape' */ + return 0; sysfs_set_num(sra, NULL, "suspend_hi", 0); sysfs_set_num(sra, NULL, "suspend_lo", 0); grow_backup(sra, 0, stripes, @@ -1536,7 +1550,8 @@ static int child_shrink(int afd, struct mdinfo *sra, unsigned long stripes, int rv; int degraded = 0; - posix_memalign((void**)&buf, 4096, disks * chunk); + if (posix_memalign((void**)&buf, 4096, disks * chunk)) + return 0; start = sra->component_size - stripes * chunk/512; sysfs_set_num(sra, NULL, "sync_max", start); sysfs_set_str(sra, NULL, "sync_action", "reshape"); @@ -1575,7 +1590,8 @@ static int child_same_size(int afd, struct mdinfo *sra, unsigned long stripes, int degraded = 0; - posix_memalign((void**)&buf, 4096, disks * chunk); + if (posix_memalign((void**)&buf, 4096, disks * chunk)) + return 0; sysfs_set_num(sra, NULL, "suspend_lo", 0); sysfs_set_num(sra, NULL, "suspend_hi", 0); @@ -1727,11 +1743,23 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt continue; /* Wrong uuid */ } - if (info->array.utime > __le64_to_cpu(bsb.mtime) + 10*60 || + /* array utime and backup-mtime should be updated at much the same time, but it seems that + * sometimes they aren't... So allow considerable flexability in matching, and allow + * this test to be overridden by an environment variable. + */ + if (info->array.utime > __le64_to_cpu(bsb.mtime) + 2*60*60 || info->array.utime < __le64_to_cpu(bsb.mtime) - 10*60) { - if (verbose) - fprintf(stderr, Name ": too-old timestamp on backup-metadata on %s\n", devname); - continue; /* time stamp is too bad */ + if (check_env("MDADM_GROW_ALLOW_OLD")) { + fprintf(stderr, Name ": accepting backup with timestamp %lu " + "for array with timestamp %lu\n", + (unsigned long)__le64_to_cpu(bsb.mtime), + (unsigned long)info->array.utime); + } else { + 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') {