21ab4e
From e7bbd87a4c3892d70cb84a9c5cef33430112d7a4 Mon Sep 17 00:00:00 2001
21ab4e
From: Niels de Vos <ndevos@redhat.com>
21ab4e
Date: Fri, 6 Jan 2017 12:58:02 +0100
21ab4e
Subject: [PATCH 316/361] gfapi: create statedump when glusterd requests it
21ab4e
21ab4e
When GlusterD sends the STATEDUMP procedure to the libgfapi client, the
21ab4e
client checks if it matches the PID that should take the statedump. If
21ab4e
so, it will do a statedump for the glfs_t that is connected to this mgmt
21ab4e
connection.
21ab4e
21ab4e
See-also: http://review.gluster.org/9228
21ab4e
[ndevos: separated patch from 9228]
21ab4e
21ab4e
mainline:
21ab4e
> BUG: 1169302
21ab4e
> Reviewed-on: https://review.gluster.org/16415
21ab4e
> Smoke: Gluster Build System <jenkins@build.gluster.org>
21ab4e
> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
21ab4e
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
21ab4e
> Reviewed-by: Niels de Vos <ndevos@redhat.com>
21ab4e
> Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
21ab4e
> Reviewed-by: Prashanth Pai <ppai@redhat.com>
21ab4e
> Tested-by: Niels de Vos <ndevos@redhat.com>
21ab4e
(cherry picked from commit c9027e04456d724a3211e4b08084c96059798e1f)
21ab4e
21ab4e
BUG: 1378085
21ab4e
Change-Id: I70d6a1f4f19d525377aebc8fa57f51e513b92d84
21ab4e
Signed-off-by: Poornima G <pgurusid@redhat.com>
21ab4e
Reviewed-on: https://code.engineering.redhat.com/gerrit/101297
21ab4e
Tested-by: Milind Changire <mchangir@redhat.com>
21ab4e
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
21ab4e
---
21ab4e
 api/src/glfs-mgmt.c          | 61 ++++++++++++++++++++++++++++++++++
21ab4e
 tests/bugs/cli/bug-1169302.c | 78 ++++++++++++++++++++++++++++++++++++++++++++
21ab4e
 tests/bugs/cli/bug-1169302.t | 30 +++++++++++++----
21ab4e
 3 files changed, 162 insertions(+), 7 deletions(-)
21ab4e
 create mode 100644 tests/bugs/cli/bug-1169302.c
21ab4e
21ab4e
diff --git a/api/src/glfs-mgmt.c b/api/src/glfs-mgmt.c
21ab4e
index 8c9872c..9aa92d7 100644
21ab4e
--- a/api/src/glfs-mgmt.c
21ab4e
+++ b/api/src/glfs-mgmt.c
21ab4e
@@ -29,6 +29,7 @@
21ab4e
 #include "portmap-xdr.h"
21ab4e
 #include "xdr-common.h"
21ab4e
 #include "xdr-generic.h"
21ab4e
+#include "rpc-common-xdr.h"
21ab4e
 
21ab4e
 #include "syncop.h"
21ab4e
 #include "xlator.h"
21ab4e
@@ -116,11 +117,71 @@ mgmt_cbk_event (struct rpc_clnt *rpc, void *mydata, void *data)
21ab4e
 	return 0;
21ab4e
 }
21ab4e
 
