[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