mirror of
https://github.com/gluster/gluster-block.git
synced 2026-02-05 12:45:33 +01:00
genconfig: add support
$ gluster-block genconfig
Inadequate arguments for genconfig:
gluster-block genconfig <volname[,volume2,volume3,...]> enable-tpg <host> [--json*]
$ gluster-block genconfig testvol1,testvol2 enable-tpg 192.168.124.227
{
"storage_objects":[
{
"attributes":{
"cmd_time_out":0,
"dev_size":1073741824
},
"config":"glfs/testvol1@192.168.124.227/block-store/8effb447-875b-407e-8fe5-bd6500a96ee6",
"name":"blockX",
"plugin":"user",
"size":1073741824,
"wwn":"8effb447-875b-407e-8fe5-bd6500a96ee6"
},
...
}
Tested-by: Xiubo Li <xiubli@redhat.com>
Reviewed-by: Xiubo Li <xiubli@redhat.com>
Reviewed-by: Pranith Kumar K <pkarampu@redhat.com>
Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
This commit is contained in:
committed by
Pranith Kumar Karampuri
parent
f6bb47503e
commit
4a0ac4998a
@@ -26,6 +26,8 @@
|
||||
"[force] [--json*]"
|
||||
# define GB_REPLACE_HELP_STR "gluster-block replace <volname/blockname> " \
|
||||
"<old-node> <new-node> [force] [--json*]"
|
||||
# define GB_GENCONF_HELP_STR "gluster-block genconfig <volname[,volume2,volume3,...]> "\
|
||||
"enable-tpg <host> [--json*]"
|
||||
# define GB_INFO_HELP_STR "gluster-block info <volname/blockname> [--json*]"
|
||||
# define GB_LIST_HELP_STR "gluster-block list <volname> [--json*]"
|
||||
|
||||
@@ -49,7 +51,8 @@ typedef enum clioperations {
|
||||
DELETE_CLI = 4,
|
||||
MODIFY_CLI = 5,
|
||||
MODIFY_SIZE_CLI = 6,
|
||||
REPLACE_CLI = 7
|
||||
REPLACE_CLI = 7,
|
||||
GENCONF_CLI = 8
|
||||
} clioperations;
|
||||
|
||||
|
||||
@@ -67,6 +70,7 @@ glusterBlockCliRPC_1(void *cobj, clioperations opt)
|
||||
blockModifyCli *modify_obj;
|
||||
blockModifySizeCli *modify_size_obj;
|
||||
blockReplaceCli *replace_obj;
|
||||
blockGenConfigCli *genconfig_obj;
|
||||
blockResponse reply = {0,};
|
||||
char errMsg[2048] = {0};
|
||||
|
||||
@@ -170,6 +174,14 @@ glusterBlockCliRPC_1(void *cobj, clioperations opt)
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
case GENCONF_CLI:
|
||||
genconfig_obj = cobj;
|
||||
if (block_gen_config_cli_1(genconfig_obj, &reply, clnt) != RPC_SUCCESS) {
|
||||
LOG("cli", GB_LOG_ERROR, "%sgenconfig on volume %s failed",
|
||||
clnt_sperror(clnt, "block_gen_config_cli_1"), genconfig_obj->volume);
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -259,6 +271,30 @@ glusterBlockIsNameAcceptable(char *name)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool
|
||||
glusterBlockIsVolListAcceptable(char *name)
|
||||
{
|
||||
char *tok, *tmp;
|
||||
char delim[2] = {'\0', };
|
||||
|
||||
|
||||
if (!name || GB_STRDUP(tmp, name) < 0)
|
||||
return FALSE;
|
||||
|
||||
delim[0] = GB_VOLS_DELIMITER;
|
||||
tok = strtok(tmp, delim);
|
||||
while (tok != NULL) {
|
||||
if (!glusterBlockIsNameAcceptable(tok)) {
|
||||
GB_FREE(tmp);
|
||||
return FALSE;
|
||||
}
|
||||
tok = strtok(NULL, delim);
|
||||
}
|
||||
|
||||
GB_FREE(tmp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool
|
||||
glusterBlockIsAddrAcceptable(char *addr)
|
||||
{
|
||||
@@ -752,6 +788,48 @@ glusterBlockReplace(int argcount, char **options, int json)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
glusterBlockGenConfig(int argcount, char **options, int json)
|
||||
{
|
||||
blockGenConfigCli robj = {0};
|
||||
int ret = -1;
|
||||
char helpMsg[256] = {0, };
|
||||
|
||||
|
||||
GB_ARGCHECK_OR_RETURN(argcount, 5, "genconfig", GB_GENCONF_HELP_STR);
|
||||
|
||||
if (!glusterBlockIsVolListAcceptable(options[2])) {
|
||||
MSG("volume list(%s) should be delimited by '%c' character only\n%s\n",
|
||||
options[2], GB_VOLS_DELIMITER, GB_GENCONF_HELP_STR);
|
||||
goto out;
|
||||
}
|
||||
|
||||
GB_STRCPYSTATIC(robj.volume, options[2]);
|
||||
|
||||
if (!strcmp(options[3], "enable-tpg")) {
|
||||
if (!glusterBlockIsAddrAcceptable(options[4])) {
|
||||
MSG("host addr (%s) should be a valid ip address\n%s\n",
|
||||
options[3], GB_REPLACE_HELP_STR);
|
||||
goto out;
|
||||
}
|
||||
GB_STRCPYSTATIC(robj.addr, options[4]);
|
||||
} else {
|
||||
MSG("unknown option '%s' for genconfig:\n%s\n", options[3], GB_GENCONF_HELP_STR);
|
||||
return -1;
|
||||
}
|
||||
robj.json_resp = json;
|
||||
|
||||
ret = glusterBlockCliRPC_1(&robj, GENCONF_CLI);
|
||||
if (ret) {
|
||||
LOG("cli", GB_LOG_ERROR, "failed genconfig on volume %s", robj.volume);
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
glusterBlockParseArgs(int count, char **options)
|
||||
{
|
||||
@@ -813,7 +891,12 @@ glusterBlockParseArgs(int count, char **options)
|
||||
LOG("cli", GB_LOG_ERROR, "%s", FAILED_REPLACE);
|
||||
}
|
||||
goto out;
|
||||
|
||||
case GB_CLI_GENCONFIG:
|
||||
ret = glusterBlockGenConfig(count, options, json);
|
||||
if (ret) {
|
||||
LOG("cli", GB_LOG_ERROR, "%s", FAILED_GENCONFIG);
|
||||
}
|
||||
goto out;
|
||||
case GB_CLI_DELETE:
|
||||
ret = glusterBlockDelete(count, options, json);
|
||||
if (ret) {
|
||||
|
||||
@@ -60,7 +60,8 @@ typedef enum operations {
|
||||
REPLACE_GET_PORTAL_TPG_SRV,
|
||||
LIST_SRV,
|
||||
INFO_SRV,
|
||||
VERSION_SRV
|
||||
VERSION_SRV,
|
||||
GENCONFIG_SRV
|
||||
} operations;
|
||||
|
||||
|
||||
@@ -99,6 +100,12 @@ typedef struct blockRemoteModifyResp {
|
||||
} blockRemoteModifyResp;
|
||||
|
||||
|
||||
typedef struct soTgObj {
|
||||
struct json_object *so_arr;
|
||||
struct json_object *tg_arr;
|
||||
} soTgObj;
|
||||
|
||||
|
||||
typedef struct blockRemoteDeleteResp {
|
||||
char *d_attempt;
|
||||
char *d_success;
|
||||
@@ -2488,6 +2495,335 @@ block_replace_cli_1_svc_st(blockReplaceCli *blk, struct svc_req *rqstp)
|
||||
blockRemoteReplaceRespFree(savereply);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
struct json_object *
|
||||
getTpgObj(char *block, MetaInfo *info, blockGenConfigCli *blk, char *portal, int tag)
|
||||
{
|
||||
int auth = 0;
|
||||
uuid_t uuid;
|
||||
char alias[UUID_BUF_SIZE];
|
||||
char alias_10[11] = {'\0', };
|
||||
char lun_so[256] = {'\0', };
|
||||
|
||||
struct json_object *tpg_obj = json_object_new_object();
|
||||
struct json_object *tpg_attr_obj = json_object_new_object();
|
||||
struct json_object *tpg_luns_arr = json_object_new_array();
|
||||
struct json_object *tpg_lun_obj = json_object_new_object();
|
||||
struct json_object *tpg_portals_arr = json_object_new_array();
|
||||
struct json_object *tpg_portal_obj = json_object_new_object();
|
||||
struct json_object *tpg_params_obj = json_object_new_object();
|
||||
|
||||
|
||||
// { Tpg Object open
|
||||
auth = 1;
|
||||
if(info->passwd[0] == '\0') {
|
||||
auth = 0;
|
||||
}
|
||||
|
||||
json_object_object_add(tpg_attr_obj, "authentication", json_object_new_int(auth));
|
||||
json_object_object_add(tpg_attr_obj, "cache_dynamic_acls", json_object_new_int(1));
|
||||
json_object_object_add(tpg_attr_obj, "demo_mode_write_protect", json_object_new_int(0));
|
||||
json_object_object_add(tpg_attr_obj, "generate_node_acls", json_object_new_int(1));
|
||||
if (strcmp(blk->addr, portal)) {
|
||||
json_object_object_add(tpg_attr_obj, "tpg_enabled_sendtargets", json_object_new_int(0));
|
||||
}
|
||||
json_object_object_add(tpg_obj, "attributes", tpg_attr_obj);
|
||||
if (auth) {
|
||||
json_object_object_add(tpg_obj, "chap_password", GB_JSON_OBJ_TO_STR(info->passwd));
|
||||
json_object_object_add(tpg_obj, "chap_userid", GB_JSON_OBJ_TO_STR(info->gbid));
|
||||
}
|
||||
|
||||
if (!strcmp(blk->addr, portal)) {
|
||||
json_object_object_add(tpg_obj, "enable", json_object_new_boolean(TRUE));
|
||||
} else {
|
||||
json_object_object_add(tpg_obj, "enable", json_object_new_boolean(FALSE));
|
||||
}
|
||||
|
||||
// "luns" : [
|
||||
uuid_generate(uuid);
|
||||
uuid_unparse(uuid, alias);
|
||||
snprintf(alias_10, 11, "%.10s", alias+24);
|
||||
json_object_object_add(tpg_lun_obj, "alias", GB_JSON_OBJ_TO_STR(alias_10));
|
||||
snprintf(lun_so, 256, "/backstores/user/%s", block);
|
||||
json_object_object_add(tpg_lun_obj, "storage_object", GB_JSON_OBJ_TO_STR(lun_so));
|
||||
json_object_object_add(tpg_lun_obj, "index", json_object_new_int(0));
|
||||
json_object_array_add(tpg_luns_arr, tpg_lun_obj);
|
||||
json_object_object_add(tpg_obj, "luns", tpg_luns_arr);
|
||||
// ]
|
||||
|
||||
if (auth) {
|
||||
json_object_object_add(tpg_params_obj, "AuthMethod", GB_JSON_OBJ_TO_STR("CHAP"));
|
||||
}
|
||||
json_object_object_add(tpg_obj, "parameters", tpg_params_obj);
|
||||
|
||||
// "portals" : [
|
||||
json_object_object_add(tpg_portal_obj, "ip_address", GB_JSON_OBJ_TO_STR(portal));
|
||||
json_object_object_add(tpg_portal_obj, "port", json_object_new_int(3260));
|
||||
json_object_array_add(tpg_portals_arr, tpg_portal_obj);
|
||||
json_object_object_add(tpg_obj, "portals", tpg_portals_arr);
|
||||
// ]
|
||||
|
||||
json_object_object_add(tpg_obj, "tag", json_object_new_int(tag));
|
||||
// } Tpg Object close
|
||||
|
||||
return tpg_obj;
|
||||
}
|
||||
|
||||
|
||||
struct json_object *
|
||||
getTgObj(char *block, MetaInfo *info, blockGenConfigCli *blk)
|
||||
{
|
||||
size_t i, tag = 1;
|
||||
struct json_object *tg_obj = json_object_new_object();
|
||||
struct json_object *tpgs_arr = json_object_new_array();
|
||||
struct json_object *tpg_obj = NULL;
|
||||
char iqn[128] = {'\0', };
|
||||
|
||||
|
||||
json_object_object_add(tg_obj, "fabric", GB_JSON_OBJ_TO_STR("iscsi"));
|
||||
|
||||
// "tpgs:" : [
|
||||
// {
|
||||
for (i = 0; i < info->nhosts; i++) {
|
||||
if (blockhostIsValid (info->list[i]->status)) {
|
||||
tpg_obj = getTpgObj(block, info, blk, info->list[i]->addr, tag);
|
||||
json_object_array_add(tpgs_arr, tpg_obj);
|
||||
tag++;
|
||||
}
|
||||
}
|
||||
// },
|
||||
// ]
|
||||
|
||||
json_object_object_add(tg_obj, "tpgs", tpgs_arr);
|
||||
|
||||
snprintf(iqn, 128, "iqn.2016-12.org.gluster-block:%s", info->gbid);
|
||||
json_object_object_add(tg_obj, "wwn", GB_JSON_OBJ_TO_STR(iqn));
|
||||
|
||||
return tg_obj;
|
||||
}
|
||||
|
||||
|
||||
struct json_object *
|
||||
getSoObj(char *block, MetaInfo *info, blockGenConfigCli *blk)
|
||||
{
|
||||
char cfgstr[1024] = {'\0', };
|
||||
struct json_object *so_obj = json_object_new_object();
|
||||
struct json_object *so_obj_attr = json_object_new_object();
|
||||
|
||||
|
||||
json_object_object_add(so_obj_attr, "cmd_time_out", json_object_new_int(0));
|
||||
json_object_object_add(so_obj_attr, "dev_size", json_object_new_int64(info->size));
|
||||
|
||||
json_object_object_add(so_obj, "attributes", so_obj_attr);
|
||||
|
||||
snprintf(cfgstr, 1024, "glfs/%s@%s/block-store/%s", info->volume, blk->addr, info->gbid);
|
||||
json_object_object_add(so_obj, "config", GB_JSON_OBJ_TO_STR(cfgstr));
|
||||
json_object_object_add(so_obj, "name", GB_JSON_OBJ_TO_STR(block));
|
||||
json_object_object_add(so_obj, "plugin", GB_JSON_OBJ_TO_STR("user"));
|
||||
json_object_object_add(so_obj, "size", json_object_new_int64(info->size));
|
||||
json_object_object_add(so_obj, "wwn", GB_JSON_OBJ_TO_STR(info->gbid));
|
||||
|
||||
return so_obj;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
getSoTgArraysForAllVolume(struct soTgObj *obj, blockGenConfigCli *blk,
|
||||
char **errMsg, int *errCode)
|
||||
{
|
||||
struct glfs *glfs;
|
||||
struct glfs_fd *lkfd = NULL;
|
||||
struct glfs_fd *tgmdfd = NULL;
|
||||
struct dirent *entry;
|
||||
MetaInfo *info = NULL;
|
||||
strToCharArrayDefPtr vols;
|
||||
size_t i, j;
|
||||
int ret = -1;
|
||||
bool partOfBlock;
|
||||
struct json_object *so_obj = NULL;
|
||||
struct json_object *tg_obj = NULL;
|
||||
|
||||
|
||||
vols = getCharArrayFromDelimitedStr(blk->volume, GB_VOLS_DELIMITER);
|
||||
if (!vols) {
|
||||
LOG("mgmt", GB_LOG_ERROR,
|
||||
"getCharArrayFromDelimitedStr(%s) failed", blk->volume);
|
||||
goto optfail;
|
||||
}
|
||||
|
||||
for (i = 0; i < vols->len; i++) {
|
||||
glfs = glusterBlockVolumeInit(vols->data[i], errCode, errMsg);
|
||||
if (!glfs) {
|
||||
LOG("mgmt", GB_LOG_ERROR,
|
||||
"glusterBlockVolumeInit(%s) failed", vols->data[i]);
|
||||
goto optfail;
|
||||
}
|
||||
|
||||
lkfd = glusterBlockCreateMetaLockFile(glfs, vols->data[i], errCode, errMsg);
|
||||
if (!lkfd) {
|
||||
LOG("mgmt", GB_LOG_ERROR, "%s %s", FAILED_CREATING_META, vols->data[i]);
|
||||
goto optfail;
|
||||
}
|
||||
|
||||
GB_METALOCK_OR_GOTO(lkfd, vols->data[i], *errCode, *errMsg, out);
|
||||
|
||||
tgmdfd = glfs_opendir(glfs, GB_METADIR);
|
||||
if (!tgmdfd) {
|
||||
*errCode = errno;
|
||||
GB_ASPRINTF(errMsg, "Not able to open metadata directory for volume "
|
||||
"%s[%s]", vols->data[i], strerror(*errCode));
|
||||
LOG("mgmt", GB_LOG_ERROR, "glfs_opendir(%s): on volume %s failed[%s]",
|
||||
GB_METADIR, vols->data[i], strerror(errno));
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
while ((entry = glfs_readdir(tgmdfd))) {
|
||||
if (strcmp(entry->d_name, ".") &&
|
||||
strcmp(entry->d_name, "..") &&
|
||||
strcmp(entry->d_name, GB_TXLOCKFILE) &&
|
||||
strcmp(entry->d_name, GB_PRIO_FILENAME)) {
|
||||
|
||||
if (GB_ALLOC(info) < 0) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
ret = blockGetMetaInfo(glfs, entry->d_name, info, NULL);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
partOfBlock = false;
|
||||
for (j = 0; j < info->nhosts; j++) {
|
||||
if (blockhostIsValid(info->list[j]->status) && !strcmp(info->list[j]->addr, blk->addr)) {
|
||||
partOfBlock = true;
|
||||
}
|
||||
}
|
||||
if (!partOfBlock) {
|
||||
blockFreeMetaInfo(info);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* storage_objects */
|
||||
so_obj = getSoObj(entry->d_name, info, blk);
|
||||
json_object_array_add(obj->so_arr, so_obj);
|
||||
|
||||
/* targets */
|
||||
tg_obj = getTgObj(entry->d_name, info, blk);
|
||||
json_object_array_add(obj->tg_arr, tg_obj);
|
||||
|
||||
blockFreeMetaInfo(info);
|
||||
}
|
||||
}
|
||||
|
||||
GB_METAUNLOCK(lkfd, vols->data[i], *errCode, *errMsg);
|
||||
if (tgmdfd && glfs_closedir (tgmdfd) != 0) {
|
||||
LOG("mgmt", GB_LOG_ERROR, "glfs_closedir(%s): on volume %s failed[%s]",
|
||||
GB_METADIR, vols->data[i], strerror(errno));
|
||||
}
|
||||
if (lkfd && glfs_close(lkfd) != 0) {
|
||||
LOG("mgmt", GB_LOG_ERROR, "glfs_close(%s): on volume %s failed[%s]",
|
||||
GB_TXLOCKFILE, vols->data[i], strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
goto free;
|
||||
|
||||
out:
|
||||
GB_METAUNLOCK(lkfd, vols->data[i], *errCode, *errMsg);
|
||||
if (tgmdfd && glfs_closedir (tgmdfd) != 0) {
|
||||
LOG("mgmt", GB_LOG_ERROR, "glfs_closedir(%s): on volume %s failed[%s]",
|
||||
GB_METADIR, vols->data[i], strerror(errno));
|
||||
}
|
||||
blockFreeMetaInfo(info);
|
||||
|
||||
optfail:
|
||||
if (lkfd && glfs_close(lkfd) != 0) {
|
||||
LOG("mgmt", GB_LOG_ERROR, "glfs_close(%s): on volume %s failed[%s]",
|
||||
GB_TXLOCKFILE, vols->data[i], strerror(errno));
|
||||
}
|
||||
|
||||
free:
|
||||
strToCharArrayDefFree(vols);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
glusterBlockGenConfigSvc(blockGenConfigCli *blk,
|
||||
blockResponse *reply, char **errMsg, int *errCode)
|
||||
{
|
||||
struct soTgObj *obj = NULL;
|
||||
struct json_object *jobj = json_object_new_object();
|
||||
|
||||
|
||||
if (GB_ALLOC(obj) < 0) {
|
||||
goto out;
|
||||
}
|
||||
obj->so_arr = json_object_new_array();
|
||||
obj->tg_arr = json_object_new_array();
|
||||
|
||||
reply->exit = getSoTgArraysForAllVolume(obj, blk, errMsg, errCode);
|
||||
if(reply->exit) {
|
||||
LOG("mgmt", GB_LOG_ERROR, "getSoTgArraysPerVolume(): on volume[s] %s failed",
|
||||
blk->volume);
|
||||
goto out;
|
||||
}
|
||||
|
||||
json_object_object_add(jobj, "storage_objects", obj->so_arr);
|
||||
json_object_object_add(jobj, "targets", obj->tg_arr);
|
||||
|
||||
out:
|
||||
if(reply->exit) {
|
||||
blockFormatErrorResponse(GENCONFIG_SRV, blk->json_resp, *errCode,
|
||||
GB_DEFAULT_ERRMSG, reply);
|
||||
} else {
|
||||
GB_ASPRINTF(&reply->out, "%s\n", json_object_to_json_string_ext(jobj, JSON_C_TO_STRING_PRETTY));
|
||||
}
|
||||
json_object_put(jobj);
|
||||
GB_FREE(obj);
|
||||
|
||||
return reply->exit;
|
||||
}
|
||||
|
||||
|
||||
blockResponse *
|
||||
block_gen_config_cli_1_svc_st(blockGenConfigCli *blk, struct svc_req *rqstp)
|
||||
{
|
||||
blockResponse *reply = NULL;
|
||||
int errCode = 0;
|
||||
char *errMsg = NULL;
|
||||
|
||||
|
||||
LOG("mgmt", GB_LOG_DEBUG,
|
||||
"genconfig request, volume[s]=%s addr=%s", blk->volume, blk->addr);
|
||||
|
||||
if (GB_ALLOC(reply) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
reply->exit = -1;
|
||||
|
||||
errCode = glusterBlockGenConfigSvc(blk, reply, &errMsg, &errCode);
|
||||
if (errCode) {
|
||||
LOG("mgmt", GB_LOG_ERROR, "glusterBlockGenConfigSvc(): on volume[s] %s failed with %s",
|
||||
blk->volume, errMsg?errMsg:"");
|
||||
goto out;
|
||||
}
|
||||
|
||||
LOG("mgmt", GB_LOG_DEBUG, "genconfig cli success, volume[s]=%s", blk->volume);
|
||||
|
||||
out:
|
||||
return reply;
|
||||
}
|
||||
|
||||
@@ -4994,6 +5330,15 @@ block_replace_cli_1_svc(blockReplaceCli *blk, blockResponse *reply,
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool_t
|
||||
block_gen_config_cli_1_svc(blockGenConfigCli *blk, blockResponse *reply,
|
||||
struct svc_req *rqstp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
GB_RPC_CALL(gen_config_cli, blk, reply, rqstp, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool_t
|
||||
block_list_cli_1_svc(blockListCli *blk, blockResponse *reply,
|
||||
|
||||
@@ -124,6 +124,12 @@ struct blockReplaceCli {
|
||||
enum JsonResponseFormat json_resp;
|
||||
};
|
||||
|
||||
struct blockGenConfigCli {
|
||||
char volume[255];
|
||||
char addr[255];
|
||||
enum JsonResponseFormat json_resp;
|
||||
};
|
||||
|
||||
struct blockResponse {
|
||||
int exit; /* exit code of the command */
|
||||
string out<>; /* output; TODO: return respective objects */
|
||||
@@ -153,5 +159,6 @@ program GLUSTER_BLOCK_CLI {
|
||||
blockResponse BLOCK_MODIFY_CLI(blockModifyCli) = 5;
|
||||
blockResponse BLOCK_REPLACE_CLI(blockReplaceCli) = 6;
|
||||
blockResponse BLOCK_MODIFY_SIZE_CLI(blockModifySizeCli) = 7;
|
||||
blockResponse BLOCK_GEN_CONFIG_CLI(blockGenConfigCli) = 8;
|
||||
} = 1;
|
||||
} = 212153113; /* B2 L12 O15 C3 K11 C3 */
|
||||
|
||||
@@ -197,6 +197,79 @@ blockServerDefFree(blockServerDefPtr blkServers)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
strToCharArrayDefFree(strToCharArrayDefPtr arr)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
|
||||
if (!arr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < arr->len; i++) {
|
||||
GB_FREE(arr->data[i]);
|
||||
}
|
||||
GB_FREE(arr->data);
|
||||
GB_FREE(arr);
|
||||
}
|
||||
|
||||
|
||||
strToCharArrayDefPtr
|
||||
getCharArrayFromDelimitedStr(char *str, char delim)
|
||||
{
|
||||
strToCharArrayDefPtr arr;
|
||||
char *tmp;
|
||||
char *tok;
|
||||
char *base;
|
||||
size_t i = 0;
|
||||
|
||||
if (!str) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (GB_STRDUP(tmp, str) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
base = tmp;
|
||||
|
||||
if (GB_ALLOC(arr) < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* count number of Vols */
|
||||
while (*tmp) {
|
||||
if (*tmp == delim) {
|
||||
arr->len++;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
arr->len++;
|
||||
tmp = base; /* reset vols */
|
||||
|
||||
|
||||
if (GB_ALLOC_N(arr->data, arr->len) < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
tok = strtok(tmp, &delim);
|
||||
for (i = 0; tok != NULL; i++) {
|
||||
if (GB_STRDUP(arr->data[i], tok) < 0) {
|
||||
goto out;
|
||||
}
|
||||
tok = strtok(NULL, &delim);
|
||||
}
|
||||
|
||||
GB_FREE(base);
|
||||
return arr;
|
||||
|
||||
out:
|
||||
GB_FREE(base);
|
||||
strToCharArrayDefFree(arr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
blockhostIsValid(char *status)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
# include "utils.h"
|
||||
# include "block.h"
|
||||
|
||||
# define GB_VOLS_DELIMITER ','
|
||||
|
||||
|
||||
typedef struct blockServerDef {
|
||||
size_t nhosts;
|
||||
@@ -23,6 +25,13 @@ typedef struct blockServerDef {
|
||||
typedef blockServerDef *blockServerDefPtr;
|
||||
|
||||
|
||||
typedef struct strToCharArrayDef {
|
||||
size_t len;
|
||||
char **data;
|
||||
} strToCharArrayDef;
|
||||
typedef strToCharArrayDef *strToCharArrayDefPtr;
|
||||
|
||||
|
||||
static const char *const JsonResponseFormatLookup[] = {
|
||||
[GB_JSON_NONE] = "",
|
||||
|
||||
@@ -81,6 +90,10 @@ static const char *const ConvertStringToTrillianLookup[] = {
|
||||
};
|
||||
|
||||
|
||||
strToCharArrayDefPtr getCharArrayFromDelimitedStr(char *str, char delim);
|
||||
|
||||
void strToCharArrayDefFree(strToCharArrayDefPtr arr);
|
||||
|
||||
enum JsonResponseFormat jsonResponseFormatParse(const char *opt);
|
||||
|
||||
ssize_t glusterBlockParseSize(const char *dom, char *value);
|
||||
|
||||
@@ -93,6 +93,9 @@
|
||||
# define FAILED_REPLACE "failed in replace"
|
||||
# define FAILED_REMOTE_REPLACE "failed in remote replace portal"
|
||||
|
||||
/* Config generate */
|
||||
# define FAILED_GENCONFIG "failed in generation of config"
|
||||
|
||||
# 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)
|
||||
@@ -350,6 +353,7 @@ typedef enum gbCliCmdlineOption {
|
||||
GB_CLI_DELETE,
|
||||
GB_CLI_MODIFY,
|
||||
GB_CLI_REPLACE,
|
||||
GB_CLI_GENCONFIG,
|
||||
GB_CLI_HELP,
|
||||
GB_CLI_HYPHEN_HELP,
|
||||
GB_CLI_VERSION,
|
||||
@@ -368,6 +372,7 @@ static const char *const gbCliCmdlineOptLookup[] = {
|
||||
[GB_CLI_DELETE] = "delete",
|
||||
[GB_CLI_MODIFY] = "modify",
|
||||
[GB_CLI_REPLACE] = "replace",
|
||||
[GB_CLI_GENCONFIG] = "genconfig",
|
||||
[GB_CLI_HELP] = "help",
|
||||
[GB_CLI_HYPHEN_HELP] = "--help",
|
||||
[GB_CLI_VERSION] = "version",
|
||||
|
||||
Reference in New Issue
Block a user