From: "M. Mohan Kumar" <mohan@xxxxxxxxxx> A new parameter type is added to volume create command. To use BD xlator one has to specify following argument in addition to normal volume create device lv brick:<VG-NAME> for example, # gluster volume create lv_volume device lv host:/vg1 Changes from previous version * New type 'ex_type' added to volinfo structure to differentiate between posix and bd xlator * Most of the volume related commands are updated to handle BD xlator, like add-brick, heal-brick etc refuse to work when volume is BD xlator type * Only one VG (ie brick) can be specified for BD xlator during volume creation * volume info shows VG info if its of type BD xlator Here is the output from gluster volume info for volume 'bd' with BD xlator Volume Name: bd Volume ID: 068376e0-0a04-48c0-8356-0c4662892fa4 Status: Created Extended Info: BD LV Transport-type: tcp Brick: explorer: Volume Group: vg Here "Type: " is omitted because as of now BD xlator supports only one brick and only one brick information is printed. signed-off-by: M. Mohan Kumar <mohan@xxxxxxxxxx> --- cli/src/cli-cmd-parser.c | 50 +++++++++++++++- cli/src/cli-cmd-volume.c | 2 +- cli/src/cli-rpc-ops.c | 49 ++++++++++++++-- xlators/mgmt/glusterd/src/Makefile.am | 3 + xlators/mgmt/glusterd/src/glusterd-brick-ops.c | 11 ++++ xlators/mgmt/glusterd/src/glusterd-handler.c | 8 +++ xlators/mgmt/glusterd/src/glusterd-replace-brick.c | 9 +++ xlators/mgmt/glusterd/src/glusterd-store.c | 14 +++++ xlators/mgmt/glusterd/src/glusterd-store.h | 4 +- xlators/mgmt/glusterd/src/glusterd-utils.c | 7 ++- xlators/mgmt/glusterd/src/glusterd-volgen.c | 58 ++++++++++++++----- xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 66 +++++++++++++++++++++- xlators/mgmt/glusterd/src/glusterd.h | 10 +++- 13 files changed, 266 insertions(+), 25 deletions(-) diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index b29583f..2e35a37 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -167,13 +167,21 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options int32_t index = 0; char *bricks = NULL; int32_t brick_count = 0; - char *opwords[] = { "replica", "stripe", "transport", NULL }; + char *opwords[] = { "replica", "stripe", "transport", +#ifdef HAVE_BD_XLATOR + "device", +#endif + NULL }; + char *invalid_volnames[] = {"volume", "type", "subvolumes", "option", "end-volume", "all", NULL}; char *w = NULL; int op_count = 0; int32_t replica_count = 1; int32_t stripe_count = 1; +#ifdef HAVE_BD_XLATOR + char *dev_type = NULL; +#endif GF_ASSERT (words); GF_ASSERT (options); @@ -308,7 +316,26 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options goto out; } index += 2; - } else { + } +#ifdef HAVE_BD_XLATOR + else if ((strcmp (w, "device")) == 0) { + if (dev_type) { + cli_err ("'device' option given more" + " than one time"); + goto out; + } + if ((strcasecmp (words[index+1], "lv") == 0)) { + dev_type = gf_strdup ("lv"); + } else { + gf_log ("", GF_LOG_ERROR, "incorrect xlator" + " device type specified"); + ret = -1; + goto out; + } + index += 2; + } +#endif + else { GF_ASSERT (!"opword mismatch"); ret = -1; goto out; @@ -344,6 +371,17 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options goto out; } + /* BD xlator does not support multiple bricks */ +#ifdef HAVE_BD_XLATOR + if (brick_count > 1 && dev_type) { + cli_err ("BD xlator does not support multiple bricks"); + gf_log ("", GF_LOG_ERROR, + "BD xlator does not support multiple bricks"); + ret = -1; + goto out; + } +#endif + if (brick_count % sub_count) { if (type == GF_CLUSTER_TYPE_STRIPE) cli_err ("number of bricks is not a multiple of " @@ -377,6 +415,14 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options if (ret) goto out; +#ifdef HAVE_BD_XLATOR + if (dev_type) { + ret = dict_set_dynstr (dict, "device", dev_type); + if (ret) + goto out; + } +#endif + ret = dict_set_int32 (dict, "count", brick_count); if (ret) goto out; diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 9be933a..dd162a6 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1807,7 +1807,7 @@ struct cli_cmd volume_cmds[] = { cli_cmd_volume_info_cbk, "list information of all volumes"}, - { "volume create <NEW-VOLNAME> [stripe <COUNT>] [replica <COUNT>] [transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> ...", + { "volume create <NEW-VOLNAME> [stripe <COUNT>] [replica <COUNT>] [device lv] [transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> ...", cli_cmd_volume_create_cbk, "create a new volume of specified type with mentioned bricks"}, diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index a7de5bb..050abb0 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -73,6 +73,11 @@ char *cli_volume_status[] = {"Created", "Stopped" }; + +char *cli_volume_ex_type[] = {"", + "BD LV", +}; + int32_t gf_cli_get_volume (call_frame_t *frame, xlator_t *this, void *data); @@ -509,6 +514,7 @@ gf_cli_get_volume_cbk (struct rpc_req *req, struct iovec *iov, char key[1024] = {0}; char err_str[2048] = {0}; gf_cli_rsp rsp = {0}; + int32_t ex_type = 0; if (-1 == req->rpc_status) goto out; @@ -667,6 +673,11 @@ xml_output: if (ret) goto out; +#ifdef HAVE_BD_XLATOR + snprintf (key, 256, "volume%d.ex_type", i); + ret = dict_get_int32 (dict, key, &ex_type); +#endif + vol_type = type; // Distributed (stripe/replicate/stripe-replica) setups @@ -674,10 +685,19 @@ xml_output: vol_type = type + 3; cli_out ("Volume Name: %s", volname); - cli_out ("Type: %s", cli_volume_type[vol_type]); +#ifdef HAVE_BD_XLATOR + if (!ex_type) + cli_out ("Type: %s", cli_volume_type[vol_type]); +#endif cli_out ("Volume ID: %s", volume_id_str); cli_out ("Status: %s", cli_volume_status[status]); - +#ifdef HAVE_BD_XLATOR + if (ex_type) { + cli_out ("Extended Info: %s", + cli_volume_ex_type[ex_type]); + goto ttype; + } +#endif if (type == GF_CLUSTER_TYPE_STRIPE_REPLICATE) { cli_out ("Number of Bricks: %d x %d x %d = %d", (brick_count / dist_count), @@ -695,7 +715,7 @@ xml_output: (brick_count / dist_count), dist_count, brick_count); } - +ttype: cli_out ("Transport-type: %s", ((transport == 0)?"tcp": (transport == 1)?"rdma": @@ -705,7 +725,7 @@ xml_output: GF_FREE (local->get_vol.volname); local->get_vol.volname = gf_strdup (volname); - if (brick_count) + if (brick_count && !ex_type) cli_out ("Bricks:"); while (j <= brick_count) { @@ -714,7 +734,28 @@ xml_output: if (ret) goto out; +#ifdef HAVE_BD_XLATOR + if (!ex_type) + cli_out ("Brick%d: %s", j, brick); + else { + char *vg = NULL; + char *host = NULL; + char *c = NULL; + + host = gf_strdup (brick); + c = strchr (host, ':'); + if (c) + *c = '\0'; + vg = strchr (brick, '/'); + if (vg) + vg++; + cli_out ("Brick: %s: Volume Group: %s", + host, vg); + GF_FREE (host); + } +#else cli_out ("Brick%d: %s", j, brick); +#endif j++; } diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am index 485350b..84faeb4 100644 --- a/xlators/mgmt/glusterd/src/Makefile.am +++ b/xlators/mgmt/glusterd/src/Makefile.am @@ -2,6 +2,9 @@ xlator_LTLIBRARIES = glusterd.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/mgmt glusterd_la_CPPFLAGS = "-DFILTERDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/filter\"" glusterd_la_LDFLAGS = -module -avoidversion $(LIBXML2_LIBS) -lcrypto +if ENABLE_BD_XLATOR +glusterd_la_LDFLAGS += -llvm2app +endif glusterd_la_SOURCES = glusterd.c glusterd-handler.c glusterd-sm.c \ glusterd-op-sm.c glusterd-utils.c glusterd-rpc-ops.c \ glusterd-store.c glusterd-handshake.c glusterd-pmap.c \ diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c index ce81c0c..67179d8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c @@ -1059,6 +1059,17 @@ glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr) goto out; } +#ifdef HAVE_BD_XLATOR + if (volinfo->ex_type == GD_VOL_EX_BD) { + snprintf (msg, sizeof (msg), "Add brick is not supported for " + "BD volume %s.", volname); + gf_log (THIS->name, GF_LOG_ERROR, "%s", msg); + *op_errstr = gf_strdup (msg); + ret = -1; + goto out; + } +#endif + ret = glusterd_validate_volume_id (dict, volinfo); if (ret) goto out; diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index a5d1b3d..99c5a00 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -351,9 +351,17 @@ glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo, if (ret) goto out; +#ifdef HAVE_BD_XLATOR + snprintf (key, 256, "volume%d.ex_type", count); + ret = dict_set_int32 (volumes, key, volinfo->ex_type); + if (ret) + goto out; +#endif + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { char brick[1024] = {0,}; snprintf (key, 256, "volume%d.brick%d", count, i); + snprintf (brick, 1024, "%s:%s", brickinfo->hostname, brickinfo->path); buf = gf_strdup (brick); diff --git a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c index 61ee5d0..31e4028 100644 --- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c +++ b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c @@ -257,6 +257,15 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr, goto out; } +#ifdef HAVE_BD_XLATOR + if (volinfo->ex_type) { + snprintf (msg, sizeof (msg), "replace brick not supported " + "for BD xlator"); + *op_errstr = gf_strdup (msg); + goto out; + } +#endif + if (GLUSTERD_STATUS_STARTED != volinfo->status) { ret = -1; snprintf (msg, sizeof (msg), "volume: %s is not started", diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c index 07c29b9..06fcfd0 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -709,6 +709,15 @@ glusterd_volume_exclude_options_write (int fd, glusterd_volinfo_t *volinfo) if (ret) goto out; } +#ifdef HAVE_BD_XLATOR + if (volinfo->ex_type) { + snprintf (buf, sizeof (buf), "%d", volinfo->ex_type); + ret = glusterd_store_save_value (fd, + GLUSTERD_STORE_KEY_VOL_EX_TYPE, buf); + if (ret) + goto out; + } +#endif out: if (ret) gf_log ("", GF_LOG_ERROR, "Unable to write volume values" @@ -2239,6 +2248,11 @@ glusterd_store_retrieve_volume (char *volname) gf_log ("", GF_LOG_DEBUG, "Parsed as "GEOREP" " " slave:key=%s,value:%s", key, value); +#ifdef HAVE_BD_XLATOR + } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_EX_TYPE, + strlen (GLUSTERD_STORE_KEY_VOL_EX_TYPE))) { + volinfo->ex_type = atoi (value); +#endif } else { if (is_key_glusterd_hooks_friendly (key)) { diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h index af395bc..16ba7d2 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.h +++ b/xlators/mgmt/glusterd/src/glusterd-store.h @@ -74,7 +74,9 @@ typedef enum glusterd_store_ver_ac_{ #define GLUSTERD_STORE_KEY_PEER_UUID "uuid" #define GLUSTERD_STORE_KEY_PEER_HOSTNAME "hostname" #define GLUSTERD_STORE_KEY_PEER_STATE "state" - +#ifdef HAVE_BD_XLATOR +#define GLUSTERD_STORE_KEY_VOL_EX_TYPE "ex_type" +#endif #define glusterd_for_each_entry(entry, dir) \ do {\ entry = NULL;\ diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index f7d91d7..827ec6b 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -827,7 +827,12 @@ glusterd_is_brickpath_available (uuid_t uuid, char *path) if (uuid_compare (uuid, brickinfo->uuid)) continue; - if (!realpath (brickinfo->path, tmp_brickpath)) + /* For BD xlator brick path does not exist */ + if (!realpath (brickinfo->path, tmp_brickpath) +#ifdef HAVE_BD_XLATOR + && volinfo->ex_type +#endif + ) goto out; if (_is_prefix (tmp_brickpath, tmp_path)) diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index 1bdf5a1..80b4ec3 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -1603,7 +1603,10 @@ server_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, char *password = NULL; char index_basepath[PATH_MAX] = {0}; char key[1024] = {0}; - +#ifdef HAVE_BD_XLATOR + char *vgname = NULL; + char *vg = NULL; +#endif path = param; volname = volinfo->volname; get_vol_transport_type (volinfo, transt); @@ -1620,23 +1623,50 @@ server_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, } } - xl = volgen_graph_add (graph, "storage/posix", volname); - if (!xl) - return -1; +#ifdef HAVE_BD_XLATOR + if (volinfo->ex_type == GD_VOL_EX_BD) { + xl = volgen_graph_add (graph, "storage/bd_map", volname); + if (!xl) + return -1; - ret = xlator_set_option (xl, "directory", path); - if (ret) - return -1; + ret = xlator_set_option (xl, "device", "lv"); + if (ret) + return -1; - ret = xlator_set_option (xl, "volume-id", - uuid_utoa (volinfo->volume_id)); - if (ret) - return -1; + vg = gf_strdup (path); + vgname = strrchr (vg, '/'); + if (strchr(vg, '/') != vgname) { + gf_log ("glusterd", GF_LOG_ERROR, + "invalid vg specified %s", path); + GF_FREE (vg); + goto out; + } + vgname++; + ret = xlator_set_option (xl, "export", vgname); + GF_FREE (vg); + if (ret) + return -1; + } else +#endif + { + xl = volgen_graph_add (graph, "storage/posix", volname); + if (!xl) + return -1; - ret = check_and_add_debug_xl (graph, set_dict, volname, "posix"); - if (ret) - return -1; + ret = xlator_set_option (xl, "directory", path); + if (ret) + return -1; + + ret = xlator_set_option (xl, "volume-id", + uuid_utoa (volinfo->volume_id)); + if (ret) + return -1; + ret = check_and_add_debug_xl (graph, set_dict, volname, + "posix"); + if (ret) + return -1; + } xl = volgen_graph_add (graph, "features/access-control", volname); if (!xl) return -1; diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index 8299850..80939f9 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -22,6 +22,10 @@ #include "config.h" #endif +#ifdef HAVE_BD_XLATOR +#include <lvm2app.h> +#endif + #include "common-utils.h" #include "syscall.h" #include "cli1-xdr.h" @@ -585,6 +589,36 @@ out: return ret; } +#ifdef HAVE_BD_XLATOR +int +glusterd_is_valid_vg (const char *name) +{ + lvm_t handle = NULL; + vg_t vg = NULL; + char *vg_name = NULL; + int retval = -1; + + handle = lvm_init (NULL); + if (!handle) { + gf_log ("", GF_LOG_ERROR, "lvm_init failed"); + return -1; + } + vg_name = gf_strdup (name); + vg = lvm_vg_open (handle, basename (vg_name), "r", 0); + if (!vg) { + gf_log ("", GF_LOG_ERROR, "no such vg: %s", vg_name); + goto out; + } + retval = 0; +out: + if (vg) + lvm_vg_close (vg); + lvm_quit (handle); + GF_FREE (vg_name); + return retval; +} +#endif + /* op-sm */ int glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr) @@ -606,7 +640,9 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr) char msg[2048] = {0}; uuid_t volume_uuid; char *volume_uuid_str; - +#ifdef HAVE_BD_XLATOR + char *dev_type = NULL; +#endif this = THIS; if (!this) { gf_log ("glusterd", GF_LOG_ERROR, @@ -656,6 +692,11 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr) goto out; } + +#ifdef HAVE_BD_XLATOR + ret = dict_get_str (dict, "device", &dev_type); +#endif + ret = dict_get_str (dict, "bricks", &bricks); if (ret) { gf_log ("", GF_LOG_ERROR, "Unable to get bricks"); @@ -701,6 +742,19 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr) goto out; } +#ifdef HAVE_BD_XLATOR + if (dev_type) { + ret = glusterd_is_valid_vg (brick_info->path); + if (ret) { + snprintf (msg, sizeof(msg), "invalid vg %s", + brick_info->path); + *op_errstr = gf_strdup (msg); + goto out; + } + + break; + } else +#endif if (!uuid_compare (brick_info->uuid, MY_UUID)) { ret = glusterd_brick_create_path (brick_info->hostname, brick_info->path, @@ -1240,6 +1294,9 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) char *str = NULL; char *username = NULL; char *password = NULL; +#ifdef HAVE_BD_XLATOR + char *device = NULL; +#endif this = THIS; GF_ASSERT (this); @@ -1292,6 +1349,12 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) goto out; } +#ifdef HAVE_BD_XLATOR + ret = dict_get_str (dict, "device", &device); + if (!ret) + volinfo->ex_type = GD_VOL_EX_BD; +#endif + /* replica-count 1 means, no replication, file is in one brick only */ volinfo->replica_count = 1; /* stripe-count 1 means, no striping, file is present as a whole */ @@ -1403,6 +1466,7 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) goto out; } + ret = glusterd_create_volfiles_and_notify_services (volinfo); if (ret) { *op_errstr = gf_strdup ("Failed to create volume files"); diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 7afbd53..a2bbb2b 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -84,7 +84,6 @@ typedef enum glusterd_op_ { GD_OP_MAX, } glusterd_op_t; - struct glusterd_store_iter_ { int fd; FILE *file; @@ -205,6 +204,12 @@ struct _auth { typedef struct _auth auth_t; +typedef enum glusterd_vol_extended_ { + GD_VOL_EX_DEFAULT = 0, /* POSIX */ + GD_VOL_EX_BD = 1, +} glusterd_vol_extended_t; + + struct glusterd_volinfo_ { char volname[GLUSTERD_MAX_VOLUME_NAME]; int type; @@ -254,6 +259,9 @@ struct glusterd_volinfo_ { xlator_t *xl; gf_boolean_t memory_accounting; +#ifdef HAVE_BD_XLATOR + glusterd_vol_extended_t ex_type; +#endif }; typedef enum gd_node_type_ { -- 1.7.11.4