CVSROOT:        /cvs/cluster
Module name:    cluster
Branch:         RHEL5
Changes by:     [EMAIL PROTECTED]       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;
 }
 
 /**

Reply via email to