summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/gluster-block.c73
-rw-r--r--configure.ac5
-rw-r--r--docs/gluster-block.86
-rw-r--r--gluster-block.spec.in4
-rw-r--r--rpc/Makefile.am7
-rw-r--r--rpc/block_svc_routines.c736
-rw-r--r--rpc/glfs-operations.c76
-rw-r--r--rpc/glfs-operations.h11
-rw-r--r--rpc/rpcl/block.x39
-rwxr-xr-xtests/basic.t16
-rw-r--r--utils/Makefile.am2
-rw-r--r--utils/common.c24
-rw-r--r--utils/common.h15
-rw-r--r--utils/utils.h30
14 files changed, 732 insertions, 312 deletions
diff --git a/cli/gluster-block.c b/cli/gluster-block.c
index 5d9d413..d5f9c02 100644
--- a/cli/gluster-block.c
+++ b/cli/gluster-block.c
@@ -32,6 +32,12 @@ const char *argp_program_version = "" \
"or later), or the GNU General Public License, version 2 (GPLv2),\n"\
"in all cases as published by the Free Software Foundation.";
+#define GB_CREATE_HELP_STR "gluster-block create <volname/blockname> "\
+ "[ha <count>] <HOST1[,HOST2,...]> <size> [--json*]"
+
+#define GB_DELETE_HELP_STR "gluster-block delete <volname/blockname> [--json*]"
+#define GB_INFO_HELP_STR "gluster-block info <volname/blockname> [--json*]"
+#define GB_LIST_HELP_STR "gluster-block list <volname> [--json*]"
static int
glusterBlockCliRPC_1(void *cobj, clioperations opt, char **out)
@@ -159,7 +165,7 @@ glusterBlockHelp(void)
MSG("%s",
PACKAGE_NAME" ("PACKAGE_VERSION")\n"
"usage:\n"
- " gluster-block <command> <volname[/blockname]> [<args>]\n"
+ " gluster-block <command> <volname[/blockname]> [<args>] [--json*]\n"
"\n"
"commands:\n"
" create <volname/blockname> [ha <count>] <host1[,host2,...]> <size>\n"
@@ -179,12 +185,15 @@ glusterBlockHelp(void)
"\n"
" version\n"
" show version info and exit.\n"
+ "\n"
+ "supported JSON formats:\n"
+ " --json|--json-plain|--json-spaced|--json-pretty\n"
);
}
static int
-glusterBlockCreate(int argcount, char **options)
+glusterBlockCreate(int argcount, char **options, int json)
{
size_t optind = 2;
int ret = -1;
@@ -195,10 +204,10 @@ glusterBlockCreate(int argcount, char **options)
char *sep;
+ cobj.json_resp = json;
if (argcount <= optind) {
MSG("%s\n", "Insufficient arguments for create:");
- MSG("%s\n", "gluster-block create <volname/blockname> [ha <count>]"
- " <HOST1[,HOST2,...]> <size>");
+ MSG("%s\n", GB_CREATE_HELP_STR);
return -1;
}
@@ -213,8 +222,7 @@ glusterBlockCreate(int argcount, char **options)
if (!sep) {
MSG("%s\n",
"first argument '<volname/blockname>' doesn't seems to be right");
- MSG("%s\n", "gluster-block create <volname/blockname> [ha <count>] "
- " <HOST1[,HOST2,...]> <size>");
+ MSG("%s\n", GB_CREATE_HELP_STR);
LOG("cli", GB_LOG_ERROR, "%s",
"create failed while parsing <volname/blockname>");
goto out;
@@ -235,8 +243,7 @@ glusterBlockCreate(int argcount, char **options)
if (argcount - optind < 2) { /* left with servers and size so 2 */
MSG("%s\n", "Insufficient arguments for create");
- MSG("%s\n", "gluster-block create <volname/blockname> [ha <count>]"
- " <HOST1[,HOST2,...]> <size>");
+ MSG("%s\n", GB_CREATE_HELP_STR);
LOG("cli", GB_LOG_ERROR,
"failed creating block %s on volume %s with hosts %s",
cobj.block_name, cobj.volume, cobj.block_hosts);
@@ -245,8 +252,8 @@ glusterBlockCreate(int argcount, char **options)
/* next arg to 'ha count' will be servers */
if (GB_STRDUP(cobj.block_hosts, options[optind++]) < 0) {
- LOG("cli", GB_LOG_ERROR, "failed while parsing servers for block %s",
- cobj.block_name);
+ LOG("cli", GB_LOG_ERROR, "failed while parsing servers for block <%s/%s>",
+ cobj.volume, cobj.block_name);
goto out;
}
@@ -254,10 +261,9 @@ glusterBlockCreate(int argcount, char **options)
sparse_ret = glusterBlockCreateParseSize("cli", options[optind]);
if (sparse_ret < 0) {
MSG("%s\n", "last argument '<size>' doesn't seems to be right");
- MSG("%s\n", "gluster-block create <volname/blockname> [ha <count>] "
- " <HOST1[,HOST2,...]> <size>");
- LOG("cli", GB_LOG_ERROR, "failed while parsing size for block %s",
- cobj.block_name);
+ MSG("%s\n", GB_CREATE_HELP_STR);
+ LOG("cli", GB_LOG_ERROR, "failed while parsing size for block <%s/%s>",
+ cobj.volume, cobj.block_name);
goto out;
}
cobj.size = sparse_ret; /* size is unsigned long long */
@@ -283,16 +289,17 @@ glusterBlockCreate(int argcount, char **options)
static int
-glusterBlockList(int argcount, char **options)
+glusterBlockList(int argcount, char **options, int json)
{
blockListCli cobj;
char *out = NULL;
int ret = -1;
+ cobj.json_resp = json;
if (argcount != 3) {
MSG("%s\n", "Insufficient arguments for list:");
- MSG("%s\n", "gluster-block list <volname>");
+ MSG("%s\n", GB_LIST_HELP_STR);
return -1;
}
@@ -315,7 +322,7 @@ glusterBlockList(int argcount, char **options)
static int
-glusterBlockDelete(int argcount, char **options)
+glusterBlockDelete(int argcount, char **options, int json)
{
blockDeleteCli cobj;
char *out = NULL;
@@ -324,9 +331,10 @@ glusterBlockDelete(int argcount, char **options)
int ret = -1;
+ cobj.json_resp = json;
if (argcount != 3) {
MSG("%s\n", "Insufficient arguments for delete:");
- MSG("%s\n", "gluster-block delete <volname/blockname>");
+ MSG("%s\n", GB_DELETE_HELP_STR);
return -1;
}
@@ -338,7 +346,7 @@ glusterBlockDelete(int argcount, char **options)
sep = strchr(argcopy, '/');
if (!sep) {
MSG("%s\n", "argument '<volname/blockname>' doesn't seems to be right");
- MSG("%s\n", "gluster-block delete <volname/blockname>");
+ MSG("%s\n", GB_DELETE_HELP_STR);
LOG("cli", GB_LOG_ERROR, "%s",
"delete failed while parsing <volname/blockname>");
goto out;
@@ -368,7 +376,7 @@ glusterBlockDelete(int argcount, char **options)
static int
-glusterBlockInfo(int argcount, char **options)
+glusterBlockInfo(int argcount, char **options, int json)
{
blockInfoCli cobj;
char *out = NULL;
@@ -377,9 +385,10 @@ glusterBlockInfo(int argcount, char **options)
int ret = -1;
+ cobj.json_resp = json;
if (argcount != 3) {
MSG("%s\n", "Insufficient arguments for info:");
- MSG("%s\n", "gluster-block info <volname/blockname>");
+ MSG("%s\n", GB_INFO_HELP_STR);
return -1;
}
@@ -391,7 +400,7 @@ glusterBlockInfo(int argcount, char **options)
sep = strchr(argcopy, '/');
if (!sep) {
MSG("%s\n", "argument '<volname/blockname>' doesn't seems to be right");
- MSG("%s\n", "gluster-block info <volname/blockname>");
+ MSG("%s\n", GB_INFO_HELP_STR);
LOG("cli", GB_LOG_ERROR, "%s",
"info failed while parsing <volname/blockname>");
goto out;
@@ -426,6 +435,7 @@ glusterBlockParseArgs(int count, char **options)
{
int ret = 0;
size_t opt = 0;
+ int json = GB_JSON_NONE;
opt = glusterBlockCLIOptEnumParse(options[1]);
@@ -434,24 +444,35 @@ glusterBlockParseArgs(int count, char **options)
return -1;
}
+ if (opt > 0 && opt < GB_CLI_HELP) {
+ json = jsonResponseFormatParse (options[count-1]);
+ if (json == GB_JSON_MAX) {
+ MSG("expecting '--json*', but argument %s doesn't seem to be matching",
+ options[count-1]);
+ return -1;
+ } else if (json != GB_JSON_NONE) {
+ count--;/*Commands don't need to handle json*/
+ }
+ }
+
while (1) {
switch (opt) {
case GB_CLI_CREATE:
- ret = glusterBlockCreate(count, options);
+ ret = glusterBlockCreate(count, options, json);
if (ret && ret != EEXIST) {
LOG("cli", GB_LOG_ERROR, "%s", FAILED_CREATE);
}
goto out;
case GB_CLI_LIST:
- ret = glusterBlockList(count, options);
+ ret = glusterBlockList(count, options, json);
if (ret) {
LOG("cli", GB_LOG_ERROR, "%s", FAILED_LIST);
}
goto out;
case GB_CLI_INFO:
- ret = glusterBlockInfo(count, options);
+ ret = glusterBlockInfo(count, options, json);
if (ret) {
LOG("cli", GB_LOG_ERROR, "%s", FAILED_INFO);
}
@@ -462,7 +483,7 @@ glusterBlockParseArgs(int count, char **options)
goto out;
case GB_CLI_DELETE:
- ret = glusterBlockDelete(count, options);
+ ret = glusterBlockDelete(count, options, json);
if (ret) {
LOG("cli", GB_LOG_ERROR, "%s", FAILED_DELETE);
}
diff --git a/configure.ac b/configure.ac
index d0533c5..542b5b6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -64,6 +64,11 @@ PKG_CHECK_MODULES([GFAPI], [glusterfs-api >= 7.3.6],,
AC_SUBST(GFAPI_CFLAGS)
AC_SUBST(GFAPI_LIBS)
+PKG_CHECK_MODULES([JSONC], [json-c],,
+ [AC_MSG_ERROR([json-c library is required to build gluster-block])])
+AC_SUBST(JSONC_CFLAGS)
+AC_SUBST(JSONC_LIBS)
+
AC_CHECK_LIB([uuid], [uuid_generate], [UUID="-luuid"],
AC_MSG_ERROR([uuid library is required to build gluster-block]))
AC_SUBST(UUID)
diff --git a/docs/gluster-block.8 b/docs/gluster-block.8
index f50e95c..66d29e7 100644
--- a/docs/gluster-block.8
+++ b/docs/gluster-block.8
@@ -12,6 +12,7 @@ gluster-block - Gluster Block Storage Console Manager (command line utility)
<\fBcreate|list|info|delete\fR>
<\fBvolname\fR[\fB/blockname\fR]>
[\fB<args>\fR]
+[\fB--json*\fR]
.PP
@@ -62,6 +63,8 @@ show this message and exit.
show version info and exit.
.PP
+.SH SUPPORTED JSON-FORMATS
+--json | --json-plain | --json-spaced | --json-pretty
.SH EXAMPLES
.nf
@@ -71,6 +74,9 @@ To create a block device of size 1GiB
To create a block device of size 1GiB with multi-path(replica) 3
.B # gluster-block create blockVol/sampleBlock ha 3 ${HOST1},${HOST2},${HOST3} 1GiB
+To create a block device of size 1GiB and expect response in json format
+.B # gluster-block create blockVol/sampleBlock ${HOST} 1GiB --json
+
You can pass more no. of nodes than ha count, this will actually help create in recovering from
failures, incase creation of block fails on any of scheduled(always first in list) ha count nodes.
.B # gluster-block create blockVol/sampleBlock ha 3 ${HOST1},${HOST2},${HOST3},${HOST4},${HOST5} 1GiB
diff --git a/gluster-block.spec.in b/gluster-block.spec.in
index af840bc..b784be0 100644
--- a/gluster-block.spec.in
+++ b/gluster-block.spec.in
@@ -19,6 +19,7 @@ URL: https://github.com/gluster/gluster-block
Source0: @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz
BuildRequires: glusterfs-api-devel >= 3.6.0
+BuildRequires: json-c-devel
BuildRequires: help2man >= 1.36
%if ( 0%{?_with_systemd:1} )
BuildRequires: systemd-units
@@ -55,6 +56,9 @@ rm -rf ${RPM_BUILD_ROOT}
%endif
%changelog
+* Mon Mar 27 2017 Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+- add json-c-devel to build dependency list
+
* Mon Mar 6 2017 Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
- conditionally enable with_systemd flag
diff --git a/rpc/Makefile.am b/rpc/Makefile.am
index 4dd7439..8cabcc1 100644
--- a/rpc/Makefile.am
+++ b/rpc/Makefile.am
@@ -6,10 +6,11 @@ libgbrpc_la_SOURCES = block_svc_routines.c glfs-operations.c
noinst_HEADERS = glfs-operations.h
-libgbrpc_la_CFLAGS = $(GFAPI_CFLAGS) -DDATADIR=\"$(localstatedir)\" \
- -I$(top_srcdir)/utils/ -I$(top_builddir)/rpc/rpcl
+libgbrpc_la_CFLAGS = $(GFAPI_CFLAGS) $(JSONC_CFLAGS) \
+ -DDATADIR=\"$(localstatedir)\" \
+ -I$(top_srcdir)/utils/ -I$(top_builddir)/rpc/rpcl
-libgbrpc_la_LIBADD = $(GFAPI_LIBS) $(UUID) rpcl/libgbrpcxdr.la
+libgbrpc_la_LIBADD = $(GFAPI_LIBS) $(JSONC_LIBS) $(UUID) rpcl/libgbrpcxdr.la
libgbrpc_ladir = $(includedir)/gluster-block/rpc
diff --git a/rpc/block_svc_routines.c b/rpc/block_svc_routines.c
index 6a4bced..b966e05 100644
--- a/rpc/block_svc_routines.c
+++ b/rpc/block_svc_routines.c
@@ -15,6 +15,7 @@
# include <pthread.h>
# include <netdb.h>
# include <uuid/uuid.h>
+# include <json-c/json.h>
# define UUID_BUF_SIZE 38
@@ -108,6 +109,26 @@ getLastWordNoDot(char *line)
}
+static int
+mapJsonFlagToJsonCstring(int jsonflag)
+{
+ switch (jsonflag) {
+ case GB_JSON_PLAIN:
+ return JSON_C_TO_STRING_PLAIN;
+
+ case GB_JSON_DEFAULT:
+ case GB_JSON_SPACED:
+ return JSON_C_TO_STRING_SPACED;
+
+ case GB_JSON_PRETTY:
+ return JSON_C_TO_STRING_PRETTY;
+
+ default:
+ return JSON_C_TO_STRING_SPACED;
+ }
+}
+
+
static void
blockCreateParsedRespFree(blockRemoteCreateResp *savereply)
{
@@ -411,10 +432,11 @@ glusterBlockCreateRemote(void *data)
int ret;
blockRemoteObj *args = (blockRemoteObj *)data;
blockCreate cobj = *(blockCreate *)args->obj;
+ char *errMsg = NULL;
GB_METAUPDATE_OR_GOTO(lock, args->glfs, cobj.block_name, cobj.volume,
- ret, out, "%s: CONFIGINPROGRESS\n", args->addr);
+ ret, errMsg, out, "%s: CONFIGINPROGRESS\n", args->addr);
ret = glusterBlockCallRPC_1(args->addr, &cobj, CREATE_SRV, &args->reply);
if (ret) {
@@ -433,23 +455,25 @@ glusterBlockCreateRemote(void *data)
}
GB_METAUPDATE_OR_GOTO(lock, args->glfs, cobj.block_name, cobj.volume,
- ret, out, "%s: CONFIGFAIL\n", args->addr);
+ ret, errMsg, out, "%s: CONFIGFAIL\n", args->addr);
LOG("mgmt", GB_LOG_ERROR, "%s for block %s on host %s volume %s",
FAILED_REMOTE_CREATE, cobj.block_name, args->addr, args->volume);
goto out;
}
GB_METAUPDATE_OR_GOTO(lock, args->glfs, cobj.block_name, cobj.volume,
- ret, out, "%s: CONFIGSUCCESS\n", args->addr);
+ ret, errMsg, out, "%s: CONFIGSUCCESS\n", args->addr);
out:
if (!args->reply) {
- if (asprintf(&args->reply, "failed to config on %s", args->addr) == -1) {
+ if (GB_ASPRINTF(&args->reply, "failed to config on %s %s\n", args->addr,
+ errMsg?errMsg:"") == -1) {
ret = -1;
}
}
args->exit = ret;
+ GB_FREE (errMsg);
return NULL;
}
@@ -521,10 +545,11 @@ glusterBlockDeleteRemote(void *data)
int ret;
blockRemoteObj *args = (blockRemoteObj *)data;
blockDelete dobj = *(blockDelete *)args->obj;
+ char *errMsg = NULL;
GB_METAUPDATE_OR_GOTO(lock, args->glfs, dobj.block_name, args->volume,
- ret, out, "%s: CLEANUPINPROGRESS\n", args->addr);
+ ret, errMsg, out, "%s: CLEANUPINPROGRESS\n", args->addr);
ret = glusterBlockCallRPC_1(args->addr, &dobj, DELETE_SRV, &args->reply);
if (ret) {
if (errno == ENETUNREACH || errno == ECONNREFUSED || errno == ETIMEDOUT) {
@@ -542,21 +567,22 @@ glusterBlockDeleteRemote(void *data)
}
GB_METAUPDATE_OR_GOTO(lock, args->glfs, dobj.block_name, args->volume,
- ret, out, "%s: CLEANUPFAIL\n", args->addr);
+ ret, errMsg, out, "%s: CLEANUPFAIL\n", args->addr);
LOG("mgmt", GB_LOG_ERROR, "%s for block %s on host %s volume %s",
FAILED_REMOTE_DELETE, dobj.block_name, args->addr, args->volume);
goto out;
}
GB_METAUPDATE_OR_GOTO(lock, args->glfs, dobj.block_name, args->volume,
- ret, out, "%s: CLEANUPSUCCESS\n", args->addr);
+ ret, errMsg, out, "%s: CLEANUPSUCCESS\n", args->addr);
out:
if (!args->reply) {
- if (asprintf(&args->reply, "failed to delete config on %s",
- args->addr) == -1) {
+ if (GB_ASPRINTF(&args->reply, "failed to delete config on %s",
+ args->addr) == -1) {
ret = -1;
}
}
+ GB_FREE(errMsg);
args->exit = ret;
return NULL;
@@ -623,15 +649,15 @@ glusterBlockDeleteRemoteAsync(MetaInfo *info,
/* collect return */
for (i = 0; i < count; i++) {
if (args[i].exit) {
- if (asprintf(&d_attempt, "%s %s",
- (a_tmp==NULL?"":a_tmp), args[i].addr) == -1) {
+ if (GB_ASPRINTF(&d_attempt, "%s %s",
+ (a_tmp==NULL?"":a_tmp), args[i].addr) == -1) {
goto out;
}
GB_FREE(a_tmp);
a_tmp = d_attempt;
} else {
- if (asprintf(&d_success, "%s %s",
- (s_tmp==NULL?"":s_tmp), args[i].addr) == -1) {
+ if (GB_ASPRINTF(&d_success, "%s %s",
+ (s_tmp==NULL?"":s_tmp), args[i].addr) == -1) {
goto out;
}
GB_FREE(s_tmp);
@@ -641,8 +667,8 @@ glusterBlockDeleteRemoteAsync(MetaInfo *info,
if (d_attempt) {
a_tmp = local->d_attempt;
- if (asprintf(&local->d_attempt, "%s %s",
- (a_tmp==NULL?"":a_tmp), d_attempt) == -1) {
+ if (GB_ASPRINTF(&local->d_attempt, "%s %s",
+ (a_tmp==NULL?"":a_tmp), d_attempt) == -1) {
goto out;
}
GB_FREE(a_tmp);
@@ -651,8 +677,8 @@ glusterBlockDeleteRemoteAsync(MetaInfo *info,
if (d_success) {
s_tmp = local->d_success;
- if (asprintf(&local->d_success, "%s %s",
- (s_tmp==NULL?"":s_tmp), d_success) == -1) {
+ if (GB_ASPRINTF(&local->d_success, "%s %s",
+ (s_tmp==NULL?"":s_tmp), d_success) == -1) {
goto out;
}
GB_FREE(s_tmp);
@@ -694,6 +720,7 @@ glusterBlockCleanUp(operations opt, struct glfs *glfs, char *blockname,
blockRemoteDeleteResp *drobj;
blockRemoteCreateResp *crobj;
int asyncret = 0;
+ char *errMsg = NULL;
switch(opt) {
case CREATE_SRV:
@@ -712,7 +739,7 @@ glusterBlockCleanUp(operations opt, struct glfs *glfs, char *blockname,
goto out;
}
- ret = blockGetMetaInfo(glfs, blockname, info);
+ ret = blockGetMetaInfo(glfs, blockname, info, NULL);
if (ret) {
goto out;
}
@@ -751,7 +778,7 @@ glusterBlockCleanUp(operations opt, struct glfs *glfs, char *blockname,
goto out;
}
- ret = blockGetMetaInfo(glfs, blockname, info);
+ ret = blockGetMetaInfo(glfs, blockname, info, NULL);
if (ret) {
goto out;
}
@@ -767,17 +794,17 @@ glusterBlockCleanUp(operations opt, struct glfs *glfs, char *blockname,
if (cleanupsuccess == info->nhosts) {
GB_METAUPDATE_OR_GOTO(lock, glfs, blockname, info->volume,
- ret, out, "ENTRYDELETE: INPROGRESS\n");
+ ret, errMsg, out, "ENTRYDELETE: INPROGRESS\n");
if (glusterBlockDeleteEntry(glfs, info->volume, info->gbid)) {
GB_METAUPDATE_OR_GOTO(lock, glfs, blockname, info->volume,
- ret, out, "ENTRYDELETE: FAIL\n");
+ ret, errMsg, out, "ENTRYDELETE: FAIL\n");
LOG("mgmt", GB_LOG_ERROR, "%s %s for block %s", FAILED_DELETING_FILE,
info->volume, blockname);
ret = -1;
goto out;
}
GB_METAUPDATE_OR_GOTO(lock, glfs, blockname, info->volume,
- ret, out, "ENTRYDELETE: SUCCESS\n");
+ ret, errMsg, out, "ENTRYDELETE: SUCCESS\n");
ret = glusterBlockDeleteMetaFile(glfs, info->volume, blockname);
if (ret) {
LOG("mgmt", GB_LOG_ERROR, "%s %s for block %s",
@@ -789,6 +816,7 @@ glusterBlockCleanUp(operations opt, struct glfs *glfs, char *blockname,
out:
blockFreeMetaInfo(info);
+ GB_FREE (errMsg);
return asyncret?asyncret:ret;
}
@@ -816,7 +844,7 @@ glusterBlockAuditRequest(struct glfs *glfs,
goto out;
}
- ret = blockGetMetaInfo(glfs, blk->block_name, info);
+ ret = blockGetMetaInfo(glfs, blk->block_name, info, NULL);
if (ret) {
goto out;
}
@@ -898,12 +926,130 @@ glusterBlockAuditRequest(struct glfs *glfs,
return ret;
}
+void
+block_format_error_response (int json_resp, int errCode, char *errMsg,
+ struct blockResponse *reply)
+{
+ json_object *json_obj = NULL;
+ reply->exit = errCode;
+ if (json_resp) {
+ json_obj = json_object_new_object();
+ json_object_object_add(json_obj, "RESULT", json_object_new_string("FAIL"));
+ json_object_object_add(json_obj, "errCode", json_object_new_int(errCode));
+ json_object_object_add(json_obj, "errMsg", json_object_new_string(errMsg));
+ GB_ASPRINTF(&reply->out, "%s\n",
+ json_object_to_json_string_ext(json_obj,
+ mapJsonFlagToJsonCstring(json_resp)));
+ json_object_put(json_obj);
+ } else {
+ GB_ASPRINTF (&reply->out, "%s\nRESULT:FAIL\n", errMsg);
+ }
+}
+
+void
+block_create_cli_format_response(blockCreateCli *blk, int errCode,
+ char *errMsg, blockRemoteCreateResp *savereply,
+ struct blockResponse *reply)
+{
+ json_object *json_obj = NULL;
+ json_object *json_array = NULL;
+ char *tmp = NULL;
+ char *portals = NULL;
+ int i = 0;
+
+ if (!reply) {
+ return;
+ }
+
+ if (errCode < 0) {
+ errCode = 255;
+ }
+
+ if (errMsg) {
+ block_format_error_response(blk->json_resp, errCode, errMsg, reply);
+ return;
+ }
+
+ if (blk->json_resp) {
+ json_obj = json_object_new_object();
+ json_object_object_add(json_obj, "IQN",
+ json_object_new_string(savereply->iqn));
+
+ json_array = json_object_new_array();
+
+ for (i = 0; i < savereply->nportal; i++) {
+ json_object_array_add(json_array,
+ json_object_new_string(savereply->portal[i]));
+ }
+
+ json_object_object_add(json_obj, "PORTAL(S)", json_array);
+
+ if (savereply->obj->d_attempt || savereply->obj->d_success) {
+ json_object_put(json_array);
+ json_array = json_object_new_array();
+
+ if (savereply->obj->d_attempt) {
+ tmp = strtok (savereply->obj->d_attempt, " ");
+ while (tmp!= NULL)
+ {
+ json_object_array_add(json_array, json_object_new_string(tmp));
+ tmp = strtok (NULL, " ");
+ }
+ }
+
+ if (savereply->obj->d_success) {
+ tmp = strtok (savereply->obj->d_success, " ");
+ while (tmp!= NULL)
+ {
+ json_object_array_add(json_array, json_object_new_string(tmp));
+ tmp = strtok (NULL, " ");
+ }
+ }
+ tmp = NULL;
+ json_object_object_add(json_obj, "REWIND ON", json_array);
+ }
+
+ json_object_object_add(json_obj, "RESULT",
+ errCode?json_object_new_string("FAIL"):json_object_new_string("SUCCESS"));
+
+ GB_ASPRINTF(&reply->out, "%s\n",
+ json_object_to_json_string_ext(json_obj,
+ mapJsonFlagToJsonCstring(blk->json_resp)));
+ json_object_put(json_array);
+ json_object_put(json_obj);
+ } else {
+ for (i = 0; i < savereply->nportal; i++) {
+ if (GB_ASPRINTF(&portals, "%s %s",
+ tmp!=NULL?tmp:"", savereply->portal[i]) == -1) {
+ goto out;
+ }
+ GB_FREE(tmp);
+ tmp = portals;
+ }
+
+ /* save 'failed on'*/
+ tmp = NULL;
+ if (savereply->obj->d_attempt || savereply->obj->d_success) {
+ if (GB_ASPRINTF(&tmp, "REWIND ON: %s %s\n",
+ savereply->obj->d_attempt?savereply->obj->d_attempt:"",
+ savereply->obj->d_success?savereply->obj->d_success:"") == -1) {
+ goto out;
+ }
+ }
+
+ GB_ASPRINTF(&reply->out, "IQN: %s\nPORTAL(S): %s\n%sRESULT: %s\n",
+ savereply->iqn, portals, tmp?tmp:"", errCode?"FAIL":"SUCCESS");
+ }
+
+ out:
+ GB_FREE(tmp);
+ return;
+}
blockResponse *
block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp)
{
- int ret = -1;
- size_t i;
+ int errCode = -1;
uuid_t uuid;
blockRemoteCreateResp *savereply = NULL;
char gbid[UUID_BUF_SIZE];
@@ -912,8 +1058,7 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp)
struct glfs *glfs = NULL;
struct glfs_fd *lkfd = NULL;
blockServerDefPtr list = NULL;
- char *tmp = NULL;
- char *portals = NULL;
+ char *errMsg = NULL;
if (GB_ALLOC(reply) < 0) {
@@ -927,8 +1072,8 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp)
LOG("mgmt", GB_LOG_ERROR, "for block %s multipath request:%d is greater "
"than provided block-hosts:%s on volume %s",
blk->block_name, blk->mpath, blk->block_hosts, blk->volume);
- if (asprintf(&reply->out, "multipath req: %d > block-hosts: %s\n",
- blk->mpath, blk->block_hosts) == -1) {
+ if (GB_ASPRINTF(&errMsg, "multipath req: %d > block-hosts: %s\n",
+ blk->mpath, blk->block_hosts) == -1) {
reply->exit = -1;
goto optfail;
}
@@ -936,7 +1081,7 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp)
goto optfail;
}
- glfs = glusterBlockVolumeInit(blk->volume);
+ glfs = glusterBlockVolumeInit(blk->volume, &errCode, &errMsg);
if (!glfs) {
LOG("mgmt", GB_LOG_ERROR,
"glusterBlockVolumeInit(%s) for block %s with hosts %s failed",
@@ -944,25 +1089,25 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp)
goto optfail;
}
- lkfd = glusterBlockCreateMetaLockFile(glfs, blk->volume);
+ lkfd = glusterBlockCreateMetaLockFile(glfs, blk->volume, &errCode, &errMsg);
if (!lkfd) {
LOG("mgmt", GB_LOG_ERROR, "%s %s for block %s with hosts %s",
FAILED_CREATING_META, blk->volume, blk->block_name, blk->block_hosts);
goto optfail;
}
- GB_METALOCK_OR_GOTO(lkfd, blk->volume, ret, out);
+ GB_METALOCK_OR_GOTO(lkfd, blk->volume, errCode, errMsg, out);
if (!glfs_access(glfs, blk->block_name, F_OK)) {
LOG("mgmt", GB_LOG_ERROR,
"block with name %s already exist in the volume %s",
blk->block_name, blk->volume);
- if (asprintf(&reply->out, "BLOCK with name: '%s' already EXIST\n",
- blk->block_name) == -1) {
- ret = -1;
+ if (GB_ASPRINTF(&errMsg, "BLOCK with name: '%s' already EXIST\n",
+ blk->block_name) == -1) {
+ errCode = ENOMEM;
goto exist;
}
- ret = EEXIST;
+ errCode = EEXIST;
goto exist;
}
@@ -970,95 +1115,61 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp)
uuid_unparse(uuid, gbid);
GB_METAUPDATE_OR_GOTO(lock, glfs, blk->block_name, blk->volume,
- ret, exist, "VOLUME: %s\nGBID: %s\nSIZE: %zu\n"
+ errCode, errMsg, exist,
+ "VOLUME: %s\nGBID: %s\nSIZE: %zu\n"
"HA: %d\nENTRYCREATE: INPROGRESS\n",
blk->volume, gbid, blk->size, blk->mpath);
- ret = glusterBlockCreateEntry(glfs, blk, gbid);
- if (ret) {
+ if (glusterBlockCreateEntry(glfs, blk, gbid, &errCode, &errMsg)) {
GB_METAUPDATE_OR_GOTO(lock, glfs, blk->block_name, blk->volume,
- ret, exist, "ENTRYCREATE: FAIL\n");
+ errCode, errMsg, exist, "ENTRYCREATE: FAIL\n");
LOG("mgmt", GB_LOG_ERROR, "%s volume: %s host: %s",
FAILED_CREATING_FILE, blk->volume, blk->block_hosts);
goto exist;
}
GB_METAUPDATE_OR_GOTO(lock, glfs, blk->block_name, blk->volume,
- ret, exist, "ENTRYCREATE: SUCCESS\n");
+ errCode, errMsg, exist, "ENTRYCREATE: SUCCESS\n");
strcpy(cobj.volume, blk->volume);
strcpy(cobj.block_name, blk->block_name);
cobj.size = blk->size;
strcpy(cobj.gbid, gbid);
- ret = glusterBlockCreateRemoteAsync(list, 0, blk->mpath,
- glfs, &cobj, &savereply);
- if (ret) {
- if (ret == EKEYEXPIRED) {
+ errCode = glusterBlockCreateRemoteAsync(list, 0, blk->mpath,
+ glfs, &cobj, &savereply);
+ if (errCode) {
+ if (errCode == EKEYEXPIRED) {
LOG("mgmt", GB_LOG_ERROR, "glusterBlockCreateRemoteAsync: return %d"
" rewinding the create request for block %s on volume %s with hosts %s",
- ret, blk->block_name, blk->volume, blk->block_hosts);
+ errCode, blk->block_name, blk->volume, blk->block_hosts);
glusterBlockCleanUp(CREATE_SRV, glfs, blk->block_name, TRUE, &savereply);
goto exist;
}
LOG("mgmt", GB_LOG_WARNING, "glusterBlockCreateRemoteAsync: return %d"
- " %s for block %s on volume %s with hosts %s", ret,
+ " %s for block %s on volume %s with hosts %s", errCode,
FAILED_REMOTE_AYNC_CREATE, blk->block_name,
blk->volume, blk->block_hosts);
}
/* Check Point */
- ret = glusterBlockAuditRequest(glfs, blk, &cobj, list, &savereply);
- if (ret) {
+ errCode = glusterBlockAuditRequest(glfs, blk, &cobj, list, &savereply);
+ if (errCode) {
LOG("mgmt", GB_LOG_ERROR, "glusterBlockAuditRequest: return %d"
- "volume: %s hosts: %s blockname %s", ret,
+ "volume: %s hosts: %s blockname %s", errCode,
blk->volume, blk->block_hosts, blk->block_name);
}
- for (i = 0; i < savereply->nportal; i++) {
- if (asprintf(&portals, "%s %s",
- tmp!=NULL?tmp:"", savereply->portal[i]) == -1) {
- portals = tmp;
- goto exist;
- }
- GB_FREE(tmp);
- tmp = portals;
- }
-
- /* save 'failed on'*/
- tmp = NULL;
- if (savereply->obj->d_attempt || savereply->obj->d_success) {
- if (asprintf(&tmp, "REWIND ON: %s %s\n",
- savereply->obj->d_attempt?savereply->obj->d_attempt:"",
- savereply->obj->d_success?savereply->obj->d_success:""
- ) == -1) {
- ret = -1;
- goto exist;
- }
- }
-
- if (asprintf(&reply->out,
- "IQN: %s\nPORTAL(S): %s\n%sRESULT: %s\n",
- savereply->iqn, portals, tmp?tmp:"",
- ret?"FAIL":"SUCCESS") == -1) {
- ret = -1;
- goto exist;
- }
-
exist:
- if (ret == EKEYEXPIRED) {
- if (asprintf(&reply->out,
- "Looks like targetcli and tcmu-runner are not installed on few nodes.\n"
- "RESULT:FAIL\n") == -1) {
- ret = -1;
+ if (errCode == EKEYEXPIRED) {
+ GB_ASPRINTF(&errMsg, "Looks like targetcli and tcmu-runner are not "
+ "installed on few nodes.\n");
}
- }
- GB_METAUNLOCK(lkfd, blk->volume, ret);
+ GB_METAUNLOCK(lkfd, blk->volume, errCode, errMsg);
out:
- reply->exit = ret;
if (lkfd && glfs_close(lkfd) != 0) {
LOG("mgmt", GB_LOG_ERROR, "glfs_close(%s): on volume %s for "
@@ -1066,12 +1177,12 @@ block_create_cli_1_svc(blockCreateCli *blk, struct svc_req *rqstp)
blk->block_name, strerror(errno));
}
- glfs_fini(glfs);
- blockCreateParsedRespFree(savereply);
- GB_FREE(tmp);
-
optfail:
+ block_create_cli_format_response(blk, errCode, errMsg, savereply, reply);
+ GB_FREE(errMsg);
blockServerDefFree(list);
+ glfs_fini(glfs);
+ blockCreateParsedRespFree(savereply);
return reply;
}
@@ -1100,47 +1211,47 @@ block_create_1_svc(blockCreate *blk, struct svc_req *rqstp)
ret = WEXITSTATUS(system(GB_TGCLI_GLFS_CHECK));
if (ret == EKEYEXPIRED || ret == 1) {
reply->exit = EKEYEXPIRED;
- if (asprintf(&reply->out,
+ if (GB_ASPRINTF(&reply->out,
"check if targetcli and tcmu-runner are installed.") == -1) {
goto out;
}
goto out;
}
- if (asprintf(&backstore, "%s %s %s %zu %s@%s%s/%s %s", GB_TGCLI_GLFS,
- GB_CREATE, blk->block_name, blk->size, blk->volume,
- blk->ipaddr, GB_STOREDIR, blk->gbid, blk->gbid) == -1) {
+ if (GB_ASPRINTF(&backstore, "%s %s %s %zu %s@%s%s/%s %s", GB_TGCLI_GLFS,
+ GB_CREATE, blk->block_name, blk->size, blk->volume,
+ blk->ipaddr, GB_STOREDIR, blk->gbid, blk->gbid) == -1) {
goto out;
}
- if (asprintf(&iqn, "%s %s %s%s", GB_TGCLI_ISCSI, GB_CREATE,
- GB_TGCLI_IQN_PREFIX, blk->gbid) == -1) {
+ if (GB_ASPRINTF(&iqn, "%s %s %s%s", GB_TGCLI_ISCSI, GB_CREATE,
+ GB_TGCLI_IQN_PREFIX, blk->gbid) == -1) {
goto out;
}
- if (asprintf(&lun, "%s/%s%s/tpg1/luns %s %s/%s", GB_TGCLI_ISCSI,
- GB_TGCLI_IQN_PREFIX, blk->gbid, GB_CREATE,
- GB_TGCLI_GLFS_PATH, blk->block_name) == -1) {
+ if (GB_ASPRINTF(&lun, "%s/%s%s/tpg1/luns %s %s/%s", GB_TGCLI_ISCSI,
+ GB_TGCLI_IQN_PREFIX, blk->gbid, GB_CREATE,
+ GB_TGCLI_GLFS_PATH, blk->block_name) == -1) {
goto out;
}
- if (asprintf(&portal, "%s/%s%s/tpg1/portals create %s",
- GB_TGCLI_ISCSI, GB_TGCLI_IQN_PREFIX, blk->gbid,
- blk->ipaddr) == -1) {
+ if (GB_ASPRINTF(&portal, "%s/%s%s/tpg1/portals create %s",
+ GB_TGCLI_ISCSI, GB_TGCLI_IQN_PREFIX, blk->gbid,
+ blk->ipaddr) == -1) {
goto out;
}
- if (asprintf(&attr, "%s/%s%s/tpg1 set attribute %s",
- GB_TGCLI_ISCSI, GB_TGCLI_IQN_PREFIX, blk->gbid,
- GB_TGCLI_ATTRIBUTES) == -1) {
+ if (GB_ASPRINTF(&attr, "%s/%s%s/tpg1 set attribute %s",
+ GB_TGCLI_ISCSI, GB_TGCLI_IQN_PREFIX, blk->gbid,
+ GB_TGCLI_ATTRIBUTES) == -1) {
goto out;
}
- if (asprintf(&exec, "%s && %s && %s && %s && %s && %s && %s",
- GB_TGCLI_GLOBALS, backstore, iqn, lun, portal, attr,
- GB_TGCLI_SAVE) == -1) {
+ if (GB_ASPRINTF(&exec, "%s && %s && %s && %s && %s && %s && %s",
+ GB_TGCLI_GLOBALS, backstore, iqn, lun, portal, attr,
+ GB_TGCLI_SAVE) == -1) {
goto out;
}
@@ -1177,17 +1288,96 @@ block_create_1_svc(blockCreate *blk, struct svc_req *rqstp)
return reply;
}
+void
+block_delete_cli_format_response(blockDeleteCli *blk, int errCode, char *errMsg,
+ blockRemoteDeleteResp *savereply,
+ struct blockResponse *reply)
+{
+ json_object *json_obj = NULL;
+ json_object *json_array1 = NULL;
+ json_object *json_array2 = NULL;
+ char *tmp = NULL;
+
+ if (!reply) {
+ return;
+ }
+
+ if (errCode < 0) {
+ errCode = 255;
+ }
+
+ reply->exit = errCode;
+
+ if (errMsg) {
+ block_format_error_response(blk->json_resp, errCode, errMsg, reply);
+ return;
+ }
+
+ if (blk->json_resp) {
+ json_obj = json_object_new_object();
+
+ if (savereply->d_attempt) {
+ json_array1 = json_object_new_array();
+ tmp = strtok (savereply->d_attempt, " ");
+ while (tmp!= NULL)
+ {
+ json_object_array_add(json_array1, json_object_new_string(tmp));
+ tmp = strtok (NULL, " ");
+ }
+ tmp = NULL;
+ json_object_object_add(json_obj, "FAILED ON", json_array1);
+ }
+
+ if (savereply->d_success) {
+ json_array2 = json_object_new_array();
+ tmp = strtok (savereply->d_success, " ");
+ while (tmp!= NULL)
+ {
+ json_object_array_add(json_array2, json_object_new_string(tmp));
+ tmp = strtok (NULL, " ");
+ }
+ tmp = NULL;
+ json_object_object_add(json_obj, "SUCCESSFUL ON", json_array2);
+ }
+
+ json_object_object_add(json_obj, "RESULT",
+ errCode?json_object_new_string("FAIL"):json_object_new_string("SUCCESS"));
+
+ GB_ASPRINTF(&reply->out, "%s\n",
+ json_object_to_json_string_ext(json_obj,
+ mapJsonFlagToJsonCstring(blk->json_resp)));
+
+ json_object_put(json_array1);
+ json_object_put(json_array2);
+ json_object_put(json_obj);
+ } else {
+ /* save 'failed on'*/
+ if (savereply->d_attempt) {
+ if (GB_ASPRINTF(&tmp, "FAILED ON: %s\n", savereply->d_attempt) == -1)
+ goto out;
+ }
+
+ if (GB_ASPRINTF(&reply->out,
+ "%sSUCCESSFUL ON: %s\nRESULT: %s\n", tmp?tmp:"",
+ savereply->d_success?savereply->d_success:"None",
+ errCode?"FAIL":"SUCCESS") == -1) {
+ goto out;
+ }
+ }
+ out:
+ GB_FREE (tmp);
+ return;
+}
blockResponse *
block_delete_cli_1_svc(blockDeleteCli *blk, struct svc_req *rqstp)
{
- int ret = -1;
- char *tmp = NULL;
blockRemoteDeleteResp *savereply = NULL;
static blockResponse *reply = NULL;
struct glfs *glfs;
struct glfs_fd *lkfd = NULL;
-
+ char *errMsg = NULL;
+ int errCode = 0;
if (GB_ALLOC(reply) < 0) {
return NULL;
@@ -1198,71 +1388,57 @@ block_delete_cli_1_svc(blockDeleteCli *blk, struct svc_req *rqstp)
return NULL;
}
- glfs = glusterBlockVolumeInit(blk->volume);
+ glfs = glusterBlockVolumeInit(blk->volume, &errCode, &errMsg);
if (!glfs) {
LOG("mgmt", GB_LOG_ERROR,
"glusterBlockVolumeInit(%s) for block %s failed",
blk->volume, blk->block_name);
- goto out;
+ goto optfail;
}
- lkfd = glusterBlockCreateMetaLockFile(glfs, blk->volume);
+ lkfd = glusterBlockCreateMetaLockFile(glfs, blk->volume, &errCode, &errMsg);
if (!lkfd) {
LOG("mgmt", GB_LOG_ERROR, "%s %s for block %s",
FAILED_CREATING_META, blk->volume, blk->block_name);
- goto out;
+ goto optfail;
}
- GB_METALOCK_OR_GOTO(lkfd, blk->volume, ret, out);
+ GB_METALOCK_OR_GOTO(lkfd, blk->volume, errCode, errMsg, optfail);
if (glfs_access(glfs, blk->block_name, F_OK)) {
LOG("mgmt", GB_LOG_ERROR,
"block with name %s doesn't exist in the volume %s",
blk->block_name, blk->volume);
- GB_STRDUP(reply->out, "BLOCK doesn't EXIST");
- reply->exit = ENOENT;
+ GB_ASPRINTF(&errMsg, "block %s/%s doesn't exist", blk->volume,
+ blk->block_name);
+ errCode = ENOENT;
goto out;
}
- ret = glusterBlockCleanUp(DELETE_SRV, glfs, blk->block_name, TRUE, &savereply);
- if (ret) {
+ errCode = glusterBlockCleanUp(DELETE_SRV, glfs, blk->block_name, TRUE,
+ &savereply);
+ if (errCode) {
LOG("mgmt", GB_LOG_WARNING, "glusterBlockCleanUp: return %d "
- "on block %s for volume %s", ret, blk->block_name, blk->volume);
+ "on block %s for volume %s", errCode, blk->block_name, blk->volume);
}
out:
- if (ret == EKEYEXPIRED) {
- if (asprintf(&reply->out,
- "Looks like targetcli and tcmu-runner are not installed on few nodes.\n"
- "RESULT:FAIL\n") == -1) {
- ret = -1;
- }
- } else {
- /* save 'failed on'*/
- if (savereply->d_attempt) {
- if (asprintf(&tmp, "FAILED ON: %s\n", savereply->d_attempt) == -1) {
- ret = -1;
- }
- }
-
- if (asprintf(&reply->out,
- "%sSUCCESSFUL ON: %s\nRESULT: %s\n", tmp?tmp:"",
- savereply->d_success?savereply->d_success:"None",
- ret?"FAIL":"SUCCESS") == -1) {
- ret = -1;
- }
+ if (errCode == EKEYEXPIRED) {
+ GB_ASPRINTF(&errMsg, "Looks like targetcli and tcmu-runner are not "
+ "installed on few nodes.\n");
}
- GB_METAUNLOCK(lkfd, blk->volume, ret);
-
- reply->exit = ret;
+ GB_METAUNLOCK(lkfd, blk->volume, errCode, errMsg);
+ optfail:
if (lkfd && glfs_close(lkfd) != 0) {
LOG("mgmt", GB_LOG_ERROR,
"glfs_close(%s): for block %s on volume %s failed[%s]",
GB_TXLOCKFILE, blk->block_name, blk->volume, strerror(errno));
}
+
+ block_delete_cli_format_response(blk, errCode, errMsg, savereply, reply);
glfs_fini(glfs);
if (savereply) {
@@ -1270,7 +1446,6 @@ block_delete_cli_1_svc(blockDeleteCli *blk, struct svc_req *rqstp)
GB_FREE(savereply->d_success);
GB_FREE(savereply);
}
- GB_FREE(tmp);
return reply;
}
@@ -1296,39 +1471,39 @@ block_delete_1_svc(blockDelete *blk, struct svc_req *rqstp)
ret = WEXITSTATUS(system(GB_TGCLI_GLFS_CHECK));
if (ret == EKEYEXPIRED || ret == 1) {
reply->exit = EKEYEXPIRED;
- if (asprintf(&reply->out,
- "check if targetcli and tcmu-runner are installed.") == -1) {
+ if (GB_ASPRINTF(&reply->out,
+ "check if targetcli and tcmu-runner are installed.") == -1) {
goto out;
}
goto out;
}
- if (asprintf(&exec, GB_TGCLI_CHECK, blk->block_name) == -1) {
+ if (GB_ASPRINTF(&exec, GB_TGCLI_CHECK, blk->block_name) == -1) {
goto out;
}
/* Check if block exist on this node ? */
if (WEXITSTATUS(system(exec)) == 1) {
reply->exit = 0;
- if (asprintf(&reply->out, "No %s.", blk->block_name) == -1) {
+ if (GB_ASPRINTF(&reply->out, "No %s.", blk->block_name) == -1) {
goto out;
}
goto out;
}
GB_FREE(exec);
- if (asprintf(&iqn, "%s %s %s%s", GB_TGCLI_ISCSI, GB_DELETE,
- GB_TGCLI_IQN_PREFIX, blk->gbid) == -1) {
+ if (GB_ASPRINTF(&iqn, "%s %s %s%s", GB_TGCLI_ISCSI, GB_DELETE,
+ GB_TGCLI_IQN_PREFIX, blk->gbid) == -1) {
goto out;
}
- if (asprintf(&backstore, "%s %s %s", GB_TGCLI_GLFS,
- GB_DELETE, blk->block_name) == -1) {
+ if (GB_ASPRINTF(&backstore, "%s %s %s", GB_TGCLI_GLFS,
+ GB_DELETE, blk->block_name) == -1) {
goto out;
}
- if (asprintf(&exec, "%s && %s && %s", backstore, iqn,
- GB_TGCLI_SAVE) == -1) {
+ if (GB_ASPRINTF(&exec, "%s && %s && %s", backstore, iqn,
+ GB_TGCLI_SAVE) == -1) {
goto out;
}
@@ -1373,27 +1548,41 @@ block_list_cli_1_svc(blockListCli *blk, struct svc_req *rqstp)
struct dirent *entry;
char *tmp = NULL;
char *filelist = NULL;
- int ret = -1;
+ json_object *json_obj = NULL;
+ json_object *json_array = NULL;
+ int errCode = 0;
+ char *errMsg = NULL;
+
+ if (GB_ALLOC(reply) < 0) {
+ return NULL;
+ }
- glfs = glusterBlockVolumeInit(blk->volume);
+ if (blk->json_resp) {
+ json_obj = json_object_new_object();
+ json_array = json_object_new_array();
+ }
+
+ glfs = glusterBlockVolumeInit(blk->volume, &errCode, &errMsg);
if (!glfs) {
LOG("mgmt", GB_LOG_ERROR,
"glusterBlockVolumeInit(%s) failed", blk->volume);
- goto out;
+ goto optfail;
}
- lkfd = glusterBlockCreateMetaLockFile(glfs, blk->volume);
+ lkfd = glusterBlockCreateMetaLockFile(glfs, blk->volume, &errCode, &errMsg);
if (!lkfd) {
- LOG("mgmt", GB_LOG_ERROR, "%s %s",
- FAILED_CREATING_META, blk->volume);
- goto out;
+ LOG("mgmt", GB_LOG_ERROR, "%s %s", FAILED_CREATING_META, blk->volume);
+ goto optfail;
}
- GB_METALOCK_OR_GOTO(lkfd, blk->volume, ret, out);
+ GB_METALOCK_OR_GOTO(lkfd, blk->volume, errCode, errMsg, optfail);
tgmdfd = glfs_opendir (glfs, GB_METADIR);
if (!tgmdfd) {
+ errCode = errno;
+ GB_ASPRINTF (&errMsg, "Not able to open metadata directory for volume "
+ "%s[%s]", blk->volume, strerror(errCode));
LOG("mgmt", GB_LOG_ERROR, "glfs_opendir(%s): on volume %s failed[%s]",
GB_METADIR, blk->volume, strerror(errno));
goto out;
@@ -1403,35 +1592,72 @@ block_list_cli_1_svc(blockListCli *blk, struct svc_req *rqstp)
if (strcmp(entry->d_name, ".") &&
strcmp(entry->d_name, "..") &&
strcmp(entry->d_name, "meta.lock")) {
- if (asprintf(&filelist, "%s%s\n", (tmp==NULL?"":tmp),
- entry->d_name) == -1) {
- filelist = NULL;
+ if (blk->json_resp) {
+ json_object_array_add(json_array,
+ json_object_new_string(entry->d_name));
+ } else {
+ if (GB_ASPRINTF(&filelist, "%s%s\n", (tmp==NULL?"":tmp),
+ entry->d_name) == -1) {
+ filelist = NULL;
+ GB_FREE(tmp);
+ errCode = ENOMEM;
+ goto out;
+ }
GB_FREE(tmp);
- ret = -1;
- goto out;
+ tmp = filelist;
}
- GB_FREE(tmp);
- tmp = filelist;
}
}
- ret = 0;
+ errCode = 0;
- out:
- if (GB_ALLOC(reply) < 0) {
- return NULL;
- }
+ if (blk->json_resp)
+ json_object_object_add(json_obj, "blocks", json_array);
- reply->out = filelist? filelist:strdup("*Nil*\n");
+ out:
+ GB_METAUNLOCK(lkfd, blk->volume, errCode, errMsg);
+ optfail:
if (tgmdfd && glfs_closedir (tgmdfd) != 0) {
LOG("mgmt", GB_LOG_ERROR, "glfs_closedir(%s): on volume %s failed[%s]",
GB_METADIR, blk->volume, strerror(errno));
}
- GB_METAUNLOCK(lkfd, blk->volume, ret);
+ if (errCode < 0) {
+ errCode = 255;
+ }
+ reply->exit = errCode;
- reply->exit = ret;
+ errCode = reply->exit;
+ if (blk->json_resp) {
+ if (errCode) {
+ json_object_object_add(json_obj, "RESULT",
+ json_object_new_string("FAIL"));
+ json_object_object_add(json_obj, "errCode",
+ json_object_new_int(errCode));
+ json_object_object_add(json_obj, "errMsg",
+ json_object_new_string(errMsg));
+ } else {
+ json_object_object_add(json_obj, "RESULT",
+ json_object_new_string("SUCCESS"));
+ }
+ GB_ASPRINTF(&reply->out, "%s\n",
+ json_object_to_json_string_ext(json_obj,
+ mapJsonFlagToJsonCstring(blk->json_resp)));
+ json_object_put(json_array);
+ json_object_put(json_obj);
+ } else {
+ if (errCode) {
+ if (errMsg) {
+ GB_ASPRINTF (&reply->out, "%s\n", errMsg);
+ } else {
+ GB_ASPRINTF (&reply->out, "Not able to complete operation "
+ "successfully\n");
+ }
+ } else {
+ reply->out = filelist? filelist:strdup("*Nil*\n");
+ }
+ }
if (lkfd && glfs_close(lkfd) != 0) {
LOG("mgmt", GB_LOG_ERROR, "glfs_close(%s): on volume %s failed[%s]",
@@ -1443,97 +1669,139 @@ block_list_cli_1_svc(blockListCli *blk, struct svc_req *rqstp)
return reply;
}
+void
+block_info_cli_format_response(blockInfoCli *blk, int errCode,
+ char *errMsg, MetaInfo *info,
+ struct blockResponse *reply)
+{
+ json_object *json_obj = NULL;
+ json_object *json_array = NULL;
+ char *tmp = NULL;
+ char *out = NULL;
+ int i = 0;
+
+ if (!reply) {
+ return;
+ }
+
+ if (errCode < 0) {
+ errCode = 255;
+ }
+ if (errMsg) {
+ block_format_error_response(blk->json_resp, errCode, errMsg, reply);
+ return;
+ }
+
+ if (blk->json_resp) {
+ json_obj = json_object_new_object();
+ json_object_object_add(json_obj, "NAME", json_object_new_string(blk->block_name));
+ json_object_object_add(json_obj, "VOLUME", json_object_new_string(info->volume));
+ json_object_object_add(json_obj, "GBID", json_object_new_string(info->gbid));
+ json_object_object_add(json_obj, "SIZE", json_object_new_int64(info->size));
+ json_object_object_add(json_obj, "HA", json_object_new_int(info->mpath));
+
+ json_array = json_object_new_array();
+
+ for (i = 0; i < info->nhosts; i++) {
+ if (blockMetaStatusEnumParse(info->list[i]->status) == GB_CONFIG_SUCCESS) {
+ json_object_array_add(json_array, json_object_new_string(info->list[i]->addr));
+ }
+ }
+
+ json_object_object_add(json_obj, "BLOCK CONFIG NODE(S)", json_array);
+
+ GB_ASPRINTF(&reply->out, "%s\n",
+ json_object_to_json_string_ext(json_obj,
+ mapJsonFlagToJsonCstring(blk->json_resp)));
+ json_object_put(json_array);
+ json_object_put(json_obj);
+ } else {
+ if (GB_ASPRINTF(&tmp, "NAME: %s\nVOLUME: %s\nGBID: %s\nSIZE: %zu\n"
+ "HA: %zu\nBLOCK CONFIG NODE(S):",
+ blk->block_name, info->volume, info->gbid,
+ info->size, info->mpath) == -1) {
+ goto out;
+ }
+ for (i = 0; i < info->nhosts; i++) {
+ if (blockMetaStatusEnumParse(info->list[i]->status) == GB_CONFIG_SUCCESS) {
+ if (GB_ASPRINTF(&out, "%s %s", tmp, info->list[i]->addr) == -1) {
+ GB_FREE (tmp);
+ goto out;
+ }
+ tmp = out;
+ }
+ }
+ if (GB_ASPRINTF(&reply->out, "%s\n", tmp) == -1) {
+ GB_FREE (tmp);
+ goto out;
+ }
+ GB_FREE (tmp);
+ }
+ out:
+ return;
+}
blockResponse *
block_info_cli_1_svc(blockInfoCli *blk, struct svc_req *rqstp)
{
blockResponse *reply;
- char *out = NULL;
- char *tmp = NULL;
struct glfs *glfs;
struct glfs_fd *lkfd = NULL;
MetaInfo *info = NULL;
int ret = -1;
- size_t i;
+ int errCode = 0;
+ char *errMsg = NULL;
- glfs = glusterBlockVolumeInit(blk->volume);
+ if ((GB_ALLOC(reply) < 0) || (GB_ALLOC(info) < 0)) {
+ GB_FREE (reply);
+ GB_FREE (info);
+ return NULL;
+ }
+
+ glfs = glusterBlockVolumeInit(blk->volume, &errCode, &errMsg);
if (!glfs) {
LOG("mgmt", GB_LOG_ERROR,
"glusterBlockVolumeInit(%s) for block %s failed",
blk->volume, blk->block_name);
- goto out;
+ goto optfail;
}
- lkfd = glusterBlockCreateMetaLockFile(glfs, blk->volume);
+ lkfd = glusterBlockCreateMetaLockFile(glfs, blk->volume, &errCode, &errMsg);
if (!lkfd) {
LOG("mgmt", GB_LOG_ERROR, "%s %s for block %s",
FAILED_CREATING_META, blk->volume, blk->block_name);
- goto out;
+ goto optfail;
}
- GB_METALOCK_OR_GOTO(lkfd, blk->volume, ret, out);
+ GB_METALOCK_OR_GOTO(lkfd, blk->volume, errCode, errMsg, optfail);
- if (GB_ALLOC(info) < 0) {
- goto out;
- }
-
- ret = blockGetMetaInfo(glfs, blk->block_name, info);
+ ret = blockGetMetaInfo(glfs, blk->block_name, info, &errCode);
if (ret) {
- goto out;
- }
-
- if (asprintf(&tmp, "NAME: %s\nVOLUME: %s\nGBID: %s\nSIZE: %zu\n"
- "HA: %zu\nBLOCK CONFIG NODE(S):",
- blk->block_name, info->volume, info->gbid,
- info->size, info->mpath) == -1) {
- ret = -1;
- goto out;
- }
- for (i = 0; i < info->nhosts; i++) {
- if (blockMetaStatusEnumParse(info->list[i]->status) == GB_CONFIG_SUCCESS) {
- if (asprintf(&out, "%s %s", (tmp==NULL?"":tmp),
- info->list[i]->addr) == -1) {
- out = NULL;
- GB_FREE(tmp);
- ret = -1;
- goto out;
- }
- GB_FREE(tmp);
- tmp = out;
+ if (errCode == ENOENT) {
+ GB_ASPRINTF (&errMsg, "block %s/%s doesn't exist", blk->volume,
+ blk->block_name);
+ } else {
+ GB_ASPRINTF (&errMsg, "Not able to get metadata information for %s/%s[%s]",
+ blk->volume, blk->block_name, strerror(errCode));
}
- }
- if (asprintf(&out, "%s\n", tmp) == -1) {
- ret = -1;
goto out;
}
- ret = 0;
out:
- if (GB_ALLOC(reply) < 0) {
- return NULL;
- }
-
- if (!out) {
- if (asprintf(&out, "No Block with name %s", blk->block_name) == -1) {
- ret = -1;
- }
- }
-
- reply->out = out;
-
- GB_METAUNLOCK(lkfd, blk->volume, ret);
-
- reply->exit = ret;
+ GB_METAUNLOCK(lkfd, blk->volume, ret, errMsg);
+ optfail:
if (lkfd && glfs_close(lkfd) != 0) {
LOG("mgmt", GB_LOG_ERROR,
"glfs_close(%s): on volume %s for block %s failed[%s]",
GB_TXLOCKFILE, blk->volume, blk->block_name, strerror(errno));
}
- glfs_fini(glfs);
+ block_info_cli_format_response(blk, errCode, errMsg, info, reply);
+ glfs_fini(glfs);
+ GB_FREE(errMsg);
blockFreeMetaInfo(info);
return reply;
diff --git a/rpc/glfs-operations.c b/rpc/glfs-operations.c
index e61f2b5..007d519 100644
--- a/rpc/glfs-operations.c
+++ b/rpc/glfs-operations.c
@@ -15,7 +15,7 @@
struct glfs *
-glusterBlockVolumeInit(char *volume)
+glusterBlockVolumeInit(char *volume, int *errCode, char **errMsg)
{
struct glfs *glfs;
int ret;
@@ -23,29 +23,36 @@ glusterBlockVolumeInit(char *volume)
glfs = glfs_new(volume);
if (!glfs) {
+ *errCode = errno;
+ GB_ASPRINTF (errMsg, "Not able to Initialize volume %s [%s]", volume,
+ strerror(*errCode));
LOG("gfapi", GB_LOG_ERROR, "glfs_new(%s) from %s failed[%s]", volume,
- "localhost", strerror(errno));
+ "localhost", strerror(*errCode));
return NULL;
}
ret = glfs_set_volfile_server(glfs, "tcp", "localhost", 24007);
if (ret) {
+ *errCode = errno;
+ GB_ASPRINTF (errMsg, "Not able to add Volfile server for volume %s[%s]",
+ volume, strerror(*errCode));
LOG("gfapi", GB_LOG_ERROR, "glfs_set_volfile_server(%s) of %s "
- "failed[%s]", "localhost", volume, strerror(errno));
+ "failed[%s]", "localhost", volume, strerror(*errCode));
goto out;
}
ret = glfs_set_logging(glfs, GFAPI_LOG_FILE, GFAPI_LOG_LEVEL);
if (ret) {
+ *errCode = errno;
+ GB_ASPRINTF (errMsg, "Not able to add logging for volume %s[%s]", volume,
+ strerror(*errCode));
LOG("gfapi", GB_LOG_ERROR, "glfs_set_logging(%s, %d) on %s failed[%s]",
- GFAPI_LOG_FILE, GFAPI_LOG_LEVEL, volume, strerror(errno));
+ GFAPI_LOG_FILE, GFAPI_LOG_LEVEL, volume, strerror(*errCode));
goto out;
}
ret = glfs_init(glfs);
if (ret) {
- LOG("gfapi", GB_LOG_ERROR, "glfs_init() on %s failed[%s]", volume,
- strerror(errno) );
goto out;
}
@@ -59,16 +66,15 @@ glusterBlockVolumeInit(char *volume)
int
-glusterBlockCreateEntry(struct glfs *glfs,
- blockCreateCli *blk,
- char *gbid)
+glusterBlockCreateEntry(struct glfs *glfs, blockCreateCli *blk, char *gbid,
+ int *errCode, char **errMsg)
{
struct glfs_fd *tgfd;
int ret;
-
ret = glfs_mkdir (glfs, GB_STOREDIR, 0);
if (ret && errno != EEXIST) {
+ *errCode = errno;
LOG("gfapi", GB_LOG_ERROR,
"glfs_mkdir(%s) on volume %s for block %s failed[%s]",
GB_STOREDIR, blk->volume, blk->block_name, strerror(errno));
@@ -77,6 +83,7 @@ glusterBlockCreateEntry(struct glfs *glfs,
ret = glfs_chdir (glfs, GB_STOREDIR);
if (ret) {
+ *errCode = errno;
LOG("gfapi", GB_LOG_ERROR,
"glfs_chdir(%s) on volume %s for block %s failed[%s]",
GB_STOREDIR, blk->volume, blk->block_name, strerror(errno));
@@ -87,6 +94,7 @@ glusterBlockCreateEntry(struct glfs *glfs,
O_WRONLY | O_CREAT | O_EXCL,
S_IRUSR | S_IWUSR);
if (!tgfd) {
+ *errCode = errno;
LOG("gfapi", GB_LOG_ERROR,
"glfs_creat(%s) on volume %s for block %s failed[%s]",
gbid, blk->volume, blk->block_name, strerror(errno));
@@ -95,6 +103,7 @@ glusterBlockCreateEntry(struct glfs *glfs,
} else {
ret = glfs_ftruncate(tgfd, blk->size);
if (ret) {
+ *errCode = errno;
LOG("gfapi", GB_LOG_ERROR,
"glfs_ftruncate(%s): on volume %s for block %s"
"of size %zu failed[%s]", gbid, blk->volume, blk->block_name,
@@ -118,6 +127,7 @@ glusterBlockCreateEntry(struct glfs *glfs,
}
if (tgfd && glfs_close(tgfd) != 0) {
+ *errCode = errno;
LOG("gfapi", GB_LOG_ERROR,
"glfs_close(%s): on volume %s for block %s failed[%s]",
gbid, blk->volume, blk->block_name, strerror(errno));
@@ -127,6 +137,10 @@ glusterBlockCreateEntry(struct glfs *glfs,
}
out:
+ if (ret) {
+ GB_ASPRINTF (errMsg, "Not able to create metadata for %s/%s[%s]", blk->volume,
+ blk->block_name, strerror(*errCode));
+ }
return ret;
}
@@ -156,7 +170,8 @@ glusterBlockDeleteEntry(struct glfs *glfs, char *volume, char *gbid)
struct glfs_fd *
-glusterBlockCreateMetaLockFile(struct glfs *glfs, char *volume)
+glusterBlockCreateMetaLockFile(struct glfs *glfs, char *volume, int *errCode,
+ char **errMsg)
{
struct glfs_fd *lkfd;
int ret;
@@ -164,28 +179,33 @@ glusterBlockCreateMetaLockFile(struct glfs *glfs, char *volume)
ret = glfs_mkdir (glfs, GB_METADIR, 0);
if (ret && errno != EEXIST) {
+ *errCode = errno;
LOG("gfapi", GB_LOG_ERROR, "glfs_mkdir(%s) on volume %s failed[%s]",
- GB_METADIR, volume, strerror(errno));
+ GB_METADIR, volume, strerror(*errCode));
goto out;
}
ret = glfs_chdir (glfs, GB_METADIR);
if (ret) {
+ *errCode = errno;
LOG("gfapi", GB_LOG_ERROR, "glfs_chdir(%s) on volume %s failed[%s]",
- GB_METADIR, volume, strerror(errno));
+ GB_METADIR, volume, strerror(*errCode));
goto out;
}
lkfd = glfs_creat(glfs, GB_TXLOCKFILE, O_RDWR, S_IRUSR | S_IWUSR);
if (!lkfd) {
+ *errCode = errno;
LOG("gfapi", GB_LOG_ERROR, "glfs_creat(%s) on volume %s failed[%s]",
- GB_TXLOCKFILE, volume, strerror(errno));
+ GB_TXLOCKFILE, volume, strerror(*errCode));
goto out;
}
return lkfd;
out:
+ GB_ASPRINTF (errMsg, "Not able to create Metadata on volume %s[%s]", volume,
+ strerror (*errCode));
return NULL;
}
@@ -301,36 +321,36 @@ blockStuffMetaInfo(MetaInfo *info, char *line)
int
-blockGetMetaInfo(struct glfs* glfs, char* metafile, MetaInfo *info)
+blockGetMetaInfo(struct glfs* glfs, char* metafile, MetaInfo *info,
+ int *errCode)
{
size_t count = 0;
struct glfs_fd *tgmfd = NULL;
char line[1024];
+ char fpath[PATH_MAX] = {0};
char *tmp;
int ret;
-
- ret = glfs_chdir (glfs, GB_METADIR);
- if (ret) {
- LOG("gfapi", GB_LOG_ERROR,
- "glfs_chdir(%s) on volume %s for block %s failed[%s]",
- GB_METADIR, info->volume, metafile, strerror(errno));
- goto out;
- }
-
- tgmfd = glfs_open(glfs, metafile, O_RDONLY);
+ snprintf(fpath, sizeof fpath, "%s/%s", GB_METADIR, metafile);
+ tgmfd = glfs_open(glfs, fpath, O_RDONLY);
if (!tgmfd) {
+ if (errCode) {
+ *errCode = errno;
+ }
LOG("gfapi", GB_LOG_ERROR, "glfs_open(%s) on volume %s failed[%s]",
metafile, info->volume, strerror(errno));
ret = -1;
goto out;
}
- while (glfs_read (tgmfd, line, sizeof(line), 0) > 0) {
+ while ((ret = glfs_read (tgmfd, line, sizeof(line), 0)) > 0) {
tmp = strtok(line,"\n");
count += strlen(tmp) + 1;
ret = blockStuffMetaInfo(info, tmp);
if (ret) {
+ if (errCode) {
+ *errCode = errno;
+ }
LOG("gfapi", GB_LOG_ERROR,
"blockStuffMetaInfo: on volume %s for block %s failed[%s]",
info->volume, metafile, strerror(errno));
@@ -338,6 +358,10 @@ blockGetMetaInfo(struct glfs* glfs, char* metafile, MetaInfo *info)
}
glfs_lseek(tgmfd, count, SEEK_SET);
}
+ if (ret < 0 && errCode) {/*Failure from glfs_read*/
+ *errCode = errno;
+ goto out;
+ }
out:
if (tgmfd && glfs_close(tgmfd) != 0) {
diff --git a/rpc/glfs-operations.h b/rpc/glfs-operations.h
index 3e7f72a..47aced2 100644
--- a/rpc/glfs-operations.h
+++ b/rpc/glfs-operations.h
@@ -41,22 +41,25 @@ typedef struct MetaInfo {
struct glfs *
-glusterBlockVolumeInit(char *volume);
+glusterBlockVolumeInit(char *volume, int *errCode, char **errMsg);
int
-glusterBlockCreateEntry(struct glfs *glfs, blockCreateCli *blk, char *gbid);
+glusterBlockCreateEntry(struct glfs *glfs, blockCreateCli *blk, char *gbid,
+ int *errCode, char **errMsg);
int
glusterBlockDeleteEntry(struct glfs *glfs, char *volume, char *gbid);
struct glfs_fd *
-glusterBlockCreateMetaLockFile(struct glfs *glfs, char *volume);
+glusterBlockCreateMetaLockFile(struct glfs *glfs, char *volume, int *errCode,
+ char **errMsg);
int
glusterBlockDeleteMetaFile(struct glfs *glfs, char *volume, char *blockname);
int
-blockGetMetaInfo(struct glfs *glfs, char *metafile, MetaInfo *info);
+blockGetMetaInfo(struct glfs* glfs, char* metafile, MetaInfo *info,
+ int *errCode);
void
blockFreeMetaInfo(MetaInfo *info);
diff --git a/rpc/rpcl/block.x b/rpc/rpcl/block.x
index 4d840ff..5d9c2a5 100644
--- a/rpc/rpcl/block.x
+++ b/rpc/rpcl/block.x
@@ -3,6 +3,17 @@
%#include "rpc-pragmas.h"
#endif
+enum JsonResponseFormat {
+ GB_JSON_NONE = 0,
+
+ GB_JSON_PLAIN = 1,
+ GB_JSON_SPACED = 2,
+ GB_JSON_PRETTY = 3,
+ GB_JSON_DEFAULT = 4,
+
+ GB_JSON_MAX
+};
+
struct blockCreate {
char ipaddr[255];
char volume[255];
@@ -17,11 +28,13 @@ struct blockCreateCli {
u_int mpath; /* HA request count */
char block_name[255];
string block_hosts<>;
+ enum JsonResponseFormat json_resp;
};
struct blockDeleteCli {
char block_name[255];
char volume[255];
+ enum JsonResponseFormat json_resp;
};
struct blockDelete {
@@ -30,22 +43,31 @@ struct blockDelete {
};
struct blockInfoCli {
- char block_name[255];
- char volume[255];
+ char block_name[255];
+ char volume[255];
+ enum JsonResponseFormat json_resp;
};
struct blockListCli {
- char volume[255];
- u_quad_t offset; /* dentry d_name offset */
+ char volume[255];
+ u_quad_t offset; /* dentry d_name offset */
+ enum JsonResponseFormat json_resp;
};
struct blockResponse {
int exit; /* exit code of the command */
- string out<>; /* json output */
+ string out<>; /* output; TODO: return respective objects */
u_quad_t offset; /* dentry d_name offset */
opaque xdata<>; /* future reserve */
};
+program GLUSTER_BLOCK {
+ version GLUSTER_BLOCK_VERS {
+ blockResponse BLOCK_CREATE(blockCreate) = 1;
+ blockResponse BLOCK_DELETE(blockDelete) = 2;
+ } = 1;
+} = 21215311; /* B2 L12 O15 C3 K11 */
+
program GLUSTER_BLOCK_CLI {
version GLUSTER_BLOCK_CLI_VERS {
blockResponse BLOCK_CREATE_CLI(blockCreateCli) = 1;
@@ -54,10 +76,3 @@ program GLUSTER_BLOCK_CLI {
blockResponse BLOCK_DELETE_CLI(blockDeleteCli) = 4;
} = 1;
} = 212153113; /* B2 L12 O15 C3 K11 C3 */
-
-program GLUSTER_BLOCK {
- version GLUSTER_BLOCK_VERS {
- blockResponse BLOCK_CREATE(blockCreate) = 1;
- blockResponse BLOCK_DELETE(blockDelete) = 2;
- } = 1;
-} = 21215311; /* B2 L12 O15 C3 K11 */
diff --git a/tests/basic.t b/tests/basic.t
index 9d01154..8514cfb 100755
--- a/tests/basic.t
+++ b/tests/basic.t
@@ -39,7 +39,7 @@ function cleanup()
echo -e "\nRunning test cleanup ..."
# Block delete
- gluster-block delete ${VOLNAME}/${BLKNAME}
+ gluster-block delete ${VOLNAME}/${BLKNAME} --json-pretty
gluster --mode=script vol stop ${VOLNAME}
gluster --mode=script vol del ${VOLNAME}
@@ -85,4 +85,18 @@ TEST gluster-block list ${VOLNAME}
# Block info
TEST gluster-block info ${VOLNAME}/${BLKNAME}
+# Block delete
+gluster-block delete ${VOLNAME}/${BLKNAME}
+
+echo -e "\n*** JSON responses ***\n"
+
+# Block create and expect json response
+TEST gluster-block create ${VOLNAME}/${BLKNAME} ha 1 ${HOST} 1GiB --json-pretty
+
+# Block list and expect json response
+TEST gluster-block list ${VOLNAME} --json-pretty
+
+# Block info and expect json response
+TEST gluster-block info ${VOLNAME}/${BLKNAME} --json-pretty
+
cleanup;
diff --git a/utils/Makefile.am b/utils/Makefile.am
index 9a79c29..40442c3 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -4,7 +4,7 @@ libgb_la_SOURCES = common.c utils.c
noinst_HEADERS = common.h utils.h
-libgb_la_CFLAGS = -DDATADIR=\"$(localstatedir)\"
+libgb_la_CFLAGS = -DDATADIR=\"$(localstatedir)\" -I$(top_builddir)/rpc/rpcl
libgb_ladir = $(includedir)/gluster-block/utils
diff --git a/utils/common.c b/utils/common.c
index a605f0d..c42ce03 100644
--- a/utils/common.c
+++ b/utils/common.c
@@ -12,6 +12,30 @@
# include "common.h"
+enum JsonResponseFormat
+jsonResponseFormatParse(const char *opt)
+{
+ int i;
+
+
+ if (!opt) {
+ return GB_JSON_MAX;
+ }
+
+ if (strlen (opt) < 2 || opt[0] != '-' || opt[1] != '-') {
+ /*json option is not given*/
+ return GB_JSON_NONE;
+ }
+
+ for (i = 0; i < GB_JSON_MAX; i++) {
+ if (!strcmp(opt, JsonResponseFormatLookup[i])) {
+ return i;
+ }
+ }
+
+ return i;
+}
+
ssize_t
glusterBlockCreateParseSize(const char *dom, char *value)
diff --git a/utils/common.h b/utils/common.h
index c5ec334..b43220f 100644
--- a/utils/common.h
+++ b/utils/common.h
@@ -13,6 +13,7 @@
# define _COMMON_H 1
# include "utils.h"
+# include "block.h"
# define GB_LOGDIR DATADIR "/log/gluster-block"
# define GB_INFODIR DATADIR "/run"
@@ -37,6 +38,20 @@
# define SUN_PATH_MAX (sizeof(struct sockaddr_un) - sizeof(unsigned short int)) /*sun_family*/
+static const char *const JsonResponseFormatLookup[] = {
+ [GB_JSON_NONE] = "",
+
+ [GB_JSON_PLAIN] = "--json-plain",
+ [GB_JSON_SPACED] = "--json-spaced",
+ [GB_JSON_PRETTY] = "--json-pretty",
+ [GB_JSON_DEFAULT] = "--json",
+
+ [GB_JSON_MAX] = NULL,
+};
+
+
+enum JsonResponseFormat jsonResponseFormatParse(const char *opt);
+
ssize_t glusterBlockCreateParseSize(const char *dom, char *value);
# endif /* _COMMON_H */
diff --git a/utils/utils.h b/utils/utils.h
index f551e46..b0cf778 100644
--- a/utils/utils.h
+++ b/utils/utils.h
@@ -46,6 +46,10 @@
# define FAILED_DEPENDENCY "failed dependency, check if you have targetcli and tcmu-runner installed"
+# define FMT_WARN(fmt...) do { if (0) printf (fmt); } while (0)
+
+# define GB_ASPRINTF(ptr, fmt...) ({FMT_WARN (fmt); \
+ int __ret=asprintf(ptr, ##fmt);__ret;})
# define LOCK(x) \
do { \
@@ -86,26 +90,32 @@
fclose(fd); \
} while (0)
-# define GB_METALOCK_OR_GOTO(lkfd, volume, ret, label) \
+# define GB_METALOCK_OR_GOTO(lkfd, volume, errCode, errMsg, label) \
do { \
struct flock lock = {0, }; \
lock.l_type = F_WRLCK; \
if (glfs_posix_lock (lkfd, F_SETLKW, &lock)) { \
LOG("mgmt", GB_LOG_ERROR, "glfs_posix_lock() on " \
"volume %s failed[%s]", volume, strerror(errno)); \
- ret = -1; \
+ errCode = errno; \
+ if (!errMsg) { \
+ GB_ASPRINTF (&errMsg, "Not able to acquire " \
+ "lock on %s[%s]", volume, strerror(errCode));\
+ } \
goto label; \
} \
} while (0)
# define GB_METAUPDATE_OR_GOTO(lock, glfs, fname, \
- volume, ret, label,...) \
+ volume, ret, errMsg, label,...) \
do { \
char *write; \
struct glfs_fd *tgmfd; \
LOCK(lock); \
ret = glfs_chdir (glfs, GB_METADIR); \
if (ret) { \
+ GB_ASPRINTF(&errMsg, "Failed to update transaction log "\
+ "for %s/%s[%s]", volume, fname, strerror(errno)); \
LOG("gfapi", GB_LOG_ERROR, "glfs_chdir(%s) on " \
"volume %s failed[%s]", GB_METADIR, volume, \
strerror(errno)); \
@@ -116,6 +126,8 @@
tgmfd = glfs_creat(glfs, fname, O_WRONLY | O_APPEND, \
S_IRUSR | S_IWUSR); \
if (!tgmfd) { \
+ GB_ASPRINTF(&errMsg, "Failed to update transaction log "\
+ "for %s/%s[%s]", volume, fname, strerror(errno)); \
LOG("mgmt", GB_LOG_ERROR, "glfs_creat(%s): on " \
"volume %s failed[%s]", fname, volume, \
strerror(errno)); \
@@ -123,12 +135,14 @@
ret = -1; \
goto label; \
} \
- if (asprintf(&write, __VA_ARGS__) < 0) { \
+ if (GB_ASPRINTF(&write, __VA_ARGS__) < 0) { \
UNLOCK(lock); \
ret = -1; \
goto label; \
} \
if(glfs_write (tgmfd, write, strlen(write), 0) < 0) { \
+ GB_ASPRINTF(&errMsg, "Failed to update transaction log "\
+ "for %s/%s[%s]", volume, fname, strerror(errno)); \
LOG("mgmt", GB_LOG_ERROR, "glfs_write(%s): on " \
"volume %s failed[%s]", fname, volume, \
strerror(errno)); \
@@ -138,6 +152,8 @@
} \
GB_FREE(write); \
if (tgmfd && glfs_close(tgmfd) != 0) { \
+ GB_ASPRINTF(&errMsg, "Failed to update transaction log "\
+ "for %s/%s[%s]", volume, fname, strerror(errno)); \
LOG("mgmt", GB_LOG_ERROR, "glfs_close(%s): on " \
"volume %s failed[%s]", fname, volume, \
strerror(errno)); \
@@ -148,11 +164,15 @@
UNLOCK(lock); \
} while (0)
-# define GB_METAUNLOCK(lkfd, volume, ret) \
+# define GB_METAUNLOCK(lkfd, volume, ret, errMsg) \
do { \
struct flock lock = {0, }; \
lock.l_type = F_UNLCK; \
if (glfs_posix_lock(lkfd, F_SETLK, &lock)) { \
+ if (!errMsg) { \
+ GB_ASPRINTF (&errMsg, "Not able to acquire " \
+ "lock on %s[%s]", volume, strerror(errno)); \
+ } \
LOG("mgmt", GB_LOG_ERROR, "glfs_posix_lock() on " \
"volume %s failed[%s]", volume, strerror(errno)); \
ret = -1; \