[PATCH 06/11] nfsdcld: Add graceful exit handling and resource cleanup

Doug Nazar
2020-07-18T09:25:08Z

utils/nfsdcld/nfsdcld.c | 32 ++++++++++++++++++++++++++++++--
utils/nfsdcld/sqlite.c | 15 +++++++++++++++
utils/nfsdcld/sqlite.h | 1 +
3 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/utils/nfsdcld/nfsdcld.c b/utils/nfsdcld/nfsdcld.c
index 5ad94ce2..636c3983 100644
--- a/utils/nfsdcld/nfsdcld.c
+++ b/utils/nfsdcld/nfsdcld.c
@@ -27,6 +27,7 @@
#include <event2/event.h>
#include <stdbool.h>
#include <getopt.h>
+#include <signal.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -69,6 +70,7 @@ static int inotify_fd = -1;
static struct event *pipedir_event;
static struct event_base *evbase;
static bool old_kernel = false;
+static bool signal_received = false;

uint64_t current_epoch;
uint64_t recovery_epoch;
@@ -89,6 +91,19 @@ static struct option longopts[] =
/* forward declarations */
static void cldcb(int UNUSED(fd), short which, void *data);

+static void
+sig_die(int signal)
+{
+ if (signal_received) {
+ xlog(D_GENERAL, "forced exiting on signal %d\n", signal);
+ exit(0);
+ }
+
+ signal_received = true;
+ xlog(D_GENERAL, "exiting on signal %d\n", signal);
+ event_base_loopexit(evbase, NULL);
+}
+
static void
usage(char *progname)
{
@@ -881,14 +896,27 @@ main(int argc, char **argv)
if (rc)
goto out;

+ signal(SIGINT, sig_die);
+ signal(SIGTERM, sig_die);
+
xlog(D_GENERAL, "%s: Starting event dispatch handler.", __func__);
rc = event_base_dispatch(evbase);
if (rc < 0)
xlog(L_ERROR, "%s: event_dispatch failed: %m", __func__);

- close(clnt.cl_fd);
- close(inotify_fd);
out:
+ if (clnt.cl_event)
+ event_free(clnt.cl_event);
+ if (clnt.cl_fd != -1)
+ close(clnt.cl_fd);
+ if (pipedir_event)
+ event_free(pipedir_event);
+ if (inotify_fd != -1)
+ close(inotify_fd);
+
+ event_base_free(evbase);
+ sqlite_shutdown();
+
free(progname);
return rc;
}
diff --git a/utils/nfsdcld/sqlite.c b/utils/nfsdcld/sqlite.c
index e2586c39..8fd1d0c2 100644
--- a/utils/nfsdcld/sqlite.c
+++ b/utils/nfsdcld/sqlite.c
@@ -1404,3 +1404,18 @@ sqlite_first_time_done(void)
sqlite3_free(err);
return ret;
}
+
+/*
+ * Closes all sqlite3 resources and shuts down the library.
+ *
+ */
+void
+sqlite_shutdown(void)
+{
+ if (dbh != NULL) {
+ sqlite3_close(dbh);
+ dbh = NULL;
+ }
+
+ sqlite3_shutdown();
+}
diff --git a/utils/nfsdcld/sqlite.h b/utils/nfsdcld/sqlite.h
index 0a26ad67..044236cf 100644
--- a/utils/nfsdcld/sqlite.h
+++ b/utils/nfsdcld/sqlite.h
@@ -34,4 +34,5 @@ int sqlite_iterate_recovery(int (*cb)(struct cld_client *clnt), struct cld_clien
int sqlite_delete_cltrack_records(void);
int sqlite_first_time_done(void);

+void sqlite_shutdown(void);
#endif /* _SQLITE_H */
--
2.26.2