public inbox for cluster-cvs@sourceware.org
help / color / mirror / Atom feed
* cluster: RHEL5 - gfs2_tool, libgfs2: bz487608 - GFS2: gfs2_tool unfreeze hangs
@ 2009-03-12 11:43 Abhijith Das
  0 siblings, 0 replies; only message in thread
From: Abhijith Das @ 2009-03-12 11:43 UTC (permalink / raw)
  To: cluster-cvs-relay

Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=fe446f510da67d6e2ff9bbbaf7fc86f82c0e881f
Commit:        fe446f510da67d6e2ff9bbbaf7fc86f82c0e881f
Parent:        992658141fa495d902715fdba44f74dcbca8c8c8
Author:        Abhijith Das <adas@redhat.com>
AuthorDate:    Thu Mar 12 04:32:26 2009 -0500
Committer:     Abhijith Das <adas@redhat.com>
CommitterDate: Thu Mar 12 04:32:26 2009 -0500

gfs2_tool, libgfs2: bz487608 - GFS2: gfs2_tool unfreeze hangs

gfs2_tool tries to stat() the mountpoint in order to get to the device number
and ultimately get to the sysfs freeze tunable.

When the filesystem is frozen, followed by another process holding an exclusive
lock on the mountpoint (eg. touch creating a new file in root dir), gfs2_tool
hangs behind this lock at the stat() call.

This patch makes freeze/unfreeze stat the block device instead of the
mountpoint.

Signed-off-by: Abhijith Das <adas@redhat.com>
---
 gfs2/libgfs2/libgfs2.h |    1 +
 gfs2/libgfs2/misc.c    |   77 ++++++++++++++++++++++++++++++++++++++++++++++++
 gfs2/tool/misc.c       |    2 +-
 3 files changed, 79 insertions(+), 1 deletions(-)

diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 44205a9..9b05d0a 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -660,6 +660,7 @@ char *get_list(void);
 char **str2lines(char *str);
 char *find_debugfs_mount(void);
 char *mp2fsname(char *mp);
+char *mp2fsname2(char *devname);
 char *name2value(char *str, char *name);
 uint32_t name2u32(char *str, char *name);
 uint64_t name2u64(char *str, char *name);
diff --git a/gfs2/libgfs2/misc.c b/gfs2/libgfs2/misc.c
index 1bdbc0f..7b6b1d1 100644
--- a/gfs2/libgfs2/misc.c
+++ b/gfs2/libgfs2/misc.c
@@ -634,6 +634,83 @@ mp2fsname(char *mp)
 	return fsname;
 }
 
+/*
+ * Same as mp2fsname, except that this function doesn't stat() the mountpoint
+ * to get the device no. Used by gfs2_tool freeze/unfreeze where we don't want
+ * to touch the potetially frozen filesytem and hang gfs2_tool itself.
+ */
+char *
+mp2fsname2(char *mp)
+{
+	char device_id[PATH_MAX], *fsname = NULL;
+	struct stat statbuf;
+	DIR *d;
+	struct dirent *de;
+	struct gfs2_sbd sb;
+	FILE *fp = fopen("/proc/mounts", "r");
+	char buffer[PATH_MAX], device_name[PATH_MAX];
+	int fsdump, fspass, ret, found = 0;
+	char fspath[PATH_MAX], fsoptions[PATH_MAX], fstype[80];
+
+	/* Take care of trailing '/' */
+	if (mp[strlen(mp) - 1] == '/')
+		mp[strlen(mp) - 1] = 0;
+
+	if (fp == NULL) {
+		perror("open: /proc/mounts");
+		exit(EXIT_FAILURE);
+	}
+
+	while ((fgets(buffer, PATH_MAX - 1, fp)) != NULL) {
+		buffer[PATH_MAX - 1] = 0;
+		if (strstr(buffer, "0") == 0)
+			continue;
+
+		if ((ret = sscanf(buffer, "%s %s %s %s %d %d",
+				  device_name, fspath,
+				  fstype, fsoptions, &fsdump, &fspass)) != 6)
+			continue;
+
+		if (strcmp(fstype, "gfs2") != 0)
+			continue;
+
+		if (strcmp(fspath, mp) != 0)
+			continue;
+
+		found = 1;
+		break;
+	}
+
+	if (!found)
+		die("can't find gfs2 filesystem mounted at %s\n", mp);
+
+	if (stat(device_name, &statbuf))
+		return NULL;
+
+	memset(device_id, 0, sizeof(device_id));
+	sprintf(device_id, "%u:%u", (uint32_t)MAJOR(statbuf.st_rdev),
+		(uint32_t)MINOR(statbuf.st_rdev));
+
+	d = opendir(SYS_BASE);
+	if (!d)
+		die("can't open %s: %s\n", SYS_BASE, strerror(errno));
+
+	while ((de = readdir(d))) {
+		if (de->d_name[0] == '.')
+			continue;
+
+		if (strcmp(get_sysfs(de->d_name, "id"), device_id) == 0) {
+			fsname = strdup(de->d_name);
+			break;
+		}
+	}
+
+	fclose(fp);
+	closedir(d);
+
+	return fsname;
+}
+
 /**
  * name2value - find the value of a name-value pair in a string
  * @str_in:
diff --git a/gfs2/tool/misc.c b/gfs2/tool/misc.c
index 152a9b4..103df2f 100644
--- a/gfs2/tool/misc.c
+++ b/gfs2/tool/misc.c
@@ -91,7 +91,7 @@ do_freeze(int argc, char **argv)
 	if (optind == argc)
 		die("Usage: gfs2_tool %s <mountpoint>\n", command);
 
-	name = mp2fsname(argv[optind]);
+	name = mp2fsname2(argv[optind]);
 
 	if (strcmp(command, "freeze") == 0)
 		set_sysfs(name, "freeze", "1");


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2009-03-12 11:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-12 11:43 cluster: RHEL5 - gfs2_tool, libgfs2: bz487608 - GFS2: gfs2_tool unfreeze hangs Abhijith Das

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).