diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-volume-ops.c')
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 944 |
1 files changed, 532 insertions, 412 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index 4b6fdc219..0d322b9ad 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -30,20 +30,16 @@ #define glusterd_op_start_volume_args_get(dict, volname, flags) \ glusterd_op_stop_volume_args_get (dict, volname, flags) + int -glusterd_handle_create_volume (rpcsvc_request_t *req) +__glusterd_handle_create_volume (rpcsvc_request_t *req) { int32_t ret = -1; gf_cli_req cli_req = {{0,}}; dict_t *dict = NULL; - glusterd_brickinfo_t *brickinfo = NULL; - char *brick = NULL; char *bricks = NULL; char *volname = NULL; int brick_count = 0; - char *tmpptr = NULL; - int i = 0; - char *brick_list = NULL; void *cli_rsp = NULL; char err_str[2048] = {0,}; gf_cli_rsp rsp = {0,}; @@ -52,28 +48,26 @@ glusterd_handle_create_volume (rpcsvc_request_t *req) char *trans_type = NULL; uuid_t volume_id = {0,}; uuid_t tmp_uuid = {0}; - glusterd_volinfo_t tmpvolinfo = {{0},}; int32_t type = 0; char *username = NULL; char *password = NULL; GF_ASSERT (req); - INIT_LIST_HEAD (&tmpvolinfo.bricks); - this = THIS; GF_ASSERT(this); ret = -1; ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req); if (ret < 0) { - //failed to decode msg; req->rpc_err = GARBAGE_ARGS; - snprintf (err_str, sizeof (err_str), "Garbage args received"); + snprintf (err_str, sizeof (err_str), "Failed to decode request " + "received from cli"); + gf_log (this->name, GF_LOG_ERROR, "%s", err_str); goto out; } - gf_log (this->name, GF_LOG_INFO, "Received create volume req"); + gf_log (this->name, GF_LOG_DEBUG, "Received create volume req"); if (cli_req.dict.dict_len) { /* Unserialize the dictionary */ @@ -112,87 +106,72 @@ glusterd_handle_create_volume (rpcsvc_request_t *req) ret = dict_get_int32 (dict, "count", &brick_count); if (ret) { - snprintf (err_str, sizeof (err_str), "Unable to get volume " - "brick count"); + snprintf (err_str, sizeof (err_str), "Unable to get brick count" + " for volume %s", volname); gf_log (this->name, GF_LOG_ERROR, "%s", err_str); goto out; } ret = dict_get_int32 (dict, "type", &type); if (ret) { - snprintf (err_str, sizeof (err_str), "Unable to get volume " - "type"); + snprintf (err_str, sizeof (err_str), "Unable to get type of " + "volume %s", volname); gf_log (this->name, GF_LOG_ERROR, "%s", err_str); goto out; } ret = dict_get_str (dict, "transport", &trans_type); if (ret) { - snprintf (err_str, sizeof (err_str), "Unable to get volume " - "transport-type"); + snprintf (err_str, sizeof (err_str), "Unable to get " + "transport-type of volume %s", volname); gf_log (this->name, GF_LOG_ERROR, "%s", err_str); goto out; } ret = dict_get_str (dict, "bricks", &bricks); if (ret) { - snprintf (err_str, sizeof (err_str), "Unable to get volume " - "bricks"); + snprintf (err_str, sizeof (err_str), "Unable to get bricks for " + "volume %s", volname); gf_log (this->name, GF_LOG_ERROR, "%s", err_str); goto out; } + if (!dict_get (dict, "force")) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get 'force' flag"); + goto out; + } + uuid_generate (volume_id); free_ptr = gf_strdup (uuid_utoa (volume_id)); ret = dict_set_dynstr (dict, "volume-id", free_ptr); if (ret) { snprintf (err_str, sizeof (err_str), "Unable to set volume " - "id"); + "id of volume %s", volname); gf_log (this->name, GF_LOG_ERROR, "%s", err_str); goto out; } free_ptr = NULL; - if (bricks) { - brick_list = gf_strdup (bricks); - free_ptr = brick_list; - } - - while ( i < brick_count) { - i++; - brick= strtok_r (brick_list, " \n", &tmpptr); - brick_list = tmpptr; - ret = glusterd_brickinfo_new_from_brick (brick, &brickinfo); - if (ret) { - snprintf (err_str, sizeof (err_str), "Unable to get " - "brick info from brick %s", brick); - goto out; - } - - ret = glusterd_new_brick_validate (brick, brickinfo, err_str, - sizeof (err_str)); - if (ret) - goto out; - - list_add_tail (&brickinfo->brick_list, &tmpvolinfo.bricks); - brickinfo = NULL; - } - /* generate internal username and password */ uuid_generate (tmp_uuid); username = gf_strdup (uuid_utoa (tmp_uuid)); ret = dict_set_dynstr (dict, "internal-username", username); - if (ret) + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to set username for " + "volume %s", volname); goto out; + } uuid_generate (tmp_uuid); password = gf_strdup (uuid_utoa (tmp_uuid)); ret = dict_set_dynstr (dict, "internal-password", password); - if (ret) + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to set password for " + "volume %s", volname); goto out; + } - ret = glusterd_op_begin (req, GD_OP_CREATE_VOLUME, dict, err_str, - sizeof (err_str)); + ret = glusterd_op_begin_synctask (req, GD_OP_CREATE_VOLUME, dict); out: if (ret) { @@ -205,26 +184,23 @@ out: cli_rsp = &rsp; glusterd_to_cli (req, cli_rsp, NULL, 0, NULL, (xdrproc_t)xdr_gf_cli_rsp, dict); - if (dict) - dict_unref (dict); - ret = 0; //Client response sent, prevent second response } GF_FREE(free_ptr); - glusterd_volume_brickinfos_delete (&tmpvolinfo); - if (brickinfo) - glusterd_brickinfo_delete (brickinfo); - - glusterd_friend_sm (); - glusterd_op_sm (); - return ret; } int -glusterd_handle_cli_start_volume (rpcsvc_request_t *req) +glusterd_handle_create_volume (rpcsvc_request_t *req) +{ + return glusterd_big_locked_handler (req, + __glusterd_handle_create_volume); +} + +int +__glusterd_handle_cli_start_volume (rpcsvc_request_t *req) { int32_t ret = -1; gf_cli_req cli_req = {{0,}}; @@ -235,13 +211,15 @@ glusterd_handle_cli_start_volume (rpcsvc_request_t *req) xlator_t *this = NULL; this = THIS; + GF_ASSERT (this); GF_ASSERT (req); ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req); if (ret < 0) { - //failed to decode msg; + snprintf (errstr, sizeof (errstr), "Failed to decode message " + "received from cli"); req->rpc_err = GARBAGE_ARGS; - snprintf (errstr, sizeof (errstr), "Received garbage args"); + gf_log (this->name, sizeof (errstr), "%s", errstr); goto out; } @@ -269,7 +247,7 @@ glusterd_handle_cli_start_volume (rpcsvc_request_t *req) goto out; } - gf_log (this->name, GF_LOG_INFO, "Received start vol req" + gf_log (this->name, GF_LOG_DEBUG, "Received start vol req" " for volume %s", volname); ret = glusterd_op_begin_synctask (req, GD_OP_START_VOLUME, dict); @@ -282,16 +260,20 @@ out: snprintf (errstr, sizeof (errstr), "Operation failed"); ret = glusterd_op_send_cli_response (cli_op, ret, 0, req, dict, errstr); - if (dict) - dict_unref (dict); } return ret; } +int +glusterd_handle_cli_start_volume (rpcsvc_request_t *req) +{ + return glusterd_big_locked_handler (req, + __glusterd_handle_cli_start_volume); +} int -glusterd_handle_cli_stop_volume (rpcsvc_request_t *req) +__glusterd_handle_cli_stop_volume (rpcsvc_request_t *req) { int32_t ret = -1; gf_cli_req cli_req = {{0,}}; @@ -302,12 +284,15 @@ glusterd_handle_cli_stop_volume (rpcsvc_request_t *req) char err_str[2048] = {0,}; this = THIS; + GF_ASSERT (this); GF_ASSERT (req); ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req); if (ret < 0) { - //failed to decode msg; + snprintf (err_str, sizeof (err_str), "Failed to decode message " + "received from cli"); req->rpc_err = GARBAGE_ARGS; + gf_log (this->name, GF_LOG_ERROR, "%s", err_str); goto out; } if (cli_req.dict.dict_len) { @@ -336,33 +321,34 @@ glusterd_handle_cli_stop_volume (rpcsvc_request_t *req) goto out; } - gf_log (this->name, GF_LOG_INFO, "Received stop vol req " + gf_log (this->name, GF_LOG_DEBUG, "Received stop vol req " "for volume %s", dup_volname); - ret = glusterd_op_begin (req, GD_OP_STOP_VOLUME, dict, - err_str, sizeof (err_str)); + ret = glusterd_op_begin_synctask (req, GD_OP_STOP_VOLUME, dict); out: free (cli_req.dict.dict_val); //its malloced by xdr - glusterd_friend_sm (); - glusterd_op_sm (); - if (ret) { if (err_str[0] == '\0') snprintf (err_str, sizeof (err_str), "Operation failed"); ret = glusterd_op_send_cli_response (cli_op, ret, 0, req, dict, err_str); - if (dict) - dict_unref (dict); } return ret; } int -glusterd_handle_cli_delete_volume (rpcsvc_request_t *req) +glusterd_handle_cli_stop_volume (rpcsvc_request_t *req) +{ + return glusterd_big_locked_handler (req, + __glusterd_handle_cli_stop_volume); +} + +int +__glusterd_handle_cli_delete_volume (rpcsvc_request_t *req) { int32_t ret = -1; gf_cli_req cli_req = {{0,},}; @@ -373,12 +359,15 @@ glusterd_handle_cli_delete_volume (rpcsvc_request_t *req) xlator_t *this = NULL; this = THIS; + GF_ASSERT (this); GF_ASSERT (req); ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req); if (ret < 0) { - //failed to decode msg; + snprintf (err_str, sizeof (err_str), "Failed to decode request " + "received from cli"); + gf_log (this->name, GF_LOG_ERROR, "%s", err_str); req->rpc_err = GARBAGE_ARGS; goto out; } @@ -395,7 +384,7 @@ glusterd_handle_cli_delete_volume (rpcsvc_request_t *req) "failed to " "unserialize req-buffer to dictionary"); snprintf (err_str, sizeof (err_str), "Unable to decode " - "the command"); + "the command"); goto out; } } @@ -409,33 +398,34 @@ glusterd_handle_cli_delete_volume (rpcsvc_request_t *req) goto out; } - gf_log (this->name, GF_LOG_INFO, "Received delete vol req" + gf_log (this->name, GF_LOG_DEBUG, "Received delete vol req" "for volume %s", volname); - ret = glusterd_op_begin (req, GD_OP_DELETE_VOLUME, dict, - err_str, sizeof (err_str)); + ret = glusterd_op_begin_synctask (req, GD_OP_DELETE_VOLUME, dict); out: free (cli_req.dict.dict_val); //its malloced by xdr - glusterd_friend_sm (); - glusterd_op_sm (); - if (ret) { if (err_str[0] == '\0') snprintf (err_str, sizeof (err_str), "Operation failed"); ret = glusterd_op_send_cli_response (cli_op, ret, 0, req, dict, err_str); - if (dict) - dict_unref (dict); } return ret; } int -glusterd_handle_cli_heal_volume (rpcsvc_request_t *req) +glusterd_handle_cli_delete_volume (rpcsvc_request_t *req) +{ + return glusterd_big_locked_handler (req, + __glusterd_handle_cli_delete_volume); +} + +int +__glusterd_handle_cli_heal_volume (rpcsvc_request_t *req) { int32_t ret = -1; gf_cli_req cli_req = {{0,}}; @@ -456,6 +446,7 @@ glusterd_handle_cli_heal_volume (rpcsvc_request_t *req) } this = THIS; + GF_ASSERT (this); if (cli_req.dict.dict_len) { /* Unserialize the dictionary */ @@ -503,29 +494,29 @@ glusterd_handle_cli_heal_volume (rpcsvc_request_t *req) if (ret) goto out; - ret = glusterd_op_begin (req, GD_OP_HEAL_VOLUME, dict, - op_errstr, sizeof (op_errstr)); + ret = glusterd_op_begin_synctask (req, GD_OP_HEAL_VOLUME, dict); out: - glusterd_friend_sm (); - glusterd_op_sm (); - if (ret) { if (op_errstr[0] == '\0') snprintf (op_errstr, sizeof (op_errstr), "operation failed"); ret = glusterd_op_send_cli_response (cli_op, ret, 0, req, dict, op_errstr); - if (dict) - dict_unref (dict); - GF_FREE (op_errstr); } return ret; } int -glusterd_handle_cli_statedump_volume (rpcsvc_request_t *req) +glusterd_handle_cli_heal_volume (rpcsvc_request_t *req) +{ + return glusterd_big_locked_handler (req, + __glusterd_handle_cli_heal_volume); +} + +int +__glusterd_handle_cli_statedump_volume (rpcsvc_request_t *req) { int32_t ret = -1; gf_cli_req cli_req = {{0,}}; @@ -537,6 +528,9 @@ glusterd_handle_cli_statedump_volume (rpcsvc_request_t *req) char err_str[2048] = {0,}; xlator_t *this = NULL; + this = THIS; + GF_ASSERT (this); + GF_ASSERT (req); ret = -1; @@ -588,8 +582,7 @@ glusterd_handle_cli_statedump_volume (rpcsvc_request_t *req) gf_log (this->name, GF_LOG_INFO, "Received statedump request for " "volume %s with options %s", volname, options); - ret = glusterd_op_begin (req, GD_OP_STATEDUMP_VOLUME, dict, - err_str, sizeof (err_str)); + ret = glusterd_op_begin_synctask (req, GD_OP_STATEDUMP_VOLUME, dict); out: if (ret) { @@ -598,42 +591,110 @@ out: "Operation failed"); ret = glusterd_op_send_cli_response (cli_op, ret, 0, req, dict, err_str); - if (dict) - dict_unref (dict); } free (cli_req.dict.dict_val); - glusterd_friend_sm (); - glusterd_op_sm(); return ret; } +int +glusterd_handle_cli_statedump_volume (rpcsvc_request_t *req) +{ + return glusterd_big_locked_handler (req, + __glusterd_handle_cli_statedump_volume); +} + #ifdef HAVE_BD_XLATOR +/* + * Validates if given VG in the brick exists or not. Also checks if VG has + * GF_XATTR_VOL_ID_KEY tag set to avoid using same VG for multiple bricks. + * Tag is checked only during glusterd_op_stage_create_volume. Tag is set during + * glusterd_validate_and_create_brickpath(). + * @brick - brick info, @check_tag - check for VG tag or not + * @msg - Error message to return to caller + */ int -glusterd_is_valid_vg (const char *name) +glusterd_is_valid_vg (glusterd_brickinfo_t *brick, int check_tag, char *msg) { - lvm_t handle = NULL; - vg_t vg = NULL; - char *vg_name = NULL; - int retval = -1; + lvm_t handle = NULL; + vg_t vg = NULL; + char *vg_name = NULL; + int retval = 0; + char *p = NULL; + char *ptr = NULL; + struct dm_list *dm_lvlist = NULL; + struct dm_list *dm_seglist = NULL; + struct lvm_lv_list *lv_list = NULL; + struct lvm_property_value prop = {0, }; + struct lvm_lvseg_list *seglist = NULL; + struct dm_list *taglist = NULL; + struct lvm_str_list *strl = NULL; handle = lvm_init (NULL); if (!handle) { - gf_log ("", GF_LOG_ERROR, "lvm_init failed"); + sprintf (msg, "lvm_init failed, could not validate vg"); return -1; } - vg_name = gf_strdup (name); - vg = lvm_vg_open (handle, basename (vg_name), "r", 0); + if (*brick->vg == '\0') { /* BD xlator has vg in brick->path */ + p = gf_strdup (brick->path); + vg_name = strtok_r (p, "/", &ptr); + } else + vg_name = brick->vg; + + vg = lvm_vg_open (handle, vg_name, "r", 0); if (!vg) { - gf_log ("", GF_LOG_ERROR, "no such vg: %s", vg_name); - goto out; + sprintf (msg, "no such vg: %s", vg_name); + retval = -1; + goto out; + } + if (!check_tag) + goto next; + + taglist = lvm_vg_get_tags (vg); + if (!taglist) + goto next; + + dm_list_iterate_items (strl, taglist) { + if (!strncmp(strl->str, GF_XATTR_VOL_ID_KEY, + strlen (GF_XATTR_VOL_ID_KEY))) { + sprintf (msg, "VG %s is already part of" + " a brick", vg_name); + retval = -1; + goto out; + } + } +next: + + brick->caps = CAPS_BD | CAPS_OFFLOAD_COPY | CAPS_OFFLOAD_SNAPSHOT; + + dm_lvlist = lvm_vg_list_lvs (vg); + if (!dm_lvlist) + goto out; + + dm_list_iterate_items (lv_list, dm_lvlist) { + dm_seglist = lvm_lv_list_lvsegs (lv_list->lv); + dm_list_iterate_items (seglist, dm_seglist) { + prop = lvm_lvseg_get_property (seglist->lvseg, + "segtype"); + if (!prop.is_valid || !prop.value.string) + continue; + if (!strcmp (prop.value.string, "thin-pool")) { + brick->caps |= CAPS_THIN; + gf_log (THIS->name, GF_LOG_INFO, "Thin Pool " + "\"%s\" will be used for thin LVs", + lvm_lv_get_name (lv_list->lv)); + break; + } + } } + retval = 0; out: if (vg) lvm_vg_close (vg); lvm_quit (handle); - GF_FREE (vg_name); + if (p) + GF_FREE (p); return retval; } #endif @@ -653,80 +714,68 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr) int32_t i = 0; char *brick = NULL; char *tmpptr = NULL; - char cmd_str[1024]; xlator_t *this = NULL; glusterd_conf_t *priv = NULL; 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, - "this is NULL"); - goto out; - } + gf_boolean_t is_force = _gf_false; + this = THIS; + GF_ASSERT (this); priv = this->private; - if (!priv) { - gf_log ("glusterd", GF_LOG_ERROR, - "priv is NULL"); - goto out; - } + GF_ASSERT (priv); ret = dict_get_str (dict, "volname", &volname); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Unable to get volume name"); + gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name"); goto out; } exists = glusterd_check_volume_exists (volname); - if (exists) { snprintf (msg, sizeof (msg), "Volume %s already exists", volname); - gf_log ("", GF_LOG_ERROR, "%s", msg); - *op_errstr = gf_strdup (msg); ret = -1; goto out; } else { ret = 0; } + ret = dict_get_int32 (dict, "count", &brick_count); if (ret) { - gf_log ("", GF_LOG_ERROR, "Unable to get count"); + gf_log (this->name, GF_LOG_ERROR, "Unable to get brick count " + "for volume %s", volname); goto out; } + ret = dict_get_str (dict, "volume-id", &volume_uuid_str); if (ret) { - gf_log ("", GF_LOG_ERROR, "Unable to get volume id"); + gf_log (this->name, GF_LOG_ERROR, "Unable to get volume id of " + "volume %s", volname); goto out; } + ret = uuid_parse (volume_uuid_str, volume_uuid); if (ret) { - gf_log ("", GF_LOG_ERROR, "Unable to parse volume id"); + gf_log (this->name, GF_LOG_ERROR, "Unable to parse volume id of" + " volume %s", volname); 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"); + gf_log (this->name, GF_LOG_ERROR, "Unable to get bricks for " + "volume %s", volname); goto out; } + is_force = dict_get_str_boolean (dict, "force", _gf_false); + if (bricks) { brick_list = gf_strdup (bricks); if (!brick_list) { ret = -1; - gf_log ("", GF_LOG_ERROR, "Out of memory"); goto out; } else { free_ptr = brick_list; @@ -742,9 +791,6 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr) !glusterd_is_valid_volfpath (volname, brick)) { snprintf (msg, sizeof (msg), "brick path %s is too " "long.", brick); - gf_log ("", GF_LOG_ERROR, "%s", msg); - *op_errstr = gf_strdup (msg); - ret = -1; goto out; } @@ -752,33 +798,31 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr) ret = glusterd_brickinfo_new_from_brick (brick, &brick_info); if (ret) goto out; - snprintf (cmd_str, 1024, "%s", brick_info->path); + + ret = glusterd_new_brick_validate (brick, brick_info, msg, + sizeof (msg)); + if (ret) + goto out; + ret = glusterd_resolve_brick (brick_info); if (ret) { - gf_log ("glusterd", GF_LOG_ERROR, "cannot resolve " - "brick: %s:%s", brick_info->hostname, - brick_info->path); + gf_log (this->name, GF_LOG_ERROR, FMTSTR_RESOLVE_BRICK, + brick_info->hostname, brick_info->path); goto out; } + if (!uuid_compare (brick_info->uuid, MY_UUID)) { + #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; + if (brick_info->vg[0]) { + ret = glusterd_is_valid_vg (brick_info, 1, msg); + if (ret) + goto out; } - - break; - } else #endif - if (!uuid_compare (brick_info->uuid, MY_UUID)) { - ret = glusterd_brick_create_path (brick_info->hostname, - brick_info->path, - volume_uuid, - op_errstr); + ret = glusterd_validate_and_create_brickpath (brick_info, + volume_uuid, op_errstr, + is_force); if (ret) goto out; brick_list = tmpptr; @@ -790,7 +834,12 @@ out: GF_FREE (free_ptr); if (brick_info) glusterd_brickinfo_delete (brick_info); - gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + + if (msg[0] != '\0') { + gf_log (this->name, GF_LOG_ERROR, "%s", msg); + *op_errstr = gf_strdup (msg); + } + gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); return ret; } @@ -799,19 +848,23 @@ int glusterd_op_stop_volume_args_get (dict_t *dict, char** volname, int *flags) { int ret = -1; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); if (!dict || !volname || !flags) goto out; ret = dict_get_str (dict, "volname", volname); if (ret) { - gf_log ("", GF_LOG_ERROR, "Unable to get volume name"); + gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name"); goto out; } ret = dict_get_int32 (dict, "flags", flags); if (ret) { - gf_log ("", GF_LOG_ERROR, "Unable to get flags"); + gf_log (this->name, GF_LOG_ERROR, "Unable to get flags"); goto out; } out: @@ -860,14 +913,16 @@ glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr) glusterd_brickinfo_t *brickinfo = NULL; char msg[2048]; glusterd_conf_t *priv = NULL; + xlator_t *this = NULL; + uuid_t volume_id = {0,}; + char volid[50] = {0,}; + char xattr_volid[50] = {0,}; + int caps = 0; - priv = THIS->private; - if (!priv) { - gf_log ("glusterd", GF_LOG_ERROR, - "priv is NULL"); - ret = -1; - goto out; - } + this = THIS; + GF_ASSERT (this); + priv = this->private; + GF_ASSERT (priv); ret = glusterd_op_start_volume_args_get (dict, &volname, &flags); if (ret) @@ -876,48 +931,110 @@ glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr) exists = glusterd_check_volume_exists (volname); if (!exists) { - snprintf (msg, sizeof (msg), "Volume %s does not exist", volname); - gf_log ("", GF_LOG_ERROR, "%s", - msg); - *op_errstr = gf_strdup (msg); + snprintf (msg, sizeof (msg), FMTSTR_CHECK_VOL_EXISTS, volname); ret = -1; - } else { - ret = 0; + goto out; } ret = glusterd_volinfo_find (volname, &volinfo); - if (ret) + if (ret) { + gf_log (this->name, GF_LOG_ERROR, FMTSTR_CHECK_VOL_EXISTS, + volname); goto out; + } ret = glusterd_validate_volume_id (dict, volinfo); if (ret) goto out; + if (!(flags & GF_CLI_FLAG_OP_FORCE)) { + if (glusterd_is_volume_started (volinfo)) { + snprintf (msg, sizeof (msg), "Volume %s already " + "started", volname); + ret = -1; + goto out; + } + } + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { ret = glusterd_resolve_brick (brickinfo); if (ret) { - gf_log ("", GF_LOG_ERROR, - "Unable to resolve brick %s:%s", + gf_log (this->name, GF_LOG_ERROR, FMTSTR_RESOLVE_BRICK, brickinfo->hostname, brickinfo->path); goto out; } - if (!(flags & GF_CLI_FLAG_OP_FORCE)) { - if (glusterd_is_volume_started (volinfo)) { - snprintf (msg, sizeof (msg), "Volume %s already" - " started", volname); - gf_log ("glusterd", GF_LOG_ERROR, "%s", msg); - *op_errstr = gf_strdup (msg); - ret = -1; + if (uuid_compare (brickinfo->uuid, MY_UUID)) + continue; + + ret = gf_lstat_dir (brickinfo->path, NULL); + if (ret && (flags & GF_CLI_FLAG_OP_FORCE)) { + continue; + } else if (ret) { + snprintf (msg, sizeof (msg), "Failed to find " + "brick directory %s for volume %s. " + "Reason : %s", brickinfo->path, + volname, strerror (errno)); + goto out; + } + ret = sys_lgetxattr (brickinfo->path, GF_XATTR_VOL_ID_KEY, + volume_id, 16); + if (ret < 0 && (!(flags & GF_CLI_FLAG_OP_FORCE))) { + snprintf (msg, sizeof (msg), "Failed to get " + "extended attribute %s for brick dir %s. " + "Reason : %s", GF_XATTR_VOL_ID_KEY, + brickinfo->path, strerror (errno)); + ret = -1; + goto out; + } else if (ret < 0) { + ret = sys_lsetxattr (brickinfo->path, + GF_XATTR_VOL_ID_KEY, + volinfo->volume_id, 16, + XATTR_CREATE); + if (ret) { + snprintf (msg, sizeof (msg), "Failed to set " + "extended attribute %s on %s. Reason: " + "%s", GF_XATTR_VOL_ID_KEY, + brickinfo->path, strerror (errno)); goto out; + } else { + continue; } } + if (uuid_compare (volinfo->volume_id, volume_id)) { + snprintf (msg, sizeof (msg), "Volume id mismatch for " + "brick %s:%s. Expected volume id %s, " + "volume id %s found", brickinfo->hostname, + brickinfo->path, + uuid_utoa_r (volinfo->volume_id, volid), + uuid_utoa_r (volume_id, xattr_volid)); + ret = -1; + goto out; + } +#ifdef HAVE_BD_XLATOR + if (brickinfo->vg[0]) + caps = CAPS_BD | CAPS_THIN | + CAPS_OFFLOAD_COPY | CAPS_OFFLOAD_SNAPSHOT; + /* Check for VG/thin pool if its BD volume */ + if (brickinfo->vg[0]) { + ret = glusterd_is_valid_vg (brickinfo, 0, msg); + if (ret) + goto out; + /* if anyone of the brick does not have thin support, + disable it for entire volume */ + caps &= brickinfo->caps; + } else + caps = 0; +#endif } + volinfo->caps = caps; ret = 0; out: - gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); - + if (ret && (msg[0] != '\0')) { + gf_log (this->name, GF_LOG_ERROR, "%s", msg); + *op_errstr = gf_strdup (msg); + } return ret; } @@ -931,7 +1048,10 @@ glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr) gf_boolean_t is_run = _gf_false; glusterd_volinfo_t *volinfo = NULL; char msg[2048] = {0}; + xlator_t *this = NULL; + this = THIS; + GF_ASSERT (this); ret = glusterd_op_stop_volume_args_get (dict, &volname, &flags); if (ret) @@ -940,18 +1060,18 @@ glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr) exists = glusterd_check_volume_exists (volname); if (!exists) { - snprintf (msg, sizeof (msg), "Volume %s does not exist", volname); - gf_log ("", GF_LOG_ERROR, "%s", msg); - *op_errstr = gf_strdup (msg); + snprintf (msg, sizeof (msg), FMTSTR_CHECK_VOL_EXISTS, volname); + gf_log (this->name, GF_LOG_ERROR, "%s", msg); ret = -1; goto out; - } else { - ret = 0; } ret = glusterd_volinfo_find (volname, &volinfo); - if (ret) + if (ret) { + snprintf (msg, sizeof (msg), FMTSTR_CHECK_VOL_EXISTS, volname); + gf_log (this->name, GF_LOG_ERROR, "%s", msg); goto out; + } ret = glusterd_validate_volume_id (dict, volinfo); if (ret) @@ -964,25 +1084,22 @@ glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr) if (_gf_false == glusterd_is_volume_started (volinfo)) { snprintf (msg, sizeof(msg), "Volume %s " "is not in the started state", volname); - gf_log ("", GF_LOG_ERROR, "Volume %s " - "has not been started", volname); - *op_errstr = gf_strdup (msg); + gf_log (this->name, GF_LOG_ERROR, "%s", msg); ret = -1; goto out; } ret = glusterd_check_gsync_running (volinfo, &is_run); if (ret && (is_run == _gf_false)) - gf_log ("", GF_LOG_WARNING, "Unable to get the status" + gf_log (this->name, GF_LOG_WARNING, "Unable to get the status" " of active "GEOREP" session"); if (is_run) { - gf_log ("", GF_LOG_WARNING, GEOREP" sessions active" + gf_log (this->name, GF_LOG_WARNING, GEOREP" sessions active" "for the volume %s ", volname); snprintf (msg, sizeof(msg), GEOREP" sessions are active " "for the volume '%s'.\nUse 'volume "GEOREP" " "status' command for more info. Use 'force' " "option to ignore and stop the volume.", volname); - *op_errstr = gf_strdup (msg); ret = -1; goto out; } @@ -991,8 +1108,8 @@ glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr) snprintf (msg, sizeof (msg), "Replace brick is in progress on " "volume %s. Please retry after replace-brick " "operation is committed or aborted", volname); - gf_log (THIS->name, GF_LOG_ERROR, "%s", msg); - *op_errstr = gf_strdup (msg); + gf_log (this->name, GF_LOG_WARNING, "replace-brick in progress " + "on volume %s", volname); ret = -1; goto out; } @@ -1000,23 +1117,22 @@ glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr) if (glusterd_is_defrag_on (volinfo)) { snprintf (msg, sizeof(msg), "rebalance session is " "in progress for the volume '%s'", volname); - gf_log (THIS->name, GF_LOG_WARNING, "%s", msg); - *op_errstr = gf_strdup (msg); + gf_log (this->name, GF_LOG_WARNING, "%s", msg); ret = -1; goto out; } - if (volinfo->rb_status != GF_RB_STATUS_NONE) { + if (volinfo->rep_brick.rb_status != GF_RB_STATUS_NONE) { snprintf (msg, sizeof(msg), "replace-brick session is " "in progress for the volume '%s'", volname); - gf_log (THIS->name, GF_LOG_WARNING, "%s", msg); - *op_errstr = gf_strdup (msg); + gf_log (this->name, GF_LOG_WARNING, "%s", msg); ret = -1; goto out; } out: - - gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + if (msg[0] != 0) + *op_errstr = gf_strdup (msg); + gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); return ret; } @@ -1029,21 +1145,20 @@ glusterd_op_stage_delete_volume (dict_t *dict, char **op_errstr) gf_boolean_t exists = _gf_false; glusterd_volinfo_t *volinfo = NULL; char msg[2048] = {0}; + xlator_t *this = NULL; - ret = dict_get_str (dict, "volname", &volname); + this = THIS; + GF_ASSERT (this); + ret = dict_get_str (dict, "volname", &volname); if (ret) { - gf_log ("", GF_LOG_ERROR, "Unable to get volume name"); + gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name"); goto out; } exists = glusterd_check_volume_exists (volname); - if (!exists) { - snprintf (msg, sizeof (msg), "Volume %s does not exist", - volname); - gf_log ("", GF_LOG_ERROR, "%s", msg); - *op_errstr = gf_strdup (msg); + snprintf (msg, sizeof (msg), FMTSTR_CHECK_VOL_EXISTS, volname); ret = -1; goto out; } else { @@ -1051,9 +1166,10 @@ glusterd_op_stage_delete_volume (dict_t *dict, char **op_errstr) } ret = glusterd_volinfo_find (volname, &volinfo); - - if (ret) + if (ret) { + snprintf (msg, sizeof (msg), FMTSTR_CHECK_VOL_EXISTS, volname); goto out; + } ret = glusterd_validate_volume_id (dict, volinfo); if (ret) @@ -1063,8 +1179,16 @@ glusterd_op_stage_delete_volume (dict_t *dict, char **op_errstr) snprintf (msg, sizeof (msg), "Volume %s has been started." "Volume needs to be stopped before deletion.", volname); - gf_log ("", GF_LOG_ERROR, "%s", msg); - *op_errstr = gf_strdup (msg); + ret = -1; + goto out; + } + + if (volinfo->snap_count > 0 || !list_empty(&volinfo->snap_volumes)) { + snprintf (msg, sizeof (msg), "Cannot delete Volume %s ," + "as it has %ld snapshots. " + "To delete the volume, " + "first delete all the snapshots under it.", + volname, volinfo->snap_count); ret = -1; goto out; } @@ -1072,7 +1196,11 @@ glusterd_op_stage_delete_volume (dict_t *dict, char **op_errstr) ret = 0; out: - gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + if (msg[0] != '\0') { + gf_log (this->name, GF_LOG_ERROR, "%s", msg); + *op_errstr = gf_strdup (msg); + } + gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); return ret; } @@ -1088,11 +1216,13 @@ glusterd_op_stage_heal_volume (dict_t *dict, char **op_errstr) glusterd_conf_t *priv = NULL; dict_t *opt_dict = NULL; gf_xl_afr_op_t heal_op = GF_AFR_OP_INVALID; + xlator_t *this = NULL; - priv = THIS->private; + this = THIS; + priv = this->private; if (!priv) { ret = -1; - gf_log (THIS->name, GF_LOG_ERROR, + gf_log (this->name, GF_LOG_ERROR, "priv is NULL"); goto out; } @@ -1107,7 +1237,7 @@ glusterd_op_stage_heal_volume (dict_t *dict, char **op_errstr) if (ret) { ret = -1; snprintf (msg, sizeof (msg), "Volume %s does not exist", volname); - gf_log (THIS->name, GF_LOG_ERROR, "%s", msg); + gf_log (this->name, GF_LOG_ERROR, "%s", msg); *op_errstr = gf_strdup (msg); goto out; } @@ -1121,7 +1251,7 @@ glusterd_op_stage_heal_volume (dict_t *dict, char **op_errstr) snprintf (msg, sizeof (msg), "Volume %s is not of type " "replicate", volname); *op_errstr = gf_strdup (msg); - gf_log (THIS->name, GF_LOG_WARNING, "%s", msg); + gf_log (this->name, GF_LOG_WARNING, "%s", msg); goto out; } @@ -1147,29 +1277,37 @@ glusterd_op_stage_heal_volume (dict_t *dict, char **op_errstr) snprintf (msg, sizeof (msg), "Self-heal-daemon is " "disabled. Heal will not be triggered on volume %s", volname); - gf_log (THIS->name, GF_LOG_WARNING, "%s", msg); - *op_errstr = gf_strdup (msg); - goto out; - } - - if (!glusterd_is_nodesvc_online ("glustershd")) { - ret = -1; - snprintf (msg, sizeof (msg), "Self-heal daemon is not " - "running. Check self-heal daemon log file."); + gf_log (this->name, GF_LOG_WARNING, "%s", msg); *op_errstr = gf_strdup (msg); - gf_log (THIS->name, GF_LOG_WARNING, "%s", msg); goto out; } ret = dict_get_int32 (dict, "heal-op", (int32_t*)&heal_op); if (ret || (heal_op == GF_AFR_OP_INVALID)) { ret = -1; - snprintf (msg, sizeof (msg), "Invalid heal-op"); - *op_errstr = gf_strdup (msg); - gf_log (THIS->name, GF_LOG_WARNING, "%s", msg); + *op_errstr = gf_strdup("Invalid heal-op"); + gf_log (this->name, GF_LOG_WARNING, "%s", "Invalid heal-op"); goto out; } + switch (heal_op) { + case GF_AFR_OP_INDEX_SUMMARY: + case GF_AFR_OP_STATISTICS_HEAL_COUNT: + case GF_AFR_OP_STATISTICS_HEAL_COUNT_PER_REPLICA: + break; + default: + if (!glusterd_is_nodesvc_online("glustershd")){ + ret = -1; + *op_errstr = gf_strdup ("Self-heal daemon is " + "not running. Check self-heal " + "daemon log file."); + gf_log (this->name, GF_LOG_WARNING, "%s", + "Self-heal daemon is not running." + "Check self-heal daemon log file."); + goto out; + } + } + ret = 0; out: gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); @@ -1291,109 +1429,6 @@ 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; - } - } else if (bd_op == GF_BD_OP_SNAPSHOT_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) { - ret = -1; - 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); - 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) { @@ -1415,9 +1450,8 @@ 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 + int caps = 0; + char msg[1024] __attribute__((unused)) = {0, }; this = THIS; GF_ASSERT (this); @@ -1429,15 +1463,14 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) if (ret) { gf_log (this->name, GF_LOG_ERROR, - "Unable to allocate memory"); + "Unable to allocate memory for volinfo"); goto out; } ret = dict_get_str (dict, "volname", &volname); if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "Unable to get volume name"); + gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name"); goto out; } @@ -1446,13 +1479,15 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) ret = dict_get_int32 (dict, "type", &volinfo->type); if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Unable to get type"); + gf_log (this->name, GF_LOG_ERROR, "Unable to get type of volume" + " %s", volname); goto out; } ret = dict_get_int32 (dict, "count", &volinfo->brick_count); if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Unable to get count"); + gf_log (this->name, GF_LOG_ERROR, "Unable to get brick count of" + " volume %s", volname); goto out; } @@ -1466,16 +1501,11 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) ret = dict_get_str (dict, "bricks", &bricks); if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Unable to get bricks"); + gf_log (this->name, GF_LOG_ERROR, "Unable to get bricks for " + "volume %s", volname); goto out; } -#ifdef HAVE_BD_XLATOR - ret = dict_get_str (dict, "device", &device); - if (!ret) - volinfo->backend = GD_VOL_BK_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 */ @@ -1484,28 +1514,44 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) if (GF_CLUSTER_TYPE_REPLICATE == volinfo->type) { ret = dict_get_int32 (dict, "replica-count", &volinfo->replica_count); - if (ret) + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get " + "replica count for volume %s", volname); goto out; + } } else if (GF_CLUSTER_TYPE_STRIPE == volinfo->type) { ret = dict_get_int32 (dict, "stripe-count", &volinfo->stripe_count); - if (ret) + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get stripe" + " count for volume %s", volname); goto out; + } } else if (GF_CLUSTER_TYPE_STRIPE_REPLICATE == volinfo->type) { ret = dict_get_int32 (dict, "stripe-count", &volinfo->stripe_count); - if (ret) + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get stripe" + " count for volume %s", volname); goto out; + } ret = dict_get_int32 (dict, "replica-count", &volinfo->replica_count); - if (ret) + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get " + "replica count for volume %s", volname); goto out; + } } /* dist-leaf-count is the count of brick nodes for a given subvolume of distribute */ - volinfo->dist_leaf_count = (volinfo->stripe_count * - volinfo->replica_count); + volinfo->dist_leaf_count = glusterd_get_dist_leaf_count (volinfo); + + /* subvol_count is the count of number of subvolumes present + for a given distribute volume */ + volinfo->subvol_count = (volinfo->brick_count / + volinfo->dist_leaf_count); /* Keep sub-count same as earlier, for the sake of backward compatibility */ @@ -1515,27 +1561,28 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) ret = dict_get_str (dict, "transport", &trans_type); if (ret) { gf_log (this->name, GF_LOG_ERROR, - "Unable to get transport"); + "Unable to get transport type of volume %s", volname); goto out; } ret = dict_get_str (dict, "volume-id", &str); if (ret) { gf_log (this->name, GF_LOG_ERROR, - "Unable to get volume-id"); + "Unable to get volume-id of volume %s", volname); goto out; } ret = uuid_parse (str, volinfo->volume_id); if (ret) { gf_log (this->name, GF_LOG_ERROR, - "unable to parse uuid %s", str); + "unable to parse uuid %s of volume %s", str, volname); goto out; } ret = dict_get_str (dict, "internal-username", &username); if (ret) { gf_log (this->name, GF_LOG_ERROR, - "unable to get internal username"); + "unable to get internal username of volume %s", + volname); goto out; } glusterd_auth_set_username (volinfo, username); @@ -1543,7 +1590,8 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) ret = dict_get_str (dict, "internal-password", &password); if (ret) { gf_log (this->name, GF_LOG_ERROR, - "unable to get internal password"); + "unable to get internal password of volume %s", + volname); goto out; } glusterd_auth_set_password (volinfo, password); @@ -1566,6 +1614,7 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) if (count) brick = strtok_r (brick_list+1, " \n", &saveptr); + caps = CAPS_BD | CAPS_THIN | CAPS_OFFLOAD_COPY | CAPS_OFFLOAD_SNAPSHOT; while ( i <= count) { ret = glusterd_brickinfo_new_from_brick (brick, &brickinfo); @@ -1573,13 +1622,41 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) goto out; ret = glusterd_resolve_brick (brickinfo); - if (ret) + if (ret) { + gf_log (this->name, GF_LOG_ERROR, FMTSTR_RESOLVE_BRICK, + brickinfo->hostname, brickinfo->path); goto out; + } + +#ifdef HAVE_BD_XLATOR + if (!uuid_compare (brickinfo->uuid, MY_UUID)) { + if (brickinfo->vg[0]) { + ret = glusterd_is_valid_vg (brickinfo, 0, msg); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "%s", + msg); + goto out; + } + + /* if anyone of the brick does not have thin + support, disable it for entire volume */ + caps &= brickinfo->caps; + + + } else + caps = 0; + } +#endif + list_add_tail (&brickinfo->brick_list, &volinfo->bricks); brick = strtok_r (NULL, " \n", &saveptr); i++; } + gd_update_volume_op_versions (volinfo); + + volinfo->caps = caps; + ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT); if (ret) { glusterd_store_delete_volume (volinfo); @@ -1593,15 +1670,10 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) goto out; } - ret = glusterd_volume_compute_cksum (volinfo); - if (ret) { - *op_errstr = gf_strdup ("Failed to compute checksum of volume"); - goto out; - } - - volinfo->defrag_status = 0; + volinfo->rebal.defrag_status = 0; list_add_tail (&volinfo->vol_list, &priv->volumes); vol_added = _gf_true; + out: GF_FREE(free_ptr); if (!vol_added && volinfo) @@ -1617,18 +1689,28 @@ glusterd_op_start_volume (dict_t *dict, char **op_errstr) int flags = 0; glusterd_volinfo_t *volinfo = NULL; glusterd_brickinfo_t *brickinfo = NULL; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); ret = glusterd_op_start_volume_args_get (dict, &volname, &flags); if (ret) goto out; ret = glusterd_volinfo_find (volname, &volinfo); - - if (ret) + if (ret) { + gf_log (this->name, GF_LOG_ERROR, FMTSTR_CHECK_VOL_EXISTS, + volname); goto out; + } + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { ret = glusterd_brick_start (volinfo, brickinfo, _gf_true); - if (ret) + /* If 'force' try to start all bricks regardless of success or + * failure + */ + if (!(flags & GF_CLI_FLAG_OP_FORCE) && ret) goto out; } @@ -1641,7 +1723,48 @@ glusterd_op_start_volume (dict_t *dict, char **op_errstr) ret = glusterd_nodesvcs_handle_graph_change (volinfo); out: - gf_log ("", GF_LOG_DEBUG, "returning %d ", ret); + gf_log (this->name, GF_LOG_DEBUG, "returning %d ", ret); + return ret; +} + +int +glusterd_stop_volume (glusterd_volinfo_t *volinfo) +{ + int ret = -1; + glusterd_brickinfo_t *brickinfo = NULL; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); + + GF_VALIDATE_OR_GOTO (this->name, volinfo, out); + + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { + ret = glusterd_brick_stop (volinfo, brickinfo, _gf_false); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to stop " + "brick (%s)", brickinfo->path); + goto out; + } + } + + glusterd_set_volume_status (volinfo, GLUSTERD_STATUS_STOPPED); + + ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to store volinfo of " + "%s volume", volinfo->volname); + goto out; + } + + ret = glusterd_nodesvcs_handle_graph_change (volinfo); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to notify graph " + "change for %s volume", volinfo->volname); + goto out; + } + +out: return ret; } @@ -1653,30 +1776,28 @@ glusterd_op_stop_volume (dict_t *dict) int flags = 0; char *volname = NULL; glusterd_volinfo_t *volinfo = NULL; - glusterd_brickinfo_t *brickinfo = NULL; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); ret = glusterd_op_stop_volume_args_get (dict, &volname, &flags); if (ret) goto out; ret = glusterd_volinfo_find (volname, &volinfo); - - if (ret) + if (ret) { + gf_log (this->name, GF_LOG_ERROR, FMTSTR_CHECK_VOL_EXISTS, + volname); goto out; - - list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { - ret = glusterd_brick_stop (volinfo, brickinfo, _gf_false); - if (ret) - goto out; } - glusterd_set_volume_status (volinfo, GLUSTERD_STATUS_STOPPED); - - ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT); - if (ret) + ret = glusterd_stop_volume (volinfo); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to stop %s volume", + volname); goto out; - - ret = glusterd_nodesvcs_handle_graph_change (volinfo); + } out: return ret; } @@ -1697,18 +1818,20 @@ glusterd_op_delete_volume (dict_t *dict) ret = dict_get_str (dict, "volname", &volname); if (ret) { - gf_log ("", GF_LOG_ERROR, "Unable to get volume name"); + gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name"); goto out; } ret = glusterd_volinfo_find (volname, &volinfo); - - if (ret) + if (ret) { + gf_log (this->name, GF_LOG_ERROR, FMTSTR_CHECK_VOL_EXISTS, + volname); goto out; + } ret = glusterd_delete_volume (volinfo); out: - gf_log ("", GF_LOG_DEBUG, "returning %d", ret); + gf_log (this->name, GF_LOG_DEBUG, "returning %d", ret); return ret; } @@ -1826,7 +1949,9 @@ glusterd_clearlocks_unmount (glusterd_volinfo_t *volinfo, char *mntpt) runner_add_args (&runner, "/bin/umount", "-f", NULL); runner_argprintf (&runner, "%s", mntpt); + synclock_unlock (&priv->big_lock); ret = runner_run (&runner); + synclock_lock (&priv->big_lock); if (ret) { ret = 0; gf_log ("", GF_LOG_DEBUG, @@ -1898,7 +2023,9 @@ glusterd_clearlocks_mount (glusterd_volinfo_t *volinfo, char **xl_opts, } runner_argprintf (&runner, "%s", mntpt); + synclock_unlock (&priv->big_lock); ret = runner_run (&runner); + synclock_lock (&priv->big_lock); if (ret) { gf_log (THIS->name, GF_LOG_DEBUG, "Could not start glusterfs"); @@ -1962,7 +2089,7 @@ out: } int -glusterd_op_clearlocks_volume (dict_t *dict, char **op_errstr) +glusterd_op_clearlocks_volume (dict_t *dict, char **op_errstr, dict_t *rsp_dict) { int32_t ret = -1; int i = 0; @@ -1977,7 +2104,6 @@ glusterd_op_clearlocks_volume (dict_t *dict, char **op_errstr) char result[PATH_MAX] = {0,}; char *mntpt = NULL; char **xl_opts = NULL; - dict_t *ctx = NULL; glusterd_volinfo_t *volinfo = NULL; ret = dict_get_str (dict, "volname", &volname); @@ -2066,14 +2192,8 @@ glusterd_op_clearlocks_volume (dict_t *dict, char **op_errstr) goto umount; } - ctx = glusterd_op_get_ctx (); - if (!ctx) - /*Impossible. Only originator glusterd can - * come here. */ - goto umount; - free_ptr = gf_strdup(result); - if (dict_set_dynstr (ctx, "lk-summary", free_ptr)) { + if (dict_set_dynstr (rsp_dict, "lk-summary", free_ptr)) { GF_FREE (free_ptr); snprintf (msg, sizeof (msg), "Failed to set clear-locks " "result"); |
