From a360fddeb570fb9649151b00d79c90c61a6d3eab Mon Sep 17 00:00:00 2001 From: John Marino Date: Sun, 5 Apr 2015 13:06:49 +0200 Subject: [PATCH] HAMMER: Add "hammer abort-cleanup" command A new command has been added to HAMMER: abort-cleanup. As could be deduced from its name, this command will terminate all active cleanup operations. It takes no arguments. It works by searching the /var/run directory for pidfiles starting with "hammer.cleanup.". It gets the pid from the filename rather than by reading the contents of the pidfile. Once the pid is obtained, the SIGTERM signal is set to it. Any successfully terminated process will be announced on stdout. The SIGINT signal could also be used, but this one does not print "Terminated" on the process's terminal, which I find useful. Currently if the cleanup is interrupted another way, the pidfile will not be removed. These hammer.cleanup pidfiles will accumulate until the next "hammer abort-cleanup" command is executed. Stale pidfiles will be removed if encountered by abort-cleanup command. --- sbin/hammer/Makefile | 2 +- sbin/hammer/cmd_abort.c | 97 +++++++++++++++++++++++++++++++++++++++ sbin/hammer/cmd_cleanup.c | 16 ++++++- sbin/hammer/hammer.8 | 7 ++- sbin/hammer/hammer.c | 7 ++- sbin/hammer/hammer.h | 3 +- sbin/hammer/hammer_util.h | 7 +++ 7 files changed, 131 insertions(+), 8 deletions(-) create mode 100644 sbin/hammer/cmd_abort.c diff --git a/sbin/hammer/Makefile b/sbin/hammer/Makefile index 35788074fb..280fb3305c 100644 --- a/sbin/hammer/Makefile +++ b/sbin/hammer/Makefile @@ -5,7 +5,7 @@ SRCS= hammer.c ondisk.c blockmap.c cache.c misc.c cycle.c \ cmd_synctid.c cmd_stats.c cmd_remote.c \ cmd_pseudofs.c cmd_snapshot.c cmd_mirror.c \ cmd_cleanup.c cmd_info.c cmd_version.c cmd_volume.c \ - cmd_config.c cmd_recover.c cmd_dedup.c + cmd_config.c cmd_recover.c cmd_dedup.c cmd_abort.c MAN= hammer.8 CFLAGS+= -I${.CURDIR}/../../sys -DALIST_NO_DEBUG diff --git a/sbin/hammer/cmd_abort.c b/sbin/hammer/cmd_abort.c new file mode 100644 index 0000000000..ac6d461d45 --- /dev/null +++ b/sbin/hammer/cmd_abort.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2015 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by John Marino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of The DragonFly Project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific, prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * Each "hammer cleanup" command creates a pid file at /var/run with the + * name hammer.cleanup.$pid with the contents of $pid + * + * If the cleanup ends without incident, the pid file is removed. If the + * cleanup job is interrupted, the pid file is not removed. This is + * because SIGINT is disabled in deferrence to HAMMER ioctl. + * + * The "hammer abort-cleanup" command is simple. It scans /var/run for + * all files starting with "hammer.cleanup.", reads them, and issues a + * SIGINTR for any valid pid. Every hammer.cleanup.XXXXXX file will be + * removed after the command executes. If multiple cleanup jobs are + * running simultaneously, all of them will be aborted. + * + * It is intended any future "abort" commands are also placed in here. + */ + +#include "hammer.h" + +void +hammer_cmd_abort_cleanup(char **av __unused, int ac __unused) +{ + DIR *dir; + pid_t pid; + char *str; + int pf_fd; + struct dirent *den; + static char pidfile[PIDFILE_BUFSIZE]; + static const char prefix[] = "hammer.cleanup."; + static const char termmsg[] = "Terminated cleanup process %u\n"; + const size_t pflen = sizeof(prefix) - 1; + + if ((dir = opendir(pidfile_loc)) == NULL) { + return; + } + + while ((den = readdir(dir)) != NULL) { + if (strncmp(den->d_name, prefix, pflen) == 0) { + snprintf (pidfile, PIDFILE_BUFSIZE, "%s/%s", + pidfile_loc, den->d_name); + pid = strtol((char *)(den->d_name + pflen), &str, 10); + pf_fd = open(pidfile, O_RDONLY | O_CLOEXEC); + if (pf_fd == -1) { + continue; + } + + if (flock(pf_fd, LOCK_EX | LOCK_NB) < 0) { + if (errno == EWOULDBLOCK) { + /* error expected during cleanup */ + if (kill (pid, SIGTERM) == 0) { + printf (termmsg, pid); + } + } + } + else { + /* lock succeeded so pidfile is stale */ + flock (pf_fd, LOCK_UN); + } + close (pf_fd); + unlink (pidfile); + } + } + closedir(dir); +} diff --git a/sbin/hammer/cmd_cleanup.c b/sbin/hammer/cmd_cleanup.c index 151da3fc4d..2f3a23a587 100644 --- a/sbin/hammer/cmd_cleanup.c +++ b/sbin/hammer/cmd_cleanup.c @@ -30,8 +30,6 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $DragonFly: src/sbin/hammer/cmd_cleanup.c,v 1.6 2008/10/07 22:28:41 thomas Exp $ */ /* * Clean up specific HAMMER filesystems or all HAMMER filesystems. @@ -60,6 +58,7 @@ * (/var/hammer/root for root mount). */ +#include #include "hammer.h" struct didpfs { @@ -389,6 +388,17 @@ do_cleanup(const char *path) printf(" handle PFS #%d using %s\n", pfs.pfs_id, snapshots_path); + struct pidfh *pfh = NULL; + static char pidfile[PIDFILE_BUFSIZE]; + + snprintf (pidfile, PIDFILE_BUFSIZE, "%s/hammer.cleanup.%d", + pidfile_loc, getpid()); + pfh = pidfile_open(pidfile, 0644, NULL); + if (pfh == NULL) { + warn ("Unable to open or create %s", pidfile); + } + pidfile_write(pfh); + /* * Process the config file */ @@ -533,6 +543,8 @@ do_cleanup(const char *path) */ close(fd); usleep(1000); + pidfile_close(pfh); + pidfile_remove(pfh); } /* diff --git a/sbin/hammer/hammer.8 b/sbin/hammer/hammer.8 index 461228fcd6..c35b0df6bb 100644 --- a/sbin/hammer/hammer.8 +++ b/sbin/hammer/hammer.8 @@ -30,7 +30,7 @@ .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd February 5, 2015 +.Dd May 18, 2015 .Dt HAMMER 8 .Os .Sh NAME @@ -664,6 +664,11 @@ Work on this command is still in progress. Expected additions: An ability to remove snapshots dynamically as the file system becomes full. +.\" ==== abort-cleanup ==== +.It Cm abort-cleanup +This command will terminate all active +.Cm cleanup +processes. .\" ==== config ==== .It Cm config Op Ar filesystem Op Ar configfile .Nm ( HAMMER diff --git a/sbin/hammer/hammer.c b/sbin/hammer/hammer.c index 1efb4b8d81..1d6559c86a 100644 --- a/sbin/hammer/hammer.c +++ b/sbin/hammer/hammer.c @@ -30,8 +30,6 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $DragonFly: src/sbin/hammer/hammer.c,v 1.44 2008/11/13 02:04:27 dillon Exp $ */ #include "hammer.h" @@ -400,6 +398,10 @@ main(int ac, char **av) hammer_cmd_cleanup(av + 1, ac - 1); exit(0); } + if (strcmp(av[0], "abort-cleanup") == 0) { + hammer_cmd_abort_cleanup(av + 1, ac - 1); + exit(0); + } if (strcmp(av[0], "info") == 0) { hammer_cmd_info(av + 1, ac - 1); exit(0); @@ -635,6 +637,7 @@ usage(int exit_code) "hammer namekey2 \n" "hammer namekey32 \n" "hammer cleanup [ ...]\n" + "hammer abort-cleanup\n" "hammer info [ ...]\n" "hammer snapshot [] \n" "hammer snapshot []\n" diff --git a/sbin/hammer/hammer.h b/sbin/hammer/hammer.h index d674202d0e..9ae25ae83e 100644 --- a/sbin/hammer/hammer.h +++ b/sbin/hammer/hammer.h @@ -30,8 +30,6 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $DragonFly: src/sbin/hammer/hammer.h,v 1.27 2008/11/13 02:04:27 dillon Exp $ */ #include @@ -133,6 +131,7 @@ void hammer_cmd_volume_del(char **av, int ac); void hammer_cmd_volume_list(char **av, int ac); void hammer_cmd_dedup_simulate(char **av, int ac); void hammer_cmd_dedup(char **av, int ac); +void hammer_cmd_abort_cleanup(char **av, int ac); void hammer_get_cycle(hammer_base_elm_t base, hammer_tid_t *tidp); void hammer_set_cycle(hammer_base_elm_t base, hammer_tid_t tid); diff --git a/sbin/hammer/hammer_util.h b/sbin/hammer/hammer_util.h index e24c05a24d..d923712193 100644 --- a/sbin/hammer/hammer_util.h +++ b/sbin/hammer/hammer_util.h @@ -39,6 +39,13 @@ #include #include +/* + * pidfile management - common definitions so code is more robust + */ + +#define PIDFILE_BUFSIZE 64 +static const char pidfile_loc[] = "/var/run"; + /* * Cache management - so the user code can keep its memory use under control */ -- 2.41.0