summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c381
1 files changed, 225 insertions, 156 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index 8d7c33d..b8ecb61 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -571,36 +571,29 @@ int
glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
dict_t *rsp_dict)
{
- char *volname = NULL;
- char *name = NULL;
- char *device = NULL;
- char *tmpstr = NULL;
- char *snap_brick_dir = NULL;
- char *username = NULL;
- char *password = NULL;
+ char *volname = NULL;
+ char *name = NULL;
+ char *device = NULL;
+ char *tmpstr = NULL;
+ char *snap_brick_dir = NULL;
char snap_brick_path[PATH_MAX] = "";
- char *mnt_pt = NULL;
- char snapname[PATH_MAX] = "";
- char tmpname[PATH_MAX] = "";
- char tmp[2046] = "";
- char volname_buf[PATH_MAX] = "";
- char snap_mount[PATH_MAX] = "";
- char snapmntname[PATH_MAX] = "";
- char snapbrckcnt[PATH_MAX] = "";
- char snapbrckord[PATH_MAX] = "";
- char snapvolidname[PATH_MAX] = "";
- int ret = -1;
- int64_t i = 0;
- int64_t volume_count = 0;
- int64_t brick_count = 0;
- int64_t brick_order = 0;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- gf_boolean_t is_cg = _gf_false;
- uuid_t *cg_id = NULL;
- uuid_t *snap_volid = NULL;
- uuid_t tmp_uuid = {0};
- xlator_t *this = NULL;
+ char *mnt_pt = NULL;
+ char snapname[PATH_MAX] = "";
+ char tmp[2046] = "";
+ char key[PATH_MAX] = "";
+ char snap_mount[PATH_MAX] = "";
+ char snapmntname[PATH_MAX] = "";
+ char snapbrckcnt[PATH_MAX] = "";
+ char snapbrckord[PATH_MAX] = "";
+ int ret = -1;
+ int64_t i = 0;
+ int64_t volume_count = 0;
+ int64_t brick_count = 0;
+ int64_t brick_order = 0;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ gf_boolean_t is_cg = _gf_false;
+ xlator_t *this = NULL;
this = THIS;
@@ -610,75 +603,29 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
"get the volume count");
goto out;
}
-
- //snap-name should not be set if volume_count > 1
- ret = dict_get_str (dict, "snap-name", &name);
- if (volume_count > 1 && !ret)
- GF_ASSERT (0);
+ GF_ASSERT (volume_count);
if (volume_count > 1) {
is_cg = _gf_true;
ret = dict_get_str (dict, "cg-name", &name);
- if (is_origin_glusterd (dict)) {
- /* Generate a transaction-id for this operation and
- * save it in the dict */
- cg_id = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
- if (!cg_id) {
- gf_log (this->name, GF_LOG_ERROR,
- "Out Of Memory");
- ret = -1;
- goto out;
- }
-
- uuid_generate (*cg_id);
- ret = dict_set_bin (dict, "cg-id", cg_id, sizeof(uuid_t));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set cg-id");
- GF_FREE (cg_id);
- goto out;
- }
- }
- } else if (volume_count == 1)
- ret = dict_get_str (dict, "snap-name", &name);
-
- if (!name) {
- name = generate_snapname (volname, NULL, is_cg);
- if (!name) {
+ if (ret) {
gf_log (this->name, GF_LOG_ERROR,
- "strdup of internal snapname"
- " ((%s) failed for the "
- "volume %s", name,
- volname);
+ "failed to get cg-name");
goto out;
}
-
- tmpstr = gf_strdup (name);
- if (!tmpstr) {
- gf_log (this->name, GF_LOG_ERROR, "Out Of Memory");
- ret = -1;
- goto out;
- }
-
- if (!is_cg)
- ret = dict_set_dynstr (dict, "snap-name", tmpstr);
- else
- ret = dict_set_dynstr (dict, "cg-name", tmpstr);
+ } else {
+ ret = dict_get_str (dict, "snap-name", &name);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to set %s",
- is_cg?"cg name":"snap name");
- ret = -1;
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to get snap-name");
goto out;
}
}
- tmpstr = NULL;
snprintf (snapname, sizeof (snapname), "%s", name);
for (i = 0; i < volume_count; i++) {
- snprintf (volname_buf, sizeof (volname_buf),
- "volname%ld", i+1);
- ret = dict_get_str (dict, volname_buf,
- &volname);
+ snprintf (key, sizeof (key), "volname%ld", i+1);
+ ret = dict_get_str (dict, key, &volname);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"failed to get volume name");
@@ -712,30 +659,6 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
snprintf (snapname, sizeof (snapname), "%s_%s", name, tmp);
}
- /* generate internal username and password for the snap*/
-
- uuid_generate (tmp_uuid);
- username = gf_strdup (uuid_utoa (tmp_uuid));
- snprintf (tmpname, sizeof(tmpname), "volume%ld_username", i+1);
- ret = dict_set_dynstr (dict, tmpname, username);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snap username for "
- "volume %s", volname);
- GF_FREE (username);
- goto out;
- }
-
- uuid_generate (tmp_uuid);
- password = gf_strdup (uuid_utoa (tmp_uuid));
- snprintf (tmpname, sizeof(tmpname), "volume%ld_password", i+1);
- ret = dict_set_dynstr (dict, tmpname, password);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snap password for "
- "volume %s", volname);
- GF_FREE (password);
- goto out;
- }
-
//Also check whether geo replication is running
brick_count = 0;
@@ -816,6 +739,7 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
GF_FREE (tmpstr);
goto out;
}
+ tmpstr = NULL;
ret = snprintf (snapbrckord, sizeof(snapbrckord) - 1,
"vol%ld.brick%ld.order", i+1, brick_count);
@@ -840,28 +764,6 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
snapbrckcnt);
goto out;
}
-
- if (is_origin_glusterd (dict)) {
- snap_volid = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
- if (!snap_volid) {
- gf_log (this->name, GF_LOG_ERROR,
- "Out Of Memory");
- ret = -1;
- goto out;
- }
-
- memset (snapvolidname, '\0', sizeof(snapvolidname));
- ret = snprintf (snapvolidname, sizeof(snapvolidname) - 1,
- "vol%ld_volid", i+1);
-
- uuid_generate (*snap_volid);
- ret = dict_set_bin (dict, snapvolidname, snap_volid, sizeof(uuid_t));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set snap_volid");
- goto out;
- }
- }
}
ret = dict_set_int64 (rsp_dict, "volcount", volume_count);
@@ -2426,6 +2328,159 @@ out:
return ret;
}
+/* This is a snapshot create handler function. This function will be
+ * executed in the originator node. This function is responsible for
+ * calling mgmt_v3 framework to do the actual snap creation on all the bricks
+ *
+ * @param req RPC request object
+ * @param op gluster operation
+ * @param dict dictionary containing snapshot restore request
+ * @param err_str In case of an err this string should be populated
+ * @param len length of err_str buffer
+ *
+ * @return Negative value on Failure and 0 in success
+ */
+int
+glusterd_handle_snapshot_create (rpcsvc_request_t *req, glusterd_op_t op,
+ dict_t *dict, char *err_str, size_t len)
+{
+ int ret = -1;
+ char *volname = NULL;
+ char *name = NULL;
+ int64_t volcount = 0;
+ xlator_t *this = NULL;
+ char key[PATH_MAX] = "";
+ char *username = NULL;
+ char *password = NULL;
+ gf_boolean_t is_cg = _gf_false;
+ uuid_t *cg_id = NULL;
+ uuid_t *snap_volid = NULL;
+ uuid_t tmp_uuid = {0};
+ int i = 0;
+
+ this = THIS;
+ GF_ASSERT (this);
+ GF_ASSERT (req);
+ GF_ASSERT (dict);
+ GF_ASSERT (err_str);
+
+ ret = dict_get_int64 (dict, "volcount", &volcount);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to "
+ "get the volume count");
+ goto out;
+ }
+ GF_ASSERT (volcount);
+
+ if (volcount > 1) {
+ is_cg = _gf_true;
+ ret = dict_get_str (dict, "cg-name", &name);
+ } else {
+ ret = dict_get_str (dict, "snap-name", &name);
+ }
+
+ if (!name) {
+ name = generate_snapname (NULL, NULL, is_cg);
+ if (!name) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to generate snapname");
+ goto out;
+ }
+
+ if (!is_cg)
+ ret = dict_set_dynstr (dict, "snap-name", name);
+ else
+ ret = dict_set_dynstr (dict, "cg-name", name);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Unable to set %s",
+ is_cg?"cg name":"snap name");
+ ret = -1;
+ GF_FREE (name);
+ goto out;
+ }
+ }
+
+ if (volcount > 1) {
+ /* Generate a cg-id for this operation and
+ * save it in the dict */
+ cg_id = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
+ if (!cg_id) {
+ gf_log (this->name, GF_LOG_ERROR, "Out Of Memory");
+ ret = -1;
+ goto out;
+ }
+
+ uuid_generate (*cg_id);
+ ret = dict_set_bin (dict, "cg-id", cg_id, sizeof(uuid_t));
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set cg-id");
+ GF_FREE (cg_id);
+ goto out;
+ }
+ }
+
+ for (i = 1; i <= volcount; i++) {
+ snprintf (key, sizeof (key), "volname%d", i);
+ ret = dict_get_str (dict, key, &volname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to get volume name");
+ goto out;
+ }
+
+ /* generate internal username and password for the snap*/
+ uuid_generate (tmp_uuid);
+ username = gf_strdup (uuid_utoa (tmp_uuid));
+ snprintf (key, sizeof(key), "volume%d_username", i);
+ ret = dict_set_dynstr (dict, key, username);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set snap "
+ "username for volume %s", volname);
+ GF_FREE (username);
+ goto out;
+ }
+
+ uuid_generate (tmp_uuid);
+ password = gf_strdup (uuid_utoa (tmp_uuid));
+ snprintf (key, sizeof(key), "volume%d_password", i);
+ ret = dict_set_dynstr (dict, key, password);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set snap "
+ "password for volume %s", volname);
+ GF_FREE (password);
+ goto out;
+ }
+
+ snap_volid = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
+ if (!snap_volid) {
+ gf_log (this->name, GF_LOG_ERROR, "Out Of Memory");
+ ret = -1;
+ goto out;
+ }
+
+ snprintf (key, sizeof(key) - 1, "vol%d_volid", i);
+ uuid_generate (*snap_volid);
+ ret = dict_set_bin (dict, key, snap_volid, sizeof(uuid_t));
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set snap_volid");
+ GF_FREE (snap_volid);
+ goto out;
+ }
+ }
+
+ ret = glusterd_mgmt_v3_initiate_snap_phases (req, op, dict);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to initiate snap "
+ "phases");
+ }
+
+out:
+ return ret;
+}
+
+
/* This is a snapshot restore handler function. This function will be
* executed in the originator node. This function is responsible for
* calling mgmt_v3 framework to do the actual restore on all the bricks
@@ -3882,9 +3937,9 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
gf_boolean_t is_cg = _gf_false;
char *name = NULL;
char *volname = NULL;
- char *tmp = NULL;
+ char *tmp_name = NULL;
char volname_buf[PATH_MAX] = "";
- char snapvolidname[PATH_MAX] = "";
+ char key[PATH_MAX] = "";
xlator_t *this = NULL;
glusterd_volinfo_t *volinfo = NULL;
glusterd_snap_cg_t *cg = NULL;
@@ -3912,17 +3967,19 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
gf_log (this->name, GF_LOG_ERROR, "Unable to fetch snap-name");
goto out;
}
- tmp = gf_strdup (name);
- if (!tmp) {
+ tmp_name = gf_strdup (name);
+ if (!tmp_name) {
gf_log (this->name, GF_LOG_ERROR, "Out of memory");
+ ret = -1;
goto out;
}
- ret = dict_set_dynstr (rsp_dict, "snap-name", tmp);
+ ret = dict_set_dynstr (rsp_dict, "snap-name", tmp_name);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"Unable to set snap-name in rsp_dict");
- GF_FREE (tmp);
+ GF_FREE (tmp_name);
+ tmp_name = NULL;
goto out;
}
} else {
@@ -3931,21 +3988,23 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
gf_log (this->name, GF_LOG_ERROR, "Unable to fetch cg-name");
goto out;
}
- tmp = gf_strdup (name);
- if (!tmp) {
+ tmp_name = gf_strdup (name);
+ if (!tmp_name) {
gf_log (this->name, GF_LOG_ERROR, "Out of memory");
+ ret = -1;
goto out;
}
- ret = dict_set_str (rsp_dict, "cg-name", tmp);
+ ret = dict_set_dynstr (rsp_dict, "cg-name", tmp_name);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"Unable to set cg-name in rsp_dict");
- GF_FREE (tmp);
+ GF_FREE (tmp_name);
+ tmp_name = NULL;
goto out;
}
}
- tmp = NULL;
+ tmp_name = NULL;
ret = dict_get_bin (dict, "cg-id", (void **)&cg_id);
if (ret)
@@ -3960,6 +4019,7 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
if (!cg) {
gf_log (this->name, GF_LOG_ERROR, "cannot create the "
"consistency group %s", name);
+ ret = -1;
goto out;
}
}
@@ -3983,18 +4043,18 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
goto out;
}
- tmp = generate_snapname (volname, name, is_cg);
- if (!tmp) {
+ tmp_name = generate_snapname (volname, name, is_cg);
+ if (!tmp_name) {
gf_log (this->name,
- GF_LOG_ERROR, "strdup "
- "failed (%s)", name);
+ GF_LOG_ERROR, "strdup failed (%s)", name);
+ ret = -1;
goto out;
}
list_for_each_entry (snap, &volinfo->snaps, snap_list) {
- if (!strcmp (snap->snap_name, tmp)) {
- snprintf (err_str, sizeof (err_str), "snap "
- "with name %s already exists", tmp);
+ if (!strcmp (snap->snap_name, tmp_name)) {
+ snprintf (err_str, sizeof (err_str), "snap with"
+ " name %s already exists", tmp_name);
gf_log (this->name, GF_LOG_ERROR, "%s",
err_str);
ret = -1;
@@ -4003,11 +4063,8 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
}
}
- memset (snapvolidname, '\0', sizeof(snapvolidname));
- ret = snprintf (snapvolidname, sizeof(snapvolidname) - 1,
- "vol%d_volid", i);
-
- ret = dict_get_bin (dict, snapvolidname, (void **)&snap_volid);
+ snprintf (key, sizeof(key) - 1, "vol%d_volid", i);
+ ret = dict_get_bin (dict, key, (void **)&snap_volid);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"Unable to fetch snap_volid");
@@ -4019,11 +4076,11 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
the snap creating happens parallely.
*/
if (is_cg) {
- ret = glusterd_do_snap (volinfo, tmp, dict,
+ ret = glusterd_do_snap (volinfo, tmp_name, dict,
cg, cg_id, i, *snap_volid, name);
}
else {
- ret = glusterd_do_snap (volinfo, tmp, dict,
+ ret = glusterd_do_snap (volinfo, tmp_name, dict,
cg, cg_id, i, *snap_volid, NULL);
}
if (ret) {
@@ -4033,6 +4090,9 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
}
if (cg)
cg->volumes[i-1] = volinfo;
+
+ GF_FREE (tmp_name);
+ tmp_name = NULL;
}
if (volume_count > 1) {
@@ -4060,6 +4120,10 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
ret = 0;
out:
+
+ if (ret)
+ GF_FREE (tmp_name);
+
gf_log ("", GF_LOG_TRACE, "Returning %d", ret);
return ret;
}
@@ -4653,7 +4717,12 @@ glusterd_handle_snapshot_fn (rpcsvc_request_t *req)
switch (type) {
case GF_SNAP_OPTION_TYPE_CREATE:
- ret = glusterd_mgmt_v3_initiate_snap_phases (req, cli_op, dict);
+ ret = glusterd_handle_snapshot_create (req, cli_op, dict,
+ err_str, sizeof (err_str));
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "Snapshot create "
+ "failed: %s", err_str);
+ }
break;
case GF_SNAP_OPTION_TYPE_RESTORE:
ret = glusterd_handle_snapshot_restore (req, cli_op, dict,