diff options
-rw-r--r-- | api/src/gfapi-messages.h | 3 | ||||
-rw-r--r-- | api/src/gfapi.aliases | 2 | ||||
-rw-r--r-- | api/src/gfapi.map | 7 | ||||
-rw-r--r-- | api/src/glfs.c | 64 | ||||
-rw-r--r-- | api/src/glfs.h | 17 | ||||
-rw-r--r-- | tests/basic/gfapi/glfs_sysrq.c | 61 | ||||
-rwxr-xr-x | tests/basic/gfapi/glfs_sysrq.t | 39 |
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 |