summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/src/gfapi-messages.h3
-rw-r--r--api/src/gfapi.aliases2
-rw-r--r--api/src/gfapi.map7
-rw-r--r--api/src/glfs.c64
-rw-r--r--api/src/glfs.h17
-rw-r--r--tests/basic/gfapi/glfs_sysrq.c61
-rwxr-xr-xtests/basic/gfapi/glfs_sysrq.t39
7 files changed, 188 insertions, 5 deletions
diff --git a/api/src/gfapi-messages.h b/api/src/gfapi-messages.h
index 5deef15e3ae..6e131b5a295 100644
--- a/api/src/gfapi-messages.h
+++ b/api/src/gfapi-messages.h
@@ -40,7 +40,7 @@
*/
#define GLFS_GFAPI_BASE GLFS_MSGID_COMP_API
-#define GLFS_NUM_MESSAGES 48
+#define GLFS_NUM_MESSAGES 49
#define GLFS_MSGID_END (GLFS_GFAPI_BASE + GLFS_NUM_MESSAGES + 1)
/* Messages with message IDs */
#define glfs_msg_start_x GLFS_GFAPI_BASE, "Invalid: Start of messages"
@@ -94,6 +94,7 @@
#define API_MSG_ALLOC_FAILED (GLFS_GFAPI_BASE + 46)
#define API_MSG_CREATE_HANDLE_FAILED (GLFS_GFAPI_BASE + 47)
#define API_MSG_INODE_LINK_FAILED (GLFS_GFAPI_BASE + 48)
+#define API_MSG_STATEDUMP_FAILED (GLFS_GFAPI_BASE + 49)
/*------------*/
#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
diff --git a/api/src/gfapi.aliases b/api/src/gfapi.aliases
index d2c4ba2f037..5acfebd83d9 100644
--- a/api/src/gfapi.aliases
+++ b/api/src/gfapi.aliases
@@ -156,4 +156,6 @@ _pub_glfs_upcall_inode_get_oldpobject _glfs_upcall_inode_get_oldpobject$GFAPI_3.
_pub_glfs_upcall_inode_get_oldpstat _glfs_upcall_inode_get_oldpstat$GFAPI_3.7.16
_pub_glfs_realpath _glfs_realpath$GFAPI_3.7.17
+_pub_glfs_sysrq _glfs_sysrq$GFAPI_3.10.0
+
_pub_glfs_ipc _glfs_ipc$GFAPI_4.0.0
diff --git a/api/src/gfapi.map b/api/src/gfapi.map
index d022380497f..b6eb9a748e1 100644
--- a/api/src/gfapi.map
+++ b/api/src/gfapi.map
@@ -194,7 +194,12 @@ GFAPI_3.7.17 {
glfs_realpath;
} GFAPI_3.7.16;
+GFAPI_3.10.0 {
+ global:
+ glfs_sysrq;
+} GFAPI_3.7.17;
+
GFAPI_4.0.0 {
global:
glfs_ipc;
-} GFAPI_3.7.17;
+} GFAPI_3.10.0;
diff --git a/api/src/glfs.c b/api/src/glfs.c
index 4375774a853..94a12c0be31 100644
--- a/api/src/glfs.c
+++ b/api/src/glfs.c
@@ -40,12 +40,13 @@
#include "common-utils.h"
#include "syncop.h"
#include "call-stub.h"
-#include "gfapi-messages.h"
+#include "hashfn.h"
+#include "rpc-clnt.h"
+#include "statedump.h"
+#include "gfapi-messages.h"
#include "glfs.h"
#include "glfs-internal.h"
-#include "hashfn.h"
-#include "rpc-clnt.h"
static gf_boolean_t
@@ -1462,3 +1463,60 @@ pub_glfs_upcall_inode_get_oldpstat (struct glfs_upcall_inode *arg)
return &arg->oldp_buf;
}
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_oldpstat, 3.7.16);
+
+
+/* definitions of the GLFS_SYSRQ_* chars are in glfs.h */
+static struct glfs_sysrq_help {
+ char sysrq;
+ char *msg;
+} glfs_sysrq_help[] = {
+ { GLFS_SYSRQ_HELP, "(H)elp" },
+ { GLFS_SYSRQ_STATEDUMP, "(S)tatedump" },
+ { 0, NULL }
+};
+
+int
+pub_glfs_sysrq (struct glfs *fs, char sysrq)
+{
+ glusterfs_ctx_t *ctx = NULL;
+ int ret = 0;
+
+ if (!fs || !fs->ctx) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ ctx = fs->ctx;
+
+ switch (sysrq) {
+ case GLFS_SYSRQ_HELP:
+ {
+ char msg[1024]; /* help text should not exceed 1024 chars */
+ struct glfs_sysrq_help *usage;
+
+ msg[0] = '\0';
+ for (usage = glfs_sysrq_help; usage->sysrq; usage++) {
+ strncat (msg, usage->msg, 1024);
+ strncat (msg, " ", 1024);
+ }
+
+ /* not really an 'error', but make sure it gets logged */
+ gf_log ("glfs", GF_LOG_ERROR, "available events: %s", msg);
+
+ break;
+ }
+ case GLFS_SYSRQ_STATEDUMP:
+ gf_proc_dump_info (SIGUSR1, ctx);
+ break;
+ default:
+ gf_msg ("glfs", GF_LOG_ERROR, ENOTSUP, API_MSG_INVALID_ENTRY,
+ "'%c' is not a valid sysrq", sysrq);
+ errno = ENOTSUP;
+ ret = -1;
+ }
+out:
+ return ret;
+}
+
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_sysrq, 3.10.0);
diff --git a/api/src/glfs.h b/api/src/glfs.h
index 903492a9466..f5a0e1a2a84 100644
--- a/api/src/glfs.h
+++ b/api/src/glfs.h
@@ -773,6 +773,23 @@ void glfs_free (void *ptr) __THROW
GFAPI_PUBLIC(glfs_free, 3.7.16);
/*
+ * glfs_sysrq: send a system request to the @fs instance
+ *
+ * Different commands for @sysrq are possible, the defines for these are listed
+ * below the function definition.
+ *
+ * This function always returns success if the @sysrq is recognized. The return
+ * value does not way anythin about the result of the @sysrq execution. Not all
+ * @sysrq command will be able to return a success/failure status.
+ */
+int glfs_sysrq (glfs_t *fs, char sysrq) __THROW
+ GFAPI_PUBLIC(glfs_sysrq, 3.10.0);
+
+#define GLFS_SYSRQ_HELP 'h' /* log a message with supported sysrq commands */
+#define GLFS_SYSRQ_STATEDUMP 's' /* create a statedump */
+
+
+/*
* Nobody needs this call at all yet except for the test script.
*/
int glfs_ipc (glfs_fd_t *fd, int cmd, void *xd_in, void **xd_out) __THROW
diff --git a/tests/basic/gfapi/glfs_sysrq.c b/tests/basic/gfapi/glfs_sysrq.c
new file mode 100644
index 00000000000..c843c2a3559
--- /dev/null
+++ b/tests/basic/gfapi/glfs_sysrq.c
@@ -0,0 +1,61 @@
+/** glfs_sysrq.c
+ *
+ * Simple test application to run all glfs_syqrq() debugging calls.
+ *
+ * Usage: ./glfs_sysrq <host> <volume> <logfile>
+ */
+#include <errno.h>
+#include <stdio.h>
+
+#include <glusterfs/api/glfs.h>
+
+int
+main (int argc, char *argv[])
+{
+ /* cmdline arguments */
+ char *host = NULL;
+ char *volume = NULL;
+ char *logfile = NULL;
+
+ /* other variables */
+ glfs_t *fs = NULL;
+ int ret = 0;
+
+ if (argc != 4) {
+ fprintf (stderr, "Usage: %s <host> <volume> <logfile>\n",
+ argv[0]);
+ return -1;
+ }
+
+ host = argv[1];
+ volume = argv[2];
+ logfile = argv[3];
+
+ fs = glfs_new (volume);
+ if (!fs) {
+ return -1;
+ }
+
+ ret = glfs_set_logging (fs, logfile, 7);
+ if (ret < 0) {
+ return -1;
+ }
+
+ ret = glfs_set_volfile_server (fs, "tcp", host, 24007);
+ if (ret < 0) {
+ return -1;
+ }
+
+ ret = glfs_init (fs);
+ if (ret < 0) {
+ return -1;
+ }
+
+ /* checking of the results is easier in the script running this test */
+ glfs_sysrq (fs, GLFS_SYSRQ_HELP);
+ glfs_sysrq (fs, GLFS_SYSRQ_STATEDUMP);
+
+ glfs_fini (fs);
+
+ return 0;
+}
diff --git a/tests/basic/gfapi/glfs_sysrq.t b/tests/basic/gfapi/glfs_sysrq.t
new file mode 100755
index 00000000000..d1a0e9bc248
--- /dev/null
+++ b/tests/basic/gfapi/glfs_sysrq.t
@@ -0,0 +1,39 @@
+#!/bin/bash
+#
+# Run glfs_sysrq, a gfapi applications calling all glfs_sysrq() commands.
+# Each command generates a specific log message, or something else that can be
+# tested for existance.
+#
+
+. $(dirname $0)/../../include.rc
+. $(dirname $0)/../../volume.rc
+
+cleanup
+
+TEST glusterd
+TEST pidof glusterd
+TEST $CLI volume create $V0 $H0:$B0/brick1
+EXPECT 'Created' volinfo_field $V0 'Status'
+
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status'
+
+logdir=$(gluster --print-logdir)
+
+# clear all statedumps
+cleanup_statedump
+TEST ! test -e $statedumpdir/*.dump.*
+# vim friendly command */
+
+build_tester $(dirname $0)/glfs_sysrq.c -lgfapi
+TEST $(dirname $0)/glfs_sysrq $H0 $V0 $logdir/glfs_sysrq.log
+
+# check for the help message in the log
+TEST grep -q '"(H)elp"' $logdir/glfs_sysrq.log
+
+# see if there is a statedump
+TEST test -e $statedumpdir/*.dump.*
+# vim friendly command */
+
+cleanup_tester $(dirname $0)/glfs_sysrq
+cleanup