From 3c72850e8d00f0cf35ae054136be076a394e08e9 Mon Sep 17 00:00:00 2001 From: "M. Mohan Kumar" Date: Thu, 29 Nov 2012 21:46:07 +0530 Subject: BD Backend: CLI commands to create/delete image Cli commands added to create/delete a LV device. The following command creates lv in a given vg. $ gluster bd create :/ The following command deletes lv in a given vg. $ gluster bd delete :/ BUG: 805138 Change-Id: Ie4e100eca14e2ee32cf2bb4dd064b17230d673bf Signed-off-by: M. Mohan Kumar Reviewed-on: http://review.gluster.org/3718 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- xlators/mgmt/glusterd/src/glusterd-handler.c | 74 +++++ xlators/mgmt/glusterd/src/glusterd-op-sm.c | 94 +++++- xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 1 + xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 85 ++++++ xlators/mgmt/glusterd/src/glusterd.h | 2 + xlators/storage/bd_map/src/bd_map.c | 368 +++++++++++++++++++----- 6 files changed, 545 insertions(+), 79 deletions(-) (limited to 'xlators') diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index 9433436d0ae..1b1d113b578 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -50,6 +50,10 @@ #include "globals.h" #include "glusterd-syncop.h" +#ifdef HAVE_BD_XLATOR +#include +#endif + static int glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t uuid, char *hostname, int port, @@ -927,6 +931,73 @@ out: return ret; } +#ifdef HAVE_BD_XLATOR +int +glusterd_handle_cli_bd_op (rpcsvc_request_t *req) +{ + int32_t ret = -1; + gf_cli_req cli_req = { {0,} }; + dict_t *dict = NULL; + char *volname = NULL; + char *op_errstr = NULL; + glusterd_op_t cli_op = GD_OP_BD_OP; + + GF_ASSERT (req); + + if (!xdr_to_generic (req->msg[0], &cli_req, + (xdrproc_t)xdr_gf_cli_req)) { + /* failed to decode msg */ + req->rpc_err = GARBAGE_ARGS; + goto out; + } + + gf_log ("glusterd", GF_LOG_DEBUG, "Received bd op req"); + + if (cli_req.dict.dict_len) { + /* Unserialize the dictionary */ + dict = dict_new (); + + ret = dict_unserialize (cli_req.dict.dict_val, + cli_req.dict.dict_len, + &dict); + if (ret < 0) { + gf_log ("glusterd", GF_LOG_ERROR, + "failed to " + "unserialize req-buffer to dictionary"); + goto out; + } else { + dict->extra_stdfree = cli_req.dict.dict_val; + } + } + + ret = dict_get_str (dict, "volname", &volname); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, + "failed to get volname"); + goto out; + } + + ret = glusterd_op_begin (req, GD_OP_BD_OP, dict); + gf_cmd_log ("bd op: %s", ((ret == 0) ? "SUCCESS": "FAILED")); +out: + if (ret && dict) + dict_unref (dict); + + glusterd_friend_sm (); + glusterd_op_sm (); + + if (ret) { + if (!op_errstr) + op_errstr = gf_strdup ("operation failed"); + ret = glusterd_op_send_cli_response (cli_op, ret, 0, + req, NULL, op_errstr); + GF_FREE (op_errstr); + } + + return ret; +} +#endif + int glusterd_handle_cli_uuid_reset (rpcsvc_request_t *req) { @@ -3165,6 +3236,9 @@ rpcsvc_actor_t gd_svc_cli_actors[] = { [GLUSTER_CLI_STATEDUMP_VOLUME] = {"STATEDUMP_VOLUME", GLUSTER_CLI_STATEDUMP_VOLUME, glusterd_handle_cli_statedump_volume, NULL, 0}, [GLUSTER_CLI_LIST_VOLUME] = {"LIST_VOLUME", GLUSTER_CLI_LIST_VOLUME, glusterd_handle_cli_list_volume, NULL, 0}, [GLUSTER_CLI_CLRLOCKS_VOLUME] = {"CLEARLOCKS_VOLUME", GLUSTER_CLI_CLRLOCKS_VOLUME, glusterd_handle_cli_clearlocks_volume, NULL, 0}, +#ifdef HAVE_BD_XLATOR + [GLUSTER_CLI_BD_OP] = {"BD_OP", GLUSTER_CLI_BD_OP, glusterd_handle_cli_bd_op, NULL, 0}, +#endif }; struct rpcsvc_program gd_svc_cli_prog = { diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 4ca70516163..ac53f2e463b 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -235,6 +235,20 @@ glusterd_brick_op_build_payload (glusterd_op_t op, glusterd_brickinfo_t *brickin brick_req->name = gf_strdup (name); break; + +#ifdef HAVE_BD_XLATOR + case GD_OP_BD_OP: + { + brick_req = GF_CALLOC (1, sizeof (*brick_req), + gf_gld_mt_mop_brick_req_t); + if (!brick_req) + goto out; + + brick_req->op = GLUSTERD_BRICK_BD_OP; + brick_req->name = ""; + } + break; +#endif default: goto out; break; @@ -2356,6 +2370,9 @@ glusterd_op_build_payload (dict_t **req, char **op_errstr, dict_t *op_ctx) case GD_OP_STATEDUMP_VOLUME: case GD_OP_CLEARLOCKS_VOLUME: case GD_OP_DEFRAG_BRICK_VOLUME: +#ifdef HAVE_BD_XLATOR + case GD_OP_BD_OP: +#endif { ret = dict_get_str (dict, "volname", &volname); if (ret) { @@ -3489,7 +3506,11 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr, ret = glusterd_op_stage_clearlocks_volume (dict, op_errstr); break; - +#ifdef HAVE_BD_XLATOR + case GD_OP_BD_OP: + ret = glusterd_op_stage_bd (dict, op_errstr); + break; +#endif default: gf_log ("", GF_LOG_ERROR, "Unknown op %d", op); @@ -3585,7 +3606,11 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr, case GD_OP_CLEARLOCKS_VOLUME: ret = glusterd_op_clearlocks_volume (dict, op_errstr); break; - +#ifdef HAVE_BD_XLATOR + case GD_OP_BD_OP: + ret = 0; + break; +#endif default: gf_log ("", GF_LOG_ERROR, "Unknown op %d", op); @@ -4325,6 +4350,62 @@ _select_rxlators_for_full_self_heal (xlator_t *this, return rxlator_count; } +#ifdef HAVE_BD_XLATOR +static int +glusterd_bricks_select_bd (dict_t *dict, char **op_errstr) +{ + int ret = -1; + glusterd_conf_t *priv = NULL; + xlator_t *this = NULL; + glusterd_pending_node_t *pending_node = NULL; + glusterd_volinfo_t *volinfo = NULL; + char *volname = NULL; + glusterd_brickinfo_t *brickinfo = NULL; + int brick_index = -1; + + this = THIS; + GF_ASSERT (this); + priv = this->private; + GF_ASSERT (priv); + + ret = dict_get_str (dict, "volname", &volname); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Unable to get volname"); + goto out; + } + ret = glusterd_volinfo_find (volname, &volinfo); + if (ret) + goto out; + + pending_node = GF_CALLOC (1, sizeof (*pending_node), + gf_gld_mt_pending_node_t); + if (!pending_node) { + ret = -1; + goto out; + } + + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { + brick_index++; + if (uuid_compare (brickinfo->uuid, MY_UUID) || + !glusterd_is_brick_started (brickinfo)) { + continue; + } + pending_node->node = brickinfo; + pending_node->type = GD_NODE_BRICK; + pending_node->index = brick_index; + list_add_tail (&pending_node->list, + &opinfo.pending_bricks); + pending_node = NULL; + } + + ret = 0; + +out: + gf_log (THIS->name, GF_LOG_DEBUG, "Returning ret %d", ret); + return ret; +} +#endif + static int glusterd_bricks_select_heal_volume (dict_t *dict, char **op_errstr) { @@ -4402,7 +4483,6 @@ out: } - static int glusterd_bricks_select_rebalance_volume (dict_t *dict, char **op_errstr) { @@ -4735,6 +4815,11 @@ glusterd_op_bricks_select (glusterd_op_t op, dict_t *dict, char **op_errstr) case GD_OP_DEFRAG_BRICK_VOLUME: ret = glusterd_bricks_select_rebalance_volume (dict, op_errstr); break; +#ifdef HAVE_BD_XLATOR + case GD_OP_BD_OP: + ret = glusterd_bricks_select_bd (dict, op_errstr); + break; +#endif default: break; } @@ -5298,6 +5383,9 @@ glusterd_op_free_ctx (glusterd_op_t op, void *ctx) case GD_OP_STATEDUMP_VOLUME: case GD_OP_CLEARLOCKS_VOLUME: case GD_OP_DEFRAG_BRICK_VOLUME: +#ifdef HAVE_BD_XLATOR + case GD_OP_BD_OP: +#endif dict_unref (ctx); break; default: diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c index c18c2b5e19e..21fad7e93a2 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c @@ -139,6 +139,7 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret, case GD_OP_LIST_VOLUME: case GD_OP_CLEARLOCKS_VOLUME: case GD_OP_HEAL_VOLUME: + case GD_OP_BD_OP: { /*nothing specific to be done*/ break; diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index 8c76c8f09e1..b74bbec7c59 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -1241,6 +1241,91 @@ out: return ret; } +#ifdef HAVE_BD_XLATOR +int +glusterd_op_stage_bd (dict_t *dict, char **op_errstr) +{ + int ret = -1; + char *volname = NULL; + char *path = NULL; + char *size = NULL; + glusterd_volinfo_t *volinfo = NULL; + char msg[2048] = {0,}; + gf_xl_bd_op_t bd_op = GF_BD_OP_INVALID; + uint64_t bytes = 0; + + ret = dict_get_str (dict, "volname", &volname); + if (ret) { + snprintf (msg, sizeof(msg), "Failed to get volume name"); + gf_log (THIS->name, GF_LOG_ERROR, "%s", msg); + *op_errstr = gf_strdup (msg); + goto out; + } + + ret = dict_get_int32 (dict, "bd-op", (int32_t *)&bd_op); + if (ret) { + snprintf (msg, sizeof(msg), "Failed to get bd-op"); + gf_log (THIS->name, GF_LOG_ERROR, "%s", msg); + *op_errstr = gf_strdup (msg); + goto out; + } + + ret = dict_get_str (dict, "path", &path); + if (ret) { + snprintf (msg, sizeof(msg), "Failed to get path"); + gf_log (THIS->name, GF_LOG_ERROR, "%s", msg); + *op_errstr = gf_strdup (msg); + goto out; + } + + if (bd_op == GF_BD_OP_NEW_BD) { + ret = dict_get_str (dict, "size", &size); + if (ret) { + snprintf (msg, sizeof(msg), "Failed to get size"); + gf_log ("", GF_LOG_ERROR, "%s", msg); + *op_errstr = gf_strdup (msg); + goto out; + } + if (gf_string2bytesize (size, &bytes) < 0) { + snprintf (msg, sizeof(msg), + "Invalid size %s, suffix with KB, MB etc", + size); + gf_log ("", GF_LOG_ERROR, "%s", msg); + *op_errstr = gf_strdup (msg); + ret = -1; + goto out; + } + } + + ret = glusterd_volinfo_find (volname, &volinfo); + if (ret) { + snprintf (msg, sizeof(msg), "Volume %s does not exist", + volname); + gf_log ("", GF_LOG_ERROR, "%s", msg); + *op_errstr = gf_strdup (msg); + goto out; + } + + ret = glusterd_validate_volume_id (dict, volinfo); + if (ret) + goto out; + + if (!glusterd_is_volume_started (volinfo)) { + snprintf (msg, sizeof(msg), "Volume %s is not started", + volname); + gf_log ("", GF_LOG_ERROR, "%s", msg); + *op_errstr = gf_strdup (msg); + ret = -1; + goto out; + } + + ret = 0; +out: + gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + +#endif int glusterd_op_create_volume (dict_t *dict, char **op_errstr) diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index ea0ea6061d3..36cd8f8fc56 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -78,6 +78,7 @@ typedef enum glusterd_op_ { GD_OP_LIST_VOLUME, GD_OP_CLEARLOCKS_VOLUME, GD_OP_DEFRAG_BRICK_VOLUME, + GD_OP_BD_OP, GD_OP_MAX, } glusterd_op_t; @@ -684,6 +685,7 @@ int glusterd_op_statedump_volume (dict_t *dict, char **op_errstr); int glusterd_op_stage_clearlocks_volume (dict_t *dict, char **op_errstr); int glusterd_op_clearlocks_volume (dict_t *dict, char **op_errstr); +int glusterd_op_stage_bd (dict_t *dict, char **op_errstr); /* misc */ void glusterd_do_replace_brick (void *data); diff --git a/xlators/storage/bd_map/src/bd_map.c b/xlators/storage/bd_map/src/bd_map.c index 2db5a13cd3d..a84ee29fba2 100644 --- a/xlators/storage/bd_map/src/bd_map.c +++ b/xlators/storage/bd_map/src/bd_map.c @@ -31,7 +31,7 @@ #include "defaults.h" #include "glusterfs3-xdr.h" #include "run.h" - +#include "protocol-common.h" /* Regular fops */ @@ -155,6 +155,56 @@ out: return 0; } +int32_t +bd_delete_lv (bd_priv_t *priv, bd_entry_t *p_entry, bd_entry_t *lventry, + const char *path, int *op_errno) +{ + vg_t vg = NULL; + lv_t lv = NULL; + int op_ret = -1; + + *op_errno = 0; + BD_WR_LOCK (&priv->lock); + vg = lvm_vg_open (priv->handle, p_entry->name, "w", 0); + if (!vg) { + *op_errno = ENOENT; + BD_UNLOCK (&priv->lock); + goto out; + } + + lv = lvm_lv_from_name (vg, lventry->name); + if (!lv) { + lvm_vg_close (vg); + *op_errno = ENOENT; + BD_UNLOCK (&priv->lock); + goto out; + } + op_ret = lvm_vg_remove_lv (lv); + if (op_ret < 0) { + *op_errno = errno; + lvm_vg_close (vg); + BD_UNLOCK (&priv->lock); + goto out; + } + lvm_vg_close (vg); + + op_ret = bd_entry_rm (path); + if (op_ret < 0) { + *op_errno = EIO; + BD_UNLOCK (&priv->lock); + goto out; + } + BD_ENTRY_UPDATE_MTIME (p_entry); + + op_ret = 0; + op_errno = 0; + + BD_UNLOCK (&priv->lock); + op_ret = 0; +out: + return op_ret; +} + int32_t bd_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, dict_t *xdata) @@ -164,8 +214,6 @@ bd_unlink (call_frame_t *frame, xlator_t *this, struct iatt preparent = {0, }; struct iatt postparent = {0, }; bd_priv_t *priv = NULL; - vg_t vg = NULL; - lv_t lv = NULL; bd_entry_t *lventry = NULL; bd_entry_t *p_entry = NULL; char *vg_name = NULL; @@ -200,43 +248,8 @@ bd_unlink (call_frame_t *frame, xlator_t *this, goto out; memcpy (&preparent, p_entry->attr, sizeof(preparent)); - - BD_WR_LOCK (&priv->lock); - vg = lvm_vg_open (priv->handle, p_entry->name, "w", 0); - if (!vg) { - op_errno = ENOENT; - BD_UNLOCK (&priv->lock); - goto out; - } - - lv = lvm_lv_from_name (vg, lventry->name); - if (!lv) { - lvm_vg_close (vg); - op_errno = ENOENT; - BD_UNLOCK (&priv->lock); - goto out; - } - op_ret = lvm_vg_remove_lv (lv); - if (op_ret < 0) { - op_errno = errno; - lvm_vg_close (vg); - BD_UNLOCK (&priv->lock); - goto out; - } - lvm_vg_close (vg); - op_ret = bd_entry_rm (loc->path); - if (op_ret < 0) { - op_errno = EIO; - BD_UNLOCK (&priv->lock); - goto out; - } - BD_ENTRY_UPDATE_MTIME (p_entry); + op_ret = bd_delete_lv (priv, p_entry, lventry, loc->path, &op_errno); memcpy (&postparent, p_entry->attr, sizeof(postparent)); - op_ret = 0; - op_errno = 0; - - BD_UNLOCK (&priv->lock); - out: if (p_entry) BD_PUT_ENTRY (priv, p_entry); @@ -970,6 +983,59 @@ err: return op_ret; } +int bd_create_lv (bd_priv_t *priv, bd_entry_t *p_entry, const char *vg_name, + const char *lv_name, char *size, mode_t mode) +{ + vg_t vg = NULL; + int ret = -1; + char *path = NULL; + struct iatt iattr = {0, }; + bd_entry_t *lventry = NULL; + uint64_t extent = 0; + + BD_WR_LOCK (&priv->lock); + vg = lvm_vg_open (priv->handle, vg_name, "w", 0); + if (!vg) { + ret = -1; + goto out; + } + extent = lvm_vg_get_extent_size (vg); + if (size) + gf_string2bytesize (size, &extent); + + if (lvm_vg_create_lv_linear (vg, lv_name, extent) == NULL) { + ret = -EAGAIN; + lvm_vg_close (vg); + goto out; + } + lvm_vg_close (vg); + + gf_asprintf (&path, "/dev/%s/%s", vg_name, lv_name); + if (!path) { + ret = -ENOMEM; + lvm_vg_close (vg); + goto out; + } + bd_entry_istat (path, &iattr, IA_IFREG); + iattr.ia_size = extent; + if (!mode) + mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; + + iattr.ia_type = ia_type_from_st_mode (mode); + iattr.ia_prot = ia_prot_from_st_mode (mode); + lventry = bd_entry_add (p_entry, lv_name, &iattr, IA_IFREG); + if (!lventry) { + ret = -EAGAIN; + goto out; + } + ret = 0; +out: + BD_UNLOCK (&priv->lock); + if (path) + GF_FREE (path); + return ret; +} + int bd_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *params) @@ -977,20 +1043,16 @@ int bd_create (call_frame_t *frame, xlator_t *this, int32_t op_ret = -1; int32_t op_errno = 0; int32_t _fd = -1; - uint64_t extent = 0; bd_priv_t *priv = NULL; struct iatt stbuf = {0, }; struct iatt preparent = {0, }; struct iatt postparent = {0, }; bd_entry_t *p_entry = NULL; bd_entry_t *lventry = NULL; - vg_t vg = NULL; - lv_t lv = NULL; bd_fd_t *pfd = NULL; char *vg_name = NULL; char *volume = NULL; char *path = NULL; - struct iatt iattr = {0, }; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); @@ -1024,39 +1086,10 @@ int bd_create (call_frame_t *frame, xlator_t *this, memcpy (&preparent, p_entry->attr, sizeof(preparent)); - BD_WR_LOCK (&priv->lock); - vg = lvm_vg_open (priv->handle, p_entry->name, "w", 0); - if (!vg) { - op_errno = errno; - BD_UNLOCK (&priv->lock); - goto out; - } - extent = lvm_vg_get_extent_size (vg); - /* Create the LV */ - lv = lvm_vg_create_lv_linear (vg, loc->name, extent); - if (!lv) { - op_errno = errno; - lvm_vg_close (vg); - BD_UNLOCK (&priv->lock); - goto out; - } - lvm_vg_close (vg); - - gf_asprintf (&path, "/dev/%s/%s", p_entry->name, loc->name); - if (!path) { - op_errno = ENOMEM; - goto out; - } - bd_entry_istat (path, &iattr, IA_IFREG); - iattr.ia_size = extent; - iattr.ia_type = ia_type_from_st_mode (mode); - iattr.ia_prot = ia_prot_from_st_mode (mode); - lventry = bd_entry_add (p_entry, loc->name, &iattr, IA_IFREG); - if (!lventry) { - op_errno = EAGAIN; + op_errno = bd_create_lv (priv, p_entry, p_entry->name, loc->name, 0, + mode); + if (op_errno) goto out; - } - BD_UNLOCK (&priv->lock); BD_ENTRY (priv, lventry, loc->path); if (!lventry) { @@ -1069,6 +1102,11 @@ int bd_create (call_frame_t *frame, xlator_t *this, /* Mask O_CREATE since we created LV */ flags &= ~(O_CREAT | O_EXCL); + gf_asprintf (&path, "/dev/%s/%s", p_entry->name, loc->name); + if (!path) { + op_errno = ENOMEM; + goto out; + } _fd = open (path, flags, 0); if (_fd == -1) { op_errno = errno; @@ -2070,6 +2108,166 @@ bd_fxattrop (call_frame_t *frame, xlator_t *this, return 0; } +int bd_xl_op_create (bd_priv_t *priv, dict_t *input, dict_t *output) +{ + char *vg = NULL; + char *lv = NULL; + char *path = NULL; + bd_entry_t *p_entry = NULL; + bd_entry_t *lventry = NULL; + char *size = 0; + int ret = -1; + char *error = NULL; + int retval = -1; + char *buff = NULL; + char *buffp = NULL; + char *save = NULL; + + ret = dict_get_str (input, "size", &size); + if (ret) { + gf_asprintf (&error, "no size specified"); + goto out; + } + ret = dict_get_str (input, "path", &path); + if (ret) { + gf_asprintf (&error, "no path specified"); + goto out; + } + + buff = buffp = gf_strdup (path); + + vg = strtok_r (buff, "/", &save); + lv = strtok_r (NULL, "/", &save); + + if (!vg || !lv) { + gf_asprintf (&error, "invalid path %s", path); + ret = -1; + goto out; + } + + BD_ENTRY (priv, p_entry, vg); + if (!p_entry) { + ret = -ENOENT; + goto out; + } + BD_ENTRY (priv, lventry, path); + if (lventry) { + ret = -EEXIST; + gf_asprintf (&error, "%s already exists", lv); + BD_PUT_ENTRY (priv, lventry); + goto out; + } + + ret = bd_create_lv (priv, p_entry, vg, lv, size, 0); + if (ret < 0) { + gf_asprintf (&error, "bd_create_lv error %d", -ret); + goto out; + } + ret = 0; +out: + if (p_entry) + BD_PUT_ENTRY (priv, p_entry); + + if (buffp) + GF_FREE (buffp); + + if (error) + retval = dict_set_dynstr (output, "error", error); + return ret; +} + +int bd_xl_op_delete (bd_priv_t *priv, dict_t *input, dict_t *output) +{ + char *vg = NULL; + char *path = NULL; + bd_entry_t *p_entry = NULL; + bd_entry_t *lventry = NULL; + int ret = -1; + char *error = NULL; + int retval = -1; + char *buff = NULL; + char *buffp = NULL; + char *save = NULL; + int op_errno = 0; + + ret = dict_get_str (input, "path", &path); + if (ret) { + gf_asprintf (&error, "no path specified"); + goto out; + } + + buff = buffp = gf_strdup (path); + + vg = strtok_r (buff, "/", &save); + if (!vg) { + gf_asprintf (&error, "invalid path %s", path); + op_errno = EINVAL; + ret = -1; + goto out; + } + + BD_ENTRY (priv, p_entry, vg); + BD_ENTRY (priv, lventry, path); + if (!p_entry || !lventry) { + op_errno = -ENOENT; + gf_asprintf (&error, "%s not found", path); + ret = -1; + goto out; + } + ret = bd_delete_lv (priv, p_entry, lventry, path, &op_errno); + if (ret < 0) { + gf_asprintf (&error, "bd_delete_lv error, error:%d", op_errno); + goto out; + } + ret = 0; +out: + if (p_entry) + BD_PUT_ENTRY (priv, p_entry); + if (lventry) + BD_PUT_ENTRY (priv, lventry); + if (buffp) + GF_FREE (buffp); + if (error) + retval = dict_set_dynstr (output, "error", error); + return ret; +} + +int32_t +bd_notify (xlator_t *this, dict_t *input, dict_t *output) +{ + int ret = -1; + int retval = -1; + int32_t bdop = -1; + bd_priv_t *priv = NULL; + char *error = NULL; + + priv = this->private; + VALIDATE_OR_GOTO (priv, out); + + ret = dict_get_int32 (input, "bd-op", (int32_t *)&bdop); + if (ret) { + asprintf (&error, "no sub-op specified"); + goto out; + } + + switch (bdop) + { + case GF_BD_OP_NEW_BD: + ret = bd_xl_op_create (priv, input, output); + break; + case GF_BD_OP_DELETE_BD: + ret = bd_xl_op_delete (priv, input, output); + break; + default: + gf_asprintf (&error, "invalid bd-op %d specified", bdop); + retval = dict_set_dynstr (output, "error", error); + goto out; + } + +out: + return ret; +} + /** * notify - when parent sends PARENT_UP, send CHILD_UP event from here */ @@ -2079,6 +2277,16 @@ notify (xlator_t *this, void *data, ...) { + va_list ap; + int ret = -1; + void *data2 = NULL; + dict_t *input = NULL; + dict_t *output = NULL; + + va_start (ap, data); + data2 = va_arg (ap, dict_t *); + va_end (ap); + switch (event) { case GF_EVENT_PARENT_UP: @@ -2087,10 +2295,18 @@ notify (xlator_t *this, default_notify (this, GF_EVENT_CHILD_UP, data); } break; + case GF_EVENT_TRANSLATOR_OP: + input = data; + output = data2; + if (!output) + output = dict_new (); + ret = bd_notify (this, input, output); + break; + default: break; } - return 0; + return ret; } int32_t -- cgit