Blob Blame History Raw
commit 12604ad33b41eca2b7c6511da8d519a299787ef5
Author: Bob Peterson <rpeterso@redhat.com>
Date:   Mon Aug 12 15:08:55 2013 -0500

    gfs2_tool: catch interrupts while the metafs is mounted
    
    This patch catches interrupt signals while the metafs is mounted,
    and if interrupted, sets a flag. Later, if the caller sees the flag,
    they will unmount the metafs. That way, the metafs is never left
    mounted by accident if a gfs2_grow or gfs2_jadd is interrupted or
    killed.

diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index e994d3b..dd7420b 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -713,6 +713,8 @@ extern void increase_verbosity(void);
 extern void decrease_verbosity(void);
 /* misc.c */
 
+extern int metafs_interrupted;
+
 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);
diff --git a/gfs2/libgfs2/misc.c b/gfs2/libgfs2/misc.c
index 6f2dbdb..7f500e6 100644
--- a/gfs2/libgfs2/misc.c
+++ b/gfs2/libgfs2/misc.c
@@ -18,6 +18,7 @@
 #include <sys/sysmacros.h>
 #include <mntent.h>
 #include <sys/time.h>
+#include <signal.h>
 
 #include "libgfs2.h"
 
@@ -25,6 +26,8 @@
 #define SYS_BASE "/sys/fs/gfs2" /* FIXME: Look in /proc/mounts to find this */
 #define DIV_RU(x, y) (((x) + (y) - 1) / (y))
 
+int metafs_interrupted = 0;
+
 int compute_heightsize(struct gfs2_sbd *sdp, uint64_t *heightsize,
 	uint32_t *maxheight, uint32_t bsize1, int diptrs, int inptrs)
 {
@@ -179,10 +182,15 @@ static int lock_for_admin(struct gfs2_sbd *sdp)
 	return 0;
 }
 
+static void sighandler(int error)
+{
+	metafs_interrupted = 1;
+}
 
 int mount_gfs2_meta(struct gfs2_sbd *sdp)
 {
 	int ret;
+	struct sigaction sa = {	.sa_handler = &sighandler };
 
 	memset(sdp->metafs_path, 0, PATH_MAX);
 	snprintf(sdp->metafs_path, PATH_MAX - 1, "/tmp/.gfs2meta.XXXXXX");
@@ -190,6 +198,15 @@ int mount_gfs2_meta(struct gfs2_sbd *sdp)
 	if(!mkdtemp(sdp->metafs_path))
 		return -1;
 
+	sigaction(SIGINT, &sa, NULL);
+	sigaction(SIGILL, &sa, NULL);
+	sigaction(SIGTERM, &sa, NULL);
+	sigaction(SIGHUP, &sa, NULL);
+	sigaction(SIGABRT, &sa, NULL);
+	sigaction(SIGSEGV, &sa, NULL);
+	sigaction(SIGCONT, &sa, NULL);
+	sigaction(SIGUSR1, &sa, NULL);
+	sigaction(SIGUSR2, &sa, NULL);
 	ret = mount(sdp->path_name, sdp->metafs_path, "gfs2meta", 0, NULL);
 	if (ret) {
 		rmdir(sdp->metafs_path);
@@ -203,6 +220,7 @@ int mount_gfs2_meta(struct gfs2_sbd *sdp)
 void cleanup_metafs(struct gfs2_sbd *sdp)
 {
 	int ret;
+	struct sigaction sa = {	.sa_handler = SIG_DFL };
 
 	if (sdp->metafs_fd <= 0)
 		return;
@@ -215,6 +233,16 @@ void cleanup_metafs(struct gfs2_sbd *sdp)
 			sdp->metafs_path, strerror(errno));
 	else
 		rmdir(sdp->metafs_path);
+	sigaction(SIGINT, &sa, NULL);
+	sigaction(SIGILL, &sa, NULL);
+	sigaction(SIGTERM, &sa, NULL);
+	sigaction(SIGHUP, &sa, NULL);
+	sigaction(SIGABRT, &sa, NULL);
+	sigaction(SIGSEGV, &sa, NULL);
+	sigaction(SIGCONT, &sa, NULL);
+	sigaction(SIGUSR1, &sa, NULL);
+	sigaction(SIGUSR2, &sa, NULL);
+	metafs_interrupted = 0;
 }
 
 int set_sysfs(const char *fsname, const char *filename, const char *val)
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index d324af9..5db91d9 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -372,10 +372,13 @@ main_grow(int argc, char *argv[])
 			perror(_("Bad constants (1)"));
 			exit(EXIT_FAILURE);
 		}
