diff mbox

[nfs-ganesha,RFC,v2,11/13] tools: add new rados_grace manipulation tool

Message ID 20180503185803.25417-12-jlayton@kernel.org (mailing list archive)
State New, archived
Headers show

Commit Message

Jeff Layton May 3, 2018, 6:58 p.m. UTC
From: Jeff Layton <jlayton@redhat.com>

Add a new command-line tool for manipulating and querying the rados_grace
database. It will dump out the state of the epochs and then a list of
omap keys and their flags.

Change-Id: If57591265ce736cdcebab749651d5ab6982341d8
Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 src/nfs-ganesha.spec-in.cmake |   2 +
 src/tools/CMakeLists.txt      |   4 +
 src/tools/rados_grace_tool.c  | 178 ++++++++++++++++++++++++++++++++++
 3 files changed, 184 insertions(+)
 create mode 100644 src/tools/rados_grace_tool.c
diff mbox

Patch

diff --git a/src/nfs-ganesha.spec-in.cmake b/src/nfs-ganesha.spec-in.cmake
index e93973eda1f7..c55fad58c083 100644
--- a/src/nfs-ganesha.spec-in.cmake
+++ b/src/nfs-ganesha.spec-in.cmake
@@ -508,6 +508,7 @@  install -m 644 config_samples/xfs.conf %{buildroot}%{_sysconfdir}/ganesha
 
 %if %{with ceph}
 install -m 644 config_samples/ceph.conf %{buildroot}%{_sysconfdir}/ganesha
+install -m 755 tools/rados_grace_tool	%{buildroot}%{_sbindir}/rados_grace_tool
 %endif
 
 %if %{with rgw}
@@ -690,6 +691,7 @@  exit 0
 %defattr(-,root,root,-)
 %{_libdir}/ganesha/libfsalceph*
 %config(noreplace) %{_sysconfdir}/ganesha/ceph.conf
