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