cluster: STABLE3 - fsck.gfs2: Use fsck.ext3's method of dealing with root mounts

Bob Peterson rpeterso at fedoraproject.org
Thu Feb 11 15:17:16 UTC 2010


Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=04f7da379c163876eb346f3828de0ff152e25f5a
Commit:        04f7da379c163876eb346f3828de0ff152e25f5a
Parent:        369493ab6772a1d2f657f964ea72f2d8bb3ea854
Author:        Bob Peterson <rpeterso at redhat.com>
AuthorDate:    Thu Feb 11 09:14:14 2010 -0600
Committer:     Bob Peterson <rpeterso at redhat.com>
CommitterDate: Thu Feb 11 09:14:14 2010 -0600

fsck.gfs2: Use fsck.ext3's method of dealing with root mounts

This patch scraps the old way of determining if a gfs2 file
system is mounted and does it the way fsck.ext3 does.

rhbz#557128
---
 gfs2/libgfs2/libgfs2.h |    1 +
 gfs2/libgfs2/misc.c    |  114 +++++++++++++++++++++++++++++------------------
 2 files changed, 71 insertions(+), 44 deletions(-)

diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index d89194c..6aa9e2d 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -599,6 +599,7 @@ extern int compute_heightsize(struct gfs2_sbd *sdp, uint64_t *heightsize,
 		uint32_t *maxheight, uint32_t bsize1, int diptrs, int inptrs);
 extern int compute_constants(struct gfs2_sbd *sdp);
 extern int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount);
+extern int is_gfs2(struct gfs2_sbd *sdp);
 extern int find_gfs2_meta(struct gfs2_sbd *sdp);
 extern int dir_exists(const char *dir);
 extern int check_for_gfs2(struct gfs2_sbd *sdp);
diff --git a/gfs2/libgfs2/misc.c b/gfs2/libgfs2/misc.c
index 5ccdab4..ffa0dba 100644
--- a/gfs2/libgfs2/misc.c
+++ b/gfs2/libgfs2/misc.c
@@ -15,6 +15,7 @@
 #include <dirent.h>
 #include <linux/kdev_t.h>
 #include <sys/sysmacros.h>
+#include <mntent.h>
 
 #include "libgfs2.h"
 
@@ -99,58 +100,81 @@ int compute_constants(struct gfs2_sbd *sdp)
 int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount)
 {
 	FILE *fp;
-	char buffer[PATH_MAX];
-	char fstype[80];
-	int fsdump, fspass, ret;
-	char fspath[PATH_MAX];
-	char fsoptions[PATH_MAX];
-	char *realname;
+	struct mntent *mnt;
+	dev_t file_dev=0, file_rdev=0;
+	ino_t file_ino=0;
+	struct stat st_buf;
 
 	*ro_mount = 0;
-	realname = realpath(sdp->path_name, NULL);
-	if (!realname)
+	if ((fp = setmntent("/proc/mounts", "r")) == NULL) {
+		perror("open: /proc/mounts");
 		return 0;
-	fp = fopen("/proc/mounts", "r");
-	if (fp == NULL) {
-		free(realname);
+	}
+	if (stat(sdp->path_name, &st_buf) == 0) {
+		if (S_ISBLK(st_buf.st_mode)) {
+#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
+			file_rdev = st_buf.st_rdev;
+#endif  /* __GNU__ */
+		} else {
+			file_dev = st_buf.st_dev;
+			file_ino = st_buf.st_ino;
+		}
+	}
+	while ((mnt = getmntent (fp)) != NULL) {
+		/* Check if they specified the device instead of mnt point */
+		if (strcmp(sdp->device_name, mnt->mnt_fsname) == 0) {
+			strcpy(sdp->path_name, mnt->mnt_dir); /* fix it */
+			break;
+		}
+		if (strcmp(sdp->path_name, mnt->mnt_dir) == 0) {
+			strcpy(sdp->device_name, mnt->mnt_fsname); /* fix it */
+			break;
+		}
+		if (stat(mnt->mnt_fsname, &st_buf) == 0) {
+			if (S_ISBLK(st_buf.st_mode)) {
+#ifndef __GNU__
+				if (file_rdev && (file_rdev == st_buf.st_rdev))
+					break;
+#endif  /* __GNU__ */
+			} else {
+				if (file_dev && ((file_dev == st_buf.st_dev) &&
+						 (file_ino == st_buf.st_ino)))
+					break;
+			}
+		}
+	}
+	endmntent (fp);
+	if (mnt == NULL)
 		return 0;
+	if (stat(mnt->mnt_dir, &st_buf) < 0) {
+		if (errno == ENOENT)
+			return 0;
 	}
-	while ((fgets(buffer, PATH_MAX - 1, fp)) != NULL) {
-		buffer[PATH_MAX - 1] = 0;
-
-		if (strstr(buffer, "0") == 0)
-			continue;
-
-		ret = sscanf(buffer, "%s %s %s %s %d %d", sdp->device_name,
-				fspath, fstype, fsoptions, &fsdump, &fspass);
-		if (6 != ret)
-			continue;
-
-		if (strcmp(fstype, "gfs2") != 0)
-			continue;
+	/* Can't trust fstype because / has "rootfs". */
+	if (file_rdev && (st_buf.st_dev != file_rdev))
+		return 0;
+	if (hasmntopt(mnt, MNTOPT_RO))
+               *ro_mount = 1;
+	return 1; /* mounted */
+}
 
-		/* Check if they specified the device instead of mnt point */
-		if (strcmp(sdp->device_name, realname) == 0)
-			strcpy(sdp->path_name, fspath); /* fix it */
-		else if (strcmp(fspath, realname) != 0)
-			continue;
+int is_gfs2(struct gfs2_sbd *sdp)
+{
+	int fd, rc;
+	struct gfs2_sb sb;
 
-		if (strncmp(fsoptions, "ro,", 3) == 0 ||
-		    strcmp(fsoptions, "ro") == 0)
-			*ro_mount = 1;
-		fclose(fp);
-		free(realname);
-		if (strncmp(sdp->device_name, "/dev/loop", 9) == 0) {
-			errno = EINVAL;
-			return 0;
-		}
+	fd = open(sdp->device_name, O_RDWR);
+	if (fd < 0)
+		return 0;
 
-		return 1;
-	}
-	free(realname);
-	fclose(fp);
-	errno = EINVAL;
-	return 0;
+	rc = 0;
+	if (lseek(fd, GFS2_SB_ADDR * GFS2_BASIC_BLOCK, SEEK_SET) >= 0 &&
+	    read(fd, &sb, sizeof(sb)) == sizeof(sb) &&
+	    be32_to_cpu(sb.sb_header.mh_magic) == GFS2_MAGIC &&
+	    be32_to_cpu(sb.sb_header.mh_type) == GFS2_METATYPE_SB)
+		rc = 1;
+	close(fd);
+	return rc;
 }
 
 int check_for_gfs2(struct gfs2_sbd *sdp)
@@ -159,6 +183,8 @@ int check_for_gfs2(struct gfs2_sbd *sdp)
 
 	if (!is_pathname_mounted(sdp, &ro))
 		return -1;
+	if (!is_gfs2(sdp))
+		return -1;
 	return 0;
 }
 


More information about the cluster-commits mailing list