summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorAvra Sengupta <asengupt@redhat.com>2013-11-21 03:48:32 +0000
committerAvra Sengupta <asengupt@redhat.com>2013-12-03 02:59:13 +0000
commitf834bbc2714a52db7955474ee362321c4f6617ce (patch)
tree38ac085398675d7eea44239383393cf3c1005e13 /xlators
parent79a2b1997459cf6932e929488b0ade3535b9ced9 (diff)
glusterd/mgmtv3: Fetching snap mount path per brick.
Fetching snap mount path per brick during pre-validate and aggregating it before commit to generate all brick volfiles and all client volfiles on all nodes. Added changes to propagate the same cg-id by generating it in pre-validate and sending the same to all the nodes during commit Also fixed volume-id mismatches caused in snap-volumes leading to failures of volume status Change-Id: I0b8ed81ac93077cd50313e6eeed00f71932cf2ac Signed-off-by: Avra Sengupta <asengupt@redhat.com> Signed-off-by: Rajesh Joseph <rjoseph@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mgmt.c67
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mgmt.h4
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c649
3 files changed, 576 insertions, 144 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
index 539705021..852d60fb4 100644
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.c
+++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
@@ -371,9 +371,30 @@ out:
return ret;
}
+int
+glusterd_pre_validate_aggr_rsp_dict (glusterd_op_t op, dict_t *aggr, dict_t *rsp)
+{
+ int ret = 0;
+
+ switch (op) {
+ case GD_OP_SNAP:
+ ret = glusterd_snap_pre_validate_use_rsp_dict (aggr, rsp);
+ if (ret)
+ goto out;
+ break;
+ default:
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "Invalid op (%s)", gd_op_list[op]);
+
+ break;
+ }
+out:
+ return ret;
+}
+
int32_t
gd_mgmt_v3_pre_validate_cbk_fn (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+ int count, void *myframe)
{
int ret = -1;
struct syncargs *args = NULL;
@@ -382,6 +403,7 @@ gd_mgmt_v3_pre_validate_cbk_fn (struct rpc_req *req, struct iovec *iov,
call_frame_t *frame = NULL;
int op_ret = -1;
int op_errno = -1;
+ dict_t *rsp_dict = NULL;
GF_ASSERT(req);
GF_ASSERT(iov);
@@ -403,11 +425,39 @@ gd_mgmt_v3_pre_validate_cbk_fn (struct rpc_req *req, struct iovec *iov,
if (ret < 0)
goto out;
+ if (rsp.dict.dict_len) {
+ /* Unserialize the dictionary */
+ rsp_dict = dict_new ();
+
+ ret = dict_unserialize (rsp.dict.dict_val,
+ rsp.dict.dict_len,
+ &rsp_dict);
+ if (ret < 0) {
+ GF_FREE (rsp.dict.dict_val);
+ goto out;
+ } else {
+ rsp_dict->extra_stdfree = rsp.dict.dict_val;
+ }
+ }
+
uuid_copy (args->uuid, rsp.uuid);
+ pthread_mutex_lock (&args->lock_dict);
+ {
+ ret = glusterd_pre_validate_aggr_rsp_dict (rsp.op, args->dict,
+ rsp_dict);
+ }
+ pthread_mutex_unlock (&args->lock_dict);
+ if (ret)
+ gf_log ("", GF_LOG_ERROR, "%s",
+ "Failed to aggregate response from "
+ " node/brick");
op_ret = rsp.op_ret;
op_errno = rsp.op_errno;
out:
+ if (rsp_dict)
+ dict_unref (rsp_dict);
+
gd_mgmt_v3_collate_errors (args, op_ret, op_errno, NULL,
GLUSTERD_MGMT_V3_PRE_VALIDATE,
peerinfo, rsp.uuid);
@@ -460,7 +510,7 @@ out:
int
glusterd_mgmt_v3_pre_validate (glusterd_conf_t *conf, glusterd_op_t op,
- dict_t *req_dict, char **op_errstr, int npeers)
+ dict_t *req_dict, char **op_errstr, int npeers)
{
int ret = -1;
int peer_cnt = 0;
@@ -483,7 +533,7 @@ glusterd_mgmt_v3_pre_validate (glusterd_conf_t *conf, glusterd_op_t op,
/* Pre Validation on local node */
ret = gd_mgmt_v3_pre_validate_fn (op, req_dict, op_errstr,
- rsp_dict);
+ rsp_dict);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
@@ -504,6 +554,15 @@ glusterd_mgmt_v3_pre_validate (glusterd_conf_t *conf, glusterd_op_t op,
goto out;
}
+ ret = glusterd_pre_validate_aggr_rsp_dict (op, req_dict,
+ rsp_dict);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "%s",
+ "Failed to aggregate response from "
+ " node/brick");
+ goto out;
+ }
+
dict_unref (rsp_dict);
rsp_dict = NULL;
@@ -513,7 +572,7 @@ glusterd_mgmt_v3_pre_validate (glusterd_conf_t *conf, glusterd_op_t op,
}
/* Sending Pre Validation req to other nodes in the cluster */
- gd_syncargs_init (&args, NULL);
+ gd_syncargs_init (&args, req_dict);
synctask_barrier_init((&args));
peer_cnt = 0;
list_for_each_entry (peerinfo, peers, op_peers_list) {
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.h b/xlators/mgmt/glusterd/src/glusterd-mgmt.h
index 8c085d18c..25ce32e01 100644
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.h
+++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.h
@@ -38,4 +38,8 @@ glusterd_mgmt_v3_initiate_all_phases (rpcsvc_request_t *req, glusterd_op_t op,
int32_t
glusterd_mgmt_v3_initiate_snap_phases (rpcsvc_request_t *req, glusterd_op_t op,
dict_t *dict);
+
+int
+glusterd_snap_pre_validate_use_rsp_dict (dict_t *dst, dict_t *src);
+
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index ea26059b5..6a1fc4cea 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -44,6 +44,8 @@
#include <mntent.h>
#endif
+char *
+generate_snapname (char *volname, char *name, gf_boolean_t volume_from_cg);
/* This function will do the actual snapshot restore on the brick.
@@ -541,16 +543,162 @@ out:
}
int
+glusterd_snap_create_pre_val_use_rsp_dict (dict_t *dst, dict_t *src)
+{
+ char *snap_mount = NULL;
+ char *tmpstr = NULL;
+ char snapmntname[PATH_MAX] = "";
+ char snapbrckcnt[PATH_MAX] = "";
+ char snapbrckord[PATH_MAX] = "";
+ int ret = -1;
+ int64_t i = -1;
+ int64_t j = -1;
+ int64_t volume_count = 0;
+ int64_t brick_count = 0;
+ int64_t brick_order = 0;
+
+
+ if (!dst || !src) {
+ gf_log ("", GF_LOG_ERROR, "Source or Destination "
+ "dict is empty.");
+ goto out;
+ }
+
+ ret = dict_get_int64 (src, "volcount", &volume_count);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "failed to "
+ "get the volume count");
+ goto out;
+ }
+
+ for (i = 0; i < volume_count; i++) {
+ memset (snapbrckcnt, '\0', sizeof(snapbrckcnt));
+ ret = snprintf (snapbrckcnt, sizeof(snapbrckcnt) - 1,
+ "vol%ld_brickcount", i+1);
+ ret = dict_get_int64 (src, snapbrckcnt, &brick_count);
+ if (ret) {
+ gf_log ("", GF_LOG_TRACE,
+ "No bricks for this volume in this dict");
+ continue;
+ }
+
+ for (j = 0; j < brick_count; j++) {
+ /* Fetching data from source dict */
+ memset (snapmntname, '\0', sizeof(snapmntname));
+ ret = snprintf (snapmntname, sizeof(snapmntname) - 1,
+ "vol%ld.brick%ld", i+1, j);
+
+ ret = dict_get_ptr (src, snapmntname, (void **)&snap_mount);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Unable to fetch "
+ "snap mount path");
+ goto out;
+ }
+ memset (snapbrckord, '\0', sizeof(snapbrckord));
+ ret = snprintf (snapbrckord, sizeof(snapbrckord) - 1,
+ "vol%ld.brick%ld.order", i+1, j);
+
+ ret = dict_get_int64 (src, snapbrckord, &brick_order);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to get brick order");
+ goto out;
+ }
+
+ /* Adding the data in the dst dict */
+ memset (snapmntname, '\0', sizeof(snapmntname));
+ ret = snprintf (snapmntname, sizeof(snapmntname) - 1,
+ "vol%ld.brick%ld", i+1, brick_order);
+
+ tmpstr = gf_strdup (snap_mount);
+ if (!tmpstr) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Out Of Memory");
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_dynstr (dst, snapmntname, tmpstr);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to set %s",
+ snap_mount);
+ GF_FREE (tmpstr);
+ goto out;
+ }
+ }
+ }
+
+ ret = 0;
+out:
+
+ gf_log (THIS->name, GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
+}
+
+int
+glusterd_snap_pre_validate_use_rsp_dict (dict_t *dst, dict_t *src)
+{
+ int ret = -1;
+ int32_t snap_command = 0;
+
+ if (!dst || !src) {
+ gf_log ("", GF_LOG_ERROR, "Source or Destination "
+ "dict is empty.");
+ goto out;
+ }
+
+ ret = dict_get_int32 (dst, "type", &snap_command);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "unable to get the type of "
+ "the snapshot command");
+ goto out;
+ }
+
+ switch (snap_command) {
+ case GF_SNAP_OPTION_TYPE_CREATE:
+ ret = glusterd_snap_create_pre_val_use_rsp_dict (dst, src);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to use rsp dict");
+ goto out;
+ }
+ break;
+ default:
+ break;
+ }
+
+ ret = 0;
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
dict_t *rsp_dict)
{
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int64_t volume_count = 0;
- char volname_buf[PATH_MAX] = {0, };
- int64_t i = 0;
- xlator_t *this = NULL;
- int ret = -1;
+ 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 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;
+ xlator_t *this = NULL;
this = THIS;
@@ -560,6 +708,68 @@ 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);
+
+ 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) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "strdup of internal snapname"
+ " ((%s) failed for the "
+ "volume %s", name,
+ volname);
+ goto out;
+ }
+ }
+
+ if (!is_cg)
+ snprintf (snapname, sizeof (snapname), "%s", name);
+
+ tmpstr = gf_strdup (name);
+ if (!tmpstr) {
+ gf_log (this->name, GF_LOG_ERROR, "Out Of Memory");
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_dynstr (dict, "snap-name", tmpstr);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Unable to set snap-name");
+ ret = -1;
+ goto out;
+ }
+
+ tmpstr = NULL;
+
for (i = 0; i < volume_count; i++) {
snprintf (volname_buf, sizeof (volname_buf),
"volname%ld", i+1);
@@ -591,8 +801,210 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
"for the volume %s", volname);
goto out;
}
+
+ if (is_cg) {
+ memset(snapname, '\0', sizeof (snapname));
+ snprintf (tmp, sizeof (tmp), "%s_snap", volinfo->volname);
+ snprintf (snapname, sizeof (snapname), "%s_%s", name, tmp);
+ }
+
//Also check whether geo replication is running
+
+ brick_count = 0;
+ brick_order = 0;
+ /* Adding snap bricks mount paths to the dict */
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ if (uuid_compare (brickinfo->uuid, MY_UUID)) {
+ brick_order++;
+ continue;
+ }
+
+ memset (snapmntname, '\0', sizeof(snapmntname));
+ memset (snapbrckord, '\0', sizeof(snapbrckord));
+ memset (snap_mount, '\0', sizeof(snap_mount));
+
+ device = glusterd_get_brick_mount_details (brickinfo);
+ if (!device) {
+ gf_log (this->name, GF_LOG_ERROR, "getting device name for "
+ "the brick %s:%s failed", brickinfo->hostname,
+ brickinfo->path);
+ ret = -1;
+ goto out;
+ }
+
+ device = glusterd_build_snap_device_path (device, snapname);
+ if (!device) {
+ gf_log (this->name, GF_LOG_WARNING, "cannot copy the "
+ "snapshot device name (volname: %s, "
+ "snapname: %s)", volinfo->volname, snapname);
+ ret = -1;
+ goto out;
+ }
+
+ glusterd_replace_slash_with_hyphen (device);
+ if (device[0] == '-')
+ device[0] = '/';
+
+ ret = snprintf (snap_mount, sizeof(snap_mount) - 1,
+ "%s/%s%s-brick",
+ GLUSTERD_DEFAULT_SNAPS_BRICK_DIR,
+ snapname, device);
+ snap_mount[ret] = '\0';
+
+ ret = glusterd_get_brick_root (brickinfo->path, &mnt_pt);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "could not get the root of"
+ "the brick path %s", brickinfo->path);
+ goto out;
+ }
+
+ if (strncmp (brickinfo->path, mnt_pt, strlen (mnt_pt))) {
+ gf_log (this->name, GF_LOG_WARNING, "brick: %s brick mount: %s",
+ brickinfo->path, mnt_pt);
+ goto out;
+ }
+
+ snap_brick_dir = &brickinfo->path[strlen (mnt_pt)];
+ if (snap_brick_dir)
+ snap_brick_dir++;
+
+ snprintf (snap_brick_path, sizeof (snap_brick_path), "%s/%s",
+ snap_mount, snap_brick_dir);
+
+ ret = snprintf (snapmntname, sizeof(snapmntname) - 1,
+ "vol%ld.brick%ld", i+1, brick_count);
+ snapmntname[ret] = '\0';
+
+ tmpstr = gf_strdup (snap_brick_path);
+ if (!tmpstr) {
+ gf_log ("", GF_LOG_ERROR, "Out Of Memory");
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_dynstr (rsp_dict, snapmntname, tmpstr);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Failed to set %s",
+ snap_mount);
+ GF_FREE (tmpstr);
+ goto out;
+ }
+
+ ret = snprintf (snapbrckord, sizeof(snapbrckord) - 1,
+ "vol%ld.brick%ld.order", i+1, brick_count);
+ snapbrckord[ret] = '\0';
+
+ ret = dict_set_int64 (rsp_dict, snapbrckord, brick_order);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Failed to set brick order");
+ goto out;
+ }
+
+ brick_count++;
+ brick_order++;
+ }
+ memset (snapbrckcnt, '\0', sizeof(snapbrckcnt));
+ ret = snprintf (snapbrckcnt, sizeof(snapbrckcnt) - 1,
+ "vol%ld_brickcount", i+1);
+ snapbrckcnt[ret] = '\0';
+
+ ret = dict_set_int64 (rsp_dict, snapbrckcnt, brick_count);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Failed to set %s",
+ 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);
+ snapvolidname[ret] = '\0';
+
+ 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);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Failed to set volcount");
+ goto out;
}
+
+ ret = 0;
+out:
+ gf_log ("", GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
+}
+
+int
+glusterd_snapshot_prevalidate (dict_t *dict, char **op_errstr,
+ dict_t *rsp_dict)
+{
+ int snap_command = 0;
+ xlator_t *this = NULL;
+ int ret = -1;
+
+ this = THIS;
+
+ GF_ASSERT (this);
+ GF_ASSERT (dict);
+ GF_ASSERT (rsp_dict); //not sure if this is needed, verify.
+
+ ret = dict_get_int32 (dict, "type", &snap_command);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "unable to get the type of "
+ "the snapshot command");
+ goto out;
+ }
+
+ switch (snap_command) {
+ case (GF_SNAP_OPTION_TYPE_CREATE):
+ ret = glusterd_snapshot_create_prevalidate (dict, op_errstr,
+ rsp_dict);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "Snapshot create "
+ "pre-validation failed");
+ goto out;
+ }
+ break;
+
+ case (GF_SNAP_OPTION_TYPE_CONFIG):
+ ret = glusterd_snapshot_config_prevalidate (dict, op_errstr);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "Snapshot config "
+ "pre-validation failed");
+ goto out;
+ }
+ break;
+
+ case GF_SNAP_OPTION_TYPE_RESTORE:
+ ret = glusterd_snapshot_restore_prevalidate (dict, op_errstr);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "Snapshot restore "
+ "validation failed");
+ goto out;
+ }
+ break;
+ default:
+ gf_log (this->name, GF_LOG_WARNING, "invalid snap command");
+ goto out;
+ }
+
+ ret = 0;
out:
return ret;
}
@@ -2257,12 +2669,13 @@ out:
int32_t
glusterd_snap_create (glusterd_volinfo_t *volinfo,
glusterd_volinfo_t *snap_volinfo,
- char *description, uuid_t cg_id)
+ char *description, uuid_t *cg_id)
{
glusterd_snap_t *snap = NULL;
xlator_t *this = NULL;
glusterd_conf_t *priv = NULL;
int ret = -1;
+ uuid_t snap_uuid;
this = THIS;
priv = this->private;
@@ -2285,9 +2698,10 @@ glusterd_snap_create (glusterd_volinfo_t *volinfo,
if (description)
snap->description = gf_strdup (description);
snap->time_stamp = time (NULL);
- uuid_copy (snap->snap_id, snap_volinfo->volume_id);
- if (!uuid_is_null (cg_id))
- uuid_copy (snap->cg_id, cg_id);
+ uuid_generate (snap_uuid);
+ uuid_copy (snap->snap_id, snap_uuid);
+ if (cg_id)
+ uuid_copy (snap->cg_id, *cg_id);
snap->snap_volume = snap_volinfo;
strcpy (snap->snap_name, snap_volinfo->volname);
//TODO: replace strcpy with strncpy
@@ -2456,7 +2870,6 @@ glusterd_snap_brick_create (char *device, glusterd_volinfo_t *snap_volinfo,
int32_t ret = -1;
xlator_t *this = NULL;
glusterd_conf_t *priv = NULL;
- glusterd_brickinfo_t *snap_brickinfo = NULL;
char snap_brick_mount_path[PATH_MAX] = {0, };
char *tmp = NULL;
char *mnt_pt = NULL;
@@ -2520,7 +2933,6 @@ glusterd_snap_brick_create (char *device, glusterd_volinfo_t *snap_volinfo,
snprintf (snap_brick_path, sizeof (snap_brick_path), "%s/%s",
snap_brick_mount_path, snap_brick_dir);
-
entry = glusterd_get_mnt_entry_info (mnt_pt, mtab);
if (!entry) {
ret = -1;
@@ -2548,23 +2960,6 @@ glusterd_snap_brick_create (char *device, glusterd_volinfo_t *snap_volinfo,
gf_log (this->name, GF_LOG_DEBUG, "mounting the snapshot "
"logical device %s successful", device);
- ret = glusterd_brickinfo_new (&snap_brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "initializing the brick for the snap "
- "volume failed (snapname: %s)", snap_volinfo->volname);
- goto out;
- }
-
- strcpy (snap_brickinfo->hostname, original_brickinfo->hostname);
- strcpy (snap_brickinfo->path, snap_brick_path);
- LOCK (&snap_volinfo->lock);
- {
- list_add_tail (&snap_brickinfo->brick_list,
- &snap_volinfo->bricks);
- }
- UNLOCK (&snap_volinfo->lock);
-
ret = stat (snap_brick_path, &statbuf);
if (ret) {
gf_log (this->name, GF_LOG_WARNING, "stat of the brick %s"
@@ -2572,7 +2967,7 @@ glusterd_snap_brick_create (char *device, glusterd_volinfo_t *snap_volinfo,
snap_brick_mount_path, strerror (errno));
goto out;
}
- ret = sys_lsetxattr (snap_brickinfo->path,
+ ret = sys_lsetxattr (snap_brick_path,
GF_XATTR_VOL_ID_KEY,
snap_volinfo->volume_id, 16,
XATTR_REPLACE);
@@ -2580,7 +2975,7 @@ glusterd_snap_brick_create (char *device, glusterd_volinfo_t *snap_volinfo,
gf_log (this->name, GF_LOG_ERROR, "Failed to set "
"extended attribute %s on %s. Reason: "
"%s, snap: %s", GF_XATTR_VOL_ID_KEY,
- snap_brickinfo->path, strerror (errno),
+ snap_brick_path, strerror (errno),
snap_volinfo->volname);
goto out;
}
@@ -2591,8 +2986,6 @@ out:
gf_log (this->name, GF_LOG_WARNING, "unmounting the snap brick"
" mount %s", snap_brick_mount_path);
umount (snap_brick_mount_path);
- if (snap_brickinfo)
- glusterd_brickinfo_delete (snap_brickinfo);
}
if (mtab)
endmntent (mtab);
@@ -2608,18 +3001,21 @@ out:
*/
int32_t
glusterd_do_snap (glusterd_volinfo_t *volinfo, char *name, dict_t *dict,
- gf_boolean_t cg, uuid_t cg_id)
+ gf_boolean_t cg, uuid_t *cg_id, int volcount, uuid_t snap_volid)
{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- char *device = NULL;
- char snapname[PATH_MAX] = {0, };
- char tmp[2046] = {0, };
- glusterd_volinfo_t *snap_volume = NULL;
- char *description = NULL;
- uuid_t snap_uuid = {0, };
+ char snapname[PATH_MAX] = "";
+ char tmp[2046] = "";
+ char *snap_brick_mount_path = "";
+ char snapmntname[PATH_MAX] = "";
+ char *device = NULL;
+ char *description = NULL;
+ glusterd_brickinfo_t *snap_brickinfo = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *snap_volume = NULL;
+ int32_t ret = -1;
+ int32_t brick_count = 0;
+ xlator_t *this = NULL;
this = THIS;
GF_ASSERT (this);
@@ -2637,8 +3033,45 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *name, dict_t *dict,
ret = glusterd_volinfo_dup (volinfo, &snap_volume);
strcpy (snap_volume->volname, snapname);
snap_volume->is_snap_volume = _gf_true;
- uuid_generate (snap_uuid);
- uuid_copy (snap_volume->volume_id, snap_uuid);
+ uuid_copy (snap_volume->volume_id, snap_volid);
+
+ /* Adding snap brickinfos to the snap volinfo */
+ brick_count = 0;
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ snap_brickinfo = NULL;
+ device = NULL;
+ ret = glusterd_brickinfo_new (&snap_brickinfo);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "initializing the brick for the snap "
+ "volume failed (snapname: %s)", snap_volume->volname);
+ goto out;
+ }
+
+ memset (snapmntname, '\0', sizeof(snapmntname));
+ ret = snprintf (snapmntname, sizeof(snapmntname) - 1,
+ "vol%d.brick%d", volcount, brick_count);
+ snapmntname[ret] = '\0';
+
+ ret = dict_get_ptr (dict, snapmntname, (void **)&snap_brick_mount_path);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to fetch "
+ "snap mount path (%s)", snapmntname);
+ GF_FREE (snap_brickinfo);
+ goto out;
+ }
+
+ strcpy (snap_brickinfo->hostname, brickinfo->hostname);
+ strcpy (snap_brickinfo->path, snap_brick_mount_path);
+ uuid_copy (snap_brickinfo->uuid, brickinfo->uuid);
+ LOCK (&snap_volume->lock);
+ {
+ list_add_tail (&snap_brickinfo->brick_list,
+ &snap_volume->bricks);
+ }
+ UNLOCK (&snap_volume->lock);
+ brick_count++;
+ }
list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
if (uuid_compare (brickinfo->uuid, MY_UUID)) {
@@ -2665,9 +3098,7 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *name, dict_t *dict,
if (ret)
continue;
- /*create the complete brick here and add it to the
- volinfo
- */
+ /* create the complete brick here */
ret = glusterd_snap_brick_create (device, snap_volume,
brickinfo);
if (ret) {
@@ -2830,14 +3261,16 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
char *name = NULL;
char *volname = NULL;
char *tmp = NULL;
- char volname_buf[PATH_MAX] = {0, };
+ char volname_buf[PATH_MAX] = "";
+ char snapvolidname[PATH_MAX] = "";
xlator_t *this = NULL;
glusterd_volinfo_t *volinfo = NULL;
glusterd_snap_cg_t *cg = NULL;
glusterd_conf_t *priv = NULL;
- uuid_t cg_id;
+ uuid_t *cg_id = NULL;
+ uuid_t *snap_volid = NULL;
glusterd_snap_t *snap = NULL;
- char err_str[PATH_MAX] = {0, };
+ char err_str[PATH_MAX] = "";
this = THIS;
GF_ASSERT (this);
@@ -2851,45 +3284,18 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
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);
-
- if (volume_count > 1) {
- is_cg = _gf_true;
- ret = dict_get_str (dict, "cg-name", &name);
- uuid_generate (cg_id);
- cg = glusterd_new_snap_cg_object (volume_count);
- if (!cg) {
- gf_log (this->name, GF_LOG_ERROR,
- "cannot create the consistency"
- " group %s", name);
- goto out;
- }
- } else if (volume_count == 1) {
- ret = dict_get_str (dict, "snap-name", &name);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Unable to fetch snap-name");
+ goto out;
}
- if (!name) {
- name = generate_snapname (volname, NULL, is_cg);
- if (!name) {
- gf_log (this->name, GF_LOG_ERROR,
- "strdup of internal snapname"
- " ((%s) failed for the "
- "volume %s", name,
- volname);
- goto out;
- }
- /* If the user has not provided the snapname/cg-name, then
- one is generated by glusterd itself. Put it into the
- dict, so that cli displays the name of the snap/cg that
- was created.
- */
- if (is_cg)
- ret = dict_set_str (rsp_dict, "cg-name", name);
- else
- ret = dict_set_str (rsp_dict, "snap-name", name);
+ ret = dict_get_bin (dict, "cg-id", (void **)&cg_id);
+ if (ret)
+ gf_log (this->name, GF_LOG_DEBUG, "Not a cg.");
+ else {
+ is_cg = _gf_true;
+ gf_log (this->name, GF_LOG_DEBUG, "cg-id = %s", uuid_utoa(*cg_id));
}
for (i = 1; i < volume_count + 1; i++) {
@@ -2931,11 +3337,22 @@ 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);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to fetch snap_volid");
+ goto out;
+ }
+
/* TODO: Create a stub where the bricks are
added parallely by worker threads so that
the snap creating happens parallely.
*/
- ret = glusterd_do_snap (volinfo, tmp, dict, is_cg, cg_id);
+ ret = glusterd_do_snap (volinfo, tmp, dict, is_cg, cg_id, i, *snap_volid);
if (ret) {
gf_log (this->name, GF_LOG_WARNING, "taking the "
"snapshot of the volume %s failed", volname);
@@ -2953,7 +3370,7 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
goto out;
}
- uuid_copy (cg->cg_id, cg_id);
+ uuid_copy (cg->cg_id, *cg_id);
strncpy (cg->cg_name, name, sizeof (cg->cg_name));
ret = glusterd_add_snap_cg (priv, cg);
if (ret) {
@@ -3260,55 +3677,6 @@ out:
}
int
-glusterd_snapshot_prevalidate (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int snap_command = 0;
- xlator_t *this = NULL;
- int ret = -1;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict); //not sure if this is needed, verify.
-
- ret = dict_get_int32 (dict, "type", &snap_command);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "unable to get the type of "
- "the snapshot command");
- goto out;
- }
-
- switch (snap_command) {
- case (GF_SNAP_OPTION_TYPE_CREATE):
- ret = glusterd_snapshot_create_prevalidate (dict, op_errstr,
- rsp_dict);
- break;
-
- case (GF_SNAP_OPTION_TYPE_CONFIG):
- ret = glusterd_snapshot_config_prevalidate (dict, op_errstr);
- break;
-
- case GF_SNAP_OPTION_TYPE_RESTORE:
- ret = glusterd_snapshot_restore_prevalidate (dict, op_errstr);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Snapshot restore "
- "validation failed");
- goto out;
- }
- break;
- default:
- gf_log (this->name, GF_LOG_WARNING, "invalid snap command");
- goto out;
- }
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int
glusterd_handle_snapshot_fn (rpcsvc_request_t *req)
{
int32_t ret = 0;
@@ -3404,6 +3772,7 @@ glusterd_handle_snapshot_fn (rpcsvc_request_t *req)
case GF_SNAP_OPTION_TYPE_CONFIG:
ret = glusterd_mgmt_v3_initiate_all_phases (req, cli_op, dict);
break;
+ case GF_SNAP_OPTION_TYPE_DELETE:
case GF_SNAP_OPTION_TYPE_START:
case GF_SNAP_OPTION_TYPE_STOP:
case GF_SNAP_OPTION_TYPE_STATUS: