diff --git a/README.md b/README.md index 7722723..d1ddbe8 100644 --- a/README.md +++ b/README.md @@ -75,9 +75,11 @@ commands: [storage ] [ring-buffer ] [block-size ] + [io-timeout ] [size] create block device [defaults: ha 1, auth disable, prealloc full, size in bytes, - ring-buffer and block-size default size dependends on kernel] + ring-buffer and block-size default size dependends on kernel, + io-timeout 43s] list list available block devices. diff --git a/cli/gluster-block.c b/cli/gluster-block.c index 561603e..f2a7254 100644 --- a/cli/gluster-block.c +++ b/cli/gluster-block.c @@ -19,7 +19,8 @@ "[ha ] [auth ] " \ "[prealloc ] [storage ] " \ "[ring-buffer ] " \ - "[block-size ] " \ + "[block-size ] " \ + "[io-timeout ] " \ " [size] [--json*]" # define GB_DELETE_HELP_STR "gluster-block delete " \ "[unlink-storage ] [force] [--json*]" @@ -312,9 +313,11 @@ glusterBlockHelp(void) " [storage ]\n" " [ring-buffer ]\n" " [block-size ]\n" + " [io-timeout ]\n" " [size]\n" " create block device [defaults: ha 1, auth disable, prealloc full, size in bytes,\n" - " ring-buffer and block-size default size dependends on kernel]\n" + " ring-buffer and block-size default size dependends on kernel,\n" + " io-timeout 43s]\n" "\n" " list \n" " list available block devices.\n" @@ -640,6 +643,7 @@ glusterBlockCreate(int argcount, char **options, int json) cobj.json_resp = json; cobj.mpath = 1; cobj.prealloc = 1; + cobj.io_timeout = GB_IO_TIMEOUT_DEF; if (glusterBlockParseVolumeBlock(options[optind++], cobj.volume, cobj.block_name, sizeof(cobj.volume), sizeof(cobj.block_name), @@ -698,6 +702,25 @@ glusterBlockCreate(int argcount, char **options, int json) GB_STRCPYSTATIC(cobj.storage, options[optind++]); TAKE_SIZE=false; break; + case GB_CLI_CREATE_IO_TIMEOUT: + if (isNumber(options[optind])) { + sscanf(options[optind++], "%u", &cobj.io_timeout); + if (cobj.io_timeout < 1) { + MSG(stderr, "'io-timeout' should equal or larger than 1 second"); + MSG(stderr, GB_CREATE_HELP_STR); + LOG("cli", GB_LOG_ERROR, + "failed while parsing io-timeout for block <%s/%s>", + cobj.volume, cobj.block_name); + goto out; + } + } else { + MSG(stderr, "'io-timeout' option is incorrect, hint: should be uint type"); + MSG(stderr, GB_CREATE_HELP_STR); + LOG("cli", GB_LOG_ERROR, "failed while parsing io-timeout for block <%s/%s>", + cobj.volume, cobj.block_name); + goto out; + } + break; case GB_CLI_CREATE_RBSIZE: if (isNumber(options[optind])) { sscanf(options[optind++], "%u", &cobj.rb_size); diff --git a/daemon/gluster-blockd.c b/daemon/gluster-blockd.c index 482b8a9..99529bc 100644 --- a/daemon/gluster-blockd.c +++ b/daemon/gluster-blockd.c @@ -458,6 +458,14 @@ gbDependenciesVersionCheck(void) } GB_FREE(out); + out = gbRunnerGetOutput(CONFIGSHELL_VERSION); + if (!out[0]) { + LOG("mgmt", GB_LOG_INFO, "starting with configshell version < 1.1.25"); + } else { + LOG("mgmt", GB_LOG_INFO, "starting with configshell version - %s", out); + } + GB_FREE(out); + return; out: diff --git a/docs/gluster-block.8 b/docs/gluster-block.8 index dcdc198..1d0738d 100644 --- a/docs/gluster-block.8 +++ b/docs/gluster-block.8 @@ -26,7 +26,7 @@ Note that the gluster-blockd daemon is responsible for block management, hence t .SH COMMANDS .SS -\fBcreate\fR [ha ] [auth ] [prealloc ] [storage ] [ring-buffer ] [block-size ] [BYTES] +\fBcreate\fR [ha ] [auth ] [prealloc ] [storage ] [ring-buffer ] [block-size ] [io-timeout ] [BYTES] create block device. .TP [ha ] @@ -46,6 +46,10 @@ kernel ring buffer size for exchanging iSCSI commands, range [1MB - 1024MB] (def .TP [block-size ] kernel hw block size, aligns to 512 (default: as per kernel) +.TP +[io-timeout ] +time duration for which the tcmu-runner waits to check if the IO from gluster block hosting volume server is responsive. Ideally this value should be kept larger than both IO timeout value (default is 30s) in the iscsi client/initiator side and the gluster ping timeout (default is 42s), (default: 43s) + .TP servers in the pool where targets will be exported diff --git a/rpc/block_common.h b/rpc/block_common.h index 87e36d0..a526cb1 100644 --- a/rpc/block_common.h +++ b/rpc/block_common.h @@ -29,7 +29,7 @@ # define GB_TGCLI_GLFS_PATH "/backstores/user:glfs" # define GB_TGCLI_GLFS "targetcli " GB_TGCLI_GLFS_PATH -# define GB_TGCLI_CHECK GB_TGCLI_GLFS " ls | grep ' %s ' | grep '/%s ' > " DEVNULLPATH +# define GB_TGCLI_CHECK GB_TGCLI_GLFS " ls | grep ' %s ' | grep '/%s' > " DEVNULLPATH # define GB_TGCLI_ISCSI_PATH "/iscsi" # define GB_TGCLI_ISCSI "targetcli " GB_TGCLI_ISCSI_PATH # define GB_TGCLI_ISCSI_CHECK GB_TGCLI_ISCSI " ls | grep ' %s%s ' > " DEVNULLPATH @@ -39,6 +39,7 @@ # define GB_RING_BUFFER_STR "max_data_area_mb" # define GB_BLOCK_SIZE_STR "hw_block_size" +# define GB_IO_TIMEOUT_STR "tcmur_cmd_time_out" #define GB_CMD_TIME_OUT 130 diff --git a/rpc/block_create.c b/rpc/block_create.c index d2eb0f6..e7a4b82 100644 --- a/rpc/block_create.c +++ b/rpc/block_create.c @@ -427,10 +427,12 @@ glusterBlockCreateRemoteAsync(blockServerDefPtr list, size_t mpath, static blockResponse * -block_create_common(blockCreate *blk, char *control, char *volServer, char *prio_path) +block_create_common(blockCreate *blk, char *control, char *volServer, + char *prio_path, size_t io_timeout) { char *tmp = NULL; char *backstore = NULL; + char *io_timeout_str = NULL; char *backstore_attr = NULL; char *iqn = NULL; char *tpg = NULL; @@ -452,9 +454,10 @@ block_create_common(blockCreate *blk, char *control, char *volServer, char *prio LOG("mgmt", GB_LOG_INFO, "create request, volume=%s volserver=%s blockname=%s blockhosts=%s " - "filename=%s authmode=%d passwd=%s size=%lu", blk->volume, - volServer?volServer:blk->ipaddr, blk->block_name, blk->block_hosts, - blk->gbid, blk->auth_mode, blk->auth_mode?blk->passwd:"", blk->size); + "filename=%s authmode=%d passwd=%s size=%lu control=%s " + "io_timeout=%lu", blk->volume, volServer?volServer:blk->ipaddr, + blk->block_name, blk->block_hosts, blk->gbid, blk->auth_mode, + blk->auth_mode?blk->passwd:"", blk->size, control, io_timeout); if (GB_ALLOC(reply) < 0) { goto out; @@ -483,10 +486,18 @@ block_create_common(blockCreate *blk, char *control, char *volServer, char *prio prioCap = true; } - if (GB_ASPRINTF(&backstore, "%s %s name=%s size=%zu cfgstring=%s@%s%s/%s%s wwn=%s", + if (io_timeout) { + if (GB_ASPRINTF(&io_timeout_str, ";tcmur_cmd_time_out=%lu", + io_timeout) == -1) { + goto out; + } + } + + if (GB_ASPRINTF(&backstore, "%s %s name=%s size=%zu cfgstring=%s@%s%s/%s%s%s wwn=%s", GB_TGCLI_GLFS_PATH, GB_CREATE, blk->block_name, blk->size, blk->volume, volServer?volServer:blk->ipaddr, GB_STOREDIR, - blk->gbid, control ? control : "", blk->gbid) == -1) { + blk->gbid, io_timeout_str ? io_timeout_str : "", + control ? control : "", blk->gbid) == -1) { goto out; } @@ -698,6 +709,7 @@ block_create_common(blockCreate *blk, char *control, char *volServer, char *prio GB_FREE(backstore_attr); blockServerDefFree(list); GB_FREE(glfs_alua_sup); + GB_FREE(io_timeout_str); return reply; } @@ -706,7 +718,7 @@ block_create_common(blockCreate *blk, char *control, char *volServer, char *prio static blockResponse * block_create_1_svc_st(blockCreate *blk, struct svc_req *rqstp) { - return block_create_common(blk, NULL, NULL, NULL); + return block_create_common(blk, NULL, NULL, NULL, 0); } @@ -719,14 +731,22 @@ block_create_v2_1_svc_st(blockCreate2 *blk, struct svc_req *rqstp) char *volServer = NULL; size_t len = blk->xdata.xdata_len; size_t blk_size = 0; + size_t io_timeout = 0; struct gbXdata *xdata_val = (struct gbXdata*)blk->xdata.xdata_val; struct gbCreate3 *gbCreate3 = (struct gbCreate3 *)xdata_val->data; int n = 0; if (len > 0 && xdata_val && GB_XDATA_IS_MAGIC(xdata_val->magic)) { - if (GB_XDATA_GET_MAGIC_VER(xdata_val->magic) == 3) { + switch (GB_XDATA_GET_MAGIC_VER(xdata_val->magic)) { + case 4: + io_timeout = gbCreate3->io_timeout; + case 3: blk_size = gbCreate3->blk_size; volServer = gbCreate3->volServer; + break; + default: + LOG("mgmt", GB_LOG_ERROR, "Shouldn't be here and getting unknown verion number!"); + break; } } else if (len > 0 && len <= HOST_NAME_MAX) { volServer = (char *)blk->xdata.xdata_val; @@ -753,7 +773,8 @@ block_create_v2_1_svc_st(blockCreate2 *blk, struct svc_req *rqstp) convertTypeCreate2ToCreate(blk, &blk_v1); - return block_create_common(&blk_v1, control, volServer, blk->prio_path); + return block_create_common(&blk_v1, control, volServer, blk->prio_path, + io_timeout); } static void @@ -935,9 +956,10 @@ block_create_cli_1_svc_st(blockCreateCli *blk, struct svc_req *rqstp) LOG("mgmt", GB_LOG_INFO, "create cli request, volume=%s blockname=%s mpath=%d blockhosts=%s " - "authmode=%d size=%lu, rbsize=%d, blksize=%d", blk->volume, - blk->block_name, blk->mpath, blk->block_hosts, blk->auth_mode, blk->size, - blk->rb_size, blk->blk_size); + "authmode=%d size=%lu rbsize=%d blksize=%d io_timeout=%d", + blk->volume, blk->block_name, blk->mpath, blk->block_hosts, + blk->auth_mode, blk->size, blk->rb_size, blk->blk_size, + blk->io_timeout); if (GB_ALLOC(reply) < 0) { goto optfail; @@ -1035,10 +1057,20 @@ block_create_cli_1_svc_st(blockCreateCli *blk, struct svc_req *rqstp) goto exist; } - GB_METAUPDATE_OR_GOTO(lock, glfs, blk->block_name, blk->volume, - errCode, errMsg, exist, - "SIZE: %zu\nRINGBUFFER: %u\nBLKSIZE: %u\nENTRYCREATE: SUCCESS\n", - blk->size, blk->rb_size, blk->blk_size); + if (!resultCaps[GB_CREATE_IO_TIMEOUT_CAP]) { + GB_METAUPDATE_OR_GOTO(lock, glfs, blk->block_name, blk->volume, + errCode, errMsg, exist, + "SIZE: %zu\nRINGBUFFER: %u\nBLKSIZE: %u\n" + "IOTIMEOUT: %u\nENTRYCREATE: SUCCESS\n", + blk->size, blk->rb_size, blk->blk_size, + blk->io_timeout); + } else { + GB_METAUPDATE_OR_GOTO(lock, glfs, blk->block_name, blk->volume, + errCode, errMsg, exist, + "SIZE: %zu\nRINGBUFFER: %u\nBLKSIZE: %u\n" + "ENTRYCREATE: SUCCESS\n", + blk->size, blk->rb_size, blk->blk_size); + } GB_STRCPYSTATIC(cobj.volume, blk->volume); GB_STRCPYSTATIC(cobj.block_name, blk->block_name); @@ -1047,14 +1079,32 @@ block_create_cli_1_svc_st(blockCreateCli *blk, struct svc_req *rqstp) GB_STRCPYSTATIC(cobj.gbid, gbid); GB_STRDUP(cobj.block_hosts, blk->block_hosts); - if (blk->blk_size) { // Create V3 + if (!resultCaps[GB_CREATE_IO_TIMEOUT_CAP]) { // Create V4 unsigned int len; struct gbCreate3 *gbCreate3; len = sizeof(struct gbXdata) + sizeof(struct gbCreate3); if (GB_ALLOC_N(xdata, len) < 0) { - errCode = ENOMEM; - goto exist; + errCode = ENOMEM; + goto exist; + } + + xdata->magic = GB_XDATA_GEN_MAGIC(4); + gbCreate3 = (struct gbCreate3 *)(&xdata->data); + GB_STRCPY(gbCreate3->volServer, (char *)gbConf->volServer, sizeof(gbConf->volServer)); + gbCreate3->blk_size = blk->blk_size; + gbCreate3->io_timeout = blk->io_timeout; + + cobj.xdata.xdata_len = len; + cobj.xdata.xdata_val = (char *)xdata; + } else if (blk->blk_size) { // Create V3 + unsigned int len; + struct gbCreate3 *gbCreate3; + + len = sizeof(struct gbXdata) + sizeof(struct gbCreate3); + if (GB_ALLOC_N(xdata, len) < 0) { + errCode = ENOMEM; + goto exist; } xdata->magic = GB_XDATA_GEN_MAGIC(3); diff --git a/rpc/block_genconfig.c b/rpc/block_genconfig.c index 1bb95b5..1ac3d32 100644 --- a/rpc/block_genconfig.c +++ b/rpc/block_genconfig.c @@ -138,8 +138,9 @@ getTgObj(char *block, MetaInfo *info, blockGenConfigCli *blk) static struct json_object * getSoObj(char *block, MetaInfo *info, blockGenConfigCli *blk) { - char cfgstr[1024] = {'\0', }; + char cfgstr[2048] = {'\0', }; char control[1024] = {'\0', }; + char io_timeout[128] = {'\0', }; struct json_object *so_obj = json_object_new_object(); struct json_object *so_obj_alua_ao_tpg; struct json_object *so_obj_alua_ano_tpg; @@ -187,10 +188,16 @@ getSoObj(char *block, MetaInfo *info, blockGenConfigCli *blk) json_object_object_add(so_obj, "attributes", so_obj_attr); // } + if (info->io_timeout) { + snprintf(io_timeout, 128, ";%s=%lu", GB_IO_TIMEOUT_STR, info->io_timeout); + } + if (!strcmp(gbConf->volServer, "localhost")) { - snprintf(cfgstr, 1024, "glfs/%s@%s/block-store/%s", info->volume, blk->addr, info->gbid); + snprintf(cfgstr, 2048, "glfs/%s@%s/block-store/%s%s", info->volume, + blk->addr, info->gbid, io_timeout[0]?io_timeout:""); } else { - snprintf(cfgstr, 1024, "glfs/%s@%s/block-store/%s", info->volume, gbConf->volServer, info->gbid); + snprintf(cfgstr, 2048, "glfs/%s@%s/block-store/%s%s", info->volume, + gbConf->volServer, info->gbid, io_timeout[0]?io_timeout:""); } json_object_object_add(so_obj, "config", GB_JSON_OBJ_TO_STR(cfgstr[0]?cfgstr:NULL)); if (info->rb_size) { diff --git a/rpc/block_info.c b/rpc/block_info.c index dc9b250..27e6c12 100644 --- a/rpc/block_info.c +++ b/rpc/block_info.c @@ -26,6 +26,7 @@ blockInfoCliFormatResponse(blockInfoCli *blk, int errCode, char *out = NULL; int i = 0; char *hr_size = NULL; /* Human Readable size */ + char *timeout = NULL; if (!reply) { return; @@ -67,6 +68,13 @@ blockInfoCliFormatResponse(blockInfoCli *blk, int errCode, } } + if (GB_ASPRINTF(&timeout, "%lu Seconds", info->io_timeout) < 0) { + GB_ASPRINTF (&errMsg, "failed in blockInfoCliFormatResponse"); + blockFormatErrorResponse(INFO_SRV, blk->json_resp, ENOMEM, + errMsg, reply); + goto out; + } + if (blk->json_resp) { json_obj = json_object_new_object(); json_object_object_add(json_obj, "NAME", GB_JSON_OBJ_TO_STR(blk->block_name)); @@ -74,6 +82,7 @@ blockInfoCliFormatResponse(blockInfoCli *blk, int errCode, json_object_object_add(json_obj, "GBID", GB_JSON_OBJ_TO_STR(info->gbid)); json_object_object_add(json_obj, "SIZE", GB_JSON_OBJ_TO_STR(hr_size)); json_object_object_add(json_obj, "HA", json_object_new_int(info->mpath)); + json_object_object_add(json_obj, "IOTIMEOUT", GB_JSON_OBJ_TO_STR(timeout)); json_object_object_add(json_obj, "PASSWORD", GB_JSON_OBJ_TO_STR(info->passwd)); json_array1 = json_object_new_array(); @@ -105,9 +114,9 @@ blockInfoCliFormatResponse(blockInfoCli *blk, int errCode, json_object_put(json_obj); } else { if (GB_ASPRINTF(&tmp, "NAME: %s\nVOLUME: %s\nGBID: %s\nSIZE: %s\n" - "HA: %zu\nPASSWORD: %s\nEXPORTED ON:", + "HA: %zu\nIOTIMEOUT: %s\nPASSWORD: %s\nEXPORTED ON:", blk->block_name, info->volume, info->gbid, hr_size, - info->mpath, info->passwd) == -1) { + info->mpath, timeout, info->passwd) == -1) { goto out; } for (i = 0; i < info->nhosts; i++) { @@ -150,7 +159,8 @@ blockInfoCliFormatResponse(blockInfoCli *blk, int errCode, blockFormatErrorResponse(INFO_SRV, blk->json_resp, errCode, GB_DEFAULT_ERRMSG, reply); } - GB_FREE(hr_size); + GB_FREE (hr_size); + GB_FREE (timeout); GB_FREE (tmp); GB_FREE (tmp2); GB_FREE (tmp3); diff --git a/rpc/block_replace.c b/rpc/block_replace.c index 933843a..64117d7 100644 --- a/rpc/block_replace.c +++ b/rpc/block_replace.c @@ -122,7 +122,24 @@ glusterBlockReplaceNodeRemoteAsync(struct glfs *glfs, blockReplaceCli *blk, goto out; } - if (info->blk_size) { // Create V3 + if (info->io_timeout) { // Create V4 + unsigned int len; + struct gbCreate3 *gbCreate3; + + len = sizeof(struct gbXdata) + sizeof(struct gbCreate3); + if (GB_ALLOC_N(xdata, len) < 0) { + goto out; + } + + xdata->magic = GB_XDATA_GEN_MAGIC(4); + gbCreate3 = (struct gbCreate3 *)(&xdata->data); + GB_STRCPY(gbCreate3->volServer, (char *)gbConf->volServer, sizeof(gbConf->volServer)); + gbCreate3->blk_size = info->blk_size; + gbCreate3->io_timeout = info->io_timeout; + + cobj->xdata.xdata_len = len; + cobj->xdata.xdata_val = (char *)xdata; + } else if (info->blk_size) { // Create V3 unsigned int len; struct gbCreate3 *gbCreate3; diff --git a/rpc/block_version.c b/rpc/block_version.c index 60f94d9..3ca93f1 100644 --- a/rpc/block_version.c +++ b/rpc/block_version.c @@ -52,6 +52,9 @@ glusterBlockBuildMinCaps(void *data, operations opt) if (cblk->json_resp) { minCaps[GB_JSON_CAP] = true; } + if (cblk->io_timeout) { + minCaps[GB_CREATE_IO_TIMEOUT_CAP] = true; + } break; case DELETE_SRV: dblk = (blockDeleteCli *)data; diff --git a/rpc/glfs-operations.c b/rpc/glfs-operations.c index de4bfc0..7b3ce9f 100644 --- a/rpc/glfs-operations.c +++ b/rpc/glfs-operations.c @@ -610,6 +610,9 @@ blockStuffMetaInfo(MetaInfo *info, char *line) case GB_META_RINGBUFFER: sscanf(strchr(line, ' '), "%zu", &info->rb_size); break; + case GB_META_IO_TIMEOUT: + sscanf(strchr(line, ' '), "%lu", &info->io_timeout); + break; case GB_META_BLKSIZE: sscanf(strchr(line, ' '), "%zu", &info->blk_size); break; diff --git a/rpc/glfs-operations.h b/rpc/glfs-operations.h index bbc5fa4..4ae647e 100644 --- a/rpc/glfs-operations.h +++ b/rpc/glfs-operations.h @@ -34,6 +34,7 @@ typedef struct MetaInfo { size_t size; size_t rb_size; size_t blk_size; + size_t io_timeout; char prio_path[255]; size_t mpath; char entry[16]; /* possible strings for ENTRYCREATE: INPROGRESS|SUCCESS|FAIL */ diff --git a/rpc/rpcl/block.x b/rpc/rpcl/block.x index df62057..4afbd1f 100644 --- a/rpc/rpcl/block.x +++ b/rpc/rpcl/block.x @@ -67,6 +67,7 @@ struct blockCreateCli { u_quad_t size; u_int rb_size; /* TCMU Ring Buffer size in kernel */ u_int blk_size; /* TCMU hw block size in kernel */ + u_int io_timeout; /* Cmds timeout in tcmu-runner */ u_int mpath; /* HA request count */ bool auth_mode; bool prealloc; diff --git a/tests/basic.t b/tests/basic.t index a1f17e9..e13f9be 100755 --- a/tests/basic.t +++ b/tests/basic.t @@ -125,6 +125,10 @@ TEST gluster-block delete ${VOLNAME}/${BLKNAME} TEST gluster-block create ${VOLNAME}/${BLKNAME} ring-buffer 32 ${HOST} 1MiB TEST gluster-block delete ${VOLNAME}/${BLKNAME} +# Block create with 'io-timeout' set/delete +TEST gluster-block create ${VOLNAME}/${BLKNAME} io-timeout 44 ${HOST} 1MiB +TEST gluster-block delete ${VOLNAME}/${BLKNAME} + # Block create with 'block-size' set/delete TEST gluster-block create ${VOLNAME}/${BLKNAME} block-size 1024 ${HOST} 1MiB TEST gluster-block delete ${VOLNAME}/${BLKNAME} diff --git a/utils/capabilities.c b/utils/capabilities.c index bd6d8f8..19d41b8 100644 --- a/utils/capabilities.c +++ b/utils/capabilities.c @@ -36,6 +36,31 @@ gbCapabilitiesEnumParse(const char *cap) } +bool +gbIoTimeoutDependenciesVersionCheck(void) +{ + char *out = NULL; + int ret = true; + + + out = gbRunnerGetOutput(CONFIGSHELL_VERSION); + if (!gbDependencyVersionCompare(CONFIGSHELL_SEMICOLON, out)) { + ret = false; + goto out; + } + + GB_FREE(out); + out = gbRunnerGetOutput(TCMU_VERSION); + if (!gbDependencyVersionCompare(TCMURUNNER_IO_TIMEOUT, out)) { + ret = false; + } + +out: + GB_FREE(out); + return ret; +} + + static bool gbBlockSizeDependenciesVersionCheck(void) { @@ -146,6 +171,16 @@ gbSetCapabilties(void) GB_FREE(line); continue; } + } else if (ret == GB_CREATE_IO_TIMEOUT_CAP) { + if (!gbIoTimeoutDependenciesVersionCheck()) { + LOG ("mgmt", GB_LOG_WARNING, + "io timeout needs atleast configshell >=%s and tcmu-runner >= %s, so disabling its capability", + GB_MIN_CONFIGSHELL_SEM_VERSION, GB_MIN_TCMURUNNER_IO_TIMEOUT_VERSION); + caps[count].status = 0; + count++; + GB_FREE(line); + continue; + } } /* Part after ':' and before '\n' */ diff --git a/utils/capabilities.h b/utils/capabilities.h index 419e5f7..9ec13aa 100644 --- a/utils/capabilities.h +++ b/utils/capabilities.h @@ -50,6 +50,8 @@ enum gbCapabilities { GB_RELOAD_CAP, + GB_CREATE_IO_TIMEOUT_CAP, + GB_CAP_MAX }; @@ -62,6 +64,7 @@ static const char *const gbCapabilitiesLookup[] = { [GB_CREATE_RING_BUFFER_CAP] = "create_ring_buffer", [GB_CREATE_LOAD_BALANCE_CAP] = "create_load_balance", [GB_CREATE_BLOCK_SIZE_CAP] = "create_block_size", + [GB_CREATE_IO_TIMEOUT_CAP] = "create_io_timeout", [GB_DELETE_CAP] = "delete", [GB_DELETE_FORCE_CAP] = "delete_force", @@ -85,3 +88,4 @@ extern gbCapObj *globalCapabilities; int gbCapabilitiesEnumParse(const char *cap); void gbSetCapabilties(void); +bool gbIoTimeoutDependenciesVersionCheck(void); diff --git a/utils/gluster-block-caps.info b/utils/gluster-block-caps.info index 2e73f50..9cd8d29 100644 --- a/utils/gluster-block-caps.info +++ b/utils/gluster-block-caps.info @@ -160,3 +160,14 @@ create_block_size: true # Since: 0.5 ## reload: true + +## +# Nature: cli sub-command +# +# Label: 'io-timeout' +# +# Description: capability to create block with given cmds timeout value in tcmu-runner +# +# Since: 0.5 +## +create_io_timeout: true diff --git a/utils/utils.c b/utils/utils.c index 42de2ec..1fbe654 100644 --- a/utils/utils.c +++ b/utils/utils.c @@ -416,7 +416,16 @@ gbDependencyVersionCompare(int dependencyName, char *version) ret = true; } break; - + case CONFIGSHELL_SEMICOLON: + if (DEPENDENCY_VERSION(vNum[0], vNum[1], vNum[2]) >= GB_MIN_CONFIGSHELL_SEM_VERSION_CODE) { + ret = true; + } + break; + case TCMURUNNER_IO_TIMEOUT: + if (DEPENDENCY_VERSION(vNum[0], vNum[1], vNum[2]) >= GB_MIN_TCMURUNNER_IO_TIMEOUT_VERSION_CODE) { + ret = true; + } + break; } GB_FREE(verStr); diff --git a/utils/utils.h b/utils/utils.h index 2a873f5..8e876b7 100644 --- a/utils/utils.h +++ b/utils/utils.h @@ -42,6 +42,8 @@ # define GB_TCP_PORT 24010 # define GB_TCP_PORT_STR "24010" +# define GB_IO_TIMEOUT_DEF 43 + # define GFAPI_LOG_LEVEL 7 # define DEVNULLPATH "/dev/null" @@ -177,6 +179,7 @@ struct gbXdata { struct gbCreate3 { char volServer[HOST_NAME_MAX]; size_t blk_size; + size_t io_timeout; }; extern struct gbConf *gbConf; @@ -467,25 +470,27 @@ static const char *const gbCliCmdlineOptLookup[] = { }; typedef enum gbCliCreateOptions { - GB_CLI_CREATE_UNKNOWN = 0, - GB_CLI_CREATE_HA = 1, - GB_CLI_CREATE_AUTH = 2, - GB_CLI_CREATE_PREALLOC = 3, - GB_CLI_CREATE_STORAGE = 4, - GB_CLI_CREATE_RBSIZE = 5, - GB_CLI_CREATE_BLKSIZE = 6, + GB_CLI_CREATE_UNKNOWN = 0, + GB_CLI_CREATE_HA = 1, + GB_CLI_CREATE_AUTH = 2, + GB_CLI_CREATE_PREALLOC = 3, + GB_CLI_CREATE_STORAGE = 4, + GB_CLI_CREATE_RBSIZE = 5, + GB_CLI_CREATE_BLKSIZE = 6, + GB_CLI_CREATE_IO_TIMEOUT = 7, GB_CLI_CREATE_OPT_MAX } gbCliCreateOptions; static const char *const gbCliCreateOptLookup[] = { - [GB_CLI_CREATE_UNKNOWN] = "NONE", - [GB_CLI_CREATE_HA] = "ha", - [GB_CLI_CREATE_AUTH] = "auth", - [GB_CLI_CREATE_PREALLOC] = "prealloc", - [GB_CLI_CREATE_STORAGE] = "storage", - [GB_CLI_CREATE_RBSIZE] = "ring-buffer", - [GB_CLI_CREATE_BLKSIZE] = "block-size", + [GB_CLI_CREATE_UNKNOWN] = "NONE", + [GB_CLI_CREATE_HA] = "ha", + [GB_CLI_CREATE_AUTH] = "auth", + [GB_CLI_CREATE_PREALLOC] = "prealloc", + [GB_CLI_CREATE_STORAGE] = "storage", + [GB_CLI_CREATE_RBSIZE] = "ring-buffer", + [GB_CLI_CREATE_BLKSIZE] = "block-size", + [GB_CLI_CREATE_IO_TIMEOUT] = "io-timeout", [GB_CLI_CREATE_OPT_MAX] = NULL, }; @@ -559,6 +564,7 @@ typedef enum Metakey { GB_META_RINGBUFFER = 7, GB_META_PRIOPATH = 8, GB_META_BLKSIZE = 9, + GB_META_IO_TIMEOUT = 10, GB_METAKEY_MAX } Metakey; @@ -574,6 +580,7 @@ static const char *const MetakeyLookup[] = { [GB_META_RINGBUFFER] = "RINGBUFFER", [GB_META_PRIOPATH] = "PRIOPATH", [GB_META_BLKSIZE] = "BLKSIZE", + [GB_META_IO_TIMEOUT] = "IOTIMEOUT", [GB_METAKEY_MAX] = NULL }; @@ -660,11 +667,13 @@ typedef struct gbConfig { } gbConfig; typedef enum gbDependencies { - TCMURUNNER = 1, - TARGETCLI = 2, - RTSLIB_BLKSIZE = 3, - TARGETCLI_RELOAD = 4, - RTSLIB_RELOAD = 5, + TCMURUNNER = 1, + TARGETCLI = 2, + RTSLIB_BLKSIZE = 3, + TARGETCLI_RELOAD = 4, + RTSLIB_RELOAD = 5, + CONFIGSHELL_SEMICOLON = 6, + TCMURUNNER_IO_TIMEOUT = 7, } gbDependencies; int initGbConfig(void); diff --git a/version.h b/version.h index 0ed1f08..6d5a269 100644 --- a/version.h +++ b/version.h @@ -17,9 +17,10 @@ # define DEPENDENCY_VERSION KERNEL_VERSION -# define TARGETCLI_VERSION "targetcli --version 2>&1 | awk -F' ' '{printf $NF}'" -# define RTSLIB_VERSION "python -c 'from rtslib_fb import __version__; print(__version__)'" -# define TCMU_VERSION "tcmu-runner --version 2>&1 | awk -F' ' '{printf $NF}'" +# define TARGETCLI_VERSION "targetcli --version 2>&1 | awk -F' ' '{printf $NF}'" +# define RTSLIB_VERSION "python -c 'from rtslib_fb import __version__; print(__version__)'" +# define TCMU_VERSION "tcmu-runner --version 2>&1 | awk -F' ' '{printf $NF}'" +# define CONFIGSHELL_VERSION "python -c 'from configshell_fb import __version__; print(__version__)'" # define GLUSTER_BLOCK_VERSION "0.4" @@ -31,11 +32,15 @@ # define GB_MIN_RTSLIB_BLKSIZE_VERSION "2.1.69" # define GB_MIN_TARGETCLI_RELOAD_VERSION "2.1.fb50" # define GB_MIN_RTSLIB_RELOAD_VERSION "2.1.71" +# define GB_MIN_CONFIGSHELL_SEM_VERSION "1.1.25" +# define GB_MIN_TCMURUNNER_IO_TIMEOUT_VERSION "1.5.0" -# define GB_MIN_TCMURUNNER_VERSION_CODE DEPENDENCY_VERSION(1, 1, 3) -# define GB_MIN_TARGETCLI_VERSION_CODE DEPENDENCY_VERSION(2, 1, 49) -# define GB_MIN_RTSLIB_BLKSIZE_VERSION_CODE DEPENDENCY_VERSION(2, 1, 69) -# define GB_MIN_TARGETCLI_RELOAD_VERSION_CODE DEPENDENCY_VERSION(2, 1, 50) -# define GB_MIN_RTSLIB_RELOAD_VERSION_CODE DEPENDENCY_VERSION(2, 1, 71) +# define GB_MIN_TCMURUNNER_VERSION_CODE DEPENDENCY_VERSION(1, 1, 3) +# define GB_MIN_TARGETCLI_VERSION_CODE DEPENDENCY_VERSION(2, 1, 49) +# define GB_MIN_RTSLIB_BLKSIZE_VERSION_CODE DEPENDENCY_VERSION(2, 1, 69) +# define GB_MIN_TARGETCLI_RELOAD_VERSION_CODE DEPENDENCY_VERSION(2, 1, 50) +# define GB_MIN_RTSLIB_RELOAD_VERSION_CODE DEPENDENCY_VERSION(2, 1, 71) +# define GB_MIN_CONFIGSHELL_SEM_VERSION_CODE DEPENDENCY_VERSION(1, 1, 25) +# define GB_MIN_TCMURUNNER_IO_TIMEOUT_VERSION_CODE DEPENDENCY_VERSION(1, 5, 0) # endif /* _VERSION_H */