All of lore.kernel.org
 help / color / mirror / Atom feed
* [Cluster-devel] [PATCH 1/5] fsck.gfs2: Fix memory leaks in pass1_process_rgrp
@ 2015-02-23 18:43 Andrew Price
  2015-02-23 18:43 ` [Cluster-devel] [PATCH 2/5] libgfs2: Use the correct parent for rgrp tree insertion Andrew Price
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Andrew Price @ 2015-02-23 18:43 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Spotted by coverity: "Variable ibuf going out of scope leaks the storage
it points to"

Signed-off-by: Andrew Price <anprice@redhat.com>
---
 gfs2/fsck/pass1.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index b516a21..69c88f4 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1625,7 +1625,10 @@ static int pass1_process_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgd)
 {
 	unsigned k, n, i;
 	uint64_t *ibuf = malloc(sdp->bsize * GFS2_NBBY * sizeof(uint64_t));
-	int ret;
+	int ret = 0;
+
+	if (ibuf == NULL)
+		return FSCK_ERROR;
 
 	for (k = 0; k < rgd->ri.ri_length; k++) {
 		n = lgfs2_bm_scan(rgd, k, ibuf, GFS2_BLKST_DINODE);
@@ -1633,11 +1636,11 @@ static int pass1_process_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgd)
 		if (n) {
 			ret = pass1_process_bitmap(sdp, rgd, ibuf, n);
 			if (ret)
-				return ret;
+				goto out;
 		}
 
 		if (fsck_abort)
-			return 0;
+			goto out;
 		/*
 		  For GFS1, we have to count the "free meta" blocks in the
 		  resource group and mark them specially so we can count them
@@ -1650,12 +1653,13 @@ static int pass1_process_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgd)
 		for (i = 0; i < n; i++) {
 			gfs2_blockmap_set(bl, ibuf[i], GFS2_BLKST_UNLINKED);
 			if (fsck_abort)
-				return 0;
+				goto out;
 		}
 	}
 
+out:
 	free(ibuf);
-	return 0;
+	return ret;
 }
 
 /**
-- 
1.9.3



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Cluster-devel] [PATCH 2/5] libgfs2: Use the correct parent for rgrp tree insertion
  2015-02-23 18:43 [Cluster-devel] [PATCH 1/5] fsck.gfs2: Fix memory leaks in pass1_process_rgrp Andrew Price
@ 2015-02-23 18:43 ` Andrew Price
  2015-02-23 18:43 ` [Cluster-devel] [PATCH 3/5] libgfs2: Remove some obsolete function declarations Andrew Price
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Andrew Price @ 2015-02-23 18:43 UTC (permalink / raw)
  To: cluster-devel.redhat.com

lgfs2_rgrps_append() was using the parent of the last rgrp instead of
the last rgrp itself as the intended parent when inserting new rgrps
into the tree. This left the tree unbalanced in such a way as to make
lookups of the last node in the tree effectively a linear list search.
This was done for each rgrp insertion so, although it didn't cause a
noticeable slow-down for smaller file sytems, tests on 250TB volumes
requiring over a million resource groups would become CPU bound and
could take hours to complete.

This patch fixes lgfs2_rgrps_append() to use the correct parent node for
rgrp tree insertions, giving a significant performance improvement when
creating file systems on large volumes.

Resolves: rhbz#1194446

Signed-off-by: Andrew Price <anprice@redhat.com>
---
 gfs2/libgfs2/rgrp.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index ed8e01d..cf4385a 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -539,9 +539,9 @@ struct osi_node *lgfs2_rgrps_root(lgfs2_rgrps_t rgs)
 lgfs2_rgrp_t lgfs2_rgrps_append(lgfs2_rgrps_t rgs, struct gfs2_rindex *entry)
 {
 	lgfs2_rgrp_t rg;
-	lgfs2_rgrp_t lastrg = (lgfs2_rgrp_t)osi_last(&rgs->root);
 	struct osi_node **link = &rgs->root.osi_node;
-	struct osi_node *parent = NULL;
+	struct osi_node *parent = osi_last(&rgs->root);
+	lgfs2_rgrp_t lastrg = (lgfs2_rgrp_t)parent;
 
 	errno = EINVAL;
 	if (entry == NULL)
@@ -550,7 +550,6 @@ lgfs2_rgrp_t lgfs2_rgrps_append(lgfs2_rgrps_t rgs, struct gfs2_rindex *entry)
 	if (lastrg != NULL) { /* Tree is not empty */
 		if (entry->ri_addr <= lastrg->ri.ri_addr)
 			return NULL; /* Appending with a lower address doesn't make sense */
-		parent = osi_parent(&lastrg->node);
 		link = &lastrg->node.osi_right;
 	}
 
-- 
1.9.3



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Cluster-devel] [PATCH 3/5] libgfs2: Remove some obsolete function declarations
  2015-02-23 18:43 [Cluster-devel] [PATCH 1/5] fsck.gfs2: Fix memory leaks in pass1_process_rgrp Andrew Price
  2015-02-23 18:43 ` [Cluster-devel] [PATCH 2/5] libgfs2: Use the correct parent for rgrp tree insertion Andrew Price
