diff options
author | Prasanna Kumar Kalever <prasanna.kalever@redhat.com> | 2017-06-12 11:59:13 +0530 |
---|---|---|
committer | Prasanna Kumar Kalever <prasanna.kalever@redhat.com> | 2017-06-22 16:30:46 +0530 |
commit | 94c79620db4451bf804d6ab631c9ca59759dbc21 (patch) | |
tree | ee5c0e9430fb30812753ac1911bd8b5c163cb5fd | |
parent | 8bb5dd787e84f719940230adb24642653fcaec77 (diff) |
block: add support to prealloc = full | no option
currently we allocate sparse files for block backends in the gluster
volume, with 'prealloc = full' option introduced by this patch we should
be able to fully preallocate the backend block file.
Change-Id: Ibf32df5f978f732a3fd248693170463da6d08268
Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
-rw-r--r-- | README.md | 9 | ||||
-rw-r--r-- | cli/gluster-block.c | 38 | ||||
-rw-r--r-- | docs/gluster-block.8 | 10 | ||||
-rw-r--r-- | rpc/glfs-operations.c | 45 | ||||
-rw-r--r-- | rpc/rpcl/block.x | 1 | ||||
-rw-r--r-- | utils/common.c | 25 | ||||
-rw-r--r-- | utils/common.h | 48 |
7 files changed, 140 insertions, 36 deletions
@@ -93,13 +93,16 @@ You can run gluster-blockd as systemd service, note '/etc/sysconfig/gluster-bloc <b>CLI</b>: you can choose to run gluster-block(cli) from any node which has gluster-blockd running ```script # gluster-block --help -gluster-block (0.2) +gluster-block (0.2.1) usage: gluster-block <command> <volname[/blockname]> [<args>] [--json*] commands: - create <volname/blockname> [ha <count>] [auth enable|disable] <host1[,host2,...]> <size> - create block device. + create <volname/blockname> [ha <count>] + [auth <enable|disable>] + [prealloc <full|no>] + <host1[,host2,...]> <size> + create block device [defaults: ha 1, auth disable, prealloc no] list <volname> list available block devices. diff --git a/cli/gluster-block.c b/cli/gluster-block.c index 833f232..0aab6e6 100644 --- a/cli/gluster-block.c +++ b/cli/gluster-block.c @@ -189,8 +189,11 @@ glusterBlockHelp(void) " gluster-block <command> <volname[/blockname]> [<args>] [--json*]\n" "\n" "commands:\n" - " create <volname/blockname> [ha <count>] [auth enable|disable] <host1[,host2,...]> <size>\n" - " create block device.\n" + " create <volname/blockname> [ha <count>]\n" + " [auth <enable|disable>]\n" + " [prealloc <full|no>]\n" + " <host1[,host2,...]> <size>\n" + " create block device [defaults: ha 1, auth disable, prealloc no]\n" "\n" " list <volname>\n" " list available block devices.\n" @@ -292,10 +295,9 @@ glusterBlockModify(int argcount, char **options, int json) /* if auth given then collect status which is next by 'auth' arg */ if (!strcmp(options[optind], "auth")) { optind++; - if(strcmp (options[optind], "enable") == 0) { - mobj.auth_mode = 1; - } else if (strcmp (options[optind], "disable") == 0) { - mobj.auth_mode = 0; + ret = convertStringToTrillianParse(options[optind++]); + if(ret >= 0) { + mobj.auth_mode = ret; } else { MSG("%s\n", "'auth' option is incorrect"); MSG("%s\n", GB_MODIFY_HELP_STR); @@ -354,10 +356,9 @@ glusterBlockCreate(int argcount, char **options, int json) /* if auth given then collect boolean which is next by 'auth' arg */ if (!strcmp(options[optind], "auth")) { optind++; - if(strcmp (options[optind], "enable") == 0) { - cobj.auth_mode = 1; - } else if (strcmp (options[optind], "disable") == 0) { - cobj.auth_mode = 0; + ret = convertStringToTrillianParse(options[optind++]); + if(ret >= 0) { + cobj.auth_mode = ret; } else { MSG("%s\n", "'auth' option is incorrect"); MSG("%s\n", GB_CREATE_HELP_STR); @@ -366,7 +367,24 @@ glusterBlockCreate(int argcount, char **options, int json) cobj.volume, cobj.block_name); goto out; } + } + } + + if (argcount - optind >= 2) { /* atleast 2 needed */ + /* if prealloc given then collect boolean which is next by 'prealloc' arg */ + if (!strcmp(options[optind], "prealloc")) { optind++; + ret = convertStringToTrillianParse(options[optind++]); + if(ret >= 0) { + cobj.prealloc = ret; + } else { + MSG("%s\n", "'prealloc' option is incorrect"); + MSG("%s\n", GB_CREATE_HELP_STR); + LOG("cli", GB_LOG_ERROR, "Create failed while parsing argument " + "to prealloc for <%s/%s>", + cobj.volume, cobj.block_name); + goto out; + } } } diff --git a/docs/gluster-block.8 b/docs/gluster-block.8 index 83cfdf3..05f86c9 100644 --- a/docs/gluster-block.8 +++ b/docs/gluster-block.8 @@ -25,15 +25,18 @@ Note that the gluster-blockd daemon is responsible for block management, hence t .SH COMMANDS .SS -\fBcreate\fR <VOLNAME/NEW-BLOCKNAME> [ha <COUNT>] [auth enable|disable] <HOST1[,HOST2,..]> <BYTES> +\fBcreate\fR <VOLNAME/NEW-BLOCKNAME> [ha <COUNT>] [auth <enable|disable>] [prealloc <full|no>] <HOST1[,HOST2,..]> <BYTES> create block device. .TP [ha <COUNT>] multipath requirement for high availability (default: 1) .TP -[auth enable|disable] +[auth <enable|disable>] authentication setting (default: disable) .TP +[prealloc <full|no>] +"full" mode preallocates space by writing zeros to storage. (default: no) +.TP <HOST1,[HOST2....]> servers in the pool where targets will be exported. .TP @@ -82,6 +85,9 @@ To create a block device of size 1GiB To create a block device of size 1GiB with auth enable .B # gluster-block create blockVol/sampleBlock auth enable ${HOST} 1GiB +To create a block device of size 1GiB, by preallocating storage with zero fill +.B # gluster-block create blockVol/sampleBlock prealloc full ${HOST} 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 diff --git a/rpc/glfs-operations.c b/rpc/glfs-operations.c index 72de38f..db02620 100644 --- a/rpc/glfs-operations.c +++ b/rpc/glfs-operations.c @@ -126,37 +126,40 @@ glusterBlockCreateEntry(struct glfs *glfs, blockCreateCli *blk, char *gbid, if (ret) { *errCode = errno; LOG("gfapi", GB_LOG_ERROR, - "glfs_ftruncate(%s): on volume %s for block %s" + "glfs_ftruncate(%s): on volume %s for block %s " "of size %zu failed[%s]", gbid, blk->volume, blk->block_name, blk->size, strerror(errno)); - - if (tgfd && glfs_close(tgfd) != 0) { - LOG("gfapi", GB_LOG_ERROR, - "glfs_close(%s): on volume %s for block %s failed[%s]", - gbid, blk->volume, blk->block_name, strerror(errno)); - } - - ret = glfs_unlink(glfs, gbid); - if (ret && errno != ENOENT) { - LOG("gfapi", GB_LOG_ERROR, - "glfs_unlink(%s) on volume %s for block %s failed[%s]", - gbid, blk->volume, blk->block_name, strerror(errno)); - } - - ret = -1; - goto out; + goto unlink; } - if (tgfd && glfs_close(tgfd) != 0) { + if (blk->prealloc && glfs_zerofill(tgfd, 0, blk->size)) { *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)); + "glfs_zerofill(%s): on volume %s for block %s " + "of size %zu failed[%s]", gbid, blk->volume, blk->block_name, + blk->size, strerror(errno)); ret = -1; - goto out; + goto unlink; } } + +unlink: + 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)); + ret = -1; + } + + if (ret && glfs_unlink(glfs, gbid) && errno != ENOENT) { + *errCode = errno; + LOG("gfapi", GB_LOG_ERROR, + "glfs_unlink(%s) on volume %s for block %s failed[%s]", + gbid, blk->volume, blk->block_name, strerror(errno)); + } + out: if (ret) { GB_ASPRINTF (errMsg, "Not able to create metadata for %s/%s[%s]", blk->volume, diff --git a/rpc/rpcl/block.x b/rpc/rpcl/block.x index f5e2b8b..a47901a 100644 --- a/rpc/rpcl/block.x +++ b/rpc/rpcl/block.x @@ -38,6 +38,7 @@ struct blockCreateCli { u_quad_t size; u_int mpath; /* HA request count */ bool auth_mode; + bool prealloc; char block_name[255]; string block_hosts<>; enum JsonResponseFormat json_resp; diff --git a/utils/common.c b/utils/common.c index c6d1c34..8a8f303 100644 --- a/utils/common.c +++ b/utils/common.c @@ -121,3 +121,28 @@ glusterBlockFormatSize(const char *dom, size_t bytes) return buf; } + + +/* Return value and meaning + * 1 - true/set + * 0 - false/unset + * -1 - unknown string + */ +int +convertStringToTrillianParse(const char *opt) +{ + int i; + + + if (!opt) { + return -1; + } + + for (i = 1; i < GB_BOOL_MAX; i++) { + if (!strcmp(opt, ConvertStringToTrillianLookup[i])) { + return i%2; + } + } + + return -1; +} diff --git a/utils/common.h b/utils/common.h index 118d3f0..6503218 100644 --- a/utils/common.h +++ b/utils/common.h @@ -50,10 +50,58 @@ static const char *const JsonResponseFormatLookup[] = { }; +/* Always add new boolean data in a way that, word with jist + * 'yes/true' first to assign a odd number to it */ +typedef enum ConvertStringToTrillian { + GB_BOOL_YES = 1, + GB_BOOL_NO = 2, + + GB_BOOL_TRUE = 3, + GB_BOOL_FALSE = 4, + + GB_BOOL_ENABLE = 5, + GB_BOOL_DISABLE = 6, + + GB_BOOL_ONE = 7, + GB_BOOL_ZERO = 8, + + GB_BOOL_SET = 9, + GB_BOOL_UNSET = 10, + + GB_BOOL_FULL = 11, + + GB_BOOL_MAX +} ConvertStringToBool; + + +static const char *const ConvertStringToTrillianLookup[] = { + [GB_BOOL_YES] = "yes", + [GB_BOOL_NO] = "no", + + [GB_BOOL_TRUE] = "true", + [GB_BOOL_FALSE] = "false", + + [GB_BOOL_ENABLE] = "enable", + [GB_BOOL_DISABLE] = "disable", + + [GB_BOOL_ONE] = "1", /* true */ + [GB_BOOL_ZERO] = "0", + + [GB_BOOL_SET] = "set", + [GB_BOOL_UNSET] = "unset", + + [GB_BOOL_FULL] = "full", + + [GB_BOOL_MAX] = NULL, +}; + + enum JsonResponseFormat jsonResponseFormatParse(const char *opt); ssize_t glusterBlockParseSize(const char *dom, char *value); char* glusterBlockFormatSize(const char *dom, size_t bytes); +int convertStringToTrillianParse(const char *opt); + # endif /* _COMMON_H */ |