21ab4e
+static int
21ab4e
+mgmt_cbk_statedump (struct rpc_clnt *rpc, void *mydata, void *data)
21ab4e
+{
21ab4e
+        struct glfs      *fs          = NULL;
21ab4e
+        xlator_t         *this        = NULL;
21ab4e
+        gf_statedump      target_pid  = {0, };
21ab4e
+        struct iovec     *iov         = NULL;
21ab4e
+        int               ret         = -1;
21ab4e
+
21ab4e
+        this = mydata;
21ab4e
+        if (!this) {
21ab4e
+                gf_msg ("glfs", GF_LOG_ERROR, EINVAL,
21ab4e
+                        API_MSG_STATEDUMP_FAILED, "NULL mydata");
21ab4e
+                errno = EINVAL;
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        fs = this->private;
21ab4e
+        if (!fs) {
21ab4e
+                gf_msg ("glfs", GF_LOG_ERROR, EINVAL,
21ab4e
+                        API_MSG_STATEDUMP_FAILED, "NULL glfs");
21ab4e
+                errno = EINVAL;
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        iov = (struct iovec *)data;
21ab4e
+        if (!iov) {
21ab4e
+                gf_msg ("glfs", GF_LOG_ERROR, EINVAL,
21ab4e
+                        API_MSG_STATEDUMP_FAILED, "NULL iovec data");
21ab4e
+                errno = EINVAL;
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        ret = xdr_to_generic (*iov, &target_pid,
21ab4e
+                              (xdrproc_t)xdr_gf_statedump);
21ab4e
+        if (ret < 0) {
21ab4e
+                gf_msg ("glfs", GF_LOG_ERROR, EINVAL,
21ab4e
+                        API_MSG_STATEDUMP_FAILED,
21ab4e
+                        "Failed to decode xdr response for GF_CBK_STATEDUMP");
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
+
21ab4e
+        gf_msg_trace ("glfs", 0, "statedump requested for pid: %d",
21ab4e
+                      target_pid.pid);
21ab4e
+
21ab4e
+        if ((uint64_t)getpid() == target_pid.pid) {
21ab4e
+                gf_msg_debug ("glfs", 0, "Taking statedump for pid: %d",
21ab4e
+                              target_pid.pid);
21ab4e
+
21ab4e
+                ret = glfs_sysrq (fs, GLFS_SYSRQ_STATEDUMP);
21ab4e
+                if (ret < 0) {
21ab4e
+                        gf_msg ("glfs", GF_LOG_INFO, 0,
21ab4e
+                                API_MSG_STATEDUMP_FAILED,
21ab4e
+                                "statedump failed");
21ab4e
+                }
21ab4e
+        }
21ab4e
+out:
21ab4e
+        return ret;
21ab4e
+}
21ab4e
 
21ab4e
 rpcclnt_cb_actor_t mgmt_cbk_actors[GF_CBK_MAXVALUE] = {
21ab4e
 	[GF_CBK_FETCHSPEC] = {"FETCHSPEC", GF_CBK_FETCHSPEC, mgmt_cbk_spec },
21ab4e
 	[GF_CBK_EVENT_NOTIFY] = {"EVENTNOTIFY", GF_CBK_EVENT_NOTIFY,
21ab4e
 				 mgmt_cbk_event},
21ab4e
+        [GF_CBK_STATEDUMP] = {"STATEDUMP", GF_CBK_STATEDUMP, mgmt_cbk_statedump},
21ab4e
 };
21ab4e
 
21ab4e
 
21ab4e
diff --git a/tests/bugs/cli/bug-1169302.c b/tests/bugs/cli/bug-1169302.c
21ab4e
new file mode 100644
21ab4e
index 0000000..aa9f950
21ab4e
--- /dev/null
21ab4e
+++ b/tests/bugs/cli/bug-1169302.c
21ab4e
@@ -0,0 +1,78 @@
21ab4e
+#include <errno.h>
21ab4e
+#include <stdio.h>
21ab4e
+#include <signal.h>
21ab4e
+
21ab4e
+#include <glusterfs/api/glfs.h>
21ab4e
+#include <glusterfs/api/glfs-handles.h>
21ab4e
+
21ab4e
+int keep_running = 1;
21ab4e
+
21ab4e
+void stop_running(int sig)
21ab4e
+{
21ab4e
+        if (sig == SIGTERM)
21ab4e
+                keep_running = 0;
21ab4e
+}
21ab4e
+
21ab4e
+int
21ab4e
+main (int argc, char *argv[])
21ab4e
+{
21ab4e
+        glfs_t *fs = NULL;
21ab4e
+        int ret = 0;
21ab4e
+        glfs_fd_t *fd = NULL;
21ab4e
+        char *filename = NULL;
21ab4e
+        char *logfile = NULL;
21ab4e
+        char *host = NULL;
21ab4e
+
21ab4e
+        if (argc != 5) {
21ab4e
+                return -1;
21ab4e
+        }
21ab4e
+
21ab4e
+        host = argv[2];
21ab4e
+        logfile = argv[3];
21ab4e
+        filename = argv[4];
21ab4e
+
21ab4e
+        /* setup signal handler for exiting */
21ab4e
+        signal (SIGTERM, stop_running);
21ab4e
+
21ab4e
+        fs = glfs_new (argv[1]);
21ab4e
+        if (!fs) {
21ab4e
+                return -1;
21ab4e
+        }
21ab4e
+
21ab4e
+        ret = glfs_set_volfile_server (fs, "tcp", host, 24007);
21ab4e
+        if (ret < 0) {
21ab4e
+                return -1;
21ab4e
+        }
21ab4e
+
21ab4e
+        ret = glfs_set_logging (fs, logfile, 7);
21ab4e
+        if (ret < 0) {
21ab4e
+                return -1;
21ab4e
+        }
21ab4e
+
21ab4e
+        ret = glfs_init (fs);
21ab4e
+        if (ret < 0) {
21ab4e
+                return -1;
21ab4e
+        }
21ab4e
+
21ab4e
+        fd = glfs_creat (fs, filename, O_RDWR, 0644);
21ab4e
+        if (!fd) {
21ab4e
+                return -1;
21ab4e
+        }
21ab4e
+
21ab4e
+        /* sleep until SIGTERM has been received */
21ab4e
+        while (keep_running) {
21ab4e
+                sleep (1);
21ab4e
+        }
21ab4e
+
21ab4e
+        ret = glfs_close (fd);
21ab4e
+        if (ret < 0) {
21ab4e
+                return -1;
21ab4e
+        }
21ab4e
+
21ab4e
+        ret = glfs_fini (fs);
21ab4e
+        if (ret < 0) {
21ab4e
+                return -1;
21ab4e
+        }
21ab4e
+
21ab4e
+        return 0;
21ab4e
+}
21ab4e
diff --git a/tests/bugs/cli/bug-1169302.t b/tests/bugs/cli/bug-1169302.t
21ab4e
index 92252aa..24355e5 100755
21ab4e
--- a/tests/bugs/cli/bug-1169302.t
21ab4e
+++ b/tests/bugs/cli/bug-1169302.t
21ab4e
@@ -7,7 +7,7 @@
21ab4e
 function check_peers {
21ab4e
     $CLI_1 peer status | grep 'Peer in Cluster (Connected)' | wc -l
21ab4e
 }
21ab4e
-cleanup;
21ab4e
+cleanup
21ab4e
 
21ab4e
 #setup cluster and test volume
21ab4e
 TEST launch_cluster 3; # start 3-node virtual cluster
21ab4e
@@ -19,16 +19,32 @@ EXPECT_WITHIN $PROBE_TIMEOUT 2 check_peers;
21ab4e
 TEST $CLI_1 volume create $V0 $H1:$B1/$V0 $H2:$B2/$V0 $H3:$B3/$V0
21ab4e
 TEST $CLI_1 volume start $V0
21ab4e
 
21ab4e
-# there is no gfapi application to take statedumps yet, it will get added in
21ab4e
-# the next patch, this only tests the CLI for correctness
21ab4e
-
21ab4e
-cleanup_statedump
21ab4e
-
21ab4e
+# test CLI parameter acceptance
21ab4e
 TEST ! $CLI_1 volume statedump $V0 client $H2:0
21ab4e
 TEST ! $CLI_2 volume statedump $V0 client $H2:-1
21ab4e
 TEST $CLI_3 volume statedump $V0 client $H2:765
21ab4e
 TEST ! $CLI_1 volume statedump $V0 client $H2:
21ab4e
 TEST ! $CLI_2 volume statedump $V0 client
21ab4e
+TEST ! $CLI_3 volume statedump $V0 client $H2 $GFAPI_PID
21ab4e
+
21ab4e
+# build and run a gfapi appliction for triggering a statedump
21ab4e
+logdir=`gluster --print-logdir`
21ab4e
+STATEDUMP_TIMEOUT=60
21ab4e
+
21ab4e
+build_tester $(dirname $0)/bug-1169302.c -lgfapi
21ab4e
+$(dirname $0)/bug-1169302 $V0 $H1 $logdir/bug-1169302.log testfile & GFAPI_PID=$!
21ab4e
+
21ab4e
+cleanup_statedump
21ab4e
+
21ab4e
+# Take the statedump of the process connected to $H1, it should match the
21ab4e
+# hostname or IP-address with the connection from the bug-1169302 executable.
21ab4e
+# In our CI it seems not possible to use $H0, 'localhost', $(hostname --fqdn)
21ab4e
+# or even "127.0.0.1"....
21ab4e
+TEST $CLI_3 volume statedump $V0 client $H1:$GFAPI_PID
21ab4e
+EXPECT_WITHIN $STATEDUMP_TIMEOUT "Y" path_exists $statedumpdir/glusterdump.$GFAPI_PID*
21ab4e
+
21ab4e
+kill $GFAPI_PID
21ab4e
 
21ab4e
 cleanup_statedump
21ab4e
-cleanup;
21ab4e
+cleanup_tester $(dirname $0)/bug-1169302
21ab4e
+cleanup
21ab4e
-- 
21ab4e
1.8.3.1
21ab4e