Gitweb: http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=89f0f242424... Commit: 89f0f242424a4cc23cd73f0288d17b52d04a900d Parent: ec2b6270b291a671b70a17a12389d8fecaabd61b Author: Andrew Price anprice@redhat.com AuthorDate: Tue Oct 7 23:23:21 2014 +0100 Committer: Andrew Price anprice@redhat.com CommitterDate: Tue Oct 7 23:23:21 2014 +0100
libgfs2: metafs_path improvements
Switch the metafs_path field in struct gfs2_sbd to be a pointer instead of a char[PATH_MAX] and use strdup to set it in mount_gfs2_meta. Also rework the metafs mounting and cleanup code to back out more robustly on errors and set/reset signal handlers through a single function.
Note the SIGSEGV handler has been removed: when a SIGSEGV handler returns, execution restarts at the bad instruction which triggered it, so handling it could only ever cause an infinite loop.
Signed-off-by: Andrew Price anprice@redhat.com --- gfs2/libgfs2/libgfs2.h | 2 +- gfs2/libgfs2/misc.c | 66 +++++++++++++++++++++++++++++------------------- 2 files changed, 41 insertions(+), 27 deletions(-)
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h index 6509e9b..60c1989 100644 --- a/gfs2/libgfs2/libgfs2.h +++ b/gfs2/libgfs2/libgfs2.h @@ -326,7 +326,7 @@ struct gfs2_sbd { struct master_dir md;
int metafs_fd; - char metafs_path[PATH_MAX]; /* where metafs is mounted */ + char *metafs_path; /* where metafs is mounted */ struct special_blocks eattr_blocks;
uint64_t rg_one_length; diff --git a/gfs2/libgfs2/misc.c b/gfs2/libgfs2/misc.c index 6feccad..c72af55 100644 --- a/gfs2/libgfs2/misc.c +++ b/gfs2/libgfs2/misc.c @@ -210,8 +210,10 @@ static int lock_for_admin(struct gfs2_sbd *sdp) return -1;
error = flock(sdp->metafs_fd, LOCK_EX); - if (error) + if (error) { + close(sdp->metafs_fd); return -1; + } if (cfg_debug) printf("Got it.\n"); return 0; @@ -222,40 +224,57 @@ static void sighandler(int error) metafs_interrupted = 1; }
-int mount_gfs2_meta(struct gfs2_sbd *sdp, const char *path) +static void setsigs(void (*handler)(int)) { - 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"); - - if(!mkdtemp(sdp->metafs_path)) - return -1; + 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(SIGSEGV, &sa, NULL); sigaction(SIGCONT, &sa, NULL); sigaction(SIGUSR1, &sa, NULL); sigaction(SIGUSR2, &sa, NULL); - ret = mount(path, sdp->metafs_path, "gfs2meta", 0, NULL); - if (ret) { - rmdir(sdp->metafs_path); +} + +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)) - return -1; + 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; - struct sigaction sa = { .sa_handler = SIG_DFL };
if (sdp->metafs_fd <= 0) return; @@ -268,14 +287,9 @@ 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); + + setsigs(SIG_DFL); metafs_interrupted = 0; + free(sdp->metafs_path); + sdp->metafs_path = NULL; }
cluster-commits@lists.fedorahosted.org