@ 2015-02-23 18:43 ` Andrew Price
  2015-02-23 18:43 ` [Cluster-devel] [PATCH 4/5] gfs2-utils: Move metafs handling into gfs2/mkfs/ Andrew Price
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Andrew Price @ 2015-02-23 18:43 UTC (permalink / raw)
  To: cluster-devel.redhat.com

These functions no longer exist or never existed so there's no need to
declare them in libgfs2.h

Signed-off-by: Andrew Price <anprice@redhat.com>
---
 gfs2/libgfs2/libgfs2.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 2907e8c..4d1e540 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -674,11 +674,8 @@ extern int compute_constants(struct gfs2_sbd *sdp);
 extern int lgfs2_open_mnt(const char *path, int dirflags, int *dirfd, int devflags, int *devfd, struct mntent **mnt);
 extern int lgfs2_open_mnt_dev(const char *path, int flags, struct mntent **mnt);
 extern int lgfs2_open_mnt_dir(const char *path, int flags, struct mntent **mnt);
-extern int find_gfs2_meta(struct gfs2_sbd *sdp);
-extern int dir_exists(const char *dir);
 extern int mount_gfs2_meta(struct gfs2_sbd *sdp, const char *path);
 extern void cleanup_metafs(struct gfs2_sbd *sdp);
-extern int is_fsname(char *name);
 
 /* recovery.c */
 extern void gfs2_replay_incr_blk(struct gfs2_inode *ip, unsigned int *blk);
-- 
1.9.3



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Cluster-devel] [PATCH 4/5] gfs2-utils: Move metafs handling into gfs2/mkfs/
  2015-02-23 18:43 [Cluster-devel] [PATCH 1/5] fsck.gfs2: Fix memory leaks in pass1_process_rgrp Andrew Price
  2015-02-23 18:43 ` [Cluster-devel] [PATCH 2/5] libgfs2: Use the correct parent for rgrp tree insertion Andrew Price
  2015-02-23 18:43 ` [Cluster-devel] [PATCH 3/5] libgfs2: Remove some obsolete function declarations Andrew Price
