On Thu, 29 Sep 2011 17:53:45 +0200 Adam Kwolek <adam.kwolek@xxxxxxxxx> wrote: > When reshape is started in container on single array, all other container > members are blocked from monitoring also. After container reassembly > we have to construct the same situation. > Currently array under reshape is blocked only. > > To block whole container during reshape we have 2 cases: > 1. first assembled array is not reshaped and second is under reshape > 2. first assembled array not reshaped and second is not under reshape > > This patch addresses first case. > If current array is under reshape, block it. Second not reshaped array > will be blocked if container has any blocked array. This feels like the wrong approach. The metadata for the container should "know" if a reshape is pending and so rebuilt monitoring should be disabled. So I think we could just arrange that "struct mdinfo" has some flag which says "recovery-blocked". And we block based on that. That feels a lot more robust that looking through /sys for the other parts of the array. Could you try that please? Thanks, NeilBrown > > Signed-off-by: Adam Kwolek <adam.kwolek@xxxxxxxxx> > --- > > Assemble.c | 19 +++++++++++++++++-- > Grow.c | 28 ++++++++++++++++++++++++++++ > mdadm.h | 2 ++ > msg.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > msg.h | 1 + > 5 files changed, 100 insertions(+), 2 deletions(-) > > diff --git a/Assemble.c b/Assemble.c > index c6aad20..59ce650 100644 > --- a/Assemble.c > +++ b/Assemble.c > @@ -1526,8 +1526,23 @@ int assemble_container_content(struct supertype *st, int mdfd, > if (sysfs_set_array(content, md_get_version(mdfd)) != 0) > return 1; > > - if (content->reshape_active) > - block_subarray(content); > + > + if (st->ss->external) { > + if (content->reshape_active) { > + /* Current array in container is under reshape > + * block it from monitoring > + */ > + block_subarray(content); > + } else { > + /* If any previously assembled array is under reshape > + * currently assembled array have to be blocked before > + * array activation also. > + * Check if any array in container is blocked > + * and do the same for this one. > + */ > + block_array_if_any_is_blocked(st, content); > + } > + } > > if (sra) > sysfs_free(sra); > diff --git a/Grow.c b/Grow.c > index 4a25165..3e13c8f 100644 > --- a/Grow.c > +++ b/Grow.c > @@ -539,6 +539,34 @@ static int check_idle(struct supertype *st) > return is_idle; > } > > +/* Block currently assembed array if any array in container > + * is blocked. > + * Function has to be used during container assembly > + * to make sure that all arrays in container are blocked > + * if one is under reshape. > + * This restores situation when reshape is started when > + * all container components are blocked. > + */ > +int block_array_if_any_is_blocked(struct supertype *st, struct mdinfo *content) > +{ > + int container_dev = (st->container_dev != NoMdDev > + ? st->container_dev : st->devnum); > + char buf[1024]; > + > + fmt_devname(buf, container_dev); > + > + if (check_blocked_monitor(buf) > 0) { > + if (sysfs_get_str(content, NULL, "metadata_version", > + buf, 1024) > 0) { > + buf[9] = '-'; > + sysfs_set_str(content, NULL, "metadata_version", buf); > + } > + } > + > + return 1; > +} > + > + > static int freeze_container(struct supertype *st) > { > int container_dev = (st->container_dev != NoMdDev > diff --git a/mdadm.h b/mdadm.h > index 8dd37d9..d0ffd4d 100644 > --- a/mdadm.h > +++ b/mdadm.h > @@ -477,6 +477,8 @@ extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume); > extern int sysfs_disk_to_scsi_id(int fd, __u32 *id); > extern int sysfs_unique_holder(int devnum, long rdev); > extern int sysfs_freeze_array(struct mdinfo *sra); > +extern int block_array_if_any_is_blocked(struct supertype *st, > + struct mdinfo *content); > extern int load_sys(char *path, char *buf); > extern int reshape_prepare_fdlist(char *devname, > struct mdinfo *sra, > diff --git a/msg.c b/msg.c > index 98d6d13..f903afb 100644 > --- a/msg.c > +++ b/msg.c > @@ -424,6 +424,58 @@ int block_monitor(char *container, const int freeze) > return rv; > } > > +/* Function checks if any container member or container itself > + * is blocked (mdmon is blocked). > + * It can occur that during assembly process first array in container > + * is under reshape, this means that any activated array > + * has to be blocked also, to keep whole container blocked > + * Returns: > + * -1: error > + * 0: not blocked > + * 1: something is blocked > + */ > +int check_blocked_monitor(char *container) > +{ > + struct mdstat_ent *ent, *e; > + struct mdinfo *sra = NULL; > + int rv = 0; > + > + if (check_mdmon_version(container)) > + return -1; > + > + ent = mdstat_read(0, 0); > + if (!ent) { > + fprintf(stderr, Name > + ": failed to read /proc/mdstat while checking" > + " if mdmon is disabled\n"); > + return -1; > + } > + > + /* check if any container member is frozen */ > + for (e = ent; e; e = e->next) { > + if (!is_container_member(e, container)) > + continue; > + sysfs_free(sra); > + sra = sysfs_read(-1, e->devnum, GET_VERSION); > + if (!sra) { > + fprintf(stderr, Name > + ": failed to read sysfs for subarray%s\n", > + to_subarray(e, container)); > + break; > + } > + /* check frozen state */ > + if (sra->text_version[0] == '-') { > + rv = 1; > + break; > + } > + } > + > + sysfs_free(sra); > + free_mdstat(ent); > + > + return rv; > +} > + > void unblock_monitor(char *container, const int unfreeze) > { > struct mdstat_ent *ent, *e; > diff --git a/msg.h b/msg.h > index c6d037d..fb5815e 100644 > --- a/msg.h > +++ b/msg.h > @@ -32,6 +32,7 @@ extern int block_subarray(struct mdinfo *sra); > extern int unblock_subarray(struct mdinfo *sra, const int unfreeze); > extern int block_monitor(char *container, const int freeze); > extern void unblock_monitor(char *container, const int unfreeze); > +extern int check_blocked_monitor(char *container); > extern int fping_monitor(int sock); > extern int ping_manager(char *devname); >
Attachment:
signature.asc
Description: PGP signature