diff options
Diffstat (limited to 'xlators')
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 74 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 94 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 85 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 2 | ||||
| -rw-r--r-- | xlators/storage/bd_map/src/bd_map.c | 368 | 
6 files changed, 545 insertions, 79 deletions
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 <lvm2app.h> +#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 */ @@ -156,6 +156,56 @@ out:  }  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  | 
