diff options
| -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 */  | 