-		if (read_sb(sdp) < 0)
-			die( _("Error reading superblock.\n"));
+		if (read_sb(sdp) < 0) {
+			fprintf(stderr, _("Error reading superblock.\n"));
+			exit(EXIT_FAILURE);
+		}
 		if (sdp->gfs1) {
-			die( _("cannot grow gfs1 filesystem\n"));
+			fprintf(stderr, _("cannot grow gfs1 filesystem\n"));
+			exit(EXIT_FAILURE);
 		}
 		fix_device_geometry(sdp);
 		if (mount_gfs2_meta(sdp)) {
@@ -387,7 +390,8 @@ main_grow(int argc, char *argv[])
 		rindex_fd = open(rindex_name, (test ? O_RDONLY : O_RDWR) | O_CLOEXEC);
 		if (rindex_fd < 0) {
 			cleanup_metafs(sdp);
-			die( _("GFS2 rindex not found.  Please run fsck.gfs2.\n"));
+			perror(_("GFS2 rindex not found. Please run fsck.gfs2.\n"));
+			exit(EXIT_FAILURE);
 		}
 		/* Get master dinode */
 		sdp->master_dir = lgfs2_inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr);
@@ -402,6 +406,8 @@ main_grow(int argc, char *argv[])
 		/* we're only going to write out new RG information after   */
 		/* the existing RGs, and only write to the index at EOF.    */
 		ri_update(sdp, rindex_fd, &rgcount, &sane);
+		if (metafs_interrupted)
+			goto out;
 		fssize = filesystem_size(sdp);
 		if (!sdp->rgtree.osi_node) {
 			log_err(_("Error: No resource groups found.\n"));
@@ -424,10 +430,16 @@ main_grow(int argc, char *argv[])
 		} else {
 			int old_rg_count;
 
+			if (metafs_interrupted)
+				goto out;
 			compute_rgrp_layout(sdp, &sdp->rgtree, TRUE);
+			if (metafs_interrupted)
+				goto out;
 			debug_print_rgrps(sdp, &sdp->rgtree);
 			print_info(sdp);
 			initialize_new_portion(sdp, &old_rg_count);
+			if (metafs_interrupted)
+				goto out;
 			fix_rindex(sdp, rindex_fd, old_rg_count);
 		}
 	out:
@@ -439,6 +451,7 @@ main_grow(int argc, char *argv[])
 	}
 	close(sdp->path_fd);
 	sync();
-	log_notice( _("gfs2_grow complete.\n"));
+	if (!metafs_interrupted)
+		log_notice( _("gfs2_grow complete.\n"));
 	exit(error);
 }
diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c
index 2646829..b6cd8e4 100644
--- a/gfs2/mkfs/main_jadd.c
+++ b/gfs2/mkfs/main_jadd.c
@@ -529,6 +529,10 @@ void main_jadd(int argc, char *argv[])
 	for (sdp->md.journals = sdp->orig_journals; 
 	     sdp->md.journals < total;
 	     sdp->md.journals++) {
+		if (metafs_interrupted) {
+			cleanup_metafs(&sbd);
+			exit(130);
+		}
 		add_ir(sdp);
 		add_sc(sdp);
 		add_qc(sdp);