[Cluster-devel] cluster/gfs2/tool util.c

rpeterso at sourceware.org rpeterso at sourceware.org
Tue Nov 6 20:23:59 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	cluster
Branch: 	RHEL5
Changes by:	rpeterso at sourceware.org	2007-11-06 20:23:59

Modified files:
	gfs2/tool      : util.c 

Log message:
	Resolves: bz 354201: GFS2: gfs2_tool: unknown mountpoint on some
	mount points

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/tool/util.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.5.2.1&r2=1.5.2.2

--- cluster/gfs2/tool/util.c	2007/10/25 14:14:47	1.5.2.1
+++ cluster/gfs2/tool/util.c	2007/11/06 20:23:59	1.5.2.2
@@ -27,6 +27,7 @@
 #include <libgen.h>
 #include <dirent.h>
 #include <string.h>
+#include <linux/kdev_t.h>
 
 #define __user
 #include <linux/gfs2_ondisk.h>
@@ -282,42 +283,6 @@
 	return name;
 }
 
-/* Iterate through gfs2 dirs looking for one where the "id"
-   attribute matches devname and return the associated fsname:
-   /sys/kernel/gfs2/<fsname>/fsname
-   /sys/kernel/gfs2/<fsname>/id
-
-   The "id" attribute is the superblock id (s_id) from the kernel.
-   It often matches the device node the fs was mounted from (as
-   displayed in /proc/mounts), but not always.  
-*/
-
-char *
-devname2fsname(char *devname)
-{
-	char *fsname = NULL;
-	DIR *d;
-	struct dirent *de;
-
-	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"), devname) == 0) {
-			fsname = strdup(de->d_name);
-			break;
-		}
-	}
-
-	closedir(d);
-
-	return fsname;
-}
-
 /* The fsname can be substituted for the mountpoint on the command line.
    This is necessary when we can't resolve a devname from /proc/mounts
    to a fsname. */
@@ -349,7 +314,20 @@
 
 /**
  * mp2fsname - Find the name for a filesystem given its mountpoint
- * @mp:
+ *
+ * We do this by iterating through gfs2 dirs in /sys/fs/gfs2/ looking for
+ * one where the "id" attribute matches the device id returned by stat for
+ * the mount point.  The reason we go through all this is simple: the
+ * kernel's sysfs is named after the VFS s_id, not the device name.
+ * So it's perfectly legal to do something like this to simulate user
+ * conditions without the proper hardware:
+ *    # rm /dev/sdb1
+ *    # mkdir /dev/cciss
+ *    # mknod /dev/cciss/c0d0p1 b 8 17
+ *    # mount -tgfs2 /dev/cciss/c0d0p1 /mnt/gfs2
+ *    # gfs2_tool gettune /mnt/gfs2
+ * In this example the tuning variables are in a directory named after the
+ * VFS s_id, which in this case would be /sys/fs/gfs2/sdb1/
  *
  * Returns: the fsname
  */
@@ -357,22 +335,35 @@
 char *
 mp2fsname(char *mp)
 {
-	char *devname = NULL, *fsname = NULL;
+	char device_id[PATH_MAX], *fsname = NULL;
+	struct stat statbuf;
+	DIR *d;
+	struct dirent *de;
 
-	devname = mp2devname(mp);
+	if (stat(mp, &statbuf))
+		return NULL;
+
+	memset(device_id, 0, sizeof(device_id));
+	sprintf(device_id, "%u:%u", (uint32_t)MAJOR(statbuf.st_dev),
+		(uint32_t)MINOR(statbuf.st_dev));
+
+	d = opendir(SYS_BASE);
+	if (!d)
+		die("can't open %s: %s\n", SYS_BASE, strerror(errno));
 
-	if (devname) {
-		fsname = devname2fsname(devname);
-		if (fsname)
-			return fsname;
-		die("unknown mountpoint %s, no fsname for %s\n", mp, devname);
-	} else {
-		if (is_fsname(mp))
-			return mp;
-		die("unknown mountpoint %s, no device found\n", mp);
+	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;
+		}
 	}
 
-	return NULL;
+	closedir(d);
+
+	return fsname;
 }
 
 /**




More information about the Cluster-devel mailing list