summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrasanna Kumar Kalever <prasanna.kalever@redhat.com>2017-06-12 11:59:13 +0530
committerPrasanna Kumar Kalever <prasanna.kalever@redhat.com>2017-06-22 16:30:46 +0530
commit94c79620db4451bf804d6ab631c9ca59759dbc21 (patch)
treeee5c0e9430fb30812753ac1911bd8b5c163cb5fd
parent8bb5dd787e84f719940230adb24642653fcaec77 (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.md9
-rw-r--r--cli/gluster-block.c38
-rw-r--r--docs/gluster-block.810
-rw-r--r--rpc/glfs-operations.c45
-rw-r--r--rpc/rpcl/block.x1
-rw-r--r--utils/common.c25
-rw-r--r--utils/common.h48
7 files changed, 140 insertions, 36 deletions
diff --git a/README.md b/README.md
index 986116f..a683542 100644
--- a/README.md
+++ b/README.md
@@ -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 */