+%{_sbindir}/rados_grace_tool
 %if %{with man_page}
 %{_mandir}/*/ganesha-ceph-config.8.gz
 %endif
diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt
index 7b536193568a..3856571f3ba1 100644
--- a/src/tools/CMakeLists.txt
+++ b/src/tools/CMakeLists.txt
@@ -1,3 +1,7 @@ 
+if (USE_RADOS_RECOV)
+  add_executable(rados_grace_tool rados_grace_tool.c)
+  target_link_libraries(rados_grace_tool rados_grace ${RADOS_LIBRARIES})
+endif(USE_RADOS_RECOV)
 
 ########### install files ###############
 
diff --git a/src/tools/rados_grace_tool.c b/src/tools/rados_grace_tool.c
new file mode 100644
index 000000000000..6cc15e8f3b38
--- /dev/null
+++ b/src/tools/rados_grace_tool.c
@@ -0,0 +1,178 @@ 
+/*
+ * vim:noexpandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright 2017 Red Hat, Inc. and/or its affiliates.
+ * Author: Jeff Layton <jlayton@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * rados-grace: tool for managing coordinated grace period database
+ *
+ * This tool allows an administrator to make direct changes to the rados_grace
+ * database. See the rados_grace support library sources for more info about
+ * the internals.
+ */
+#include "config.h"
+#include <stdio.h>
+#include <stdint.h>
+#include <endian.h>
+#include <rados/librados.h>
+#include <errno.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <rados_grace.h>
+
+#define POOL_ID				"nfs-ganesha"
+#define RADOS_GRACE_OID			"grace"
+
+static int
+cluster_connect(rados_ioctx_t *io_ctx, const char *pool)
+{
+	int ret;
+	rados_t clnt;
+
+	ret = rados_create(&clnt, NULL);
+	if (ret < 0) {
+		fprintf(stderr, "rados_create: %d\n", ret);
+		return ret;
+	}
+
+	ret = rados_conf_read_file(clnt, NULL);
+	if (ret < 0) {
+		fprintf(stderr, "rados_conf_read_file: %d\n", ret);
+		return ret;
+	}
+
+	ret = rados_connect(clnt);
+	if (ret < 0) {
+		fprintf(stderr, "rados_connect: %d\n", ret);
+		return ret;
+	}
+
+	ret = rados_pool_create(clnt, pool);
+	if (ret < 0 && ret != -EEXIST) {
+		fprintf(stderr, "rados_pool_create: %d\n", ret);
+		return ret;
+	}
+
+	ret = rados_ioctx_create(clnt, pool, io_ctx);
+	if (ret < 0) {
+		fprintf(stderr, "rados_ioctx_create: %d\n", ret);
+		return ret;
+	}
+	return 0;
+}
+
+static void usage(const char **argv)
+{
+	fprintf(stderr,
+		"Usage:\n%s [dump|start|join|lift|remove|enforce|noenforce] [ nodeid ... ]\n",
+		argv[0]);
+}
+
+int main(int argc, const char **argv)
+{
+	int		ret, nodes = 0;
+	rados_ioctx_t	io_ctx;
+	const char	*cmd = "dump";
+	uint64_t	cur, rec;
+
+	if (argc > 1) {
+		cmd = argv[1];
+		nodes = argc - 2;
+	}
+
+	ret = cluster_connect(&io_ctx, POOL_ID);
+	if (ret) {
+		fprintf(stderr, "Can't connect to cluster: %d\n", ret);
+		return 1;
+	}
+
+	ret = rados_grace_create(io_ctx, RADOS_GRACE_OID);
+	if (ret < 0 && ret != -EEXIST) {
+		fprintf(stderr, "Can't create grace db: %d\n", ret);
+		return 1;
+	}
+
+	if (!strcmp(cmd, "dump")) {
+		ret = rados_grace_dump(io_ctx, RADOS_GRACE_OID);
+	} else if (!strcmp(cmd, "start")) {
+		if (!nodes) {
+			fprintf(stderr, "Need at least one nodeid.\n");
+			ret = -EINVAL;
+		} else {
+			ret = rados_grace_join_bulk(io_ctx, RADOS_GRACE_OID,
+						nodes, &argv[2], &cur, &rec,
+						true);
+		}
+	} else if (!strcmp(cmd, "join")) {
+		uint64_t cur, rec;
+
+		if (!nodes) {
+			fprintf(stderr, "Need at least one nodeid.\n");
+			ret = -EINVAL;
+		} else {
+			ret = rados_grace_join_bulk(io_ctx, RADOS_GRACE_OID,
+						nodes, &argv[2], &cur, &rec,
+						false);
+		}
+	} else if (!strcmp(cmd, "lift")) {
+		if (!nodes) {
+			fprintf(stderr, "Need at least one nodeid.\n");
+			ret = -EINVAL;
+		} else {
+			ret = rados_grace_lift_bulk(io_ctx, RADOS_GRACE_OID,
+						nodes, &argv[2], &cur, &rec,
+						false);
+		}
+	} else if (!strcmp(cmd, "remove")) {
+		if (!nodes) {
+			fprintf(stderr, "Need at least one nodeid.\n");
+			ret = -EINVAL;
+		} else {
+			ret = rados_grace_lift_bulk(io_ctx, RADOS_GRACE_OID,
+						nodes, &argv[2], &cur, &rec,
+						true);
+		}
+	} else if (!strcmp(cmd, "enforce")) {
+		if (!nodes) {
+			fprintf(stderr, "Need at least one nodeid.\n");
+			ret = -EINVAL;
+		} else {
+			ret = rados_grace_enforcing_toggle(io_ctx,
+					RADOS_GRACE_OID, nodes, &argv[2],
+					&cur, &rec, true);
+		}
+	} else if (!strcmp(cmd, "noenforce")) {
+		if (!nodes) {
+			fprintf(stderr, "Need at least one nodeid.\n");
+			ret = -EINVAL;
+		} else {
+			ret = rados_grace_enforcing_toggle(io_ctx,
+					RADOS_GRACE_OID, nodes, &argv[2],
+					&cur, &rec, false);
+		}
+	} else {
+		usage(argv);
+		ret = -EINVAL;
+	}
+
+	if (ret)
+		return 1;
+	return 0;
+}