diff options
author | NeilBrown <neilb@suse.de> | 2010-01-28 11:48:03 +1100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2010-01-28 11:48:03 +1100 |
commit | 39bbb392022d7d3008a0695755ced84fa49d2231 (patch) | |
tree | 9ed8d94adda753e04c7f90f5f98f6b082dfb8cba /Grow.c | |
parent | 9f22b13fe1726f3ac4da423a3e56441590c28d9f (diff) | |
download | mdadm-39bbb392022d7d3008a0695755ced84fa49d2231.tar.gz mdadm-39bbb392022d7d3008a0695755ced84fa49d2231.tar.xz mdadm-39bbb392022d7d3008a0695755ced84fa49d2231.zip |
Grow: If bitmap interferes with grow, report this.
If a bitmap exists on an array, then current kernels cannot grow
that array.
So when we try to grow an array, test for EBUSY and if a bitmap is
present, report that the bitmap needs to be removed.
Resolves-Debian-Bug: 534571
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Grow.c')
-rw-r--r-- | Grow.c | 35 |
1 files changed, 28 insertions, 7 deletions
@@ -563,8 +563,12 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file, } else rv = ioctl(fd, SET_ARRAY_INFO, &array); if (rv != 0) { + int err = errno; fprintf(stderr, Name ": Cannot set device size for %s: %s\n", - devname, strerror(errno)); + devname, strerror(err)); + if (err == EBUSY && + (array.state & (1<<MD_SB_BITMAP_PRESENT))) + fprintf(stderr, " Bitmap must be removed before size can be changed\n"); rv = 1; goto release; } @@ -666,8 +670,12 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file, } err = sysfs_set_str(sra, NULL, "level", c); if (err) { + err = errno; fprintf(stderr, Name ": %s: could not set level to %s\n", devname, c); + if (err == EBUSY && + (array.state & (1<<MD_SB_BITMAP_PRESENT))) + fprintf(stderr, " Bitmap must be removed before level can be changed\n"); rv = 1; goto release; } @@ -733,9 +741,14 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file, c = map_num(pers, level); if (c) { rv = sysfs_set_str(sra, NULL, "level", c); - if (rv) + if (rv) { + int err = errno; fprintf(stderr, Name ": %s: could not set level to %s\n", devname, c); + if (err == EBUSY && + (array.state & (1<<MD_SB_BITMAP_PRESENT))) + fprintf(stderr, " Bitmap must be removed before level can be changed\n"); + } } } else if (!changed && !quiet) fprintf(stderr, Name ": %s: no change requested\n", @@ -1066,12 +1079,16 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file, if (ochunk == nchunk && olayout == nlayout) { array.raid_disks = ndisks; if (ioctl(fd, SET_ARRAY_INFO, &array) != 0) { + int err = errno; rv = 1; fprintf(stderr, Name ": Cannot set device shape for %s: %s\n", devname, strerror(errno)); if (ndisks < odisks && get_linux_version() < 2006030) fprintf(stderr, Name ": linux 2.6.30 or later required\n"); + if (err == EBUSY && + (array.state & (1<<MD_SB_BITMAP_PRESENT))) + fprintf(stderr, " Bitmap must be removed before shape can be changed\n"); break; } @@ -1079,17 +1096,21 @@ 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; if (sysfs_set_num(sra, NULL, "chunk_size", nchunk) < 0) - rv = 1; - if (sysfs_set_num(sra, NULL, "layout", nlayout) < 0) - rv = 1; - if (sysfs_set_num(sra, NULL, "raid_disks", ndisks) < 0) - rv = 1; + rv = 1, err = errno; + if (!rv && sysfs_set_num(sra, NULL, "layout", nlayout) < 0) + rv = 1, err = errno; + if (!rv && sysfs_set_num(sra, NULL, "raid_disks", ndisks) < 0) + rv = 1, err = errno; if (rv) { fprintf(stderr, Name ": Cannot set device shape for %s\n", devname); if (get_linux_version() < 2006030) fprintf(stderr, Name ": linux 2.6.30 or later required\n"); + if (err == EBUSY && + (array.state & (1<<MD_SB_BITMAP_PRESENT))) + fprintf(stderr, " Bitmap must be removed before shape can be changed\n"); break; } } |