@ 2015-02-23 18:43 ` Andrew Price
  2015-02-23 18:43 ` [Cluster-devel] [PATCH 5/5] gfs2_grow/jadd: Use a matching context mount option in mount_gfs2_meta Andrew Price
  2015-02-23 19:17 ` [Cluster-devel] [PATCH 1/5] fsck.gfs2: Fix memory leaks in pass1_process_rgrp Bob Peterson
  4 siblings, 0 replies; 6+ messages in thread
From: Andrew Price @ 2015-02-23 18:43 UTC (permalink / raw)
  To: cluster-devel.redhat.com

gfs2_grow and gfs2_jadd are the two remaining mounters of the metafs so
move the high-level metafs mounting bits from libgfs2/misc.c into the
mkfs directory and give them a suitable interface.

This allows the metafs-related fields to be removed from struct gfs2_sbd
and the metafs_interrupted flag and the signal handling functions
exported by libgfs2 to be pushed down into the applications.

Signed-off-by: Andrew Price <anprice@redhat.com>
---
 gfs2/libgfs2/libgfs2.h |   7 ---
 gfs2/libgfs2/misc.c    | 111 ----------------------------------------------
 gfs2/mkfs/Makefile.am  |   6 +--
 gfs2/mkfs/main_grow.c  |  10 +++--
 gfs2/mkfs/main_jadd.c  |  40 +++++++++--------
 gfs2/mkfs/metafs.c     | 118 +++++++++++++++++++++++++++++++++++++++++++++++++
 gfs2/mkfs/metafs.h     |  14 ++++++
 7 files changed, 163 insertions(+), 143 deletions(-)
 create mode 100644 gfs2/mkfs/metafs.c
 create mode 100644 gfs2/mkfs/metafs.h

diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 4d1e540..374d774 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -324,8 +324,6 @@ struct gfs2_sbd {
 	struct gfs2_inode *master_dir;
 	struct master_dir md;
 
-	int metafs_fd;
-	char *metafs_path; /* where metafs is mounted */
 	struct special_blocks eattr_blocks;
 
 	uint64_t rg_one_length;
@@ -665,17 +663,12 @@ extern void gfs_rgrp_in(struct gfs_rgrp *rg, struct gfs2_buffer_head *bh);
 extern void gfs_rgrp_out(struct gfs_rgrp *rg, struct gfs2_buffer_head *bh);
 
 /* misc.c */
-
-extern int metafs_interrupted;
-
 extern int compute_heightsize(unsigned bsize, uint64_t *heightsize,
 		uint32_t *maxheight, uint32_t bsize1, int diptrs, int inptrs);
 extern int compute_constants(struct gfs2_sbd *sdp);
 extern int lgfs2_open_mnt(const char *path, int dirflags, int *dirfd, int devflags, int *devfd, struct mntent **mnt);
 extern int lgfs2_open_mnt_dev(const char *path, int flags, struct mntent **mnt);
 extern int lgfs2_open_mnt_dir(const char *path, int flags, struct mntent **mnt);
-extern int mount_gfs2_meta(struct gfs2_sbd *sdp, const char *path);
-extern void cleanup_metafs(struct gfs2_sbd *sdp);
 
 /* recovery.c */
 extern void gfs2_replay_incr_blk(struct gfs2_inode *ip, unsigned int *blk);
diff --git a/gfs2/libgfs2/misc.c b/gfs2/libgfs2/misc.c
index c72af55..cb2a231 100644
--- a/gfs2/libgfs2/misc.c
+++ b/gfs2/libgfs2/misc.c
@@ -1,32 +1,17 @@
 #include "clusterautoconfig.h"
 
-#include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
-#include <stdint.h>
 #include <inttypes.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <time.h>
-#include <errno.h>
-#include <sys/mount.h>
-#include <linux/types.h>
-#include <sys/file.h>
-#include <dirent.h>
-#include <sys/sysmacros.h>
-#include <mntent.h>
-#include <signal.h>
 
 #include "libgfs2.h"
-#include "config.h"
 
 #define PAGE_SIZE (4096)
 #define DIV_RU(x, y) (((x) + (y) - 1) / (y))
 
-int metafs_interrupted = 0;
-
 int compute_heightsize(unsigned bsize, uint64_t *heightsize,
 	uint32_t *maxheight, uint32_t bsize1, int diptrs, int inptrs)
 {
@@ -197,99 +182,3 @@ int lgfs2_open_mnt_dir(const char *path, int flags, struct mntent **mnt)
 		close(devfd);
 	return dirfd;
 }
-
-static int lock_for_admin(struct gfs2_sbd *sdp)
-{
-	int error;
-
-	if (cfg_debug)
-		printf("\nTrying to get admin lock...\n");
-
-	sdp->metafs_fd = open(sdp->metafs_path, O_RDONLY | O_NOFOLLOW);
-	if (sdp->metafs_fd < 0)
-		return -1;
-
-	error = flock(sdp->metafs_fd, LOCK_EX);
-	if (error) {
-		close(sdp->metafs_fd);
-		return -1;
-	}
-	if (cfg_debug)
-		printf("Got it.\n");
-	return 0;
-}
-
-static void sighandler(int error)
-{
-	metafs_interrupted = 1;
-}
-
-static void setsigs(void (*handler)(int))
-{
-	struct sigaction sa = {	.sa_handler = handler };
-
-	sigaction(SIGINT, &sa, NULL);
-	sigaction(SIGILL, &sa, NULL);
-	sigaction(SIGTERM, &sa, NULL);
-	sigaction(SIGHUP, &sa, NULL);
-	sigaction(SIGABRT, &sa, NULL);
-	sigaction(SIGCONT, &sa, NULL);
-	sigaction(SIGUSR1, &sa, NULL);
-	sigaction(SIGUSR2, &sa, NULL);
-}
-
-int mount_gfs2_meta(struct gfs2_sbd *sdp, const char *path)
-{
-	int ret;
-
-	sdp->metafs_path = strdup("/tmp/.gfs2meta.XXXXXX");
-	if (sdp->metafs_path == NULL)
-		return -1;
-
-	if(!mkdtemp(sdp->metafs_path))
-		goto err_free;
-
-	setsigs(sighandler);
-
-	ret = mount(path, sdp->metafs_path, "gfs2meta", 0, NULL);
-	if (ret)
-		goto err_rmdir;
-
-	if (lock_for_admin(sdp))
-		goto err_umount;
-
-	return 0;
-
-err_umount:
-	if (umount(sdp->metafs_path))
-		fprintf(stderr, "Could not unmount %s: %s\n", sdp->metafs_path, strerror(errno));
-	setsigs(SIG_DFL);
-err_rmdir:
-	rmdir(sdp->metafs_path);
-err_free:
-	free(sdp->metafs_path);
-	sdp->metafs_path = NULL;
-	return -1;
-}
-
-void cleanup_metafs(struct gfs2_sbd *sdp)
-{
-	int ret;
-
-	if (sdp->metafs_fd <= 0)
-		return;
-
-	fsync(sdp->metafs_fd);
-	close(sdp->metafs_fd);
-	ret = umount(sdp->metafs_path);
-	if (ret)
-		fprintf(stderr, "Couldn't unmount %s : %s\n",
-			sdp->metafs_path, strerror(errno));
-	else
-		rmdir(sdp->metafs_path);
-
-	setsigs(SIG_DFL);
-	metafs_interrupted = 0;
-	free(sdp->metafs_path);
-	sdp->metafs_path = NULL;
-}
diff --git a/gfs2/mkfs/Makefile.am b/gfs2/mkfs/Makefile.am
index 822b41e..475f1a8 100644
--- a/gfs2/mkfs/Makefile.am
+++ b/gfs2/mkfs/Makefile.am
@@ -9,7 +9,7 @@ COMMON_CPPFLAGS = \
 
 sbin_PROGRAMS = mkfs.gfs2 gfs2_jadd gfs2_grow
 
-noinst_HEADERS = gfs2_mkfs.h
+noinst_HEADERS = gfs2_mkfs.h metafs.h
 
 mkfs_gfs2_SOURCES = main_mkfs.c
 mkfs_gfs2_CPPFLAGS = $(COMMON_CPPFLAGS)
@@ -17,13 +17,13 @@ mkfs_gfs2_CFLAGS = $(blkid_CFLAGS)
 mkfs_gfs2_LDFLAGS = $(blkid_LIBS)
 mkfs_gfs2_LDADD	= $(top_builddir)/gfs2/libgfs2/libgfs2.la
 
-gfs2_grow_SOURCES = main_grow.c
+gfs2_grow_SOURCES = main_grow.c metafs.c
 gfs2_grow_CPPFLAGS = $(COMMON_CPPFLAGS)
 gfs2_grow_CFLAGS = $(blkid_CFLAGS)
 gfs2_grow_LDFLAGS = $(blkid_LIBS)
 gfs2_grow_LDADD = $(top_builddir)/gfs2/libgfs2/libgfs2.la
 
-gfs2_jadd_SOURCES = main_jadd.c
+gfs2_jadd_SOURCES = main_jadd.c metafs.c
 gfs2_jadd_CPPFLAGS = $(COMMON_CPPFLAGS)
 gfs2_jadd_LDADD = $(top_builddir)/gfs2/libgfs2/libgfs2.la
 
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index 3ab8e72..c3ae4b7 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -27,6 +27,7 @@
 #include <logging.h>
 #include "libgfs2.h"
 #include "gfs2_mkfs.h"
+#include "metafs.h"
 
 #define BUF_SIZE 4096
 #define MB (1024 * 1024)
@@ -359,6 +360,7 @@ int main(int argc, char *argv[])
 	decode_arguments(argc, argv, sdp);
 	
 	for(; (argc - optind) > 0; optind++) {
+		struct metafs mfs = {0};
 		struct mntent *mnt;
 		unsigned rgcount;
 		unsigned old_rg_count;
@@ -394,13 +396,13 @@ int main(int argc, char *argv[])
 			exit(EXIT_FAILURE);
 		}
 		fix_device_geometry(sdp);
-		if (mount_gfs2_meta(sdp, mnt->mnt_dir)) {
+		if (mount_gfs2_meta(&mfs, mnt->mnt_dir, (print_level > MSG_NOTICE))) {
 			perror(_("Failed to mount GFS2 meta file system"));
 			exit(EXIT_FAILURE);
 		}
-		rindex_fd = open_rindex(sdp->metafs_path, (test ? O_RDONLY : O_RDWR));
+		rindex_fd = open_rindex(mfs.path, (test ? O_RDONLY : O_RDWR));
 		if (rindex_fd < 0) {
-			cleanup_metafs(sdp);
+			cleanup_metafs(&mfs);
 			exit(EXIT_FAILURE);
 		}
 		/* Get master dinode */
@@ -456,7 +458,7 @@ int main(int argc, char *argv[])
 	out:
 		lgfs2_rgrps_free(&rgs);
 		close(rindex_fd);
-		cleanup_metafs(sdp);
+		cleanup_metafs(&mfs);
 		close(sdp->device_fd);
 
 		if (metafs_interrupted)
diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c
index fea474a..d83ec2b 100644
--- a/gfs2/mkfs/main_jadd.c
+++ b/gfs2/mkfs/main_jadd.c
@@ -24,6 +24,7 @@
 #include <linux/types.h>
 #include "libgfs2.h"
 #include "gfs2_mkfs.h"
+#include "metafs.h"
 
 #define RANDOM(values) ((values) * (random() / (RAND_MAX + 1.0)))
 
@@ -38,25 +39,26 @@ struct jadd_opts {
 	unsigned debug:1;
 };
 
-static void
-make_jdata(int fd, const char *value)
+#define JA_FL_SET   0
+#define JA_FL_CLEAR 1
+static void set_flags(int fd, int op, uint32_t flags)
 {
         int err;
-        uint32_t val;
+	uint32_t val;
 
         err = ioctl(fd, FS_IOC_GETFLAGS, &val);
-        if (err){
+        if (err) {
 		perror("GETFLAGS");
 		exit(EXIT_FAILURE);
 	}
 
-        if (strcmp(value, "set") == 0)
-                val |= FS_JOURNAL_DATA_FL;
-        if (strcmp(value, "clear") == 0)
-                val &= ~FS_JOURNAL_DATA_FL;
-        err = ioctl(fd, FS_IOC_SETFLAGS, &val);
+        if (op == JA_FL_SET)
+                val |= flags;
+        else if (op == JA_FL_CLEAR)
+                val &= ~flags;
 
-        if (err){
+        err = ioctl(fd, FS_IOC_SETFLAGS, &val);
+        if (err) {
 		perror("SETFLAGS");
 		exit(EXIT_FAILURE);
 	}
@@ -272,7 +274,8 @@ static void add_ir(struct jadd_opts *opts)
 
 	{
 		struct gfs2_inum_range ir;
-		make_jdata(fd, "set");
+
+		set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL);
 		memset(&ir, 0, sizeof(struct gfs2_inum_range));
 		if (write(fd, (void*)&ir, sizeof(struct gfs2_inum_range)) !=
 		    sizeof(struct gfs2_inum_range)) {
@@ -301,7 +304,7 @@ static void add_sc(struct jadd_opts *opts)
 
 	{
 		struct gfs2_statfs_change sc;
-		make_jdata(fd, "set");
+		set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL);
 
 		memset(&sc, 0, sizeof(struct gfs2_statfs_change));
 		if (write(fd, (void*)&sc, sizeof(struct gfs2_statfs_change)) !=
@@ -338,7 +341,7 @@ static void add_qc(struct gfs2_sbd *sdp, struct jadd_opts *opts)
 		struct gfs2_buffer_head dummy_bh;
 
 		dummy_bh.b_data = buf;
-		make_jdata(fd, "clear");
+		set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL);
 		memset(buf, 0, sdp->bsize);
 
 		for (x=0; x<blocks; x++) {
@@ -433,7 +436,7 @@ static void add_j(struct gfs2_sbd *sdp, struct jadd_opts *opts)
 		struct gfs2_log_header lh;
 		uint64_t seq = RANDOM(blocks);
 
-		make_jdata(fd, "clear");
+		set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL);
 		memset(buf, 0, sdp->bsize);
 		for (x=0; x<blocks; x++) {
 			if (write(fd, buf, sdp->bsize) != sdp->bsize) {
@@ -491,6 +494,7 @@ int main(int argc, char *argv[])
 {
 	struct jadd_opts opts = {0};
 	struct gfs2_sbd sbd, *sdp = &sbd;
+	struct metafs mfs = {0};
 	struct mntent *mnt;
 	unsigned int total;
 
@@ -517,12 +521,12 @@ int main(int argc, char *argv[])
 	}
 	gather_info(sdp, &opts);
 
-	if (mount_gfs2_meta(sdp, mnt->mnt_dir)) {
+	if (mount_gfs2_meta(&mfs, mnt->mnt_dir, opts.debug)) {
 		perror("GFS2 metafs");
 		exit(EXIT_FAILURE);
 	}
 
-	if (build_paths(sdp->metafs_path, &opts)) {
+	if (build_paths(mfs.path, &opts)) {
 		perror(_("Failed to build paths"));
 		exit(EXIT_FAILURE);
 	}
@@ -538,7 +542,7 @@ int main(int argc, char *argv[])
 	     opts.journals < total;
 	     opts.journals++) {
 		if (metafs_interrupted) {
-			cleanup_metafs(&sbd);
+			cleanup_metafs(&mfs);
 			exit(130);
 		}
 		add_ir(&opts);
@@ -551,7 +555,7 @@ int main(int argc, char *argv[])
 	free(opts.per_node);
 	free(opts.jindex);
 	close(sdp->path_fd);
-	cleanup_metafs(sdp);
+	cleanup_metafs(&mfs);
 	sync();
 	print_results(&opts);
 
diff --git a/gfs2/mkfs/metafs.c b/gfs2/mkfs/metafs.c
new file mode 100644
index 0000000..12b1cdb
--- /dev/null
+++ b/gfs2/mkfs/metafs.c
@@ -0,0 +1,118 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <signal.h>
+#include <libintl.h>
+#include <locale.h>
+#define _(String) gettext(String)
+
+#include "metafs.h"
+
+int metafs_interrupted;
+
+static int lock_for_admin(struct metafs *mfs, int debug)
+{
+	int error;
+
+	if (debug)
+		printf(_("Trying to get admin lock..."));
+
+	mfs->fd = open(mfs->path, O_RDONLY | O_NOFOLLOW);
+	if (mfs->fd < 0)
+		return -1;
+
+	error = flock(mfs->fd, LOCK_EX);
+	if (error) {
+		close(mfs->fd);
+		return -1;
+	}
+	if (debug)
+		printf(_("locked.\n"));
+	return 0;
+}
+
+static void sighandler(int error)
+{
+	metafs_interrupted = 1;
+}
+
+static void setsigs(void (*handler)(int))
+{
+	struct sigaction sa = {	.sa_handler = handler };
+
+	sigaction(SIGINT, &sa, NULL);
+	sigaction(SIGILL, &sa, NULL);
+	sigaction(SIGTERM, &sa, NULL);
+	sigaction(SIGHUP, &sa, NULL);
+	sigaction(SIGABRT, &sa, NULL);
+	sigaction(SIGCONT, &sa, NULL);
+	sigaction(SIGUSR1, &sa, NULL);
+	sigaction(SIGUSR2, &sa, NULL);
+}
+
+int mount_gfs2_meta(struct metafs *mfs, const char *path, int debug)
+{
+	int ret;
+
+	mfs->path = strdup("/tmp/.gfs2meta.XXXXXX");
+	if (mfs->path == NULL)
+		return -1;
+
+	if(!mkdtemp(mfs->path))
+		goto err_free;
+
+	setsigs(sighandler);
+
+	ret = mount(path, mfs->path, "gfs2meta", 0, NULL);
+	if (ret)
+		goto err_rmdir;
+
+	if (lock_for_admin(mfs, debug))
+		goto err_umount;
+
+	return 0;
+
+err_umount:
+	if (umount(mfs->path))
+		/* Translators: the first %s here is a path, the second is an error message */
+		fprintf(stderr, _("Could not unmount %s: %s\n"),
+		                    mfs->path, strerror(errno));
+	setsigs(SIG_DFL);
+err_rmdir:
+	rmdir(mfs->path);
+err_free:
+	free(mfs->path);
+	mfs->path = NULL;
+	return -1;
+}
+
+void cleanup_metafs(struct metafs *mfs)
+{
+	int ret;
+
+	if (mfs->fd <= 0)
+		return;
+
+	fsync(mfs->fd);
+	close(mfs->fd);
+	ret = umount(mfs->path);
+	if (ret)
+		/* Translators: the first %s here is a path, the second is an error message */
+		fprintf(stderr, "Could not unmount %s : %s\n",
+			mfs->path, strerror(errno));
+	else
+		rmdir(mfs->path);
+
+	setsigs(SIG_DFL);
+	metafs_interrupted = 0;
+
+	free(mfs->path);
+	mfs->path = NULL;
+}
diff --git a/gfs2/mkfs/metafs.h b/gfs2/mkfs/metafs.h
new file mode 100644
index 0000000..a765634
--- /dev/null
+++ b/gfs2/mkfs/metafs.h
@@ -0,0 +1,14 @@
+#ifndef METAFS_H
+#define METAFS_H
+
+extern int metafs_interrupted;
+
+struct metafs {
+	int fd;
+	char *path;
+};
+
+extern int mount_gfs2_meta(struct metafs *mfs, const char *path, int debug);
+extern void cleanup_metafs(struct metafs *mfs);
+
+#endif /* METAFS_H */
-- 
1.9.3



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Cluster-devel] [PATCH 5/5] gfs2_grow/jadd: Use a matching context mount option in mount_gfs2_meta
  2015-02-23 18:43 [Cluster-devel] [PATCH 1/5] fsck.gfs2: Fix memory leaks in pass1_process_rgrp Andrew Price
                   ` (2 preceding siblings ...)
  2015-02-23 18:43 ` [Cluster-devel] [PATCH 4/5] gfs2-utils: Move metafs handling into gfs2/mkfs/ Andrew Price
@ 2015-02-23 18:43 ` Andrew Price
  2015-02-23 19:17 ` [Cluster-devel] [PATCH 1/5] fsck.gfs2: Fix memory leaks in pass1_process_rgrp Bob Peterson
  4 siblings, 0 replies; 6+ messages in thread
From: Andrew Price @ 2015-02-23 18:43 UTC (permalink / raw)
  To: cluster-devel.redhat.com

On a system with SELinux enabled, if a gfs2 file system is mounted with
a context= option, the tools gfs2_grow and gfs2_jadd will fail with
"Invalid argument". This is due to SELinux failing the mount due to an
mismatched context ("SELinux: mount invalid.  Same superblock, different
security settings").

In order to work around this, parse the context option of the mntent
relating to the gfs2 mount point and use it in mount_gfs2_meta().

Signed-off-by: Andrew Price <anprice@redhat.com>
---
 gfs2/mkfs/main_grow.c |  1 +
 gfs2/mkfs/main_jadd.c |  2 +-
 gfs2/mkfs/metafs.c    | 23 ++++++++++++++++++++++-
 gfs2/mkfs/metafs.h    |  2 ++
 4 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index c3ae4b7..6ba14b0 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -396,6 +396,7 @@ int main(int argc, char *argv[])
 			exit(EXIT_FAILURE);
 		}
 		fix_device_geometry(sdp);
+		mfs.context = copy_context_opt(mnt);
 		if (mount_gfs2_meta(&mfs, mnt->mnt_dir, (print_level > MSG_NOTICE))) {
 			perror(_("Failed to mount GFS2 meta file system"));
 			exit(EXIT_FAILURE);
diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c
index d83ec2b..9190d44 100644
--- a/gfs2/mkfs/main_jadd.c
+++ b/gfs2/mkfs/main_jadd.c
@@ -520,7 +520,7 @@ int main(int argc, char *argv[])
 		exit(EXIT_FAILURE);
 	}
 	gather_info(sdp, &opts);
-
+	mfs.context = copy_context_opt(mnt);
 	if (mount_gfs2_meta(&mfs, mnt->mnt_dir, opts.debug)) {
 		perror("GFS2 metafs");
 		exit(EXIT_FAILURE);
diff --git a/gfs2/mkfs/metafs.c b/gfs2/mkfs/metafs.c
index 12b1cdb..112ce2d 100644
--- a/gfs2/mkfs/metafs.c
+++ b/gfs2/mkfs/metafs.c
@@ -9,6 +9,7 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <signal.h>
+#include <mntent.h>
 #include <libintl.h>
 #include <locale.h>
 #define _(String) gettext(String)
@@ -70,7 +71,7 @@ int mount_gfs2_meta(struct metafs *mfs, const char *path, int debug)
 
 	setsigs(sighandler);
 
-	ret = mount(path, mfs->path, "gfs2meta", 0, NULL);
+	ret = mount(path, mfs->path, "gfs2meta", 0, mfs->context);
 	if (ret)
 		goto err_rmdir;
 
@@ -115,4 +116,24 @@ void cleanup_metafs(struct metafs *mfs)
 
 	free(mfs->path);
 	mfs->path = NULL;
+	free(mfs->context);
+	mfs->context = NULL;
+}
+
+/**
+ * Returns a duplicate of the 'context' mount option, or NULL if not found.
+ */
+char *copy_context_opt(struct mntent *mnt)
+{
+	char *ctx, *end;
+
+	ctx = hasmntopt(mnt, "context");
+	if (ctx == NULL)
+		return NULL;
+
+	end = strchr(ctx, ',');
+	if (end == NULL)
+		return NULL;
+
+	return strndup(ctx, end - ctx);
 }
diff --git a/gfs2/mkfs/metafs.h b/gfs2/mkfs/metafs.h
index a765634..1372977 100644
--- a/gfs2/mkfs/metafs.h
+++ b/gfs2/mkfs/metafs.h
@@ -6,9 +6,11 @@ extern int metafs_interrupted;
 struct metafs {
 	int fd;
 	char *path;
+	char *context; /* 'context=' mount option */
 };
 
 extern int mount_gfs2_meta(struct metafs *mfs, const char *path, int debug);
 extern void cleanup_metafs(struct metafs *mfs);
+extern char *copy_context_opt(struct mntent *mnt);
 
 #endif /* METAFS_H */
-- 
1.9.3



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Cluster-devel] [PATCH 1/5] fsck.gfs2: Fix memory leaks in pass1_process_rgrp
  2015-02-23 18:43 [Cluster-devel] [PATCH 1/5] fsck.gfs2: Fix memory leaks in pass1_process_rgrp Andrew Price
                   ` (3 preceding siblings ...)
  2015-02-23 18:43 ` [Cluster-devel] [PATCH 5/5] gfs2_grow/jadd: Use a matching context mount option in mount_gfs2_meta Andrew Price
@ 2015-02-23 19:17 ` Bob Peterson
  4 siblings, 0 replies; 6+ messages in thread
