From: NeilBrown Date: Wed, 15 Dec 2010 22:07:51 +0000 (+1100) Subject: Grow: check container is idle before freezing it. X-Git-Tag: mdadm-3.2~179 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d7ca196cbda7ec5e6d2a3139a5545e3e0d57a67e;p=thirdparty%2Fmdadm.git Grow: check container is idle before freezing it. Before we freeze a container in preparation for growing a subarray, we need to be sure all the subarrays are idle. This test is racy as recovery could start at any moment following a failure. However it is still useful as it stops us from even trying to start a reshape while a reshape or recovery is active. Signed-off-by: NeilBrown --- diff --git a/Grow.c b/Grow.c index 222d755c..af605a86 100644 --- a/Grow.c +++ b/Grow.c @@ -467,17 +467,41 @@ static int child_same_size(int afd, struct mdinfo *sra, unsigned long blocks, int disks, int chunk, int level, int layout, int data, int dests, int *destfd, unsigned long long *destoffsets); +static int check_idle(struct supertype *st) +{ + /* Check that all member arrays for this container, or the + * container of this array, are idle + */ + int container_dev = (st->container_dev != NoMdDev + ? st->container_dev : st->devnum); + char container[40]; + struct mdstat_ent *ent, *e; + int is_idle = 1; + + fmt_devname(container, container_dev); + ent = mdstat_read(0, 0); + for (e = ent ; e; e = e->next) { + if (!is_container_member(e, container)) + continue; + if (e->percent >= 0) { + is_idle = 0; + break; + } + } + free_mdstat(ent); + return is_idle; +} + static int freeze_container(struct supertype *st) { int container_dev = (st->container_dev != NoMdDev ? st->container_dev : st->devnum); - char *container = devnum2devname(container_dev); + char container[40]; - if (!container) { - fprintf(stderr, Name - ": could not determine container name, freeze aborted\n"); - return -2; - } + if (!check_idle(st)) + return -1; + + fmt_devname(container, container_dev); if (block_monitor(container, 1)) { fprintf(stderr, Name ": failed to freeze container\n"); @@ -491,13 +515,9 @@ static void unfreeze_container(struct supertype *st) { int container_dev = (st->container_dev != NoMdDev ? st->container_dev : st->devnum); - char *container = devnum2devname(container_dev); - - if (!container) { - fprintf(stderr, Name - ": could not determine container name, unfreeze aborted\n"); - return; - } + char container[40]; + + fmt_devname(container, container_dev); unblock_monitor(container, 1); }