From 8732ee5319bfe4649473c29458a6ab65b73d5516 Mon Sep 17 00:00:00 2001 From: Rajesh Joseph Date: Sun, 27 Jul 2014 10:36:52 -0400 Subject: glusterd/snapshot: Proper err msg for snapshot create command problem: Snapshot command fails if one or more bricks are not thinly provisioned. But the error message is a generic error message which is confusing to the user. fix: Provide correct error message in case of failure. Change-Id: Iad247f966423a8f73ef6da57cab7ed6cddc05861 BUG: 1123646 Signed-off-by: Rajesh Joseph Reviewed-on: http://review.gluster.org/8377 Reviewed-by: Krishnan Parthasarathi Tested-by: Krishnan Parthasarathi --- xlators/mgmt/glusterd/src/glusterd-snapshot.c | 77 +++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) (limited to 'xlators/mgmt/glusterd/src/glusterd-snapshot.c') diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c index 2f9f68e97e1..6fa4506b18a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c @@ -1629,6 +1629,73 @@ out: return ret; } +/* This function will check whether the given device + * is a thinly provisioned LV or not. + * + * @param device LV device path + * + * @return _gf_true if LV is thin else _gf_false + */ +gf_boolean_t +glusterd_is_thinp_brick (char *device) +{ + int ret = -1; + char msg [1024] = ""; + char pool_name [PATH_MAX] = ""; + char *ptr = NULL; + xlator_t *this = NULL; + runner_t runner = {0,}; + gf_boolean_t is_thin = _gf_false; + + this = THIS; + + GF_VALIDATE_OR_GOTO ("glusterd", this, out); + GF_VALIDATE_OR_GOTO (this->name, device, out); + + snprintf (msg, sizeof (msg), "Get thin pool name for device %s", + device); + + runinit (&runner); + + runner_add_args (&runner, "/sbin/lvs", "--noheadings", "-o", "pool_lv", + device, NULL); + runner_redir (&runner, STDOUT_FILENO, RUN_PIPE); + runner_log (&runner, this->name, GF_LOG_DEBUG, msg); + + ret = runner_start (&runner); + if (ret == -1) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get thin pool " + "name for device %s", device); + runner_end (&runner); + goto out; + } + + ptr = fgets(pool_name, sizeof(pool_name), + runner_chio (&runner, STDOUT_FILENO)); + if (!ptr || !strlen(pool_name)) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get pool name " + "for device %s", device); + runner_end (&runner); + ret = -1; + goto out; + } + + runner_end (&runner); + + /* Trim all the whitespaces. */ + ptr = gf_trim (pool_name); + + /* If the LV has thin pool associated with this + * then it is a thinly provisioned LV else it is + * regular LV */ + if (0 != ptr [0]) { + is_thin = _gf_true; + } + +out: + return is_thin; +} + int glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr, dict_t *rsp_dict) @@ -1816,6 +1883,16 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr, goto out; } + if (!glusterd_is_thinp_brick (device)) { + snprintf (err_str, sizeof (err_str), + "Snapshot is supported only for " + "thin provisioned LV. Ensure that " + "all bricks of %s are thinly " + "provisioned LV.", volinfo->volname); + ret = -1; + goto out; + } + device = glusterd_build_snap_device_path (device, snap_volname, brick_count); -- cgit