From: Bob Peterson @ 2015-02-23 19:17 UTC (permalink / raw)
  To: cluster-devel.redhat.com

ACK to all five in the series.

----- Original Message -----
> Spotted by coverity: "Variable ibuf going out of scope leaks the storage
> it points to"
> 
> Signed-off-by: Andrew Price <anprice@redhat.com>
> ---
>  gfs2/fsck/pass1.c | 14 +++++++++-----
>  1 file changed, 9 insertions(+), 5 deletions(-)
> 
> diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
> index b516a21..69c88f4 100644
> --- a/gfs2/fsck/pass1.c
> +++ b/gfs2/fsck/pass1.c
> @@ -1625,7 +1625,10 @@ static int pass1_process_rgrp(struct gfs2_sbd *sdp,
> struct rgrp_tree *rgd)
>  {
>  	unsigned k, n, i;
>  	uint64_t *ibuf = malloc(sdp->bsize * GFS2_NBBY * sizeof(uint64_t));
> -	int ret;
> +	int ret = 0;
> +
> +	if (ibuf == NULL)
> +		return FSCK_ERROR;
>  
>  	for (k = 0; k < rgd->ri.ri_length; k++) {
>  		n = lgfs2_bm_scan(rgd, k, ibuf, GFS2_BLKST_DINODE);
> @@ -1633,11 +1636,11 @@ static int pass1_process_rgrp(struct gfs2_sbd *sdp,
> struct rgrp_tree *rgd)
>  		if (n) {
>  			ret = pass1_process_bitmap(sdp, rgd, ibuf, n);
>  			if (ret)
> -				return ret;
> +				goto out;
>  		}
>  
>  		if (fsck_abort)
> -			return 0;
> +			goto out;
>  		/*
>  		  For GFS1, we have to count the "free meta" blocks in the
>  		  resource group and mark them specially so we can count them
> @@ -1650,12 +1653,13 @@ static int pass1_process_rgrp(struct gfs2_sbd *sdp,
> struct rgrp_tree *rgd)
>  		for (i = 0; i < n; i++) {
>  			gfs2_blockmap_set(bl, ibuf[i], GFS2_BLKST_UNLINKED);
>  			if (fsck_abort)
> -				return 0;
> +				goto out;
>  		}
>  	}
>  
> +out:
>  	free(ibuf);
> -	return 0;
> +	return ret;
>  }
>  
>  /**
> --
> 1.9.3
> 
> 



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-02-23 19:17 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-23 18:43 [Cluster-devel] [PATCH 1/5] fsck.gfs2: Fix memory leaks in pass1_process_rgrp Andrew Price
2015-02-23 18:43 ` [Cluster-devel] [PATCH 2/5] libgfs2: Use the correct parent for rgrp tree insertion Andrew Price
2015-02-23 18:43 ` [Cluster-devel] [PATCH 3/5] libgfs2: Remove some obsolete function declarations Andrew Price
2015-02-23 18:43 ` [Cluster-devel] [PATCH 4/5] gfs2-utils: Move metafs handling into gfs2/mkfs/ Andrew Price
2015-02-23 18:43 ` [Cluster-devel] [PATCH 5/5] gfs2_grow/jadd: Use a matching context mount option in mount_gfs2_meta Andrew Price
2015-02-23 19:17 ` [Cluster-devel] [PATCH 1/5] fsck.gfs2: Fix memory leaks in pass1_process_rgrp Bob Peterson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.