Dan Williams: Grow: fix hang when reshape completes too fast

Martin F. Krafft madduck at alioth.debian.org
Thu May 7 12:11:42 UTC 2009


Module: mdadm
Branch: debian/experimental
Commit: 48924014b02dd0e8046f58a4c6c9a2903a9b1dbd
URL:    http://git.debian.org/?p=pkg-mdadm/mdadm.git;a=commit;h=48924014b02dd0e8046f58a4c6c9a2903a9b1dbd

Author: Dan Williams <dan.j.williams at intel.com>
Date:   Sun Apr 12 00:58:28 2009 -0700

Grow: fix hang when reshape completes too fast

For short reshapes the kernel may be done before mdadm can check that
progress has passed the critical section.

Signed-off-by: Dan Williams <dan.j.williams at intel.com>





---

 Grow.c  |    8 ++++++++
 mdadm.h |    2 ++
 sysfs.c |   20 ++++++++++++++++++++
 3 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/Grow.c b/Grow.c
index 14e48f5..7083c18 100644
--- a/Grow.c
+++ b/Grow.c
@@ -809,12 +809,20 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
 		/* wait for reshape to pass the critical region */
 		while(1) {
 			unsigned long long comp;
+			char a[20];
+
 			if (sysfs_get_ll(sra, NULL, "sync_completed", &comp)<0) {
 				sleep(5);
 				break;
 			}
 			if (comp >= nstripe)
 				break;
+
+			/* perhaps the entire reshape has completed */
+			if (comp == 0 &&
+			    sysfs_get_str(sra, NULL, "sync_action", a, sizeof(a)) == 0 &&
+			    strncmp(a, "idle", 4) == 0)
+				break;
 			sleep(1);
 		}
 
diff --git a/mdadm.h b/mdadm.h
index c33ec24..82c7ded 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -372,6 +372,8 @@ extern int sysfs_set_num(struct mdinfo *sra, struct mdinfo *dev,
 extern int sysfs_uevent(struct mdinfo *sra, char *event);
 extern int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
 			char *name, unsigned long long *val);
+extern int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev,
+			 char *name, char *buf, int buf_len);
 extern int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms);
 extern int sysfs_set_array(struct mdinfo *info, int vers);
 extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd);
diff --git a/sysfs.c b/sysfs.c
index 48d1f54..31c92f7 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -466,6 +466,26 @@ int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
 	return 0;
 }
 
+int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev,
+		  char *name, char *buf, int buf_len)
+{
+	char fname[50];
+	int n;
+	int fd;
+
+	sprintf(fname, "/sys/block/%s/md/%s/%s",
+		sra->sys_name, dev?dev->sys_name:"", name);
+	fd = open(fname, O_RDONLY);
+	if (fd < 0)
+		return -1;
+	n = read(fd, buf, buf_len);
+	close(fd);
+	if (n <= 0)
+		return -1;
+	buf[n] = 0;
+	return 0;
+}
+
 int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms)
 {
 	unsigned long sec;




More information about the pkg-mdadm-commits mailing list