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);