summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-utils.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c1648
1 files changed, 1407 insertions, 241 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 8e96be9..7883a98 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -13,6 +13,12 @@
#endif
#include <inttypes.h>
+#if !defined(__NetBSD__) && !defined(GF_DARWIN_HOST_OS)
+#include <mntent.h>
+#else
+#include "mntent_compat.h"
+#endif
+
#include "globals.h"
#include "glusterfs.h"
#include "compat.h"
@@ -44,7 +50,6 @@
#include <inttypes.h>
#include <signal.h>
#include <sys/types.h>
-#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <rpc/pmap_clnt.h>
@@ -56,11 +61,6 @@
#include <lvm2app.h>
#endif
-
-#ifdef GF_LINUX_HOST_OS
-#include <mntent.h>
-#endif
-
#ifdef GF_SOLARIS_HOST_OS
#include <sys/sockio.h>
#endif
@@ -709,7 +709,7 @@ glusterd_snap_volinfo_restore (dict_t *rsp_dict,
/* Adding missed delete to the dict */
ret = glusterd_add_missed_snaps_to_dict
(rsp_dict,
- snap_volinfo->volname,
+ snap_volinfo,
brickinfo,
brick_count + 1,
GF_SNAP_OPTION_TYPE_RESTORE);
@@ -2241,12 +2241,17 @@ out:
return ret;
}
+/* The prefix represents the type of volume to be added.
+ * It will be "volume" for normal volumes, and snap# like
+ * snap1, snap2, for snapshot volumes
+ */
int32_t
glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
- dict_t *dict, int32_t count)
+ dict_t *dict, int32_t count,
+ char *prefix)
{
int32_t ret = -1;
- char prefix[512] = {0,};
+ char pfx[512] = {0,};
char key[512] = {0,};
glusterd_brickinfo_t *brickinfo = NULL;
int32_t i = 1;
@@ -2263,89 +2268,101 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
GF_ASSERT (this);
GF_ASSERT (dict);
GF_ASSERT (volinfo);
+ GF_ASSERT (prefix);
- snprintf (key, sizeof (key), "volume%d.name", count);
+ snprintf (key, sizeof (key), "%s%d.name", prefix, count);
ret = dict_set_str (dict, key, volinfo->volname);
if (ret)
goto out;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.type", count);
+ snprintf (key, sizeof (key), "%s%d.type", prefix, count);
ret = dict_set_int32 (dict, key, volinfo->type);
if (ret)
goto out;
- snprintf (key, sizeof (key), "volume%d.is_volume_restored", count);
- ret = dict_set_int32 (dict, key, volinfo->is_volume_restored);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to set "
- "is_volume_restored option for %s volume",
- volinfo->volname);
+ snprintf (key, sizeof (key), "volume%d.restored_from_snap", count);
+ ret = dict_set_dynstr_with_alloc
+ (dict, key,
+ uuid_utoa (volinfo->restored_from_snap));
+ if (ret)
goto out;
+
+ if (strlen (volinfo->parent_volname) > 0) {
+ snprintf (key, sizeof (key), "%s%d.parent_volname",
+ prefix, count);
+ ret = dict_set_dynstr_with_alloc (dict, key,
+ volinfo->parent_volname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to set parent_volname for %s",
+ volinfo->volname);
+ goto out;
+ }
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.brick_count", count);
+ snprintf (key, sizeof (key), "%s%d.brick_count", prefix, count);
ret = dict_set_int32 (dict, key, volinfo->brick_count);
if (ret)
goto out;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.version", count);
+ snprintf (key, sizeof (key), "%s%d.version", prefix, count);
ret = dict_set_int32 (dict, key, volinfo->version);
if (ret)
goto out;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.status", count);
+ snprintf (key, sizeof (key), "%s%d.status", prefix, count);
ret = dict_set_int32 (dict, key, volinfo->status);
if (ret)
goto out;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.sub_count", count);
+ snprintf (key, sizeof (key), "%s%d.sub_count", prefix, count);
ret = dict_set_int32 (dict, key, volinfo->sub_count);
if (ret)
goto out;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.stripe_count", count);
+ snprintf (key, sizeof (key), "%s%d.stripe_count", prefix, count);
ret = dict_set_int32 (dict, key, volinfo->stripe_count);
if (ret)
goto out;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.replica_count", count);
+ snprintf (key, sizeof (key), "%s%d.replica_count", prefix, count);
ret = dict_set_int32 (dict, key, volinfo->replica_count);
if (ret)
goto out;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.dist_count", count);
+ snprintf (key, sizeof (key), "%s%d.dist_count", prefix, count);
ret = dict_set_int32 (dict, key, volinfo->dist_leaf_count);
if (ret)
goto out;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.ckusm", count);
+ snprintf (key, sizeof (key), "%s%d.ckusm", prefix, count);
ret = dict_set_int64 (dict, key, volinfo->cksum);
if (ret)
goto out;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.transport_type", count);
+ snprintf (key, sizeof (key), "%s%d.transport_type", prefix, count);
ret = dict_set_uint32 (dict, key, volinfo->transport_type);
if (ret)
goto out;
- snprintf (key, sizeof (key), "volume%d.is_snap_volume", count);
+ snprintf (key, sizeof (key), "%s%d.is_snap_volume", prefix, count);
ret = dict_set_uint32 (dict, key, volinfo->is_snap_volume);
if (ret) {
gf_log (THIS->name, GF_LOG_ERROR, "Unable to set %s", key);
goto out;
}
- snprintf (key, sizeof (key), "volume%d.snap-max-hard-limit", count);
+ snprintf (key, sizeof (key), "%s%d.snap-max-hard-limit", prefix, count);
ret = dict_set_uint64 (dict, key, volinfo->snap_max_hard_limit);
if (ret) {
gf_log (THIS->name, GF_LOG_ERROR, "Unable to set %s", key);
@@ -2358,14 +2375,14 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
goto out;
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.volume_id", count);
+ snprintf (key, sizeof (key), "%s%d.volume_id", prefix, count);
ret = dict_set_dynstr (dict, key, volume_id_str);
if (ret)
goto out;
volume_id_str = NULL;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.username", count);
+ snprintf (key, sizeof (key), "%s%d.username", prefix, count);
str = glusterd_auth_get_username (volinfo);
if (str) {
ret = dict_set_dynstr (dict, key, gf_strdup (str));
@@ -2374,7 +2391,7 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.password", count);
+ snprintf (key, sizeof (key), "%s%d.password", prefix, count);
str = glusterd_auth_get_password (volinfo);
if (str) {
ret = dict_set_dynstr (dict, key, gf_strdup (str));
@@ -2383,7 +2400,7 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
}
memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d.rebalance", count);
+ snprintf (key, 256, "%s%d.rebalance", prefix, count);
ret = dict_set_int32 (dict, key, volinfo->rebal.defrag_cmd);
if (ret)
goto out;
@@ -2395,22 +2412,22 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
goto out;
}
memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d.rebalance-id", count);
+ snprintf (key, 256, "%s%d.rebalance-id", prefix, count);
ret = dict_set_dynstr (dict, key, rebalance_id_str);
if (ret)
goto out;
rebalance_id_str = NULL;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.rebalance-op", count);
+ snprintf (key, sizeof (key), "%s%d.rebalance-op", prefix, count);
ret = dict_set_uint32 (dict, key, volinfo->rebal.op);
if (ret)
goto out;
if (volinfo->rebal.dict) {
- snprintf (prefix, sizeof (prefix), "volume%d", count);
+ snprintf (pfx, sizeof (pfx), "%s%d", prefix, count);
ctx.dict = dict;
- ctx.prefix = prefix;
+ ctx.prefix = pfx;
ctx.opt_count = 1;
ctx.key_name = "rebal-dict-key";
ctx.val_name = "rebal-dict-value";
@@ -2425,7 +2442,7 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
}
memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d."GLUSTERD_STORE_KEY_RB_STATUS, count);
+ snprintf (key, 256, "%s%d."GLUSTERD_STORE_KEY_RB_STATUS, prefix, count);
ret = dict_set_int32 (dict, key, volinfo->rep_brick.rb_status);
if (ret)
goto out;
@@ -2433,8 +2450,8 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
if (volinfo->rep_brick.rb_status > GF_RB_STATUS_NONE) {
memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d."GLUSTERD_STORE_KEY_RB_SRC_BRICK,
- count);
+ snprintf (key, 256, "%s%d."GLUSTERD_STORE_KEY_RB_SRC_BRICK,
+ prefix, count);
gf_asprintf (&src_brick, "%s:%s",
volinfo->rep_brick.src_brick->hostname,
volinfo->rep_brick.src_brick->path);
@@ -2443,8 +2460,8 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
goto out;
memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d."GLUSTERD_STORE_KEY_RB_DST_BRICK,
- count);
+ snprintf (key, 256, "%s%d."GLUSTERD_STORE_KEY_RB_DST_BRICK,
+ prefix, count);
gf_asprintf (&dst_brick, "%s:%s",
volinfo->rep_brick.dst_brick->hostname,
volinfo->rep_brick.dst_brick->path);
@@ -2459,16 +2476,16 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.rb_id", count);
+ snprintf (key, sizeof (key), "%s%d.rb_id", prefix, count);
ret = dict_set_dynstr (dict, key, rb_id_str);
if (ret)
goto out;
rb_id_str = NULL;
}
- snprintf (prefix, sizeof (prefix), "volume%d", count);
+ snprintf (pfx, sizeof (pfx), "%s%d", prefix, count);
ctx.dict = dict;
- ctx.prefix = prefix;
+ ctx.prefix = pfx;
ctx.opt_count = 1;
ctx.key_name = "key";
ctx.val_name = "value";
@@ -2477,13 +2494,13 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
dict_foreach (volinfo->dict, _add_dict_to_prdict, &ctx);
ctx.opt_count--;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.opt-count", count);
+ snprintf (key, sizeof (key), "%s%d.opt-count", prefix, count);
ret = dict_set_int32 (dict, key, ctx.opt_count);
if (ret)
goto out;
ctx.dict = dict;
- ctx.prefix = prefix;
+ ctx.prefix = pfx;
ctx.opt_count = 1;
ctx.key_name = "slave-num";
ctx.val_name = "slave-val";
@@ -2493,42 +2510,42 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
ctx.opt_count--;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.gsync-count", count);
+ snprintf (key, sizeof (key), "%s%d.gsync-count", prefix, count);
ret = dict_set_int32 (dict, key, ctx.opt_count);
if (ret)
goto out;
list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.brick%d.hostname",
- count, i);
+ snprintf (key, sizeof (key), "%s%d.brick%d.hostname",
+ prefix, count, i);
ret = dict_set_str (dict, key, brickinfo->hostname);
if (ret)
goto out;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.brick%d.path",
- count, i);
+ snprintf (key, sizeof (key), "%s%d.brick%d.path",
+ prefix, count, i);
ret = dict_set_str (dict, key, brickinfo->path);
if (ret)
goto out;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.brick%d.decommissioned",
- count, i);
+ snprintf (key, sizeof (key), "%s%d.brick%d.decommissioned",
+ prefix, count, i);
ret = dict_set_int32 (dict, key, brickinfo->decommissioned);
if (ret)
goto out;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.brick%d.brick_id",
- count, i);
+ snprintf (key, sizeof (key), "%s%d.brick%d.brick_id",
+ prefix, count, i);
ret = dict_set_str (dict, key, brickinfo->brick_id);
if (ret)
goto out;
- snprintf (key, sizeof (key), "volume%d.brick%d.snap_status",
- count, i);
+ snprintf (key, sizeof (key), "%s%d.brick%d.snap_status",
+ prefix, count, i);
ret = dict_set_int32 (dict, key, brickinfo->snap_status);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
@@ -2538,8 +2555,8 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
goto out;
}
- snprintf (key, sizeof (key), "volume%d.brick%d.device_path",
- count, i);
+ snprintf (key, sizeof (key), "%s%d.brick%d.device_path",
+ prefix, count, i);
ret = dict_set_str (dict, key, brickinfo->device_path);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
@@ -2556,19 +2573,19 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
* in the cluster
*/
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.op-version", count);
+ snprintf (key, sizeof (key), "%s%d.op-version", prefix, count);
ret = dict_set_int32 (dict, key, volinfo->op_version);
if (ret)
goto out;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.client-op-version", count);
+ snprintf (key, sizeof (key), "%s%d.client-op-version", prefix, count);
ret = dict_set_int32 (dict, key, volinfo->client_op_version);
if (ret)
goto out;
/*Add volume Capability (BD Xlator) to dict*/
memset (key, 0 ,sizeof (key));
- snprintf (key, sizeof (key), "volume%d.caps", count);
+ snprintf (key, sizeof (key), "%s%d.caps", prefix, count);
ret = dict_set_int32 (dict, key, volinfo->caps);
out:
@@ -2576,14 +2593,17 @@ out:
GF_FREE (rebalance_id_str);
GF_FREE (rb_id_str);
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
+ gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret);
return ret;
}
+/* The prefix represents the type of volume to be added.
+ * It will be "volume" for normal volumes, and snap# like
+ * snap1, snap2, for snapshot volumes
+ */
int
glusterd_vol_add_quota_conf_to_dict (glusterd_volinfo_t *volinfo, dict_t* load,
- int vol_idx)
+ int vol_idx, char *prefix)
{
int fd = -1;
char *gfid_str = NULL;
@@ -2595,6 +2615,7 @@ glusterd_vol_add_quota_conf_to_dict (glusterd_volinfo_t *volinfo, dict_t* load,
this = THIS;
GF_ASSERT (this);
+ GF_ASSERT (prefix);
ret = glusterd_store_create_quota_conf_sh_on_absence (volinfo);
if (ret)
@@ -2631,8 +2652,8 @@ glusterd_vol_add_quota_conf_to_dict (glusterd_volinfo_t *volinfo, dict_t* load,
goto out;
}
- snprintf (key, sizeof(key)-1, "volume%d.gfid%d", vol_idx,
- gfid_idx);
+ snprintf (key, sizeof(key)-1, "%s%d.gfid%d", prefix,
+ vol_idx, gfid_idx);
key[sizeof(key)-1] = '\0';
ret = dict_set_dynstr (load, key, gfid_str);
if (ret) {
@@ -2642,19 +2663,19 @@ glusterd_vol_add_quota_conf_to_dict (glusterd_volinfo_t *volinfo, dict_t* load,
gfid_str = NULL;
}
- snprintf (key, sizeof(key)-1, "volume%d.gfid-count", vol_idx);
+ snprintf (key, sizeof(key)-1, "%s%d.gfid-count", prefix, vol_idx);
key[sizeof(key)-1] = '\0';
ret = dict_set_int32 (load, key, gfid_idx);
if (ret)
goto out;
- snprintf (key, sizeof(key)-1, "volume%d.quota-cksum", vol_idx);
+ snprintf (key, sizeof(key)-1, "%s%d.quota-cksum", prefix, vol_idx);
key[sizeof(key)-1] = '\0';
ret = dict_set_uint32 (load, key, volinfo->quota_conf_cksum);
if (ret)
goto out;
- snprintf (key, sizeof(key)-1, "volume%d.quota-version", vol_idx);
+ snprintf (key, sizeof(key)-1, "%s%d.quota-version", prefix, vol_idx);
key[sizeof(key)-1] = '\0';
ret = dict_set_uint32 (load, key, volinfo->quota_conf_version);
if (ret)
@@ -2669,7 +2690,237 @@ out:
}
int32_t
-glusterd_build_volume_dict (dict_t **vols)
+glusterd_add_missed_snaps_to_export_dict (dict_t *peer_data)
+{
+ char name_buf[PATH_MAX] = "";
+ char value[PATH_MAX] = "";
+ int32_t missed_snap_count = 0;
+ int32_t ret = -1;
+ glusterd_conf_t *priv = NULL;
+ glusterd_missed_snap_info *missed_snapinfo = NULL;
+ glusterd_snap_op_t *snap_opinfo = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ GF_ASSERT (peer_data);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ /* Add the missed_entries in the dict */
+ list_for_each_entry (missed_snapinfo, &priv->missed_snaps_list,
+ missed_snaps) {
+ list_for_each_entry (snap_opinfo,
+ &missed_snapinfo->snap_ops,
+ snap_ops_list) {
+ snprintf (name_buf, sizeof(name_buf),
+ "missed_snaps_%d", missed_snap_count);
+ snprintf (value, sizeof(value), "%s:%s=%s:%d:%s:%d:%d",
+ missed_snapinfo->node_uuid,
+ missed_snapinfo->snap_uuid,
+ snap_opinfo->snap_vol_id,
+ snap_opinfo->brick_num,
+ snap_opinfo->brick_path,
+ snap_opinfo->op,
+ snap_opinfo->status);
+
+ ret = dict_set_dynstr_with_alloc (peer_data, name_buf,
+ value);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set %s",
+ name_buf);
+ goto out;
+ }
+ missed_snap_count++;
+ }
+ }
+
+ ret = dict_set_int32 (peer_data, "missed_snap_count",
+ missed_snap_count);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set missed_snap_count");
+ goto out;
+ }
+
+out:
+ gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
+}
+
+int32_t
+glusterd_add_snap_to_dict (glusterd_snap_t *snap, dict_t *peer_data,
+ int32_t snap_count)
+{
+ char buf[NAME_MAX] = "";
+ char prefix[NAME_MAX] = "";
+ int32_t ret = -1;
+ int32_t volcount = 0;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ gf_boolean_t host_bricks = _gf_false;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ GF_ASSERT (snap);
+ GF_ASSERT (peer_data);
+
+ snprintf (prefix, sizeof(prefix), "snap%d", snap_count);
+
+ list_for_each_entry (volinfo, &snap->volumes, vol_list) {
+ volcount++;
+ ret = glusterd_add_volume_to_dict (volinfo, peer_data,
+ volcount, prefix);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to add snap:%s volume:%s "
+ "to peer_data dict for handshake",
+ snap->snapname, volinfo->volname);
+ goto out;
+ }
+
+ ret = glusterd_vol_add_quota_conf_to_dict (volinfo, peer_data,
+ volcount, prefix);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to add quota conf for "
+ "snap:%s volume:%s to peer_data "
+ "dict for handshake", snap->snapname,
+ volinfo->volname);
+ goto out;
+ }
+
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ if (!uuid_compare (brickinfo->uuid, MY_UUID)) {
+ host_bricks = _gf_true;
+ break;
+ }
+ }
+ }
+
+ snprintf (buf, sizeof(buf), "%s.host_bricks", prefix);
+ ret = dict_set_int8 (peer_data, buf, (int8_t) host_bricks);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set host_bricks for snap %s",
+ snap->snapname);
+ goto out;
+ }
+
+ snprintf (buf, sizeof(buf), "%s.volcount", prefix);
+ ret = dict_set_int32 (peer_data, buf, volcount);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set volcount for snap %s",
+ snap->snapname);
+ goto out;
+ }
+
+ snprintf (buf, sizeof(buf), "%s.snapname", prefix);
+ ret = dict_set_dynstr_with_alloc (peer_data, buf, snap->snapname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set snapname for snap %s",
+ snap->snapname);
+ goto out;
+ }
+
+ snprintf (buf, sizeof(buf), "%s.snap_id", prefix);
+ ret = dict_set_dynstr_with_alloc (peer_data, buf,
+ uuid_utoa (snap->snap_id));
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set snap_id for snap %s",
+ snap->snapname);
+ goto out;
+ }
+
+ if (snap->description) {
+ snprintf (buf, sizeof(buf), "%s.snapid", prefix);
+ ret = dict_set_dynstr_with_alloc (peer_data, buf,
+ snap->description);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set description for snap %s",
+ snap->snapname);
+ goto out;
+ }
+ }
+
+ snprintf (buf, sizeof(buf), "%s.time_stamp", prefix);
+ ret = dict_set_int64 (peer_data, buf, (int64_t)snap->time_stamp);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set time_stamp for snap %s",
+ snap->snapname);
+ goto out;
+ }
+
+ snprintf (buf, sizeof(buf), "%s.snap_restored", prefix);
+ ret = dict_set_int8 (peer_data, buf, snap->snap_restored);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set snap_restored for snap %s",
+ snap->snapname);
+ goto out;
+ }
+
+ snprintf (buf, sizeof(buf), "%s.snap_status", prefix);
+ ret = dict_set_int32 (peer_data, buf, snap->snap_status);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set snap_status for snap %s",
+ snap->snapname);
+ goto out;
+ }
+out:
+ gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
+}
+
+int32_t
+glusterd_add_snapshots_to_export_dict (dict_t *peer_data)
+{
+ int32_t snap_count = 0;
+ int32_t ret = -1;
+ glusterd_conf_t *priv = NULL;
+ glusterd_snap_t *snap = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+ GF_ASSERT (peer_data);
+
+ list_for_each_entry (snap, &priv->snapshots, snap_list) {
+ snap_count++;
+ ret = glusterd_add_snap_to_dict (snap, peer_data, snap_count);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to add snap(%s) to the "
+ " peer_data dict for handshake",
+ snap->snapname);
+ goto out;
+ }
+ }
+
+ ret = dict_set_int32 (peer_data, "snap_count", snap_count);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set snap_count");
+ goto out;
+ }
+
+out:
+ gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
+}
+
+int32_t
+glusterd_add_volumes_to_export_dict (dict_t **peer_data)
{
int32_t ret = -1;
dict_t *dict = NULL;
@@ -2677,27 +2928,31 @@ glusterd_build_volume_dict (dict_t **vols)
glusterd_volinfo_t *volinfo = NULL;
int32_t count = 0;
glusterd_dict_ctx_t ctx = {0};
+ xlator_t *this = NULL;
- priv = THIS->private;
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
dict = dict_new ();
-
if (!dict)
goto out;
list_for_each_entry (volinfo, &priv->volumes, vol_list) {
count++;
- ret = glusterd_add_volume_to_dict (volinfo, dict, count);
+ ret = glusterd_add_volume_to_dict (volinfo, dict, count,
+ "volume");
if (ret)
goto out;
if (!glusterd_is_volume_quota_enabled (volinfo))
continue;
- ret = glusterd_vol_add_quota_conf_to_dict (volinfo, dict, count);
+ ret = glusterd_vol_add_quota_conf_to_dict (volinfo, dict,
+ count, "volume");
if (ret)
goto out;
}
-
ret = dict_set_int32 (dict, "count", count);
if (ret)
goto out;
@@ -2713,18 +2968,18 @@ glusterd_build_volume_dict (dict_t **vols)
if (ret)
goto out;
- *vols = dict;
+ *peer_data = dict;
out:
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
if (ret)
dict_unref (dict);
+ gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
return ret;
}
int32_t
-glusterd_compare_friend_volume (dict_t *vols, int32_t count, int32_t *status,
- char *hostname)
+glusterd_compare_friend_volume (dict_t *peer_data, int32_t count,
+ int32_t *status, char *hostname)
{
int32_t ret = -1;
@@ -2737,14 +2992,14 @@ glusterd_compare_friend_volume (dict_t *vols, int32_t count, int32_t *status,
int32_t version = 0;
xlator_t *this = NULL;
- GF_ASSERT (vols);
+ GF_ASSERT (peer_data);
GF_ASSERT (status);
this = THIS;
GF_ASSERT (this);
snprintf (key, sizeof (key), "volume%d.name", count);
- ret = dict_get_str (vols, key, &volname);
+ ret = dict_get_str (peer_data, key, &volname);
if (ret)
goto out;
@@ -2758,7 +3013,7 @@ glusterd_compare_friend_volume (dict_t *vols, int32_t count, int32_t *status,
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "volume%d.version", count);
- ret = dict_get_int32 (vols, key, &version);
+ ret = dict_get_int32 (peer_data, key, &version);
if (ret)
goto out;
@@ -2779,7 +3034,7 @@ glusterd_compare_friend_volume (dict_t *vols, int32_t count, int32_t *status,
//
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "volume%d.ckusm", count);
- ret = dict_get_uint32 (vols, key, &cksum);
+ ret = dict_get_uint32 (peer_data, key, &cksum);
if (ret)
goto out;
@@ -2794,7 +3049,7 @@ glusterd_compare_friend_volume (dict_t *vols, int32_t count, int32_t *status,
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "volume%d.quota-version", count);
- ret = dict_get_uint32 (vols, key, &quota_version);
+ ret = dict_get_uint32 (peer_data, key, &quota_version);
if (ret) {
gf_log (this->name, GF_LOG_DEBUG, "quota-version key absent for"
" volume %s in peer %s's response", volinfo->volname,
@@ -2822,7 +3077,7 @@ glusterd_compare_friend_volume (dict_t *vols, int32_t count, int32_t *status,
//
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "volume%d.quota-cksum", count);
- ret = dict_get_uint32 (vols, key, &quota_cksum);
+ ret = dict_get_uint32 (peer_data, key, &quota_cksum);
if (ret) {
gf_log (this->name, GF_LOG_DEBUG, "quota checksum absent for "
"volume %s in peer %s's response", volinfo->volname,
@@ -2850,7 +3105,7 @@ out:
}
static int32_t
-import_prdict_dict (dict_t *vols, dict_t *dst_dict, char *key_prefix,
+import_prdict_dict (dict_t *peer_data, dict_t *dst_dict, char *key_prefix,
char *value_prefix, int opt_count, char *prefix)
{
char key[512] = {0,};
@@ -2865,7 +3120,7 @@ import_prdict_dict (dict_t *vols, dict_t *dst_dict, char *key_prefix,
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "%s.%s%d",
prefix, key_prefix, i);
- ret = dict_get_str (vols, key, &opt_key);
+ ret = dict_get_str (peer_data, key, &opt_key);
if (ret) {
snprintf (msg, sizeof (msg), "Volume dict key not "
"specified");
@@ -2875,7 +3130,7 @@ import_prdict_dict (dict_t *vols, dict_t *dst_dict, char *key_prefix,
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "%s.%s%d",
prefix, value_prefix, i);
- ret = dict_get_str (vols, key, &opt_val);
+ ret = dict_get_str (peer_data, key, &opt_val);
if (ret) {
snprintf (msg, sizeof (msg), "Volume dict value not "
"specified");
@@ -3163,7 +3418,7 @@ out:
}
int32_t
-glusterd_import_friend_volume_opts (dict_t *vols, int count,
+glusterd_import_friend_volume_opts (dict_t *peer_data, int count,
glusterd_volinfo_t *volinfo)
{
char key[512] = {0,};
@@ -3172,9 +3427,12 @@ glusterd_import_friend_volume_opts (dict_t *vols, int count,
char msg[2048] = {0};
char volume_prefix[1024] = {0};
+ GF_ASSERT (peer_data);
+ GF_ASSERT (volinfo);
+
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "volume%d.opt-count", count);
- ret = dict_get_int32 (vols, key, &opt_count);
+ ret = dict_get_int32 (peer_data, key, &opt_count);
if (ret) {
snprintf (msg, sizeof (msg), "Volume option count not "
"specified for %s", volinfo->volname);
@@ -3182,7 +3440,7 @@ glusterd_import_friend_volume_opts (dict_t *vols, int count,
}
snprintf (volume_prefix, sizeof (volume_prefix), "volume%d", count);
- ret = import_prdict_dict (vols, volinfo->dict, "key", "value",
+ ret = import_prdict_dict (peer_data, volinfo->dict, "key", "value",
opt_count, volume_prefix);
if (ret) {
snprintf (msg, sizeof (msg), "Unable to import options dict "
@@ -3192,14 +3450,14 @@ glusterd_import_friend_volume_opts (dict_t *vols, int count,
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "volume%d.gsync-count", count);
- ret = dict_get_int32 (vols, key, &opt_count);
+ ret = dict_get_int32 (peer_data, key, &opt_count);
if (ret) {
snprintf (msg, sizeof (msg), "Gsync count not "
"specified for %s", volinfo->volname);
goto out;
}
- ret = import_prdict_dict (vols, volinfo->gsync_slaves, "slave-num",
+ ret = import_prdict_dict (peer_data, volinfo->gsync_slaves, "slave-num",
"slave-val", opt_count, volume_prefix);
if (ret) {
snprintf (msg, sizeof (msg), "Unable to import gsync sessions "
@@ -3214,10 +3472,15 @@ out:
return ret;
}
+/* The prefix represents the type of volume to be added.
+ * It will be "volume" for normal volumes, and snap# like
+ * snap1, snap2, for snapshot volumes
+ */
int32_t
-glusterd_import_new_brick (dict_t *vols, int32_t vol_count,
+glusterd_import_new_brick (dict_t *peer_data, int32_t vol_count,
int32_t brick_count,
- glusterd_brickinfo_t **brickinfo)
+ glusterd_brickinfo_t **brickinfo,
+ char *prefix)
{
char key[512] = {0,};
int ret = -1;
@@ -3230,53 +3493,54 @@ glusterd_import_new_brick (dict_t *vols, int32_t vol_count,
glusterd_brickinfo_t *new_brickinfo = NULL;
char msg[2048] = {0};
- GF_ASSERT (vols);
+ GF_ASSERT (peer_data);
GF_ASSERT (vol_count >= 0);
GF_ASSERT (brickinfo);
+ GF_ASSERT (prefix);
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.brick%d.hostname",
- vol_count, brick_count);
- ret = dict_get_str (vols, key, &hostname);
+ snprintf (key, sizeof (key), "%s%d.brick%d.hostname",
+ prefix, vol_count, brick_count);
+ ret = dict_get_str (peer_data, key, &hostname);
if (ret) {
snprintf (msg, sizeof (msg), "%s missing in payload", key);
goto out;
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.brick%d.path",
- vol_count, brick_count);
- ret = dict_get_str (vols, key, &path);
+ snprintf (key, sizeof (key), "%s%d.brick%d.path",
+ prefix, vol_count, brick_count);
+ ret = dict_get_str (peer_data, key, &path);
if (ret) {
snprintf (msg, sizeof (msg), "%s missing in payload", key);
goto out;
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.brick%d.brick_id",
- vol_count, brick_count);
- ret = dict_get_str (vols, key, &brick_id);
+ snprintf (key, sizeof (key), "%s%d.brick%d.brick_id",
+ prefix, vol_count, brick_count);
+ ret = dict_get_str (peer_data, key, &brick_id);
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.brick%d.decommissioned",
- vol_count, brick_count);
- ret = dict_get_int32 (vols, key, &decommissioned);
+ snprintf (key, sizeof (key), "%s%d.brick%d.decommissioned",
+ prefix, vol_count, brick_count);
+ ret = dict_get_int32 (peer_data, key, &decommissioned);
if (ret) {
/* For backward compatibility */
ret = 0;
}
- snprintf (key, sizeof (key), "volume%d.brick%d.snap_status",
- vol_count, brick_count);
- ret = dict_get_int32 (vols, key, &snap_status);
+ snprintf (key, sizeof (key), "%s%d.brick%d.snap_status",
+ prefix, vol_count, brick_count);
+ ret = dict_get_int32 (peer_data, key, &snap_status);
if (ret) {
snprintf (msg, sizeof (msg), "%s missing in payload", key);
goto out;
}
- snprintf (key, sizeof (key), "volume%d.brick%d.device_path",
- vol_count, brick_count);
- ret = dict_get_str (vols, key, &snap_device);
+ snprintf (key, sizeof (key), "%s%d.brick%d.device_path",
+ prefix, vol_count, brick_count);
+ ret = dict_get_str (peer_data, key, &snap_device);
if (ret) {
snprintf (msg, sizeof (msg), "%s missing in payload", key);
goto out;
@@ -3304,22 +3568,28 @@ out:
return ret;
}
+/* The prefix represents the type of volume to be added.
+ * It will be "volume" for normal volumes, and snap# like
+ * snap1, snap2, for snapshot volumes
+ */
int32_t
-glusterd_import_bricks (dict_t *vols, int32_t vol_count,
- glusterd_volinfo_t *new_volinfo)
+glusterd_import_bricks (dict_t *peer_data, int32_t vol_count,
+ glusterd_volinfo_t *new_volinfo, char *prefix)
{
int ret = -1;
int brick_count = 1;
int brickid = 0;
glusterd_brickinfo_t *new_brickinfo = NULL;
- GF_ASSERT (vols);
+ GF_ASSERT (peer_data);
GF_ASSERT (vol_count >= 0);
GF_ASSERT (new_volinfo);
+ GF_ASSERT (prefix);
while (brick_count <= new_volinfo->brick_count) {
- ret = glusterd_import_new_brick (vols, vol_count, brick_count,
- &new_brickinfo);
+ ret = glusterd_import_new_brick (peer_data, vol_count,
+ brick_count,
+ &new_brickinfo, prefix);
if (ret)
goto out;
if (new_brickinfo->brick_id[0] == '\0')
@@ -3337,9 +3607,14 @@ out:
return ret;
}
+/* The prefix represents the type of volume to be added.
+ * It will be "volume" for normal volumes, and snap# like
+ * snap1, snap2, for snapshot volumes
+ */
static int
-glusterd_import_quota_conf (dict_t *vols, int vol_idx,
- glusterd_volinfo_t *new_volinfo)
+glusterd_import_quota_conf (dict_t *peer_data, int vol_idx,
+ glusterd_volinfo_t *new_volinfo,
+ char *prefix)
{
int gfid_idx = 0;
int gfid_count = 0;
@@ -3352,6 +3627,8 @@ glusterd_import_quota_conf (dict_t *vols, int vol_idx,
this = THIS;
GF_ASSERT (this);
+ GF_ASSERT (peer_data);
+ GF_ASSERT (prefix);
if (!glusterd_is_volume_quota_enabled (new_volinfo)) {
(void) glusterd_clean_up_quota_store (new_volinfo);
@@ -3368,22 +3645,23 @@ glusterd_import_quota_conf (dict_t *vols, int vol_idx,
goto out;
}
- snprintf (key, sizeof (key)-1, "volume%d.quota-cksum", vol_idx);
+ snprintf (key, sizeof (key)-1, "%s%d.quota-cksum", prefix, vol_idx);
key[sizeof(key)-1] = '\0';
- ret = dict_get_uint32 (vols, key, &new_volinfo->quota_conf_cksum);
+ ret = dict_get_uint32 (peer_data, key, &new_volinfo->quota_conf_cksum);
if (ret)
gf_log (this->name, GF_LOG_DEBUG, "Failed to get quota cksum");
- snprintf (key, sizeof (key)-1, "volume%d.quota-version", vol_idx);
+ snprintf (key, sizeof (key)-1, "%s%d.quota-version", prefix, vol_idx);
key[sizeof(key)-1] = '\0';
- ret = dict_get_uint32 (vols, key, &new_volinfo->quota_conf_version);
+ ret = dict_get_uint32 (peer_data, key,
+ &new_volinfo->quota_conf_version);
if (ret)
gf_log (this->name, GF_LOG_DEBUG, "Failed to get quota "
"version");
- snprintf (key, sizeof (key)-1, "volume%d.gfid-count", vol_idx);
+ snprintf (key, sizeof (key)-1, "%s%d.gfid-count", prefix, vol_idx);
key[sizeof(key)-1] = '\0';
- ret = dict_get_int32 (vols, key, &gfid_count);
+ ret = dict_get_int32 (peer_data, key, &gfid_count);
if (ret)
goto out;
@@ -3397,10 +3675,10 @@ glusterd_import_quota_conf (dict_t *vols, int vol_idx,
gfid_idx = 0;
for (gfid_idx = 0; gfid_idx < gfid_count; gfid_idx++) {
- snprintf (key, sizeof (key)-1, "volume%d.gfid%d",
- vol_idx, gfid_idx);
+ snprintf (key, sizeof (key)-1, "%s%d.gfid%d",
+ prefix, vol_idx, gfid_idx);
key[sizeof(key)-1] = '\0';
- ret = dict_get_str (vols, key, &gfid_str);
+ ret = dict_get_str (peer_data, key, &gfid_str);
if (ret)
goto out;
@@ -3481,15 +3759,22 @@ out:
return ret;
}
+/* The prefix represents the type of volume to be added.
+ * It will be "volume" for normal volumes, and snap# like
+ * snap1, snap2, for snapshot volumes
+ */
int32_t
-glusterd_import_volinfo (dict_t *vols, int count,
- glusterd_volinfo_t **volinfo)
+glusterd_import_volinfo (dict_t *peer_data, int count,
+ glusterd_volinfo_t **volinfo,
+ char *prefix)
{
int ret = -1;
char key[256] = {0};
+ char *parent_volname = NULL;
char *volname = NULL;
glusterd_volinfo_t *new_volinfo = NULL;
char *volume_id_str = NULL;
+ char *restored_snap = NULL;
char msg[2048] = {0};
char *src_brick = NULL;
char *dst_brick = NULL;
@@ -3501,50 +3786,49 @@ glusterd_import_volinfo (dict_t *vols, int count,
int client_op_version = 0;
uint32_t is_snap_volume = 0;
- GF_ASSERT (vols);
+ GF_ASSERT (peer_data);
GF_ASSERT (volinfo);
+ GF_ASSERT (prefix);
- snprintf (key, sizeof (key), "volume%d.name", count);
- ret = dict_get_str (vols, key, &volname);
+ snprintf (key, sizeof (key), "%s%d.name", prefix, count);
+ ret = dict_get_str (peer_data, key, &volname);
if (ret) {
snprintf (msg, sizeof (msg), "%s missing in payload", key);
goto out;
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.is_snap_volume", count);
- ret = dict_get_uint32 (vols, key, &is_snap_volume);
+ snprintf (key, sizeof (key), "%s%d.is_snap_volume", prefix, count);
+ ret = dict_get_uint32 (peer_data, key, &is_snap_volume);
if (ret) {
snprintf (msg, sizeof (msg), "%s missing in payload for %s",
key, volname);
goto out;
}
- if (is_snap_volume == _gf_true) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "Not syncing snap volume %s", volname);
- ret = 0;
- goto out;
- }
-
ret = glusterd_volinfo_new (&new_volinfo);
if (ret)
goto out;
strncpy (new_volinfo->volname, volname, sizeof (new_volinfo->volname));
-
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.type", count);
- ret = dict_get_int32 (vols, key, &new_volinfo->type);
+ snprintf (key, sizeof (key), "%s%d.type", prefix, count);
+ ret = dict_get_int32 (peer_data, key, &new_volinfo->type);
if (ret) {
snprintf (msg, sizeof (msg), "%s missing in payload for %s",
key, volname);
goto out;
}
+ snprintf (key, sizeof (key), "%s%d.parent_volname", prefix, count);
+ ret = dict_get_str (peer_data, key, &parent_volname);
+ if (!ret)
+ strncpy (new_volinfo->parent_volname, parent_volname,
+ sizeof(new_volinfo->parent_volname));
+
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.brick_count", count);
- ret = dict_get_int32 (vols, key, &new_volinfo->brick_count);
+ snprintf (key, sizeof (key), "%s%d.brick_count", prefix, count);
+ ret = dict_get_int32 (peer_data, key, &new_volinfo->brick_count);
if (ret) {
snprintf (msg, sizeof (msg), "%s missing in payload for %s",
key, volname);
@@ -3552,8 +3836,8 @@ glusterd_import_volinfo (dict_t *vols, int count,
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.version", count);
- ret = dict_get_int32 (vols, key, &new_volinfo->version);
+ snprintf (key, sizeof (key), "%s%d.version", prefix, count);
+ ret = dict_get_int32 (peer_data, key, &new_volinfo->version);
if (ret) {
snprintf (msg, sizeof (msg), "%s missing in payload for %s",
key, volname);
@@ -3561,8 +3845,8 @@ glusterd_import_volinfo (dict_t *vols, int count,
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.status", count);
- ret = dict_get_int32 (vols, key, (int32_t *)&new_volinfo->status);
+ snprintf (key, sizeof (key), "%s%d.status", prefix, count);
+ ret = dict_get_int32 (peer_data, key, (int32_t *)&new_volinfo->status);
if (ret) {
snprintf (msg, sizeof (msg), "%s missing in payload for %s",
key, volname);
@@ -3570,8 +3854,8 @@ glusterd_import_volinfo (dict_t *vols, int count,
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.sub_count", count);
- ret = dict_get_int32 (vols, key, &new_volinfo->sub_count);
+ snprintf (key, sizeof (key), "%s%d.sub_count", prefix, count);
+ ret = dict_get_int32 (peer_data, key, &new_volinfo->sub_count);
if (ret) {
snprintf (msg, sizeof (msg), "%s missing in payload for %s",
key, volname);
@@ -3581,8 +3865,8 @@ glusterd_import_volinfo (dict_t *vols, int count,
/* not having a 'stripe_count' key is not a error
(as peer may be of old version) */
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.stripe_count", count);
- ret = dict_get_int32 (vols, key, &new_volinfo->stripe_count);
+ snprintf (key, sizeof (key), "%s%d.stripe_count", prefix, count);
+ ret = dict_get_int32 (peer_data, key, &new_volinfo->stripe_count);
if (ret)
gf_log (THIS->name, GF_LOG_INFO,
"peer is possibly old version");
@@ -3590,8 +3874,8 @@ glusterd_import_volinfo (dict_t *vols, int count,
/* not having a 'replica_count' key is not a error
(as peer may be of old version) */
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.replica_count", count);
- ret = dict_get_int32 (vols, key, &new_volinfo->replica_count);
+ snprintf (key, sizeof (key), "%s%d.replica_count", prefix, count);
+ ret = dict_get_int32 (peer_data, key, &new_volinfo->replica_count);
if (ret)
gf_log (THIS->name, GF_LOG_INFO,
"peer is possibly old version");
@@ -3599,16 +3883,16 @@ glusterd_import_volinfo (dict_t *vols, int count,
/* not having a 'dist_count' key is not a error
(as peer may be of old version) */
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.dist_count", count);
- ret = dict_get_int32 (vols, key, &new_volinfo->dist_leaf_count);
+ snprintf (key, sizeof (key), "%s%d.dist_count", prefix, count);
+ ret = dict_get_int32 (peer_data, key, &new_volinfo->dist_leaf_count);
if (ret)
gf_log (THIS->name, GF_LOG_INFO,
"peer is possibly old version");
new_volinfo->subvol_count = new_volinfo->brick_count/
glusterd_get_dist_leaf_count (new_volinfo);
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.ckusm", count);
- ret = dict_get_uint32 (vols, key, &new_volinfo->cksum);
+ snprintf (key, sizeof (key), "%s%d.ckusm", prefix, count);
+ ret = dict_get_uint32 (peer_data, key, &new_volinfo->cksum);
if (ret) {
snprintf (msg, sizeof (msg), "%s missing in payload for %s",
key, volname);
@@ -3616,8 +3900,8 @@ glusterd_import_volinfo (dict_t *vols, int count,
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.volume_id", count);
- ret = dict_get_str (vols, key, &volume_id_str);
+ snprintf (key, sizeof (key), "%s%d.volume_id", prefix, count);
+ ret = dict_get_str (peer_data, key, &volume_id_str);
if (ret) {
snprintf (msg, sizeof (msg), "%s missing in payload for %s",
key, volname);
@@ -3627,8 +3911,8 @@ glusterd_import_volinfo (dict_t *vols, int count,
uuid_parse (volume_id_str, new_volinfo->volume_id);
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.username", count);
- ret = dict_get_str (vols, key, &str);
+ snprintf (key, sizeof (key), "%s%d.username", prefix, count);
+ ret = dict_get_str (peer_data, key, &str);
if (!ret) {
ret = glusterd_auth_set_username (new_volinfo, str);
if (ret)
@@ -3636,8 +3920,8 @@ glusterd_import_volinfo (dict_t *vols, int count,
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.password", count);
- ret = dict_get_str (vols, key, &str);
+ snprintf (key, sizeof (key), "%s%d.password", prefix, count);
+ ret = dict_get_str (peer_data, key, &str);
if (!ret) {
ret = glusterd_auth_set_password (new_volinfo, str);
if (ret)
@@ -3645,8 +3929,8 @@ glusterd_import_volinfo (dict_t *vols, int count,
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.transport_type", count);
- ret = dict_get_uint32 (vols, key, &new_volinfo->transport_type);
+ snprintf (key, sizeof (key), "%s%d.transport_type", prefix, count);
+ ret = dict_get_uint32 (peer_data, key, &new_volinfo->transport_type);
if (ret) {
snprintf (msg, sizeof (msg), "%s missing in payload for %s",
key, volname);
@@ -3655,17 +3939,19 @@ glusterd_import_volinfo (dict_t *vols, int count,
new_volinfo->is_snap_volume = is_snap_volume;
- snprintf (key, sizeof (key), "volume%d.is_volume_restored", count);
- ret = dict_get_uint32 (vols, key, &new_volinfo->is_volume_restored);
+ snprintf (key, sizeof (key), "%s%d.restored_from_snap", prefix, count);
+ ret = dict_get_str (peer_data, key, &restored_snap);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to get "
- "is_volume_restored option for %s",
- volname);
+ snprintf (msg, sizeof (msg), "%s missing in payload for %s",
+ key, volname);
goto out;
}
- snprintf (key, sizeof (key), "volume%d.snap-max-hard-limit", count);
- ret = dict_get_uint64 (vols, key, &new_volinfo->snap_max_hard_limit);
+ uuid_parse (restored_snap, new_volinfo->restored_from_snap);
+
+ snprintf (key, sizeof (key), "%s%d.snap-max-hard-limit", prefix, count);
+ ret = dict_get_uint64 (peer_data, key,
+ &new_volinfo->snap_max_hard_limit);
if (ret) {
snprintf (msg, sizeof (msg), "%s missing in payload for %s",
key, volname);
@@ -3673,8 +3959,8 @@ glusterd_import_volinfo (dict_t *vols, int count,
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.rebalance", count);
- ret = dict_get_uint32 (vols, key, &new_volinfo->rebal.defrag_cmd);
+ snprintf (key, sizeof (key), "%s%d.rebalance", prefix, count);
+ ret = dict_get_uint32 (peer_data, key, &new_volinfo->rebal.defrag_cmd);
if (ret) {
snprintf (msg, sizeof (msg), "%s missing in payload for %s",
key, volname);
@@ -3682,8 +3968,8 @@ glusterd_import_volinfo (dict_t *vols, int count,
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.rebalance-id", count);
- ret = dict_get_str (vols, key, &rebalance_id_str);
+ snprintf (key, sizeof (key), "%s%d.rebalance-id", prefix, count);
+ ret = dict_get_str (peer_data, key, &rebalance_id_str);
if (ret) {
/* This is not present in older glusterfs versions,
* so don't error out
@@ -3694,15 +3980,17 @@ glusterd_import_volinfo (dict_t *vols, int count,
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.rebalance-op", count);
- ret = dict_get_uint32 (vols, key,(uint32_t *) &new_volinfo->rebal.op);
+ snprintf (key, sizeof (key), "%s%d.rebalance-op", prefix, count);
+ ret = dict_get_uint32 (peer_data, key,
+ (uint32_t *) &new_volinfo->rebal.op);
if (ret) {
/* This is not present in older glusterfs versions,
* so don't error out
*/
ret = 0;
}
- ret = gd_import_friend_volume_rebal_dict (vols, count, new_volinfo);
+ ret = gd_import_friend_volume_rebal_dict (peer_data, count,
+ new_volinfo);
if (ret) {
snprintf (msg, sizeof (msg), "Failed to import rebalance dict "
"for volume.");
@@ -3710,8 +3998,8 @@ glusterd_import_volinfo (dict_t *vols, int count,
}
memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d."GLUSTERD_STORE_KEY_RB_STATUS, count);
- ret = dict_get_int32 (vols, key, &rb_status);
+ snprintf (key, 256, "%s%d."GLUSTERD_STORE_KEY_RB_STATUS, prefix, count);
+ ret = dict_get_int32 (peer_data, key, &rb_status);
if (ret)
goto out;
new_volinfo->rep_brick.rb_status = rb_status;
@@ -3719,9 +4007,9 @@ glusterd_import_volinfo (dict_t *vols, int count,
if (new_volinfo->rep_brick.rb_status > GF_RB_STATUS_NONE) {
memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d."GLUSTERD_STORE_KEY_RB_SRC_BRICK,
- count);
- ret = dict_get_str (vols, key, &src_brick);
+ snprintf (key, 256, "%s%d."GLUSTERD_STORE_KEY_RB_SRC_BRICK,
+ prefix, count);
+ ret = dict_get_str (peer_data, key, &src_brick);
if (ret)
goto out;
@@ -3734,9 +4022,9 @@ glusterd_import_volinfo (dict_t *vols, int count,
}
memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d."GLUSTERD_STORE_KEY_RB_DST_BRICK,
- count);
- ret = dict_get_str (vols, key, &dst_brick);
+ snprintf (key, 256, "%s%d."GLUSTERD_STORE_KEY_RB_DST_BRICK,
+ prefix, count);
+ ret = dict_get_str (peer_data, key, &dst_brick);
if (ret)
goto out;
@@ -3749,8 +4037,8 @@ glusterd_import_volinfo (dict_t *vols, int count,
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.rb_id", count);
- ret = dict_get_str (vols, key, &rb_id_str);
+ snprintf (key, sizeof (key), "%s%d.rb_id", prefix, count);
+ ret = dict_get_str (peer_data, key, &rb_id_str);
if (ret) {
/* This is not present in older glusterfs versions,
* so don't error out
@@ -3762,7 +4050,8 @@ glusterd_import_volinfo (dict_t *vols, int count,
}
- ret = glusterd_import_friend_volume_opts (vols, count, new_volinfo);
+ ret = glusterd_import_friend_volume_opts (peer_data, count,
+ new_volinfo);
if (ret)
goto out;
@@ -3775,13 +4064,13 @@ glusterd_import_volinfo (dict_t *vols, int count,
* present. Only one being present is a failure
*/
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.op-version", count);
- ret = dict_get_int32 (vols, key, &op_version);
+ snprintf (key, sizeof (key), "%s%d.op-version", prefix, count);
+ ret = dict_get_int32 (peer_data, key, &op_version);
if (ret)
ret = 0;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.client-op-version", count);
- ret = dict_get_int32 (vols, key, &client_op_version);
+ snprintf (key, sizeof (key), "%s%d.client-op-version", prefix, count);
+ ret = dict_get_int32 (peer_data, key, &client_op_version);
if (ret)
ret = 0;
@@ -3800,11 +4089,11 @@ glusterd_import_volinfo (dict_t *vols, int count,
}
memset (key, 0 ,sizeof (key));
- snprintf (key, sizeof (key), "volume%d.caps", count);
+ snprintf (key, sizeof (key), "%s%d.caps", prefix, count);
/*This is not present in older glusterfs versions, so ignore ret value*/
- ret = dict_get_int32 (vols, key, &new_volinfo->caps);
+ ret = dict_get_int32 (peer_data, key, &new_volinfo->caps);
- ret = glusterd_import_bricks (vols, count, new_volinfo);
+ ret = glusterd_import_bricks (peer_data, count, new_volinfo, prefix);
if (ret)
goto out;
@@ -3881,7 +4170,11 @@ glusterd_volinfo_stop_stale_bricks (glusterd_volinfo_t *new_volinfo,
old_brickinfo->hostname,
old_brickinfo->path,
new_volinfo, &new_brickinfo);
- if (ret) {
+ /* If the brick is stale, i.e it's not a part of the new volume
+ * or if it's part of the new volume and is pending a snap,
+ * then stop the brick process
+ */
+ if (ret || (new_brickinfo->snap_status == -1)) {
/*TODO: may need to switch to 'atomic' flavour of
* brick_stop, once we make peer rpc program also
* synctask enabled*/
@@ -3903,9 +4196,34 @@ int32_t
glusterd_delete_stale_volume (glusterd_volinfo_t *stale_volinfo,
glusterd_volinfo_t *valid_volinfo)
{
+ int32_t ret = -1;
+ glusterd_volinfo_t *temp_volinfo = NULL;
+ glusterd_volinfo_t *voliter = NULL;
+ xlator_t *this = NULL;
+
GF_ASSERT (stale_volinfo);
GF_ASSERT (valid_volinfo);
+ /* Copy snap_volumes list from stale_volinfo to valid_volinfo */
+ valid_volinfo->snap_count = 0;
+ list_for_each_entry_safe (voliter, temp_volinfo,
+ &stale_volinfo->snap_volumes, snapvol_list) {
+ list_add_tail (&voliter->snapvol_list,
+ &valid_volinfo->snap_volumes);
+ valid_volinfo->snap_count++;
+ }
+
+ if ((!uuid_is_null (stale_volinfo->restored_from_snap)) &&
+ (uuid_compare (stale_volinfo->restored_from_snap,
+ valid_volinfo->restored_from_snap))) {
+ ret = glusterd_lvm_snapshot_remove (NULL, stale_volinfo);
+ if (ret) {
+ gf_log(this->name, GF_LOG_WARNING,
+ "Failed to remove lvm snapshot for "
+ "restored volume %s", stale_volinfo->volname);
+ }
+ }
+
/* If stale volume is in started state, copy the port numbers of the
* local bricks if they exist in the valid volume information.
* stop stale bricks. Stale volume information is going to be deleted.
@@ -3992,7 +4310,7 @@ out:
}
int32_t
-glusterd_import_friend_volume (dict_t *vols, size_t count)
+glusterd_import_friend_volume (dict_t *peer_data, size_t count)
{
int32_t ret = -1;
@@ -4001,13 +4319,14 @@ glusterd_import_friend_volume (dict_t *vols, size_t count)
glusterd_volinfo_t *old_volinfo = NULL;
glusterd_volinfo_t *new_volinfo = NULL;
- GF_ASSERT (vols);
+ GF_ASSERT (peer_data);
this = THIS;
GF_ASSERT (this);
priv = this->private;
GF_ASSERT (priv);
- ret = glusterd_import_volinfo (vols, count, &new_volinfo);
+ ret = glusterd_import_volinfo (peer_data, count,
+ &new_volinfo, "volume");
if (ret)
goto out;
@@ -4033,7 +4352,8 @@ glusterd_import_friend_volume (dict_t *vols, size_t count)
if (ret)
goto out;
- ret = glusterd_import_quota_conf (vols, count, new_volinfo);
+ ret = glusterd_import_quota_conf (peer_data, count,
+ new_volinfo, "volume");
if (ret)
goto out;
@@ -4045,20 +4365,20 @@ out:
}
int32_t
-glusterd_import_friend_volumes (dict_t *vols)
+glusterd_import_friend_volumes (dict_t *peer_data)
{
int32_t ret = -1;
int32_t count = 0;
int i = 1;
- GF_ASSERT (vols);
+ GF_ASSERT (peer_data);
- ret = dict_get_int32 (vols, "count", &count);
+ ret = dict_get_int32 (peer_data, "count", &count);
if (ret)
goto out;
while (i <= count) {
- ret = glusterd_import_friend_volume (vols, i);
+ ret = glusterd_import_friend_volume (peer_data, i);
if (ret)
goto out;
i++;
@@ -4159,25 +4479,840 @@ out:
}
int32_t
-glusterd_compare_friend_data (dict_t *vols, int32_t *status, char *hostname)
+glusterd_perform_missed_op (glusterd_snap_t *snap, int32_t op)
{
- int32_t ret = -1;
- int32_t count = 0;
- int i = 1;
- gf_boolean_t update = _gf_false;
- gf_boolean_t stale_nfs = _gf_false;
- gf_boolean_t stale_shd = _gf_false;
- gf_boolean_t stale_qd = _gf_false;
+ dict_t *dict = NULL;
+ int32_t ret = -1;
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *snap_volinfo = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ xlator_t *this = NULL;
+ uuid_t null_uuid = {0};
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+ GF_ASSERT (snap);
+
+ dict = dict_new();
+ if (!dict) {
+ gf_log (this->name, GF_LOG_ERROR, "Unable to create dict");
+ ret = -1;
+ goto out;
+ }
+
+ switch (op) {
+ case GF_SNAP_OPTION_TYPE_DELETE:
+ ret = glusterd_snap_remove (dict, snap, _gf_true, _gf_false);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to remove snap");
+ goto out;
+ }
+
+ break;
+ case GF_SNAP_OPTION_TYPE_RESTORE:
+ /* TODO : As of now there is only volume in snapshot.
+ * Change this when multiple volume snapshot is introduced
+ */
+ snap_volinfo = list_entry (snap->volumes.next,
+ glusterd_volinfo_t, vol_list);
+
+ /* Find the parent volinfo */
+ ret = glusterd_volinfo_find (snap_volinfo->parent_volname,
+ &volinfo);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Could not get volinfo of %s",
+ snap_volinfo->parent_volname);
+ goto out;
+ }
+
+ /* Bump down the original volinfo's version, coz it would have
+ * incremented already due to volume handshake
+ */
+ volinfo->version--;
+ uuid_copy (volinfo->restored_from_snap, null_uuid);
+
+ /* Perform the restore */
+ ret = gd_restore_snap_volume (dict, volinfo, snap_volinfo);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to restore "
+ "snap for %s", snap->snapname);
+ volinfo->version++;
+ goto out;
+ }
+
+ break;
+ default:
+ /* The entry must be a create, delete, or
+ * restore entry
+ */
+ gf_log (this->name, GF_LOG_ERROR, "Invalid missed snap entry");
+ ret = -1;
+ goto out;
+ }
+
+out:
+ dict_unref (dict);
+ gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
+}
+
+/* Perform missed deletes and restores on this node */
+int32_t
+glusterd_perform_missed_snap_ops ()
+{
+ int32_t ret = -1;
+ int32_t op_status = -1;
+ glusterd_conf_t *priv = NULL;
+ glusterd_missed_snap_info *missed_snapinfo = NULL;
+ glusterd_snap_op_t *snap_opinfo = NULL;
+ glusterd_snap_t *snap = NULL;
+ uuid_t snap_uuid = {0,};
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ list_for_each_entry (missed_snapinfo, &priv->missed_snaps_list,
+ missed_snaps) {
+ /* If the pending snap_op is not for this node then continue */
+ if (strcmp (missed_snapinfo->node_uuid, uuid_utoa (MY_UUID)))
+ continue;
+
+ /* Find the snap id */
+ uuid_parse (missed_snapinfo->snap_uuid, snap_uuid);
+ snap = NULL;
+ snap = glusterd_find_snap_by_id (snap_uuid);
+ if (!snap) {
+ /* If the snap is not found, then a delete or a
+ * restore can't be pending on that snap_uuid.
+ */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Not a pending delete or restore op");
+ continue;
+ }
- GF_ASSERT (vols);
+ op_status = GD_MISSED_SNAP_PENDING;
+ list_for_each_entry (snap_opinfo, &missed_snapinfo->snap_ops,
+ snap_ops_list) {
+ /* If the snap_op is create or its status is
+ * GD_MISSED_SNAP_DONE then continue
+ */
+ if ((snap_opinfo->status == GD_MISSED_SNAP_DONE) ||
+ (snap_opinfo->op == GF_SNAP_OPTION_TYPE_CREATE))
+ continue;
+
+ /* Perform the actual op for the first time for
+ * this snap, and mark the snap_status as
+ * GD_MISSED_SNAP_DONE. For other entries for the same
+ * snap, just mark the entry as done.
+ */
+ if (op_status == GD_MISSED_SNAP_PENDING) {
+ ret = glusterd_perform_missed_op
+ (snap,
+ snap_opinfo->op);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to perform missed snap op");
+ goto out;
+ }
+ op_status = GD_MISSED_SNAP_DONE;
+ }
+
+ snap_opinfo->status = GD_MISSED_SNAP_DONE;
+ }
+ }
+
+ ret = 0;
+out:
+ gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
+}
+
+/* Import friend volumes missed_snap_list and update *
+ * missed_snap_list if need be */
+int32_t
+glusterd_import_friend_missed_snap_list (dict_t *peer_data)
+{
+ int32_t missed_snap_count = -1;
+ int32_t ret = -1;
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ GF_ASSERT (peer_data);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ /* Add the friends missed_snaps entries to the in-memory list */
+ ret = dict_get_int32 (peer_data, "missed_snap_count",
+ &missed_snap_count);
+ if (ret) {
+ gf_log (this->name, GF_LOG_INFO,
+ "No missed snaps");
+ ret = 0;
+ goto out;
+ }
+
+ ret = glusterd_add_missed_snaps_to_list (peer_data,
+ missed_snap_count);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to add missed snaps to list");
+ goto out;
+ }
+
+ ret = glusterd_perform_missed_snap_ops ();
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to perform snap operations");
+ /* Not going to out at this point coz some *
+ * missed ops might have been performed. We *
+ * need to persist the current list *
+ */
+ }
+
+ ret = glusterd_store_update_missed_snaps ();
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to update missed_snaps_list");
+ goto out;
+ }
+
+out:
+ gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
+}
+
+/* Check for the peer_snap_name in the list of existing snapshots.
+ * If a snap exists with the same name and a different snap_id, then
+ * there is a conflict. Set conflict as _gf_true, and snap to the
+ * conflicting snap object. If a snap exists with the same name, and the
+ * same snap_id, then there is no conflict. Set conflict as _gf_false
+ * and snap to the existing snap object. If no snap exists with the
+ * peer_snap_name, then there is no conflict. Set conflict as _gf_false
+ * and snap to NULL.
+ */
+void
+glusterd_is_peer_snap_conflicting (char *peer_snap_name, char *peer_snap_id,
+ gf_boolean_t *conflict,
+ glusterd_snap_t **snap, char *hostname)
+{
+ uuid_t peer_snap_uuid = {0,};
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ GF_ASSERT (peer_snap_name);
+ GF_ASSERT (peer_snap_id);
+ GF_ASSERT (conflict);
+ GF_ASSERT (snap);
+ GF_ASSERT (hostname);
+
+ *snap = glusterd_find_snap_by_name (peer_snap_name);
+ if (*snap) {
+ uuid_parse (peer_snap_id, peer_snap_uuid);
+ if (!uuid_compare (peer_snap_uuid, (*snap)->snap_id)) {
+ /* Current node contains the same snap having
+ * the same snapname and snap_id
+ */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Snapshot %s from peer %s present in "
+ "localhost", peer_snap_name, hostname);
+ *conflict = _gf_false;
+ } else {
+ /* Current node contains the same snap having
+ * the same snapname but different snap_id
+ */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Snapshot %s from peer %s conflicts with "
+ "snapshot in localhost", peer_snap_name,
+ hostname);
+ *conflict = _gf_true;
+ }
+ } else {
+ /* Peer contains snapshots missing on the current node */
+ gf_log (this->name, GF_LOG_INFO,
+ "Snapshot %s from peer %s missing on localhost",
+ peer_snap_name, hostname);
+ *conflict = _gf_false;
+ }
+}
+
+/* Check if the local node is hosting any bricks for the given snapshot */
+gf_boolean_t
+glusterd_are_snap_bricks_local (glusterd_snap_t *snap)
+{
+ gf_boolean_t is_local = _gf_false;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ GF_ASSERT (snap);
+
+ list_for_each_entry (volinfo, &snap->volumes, vol_list) {
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ if (!uuid_compare (brickinfo->uuid, MY_UUID)) {
+ is_local = _gf_true;
+ goto out;
+ }
+ }
+ }
+
+out:
+ gf_log (this->name, GF_LOG_TRACE, "Returning %d", is_local);
+ return is_local;
+}
+
+/* Check if the peer has missed any snap delete for the given snap_id */
+gf_boolean_t
+glusterd_peer_has_missed_snap_delete (glusterd_peerinfo_t *peerinfo,
+ char *peer_snap_id)
+{
+ char *peer_uuid = NULL;
+ gf_boolean_t missed_delete = _gf_false;
+ glusterd_conf_t *priv = NULL;
+ glusterd_missed_snap_info *missed_snapinfo = NULL;
+ glusterd_snap_op_t *snap_opinfo = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+ GF_ASSERT (peerinfo);
+ GF_ASSERT (peer_snap_id);
+
+ peer_uuid = uuid_utoa (peerinfo->uuid);
+
+ list_for_each_entry (missed_snapinfo, &priv->missed_snaps_list,
+ missed_snaps) {
+ /* Look for missed snap for the same peer, and
+ * the same snap_id
+ */
+ if ((!strcmp (peer_uuid, missed_snapinfo->node_uuid)) &&
+ (!strcmp (peer_snap_id, missed_snapinfo->snap_uuid))) {
+ /* Check if the missed snap's op is delete and the
+ * status is pending
+ */
+ list_for_each_entry (snap_opinfo,
+ &missed_snapinfo->snap_ops,
+ snap_ops_list) {
+ if ((snap_opinfo->op ==
+ GF_SNAP_OPTION_TYPE_DELETE) &&
+ (snap_opinfo->status ==
+ GD_MISSED_SNAP_PENDING)) {
+ missed_delete = _gf_true;
+ goto out;
+ }
+ }
+ }
+ }
+
+out:
+ gf_log (this->name, GF_LOG_TRACE, "Returning %d", missed_delete);
+ return missed_delete;
+}
+
+/* Genrate and store snap volfiles for imported snap object */
+int32_t
+glusterd_gen_snap_volfiles (glusterd_volinfo_t *snap_vol, char *peer_snap_name)
+{
+ int32_t ret = -1;
+ xlator_t *this = NULL;
+ glusterd_volinfo_t *parent_volinfo = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ GF_ASSERT (snap_vol);
+ GF_ASSERT (peer_snap_name);
+
+ ret = glusterd_store_volinfo (snap_vol, GLUSTERD_VOLINFO_VER_AC_NONE);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to store snapshot "
+ "volinfo (%s) for snap %s", snap_vol->volname,
+ peer_snap_name);
+ goto out;
+ }
+
+ ret = generate_brick_volfiles (snap_vol);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "generating the brick volfiles for the "
+ "snap %s failed", peer_snap_name);
+ goto out;
+ }
+
+ ret = generate_client_volfiles (snap_vol, GF_CLIENT_TRUSTED);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "generating the trusted client volfiles for "
+ "the snap %s failed", peer_snap_name);
+ goto out;
+ }
+
+ ret = generate_client_volfiles (snap_vol, GF_CLIENT_OTHER);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "generating the client volfiles for the "
+ "snap %s failed", peer_snap_name);
+ goto out;
+ }
+
+ ret = glusterd_volinfo_find (snap_vol->parent_volname,
+ &parent_volinfo);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Parent volinfo "
+ "not found for %s volume of snap %s",
+ snap_vol->volname, peer_snap_name);
+ goto out;
+ }
+
+ glusterd_list_add_snapvol (parent_volinfo, snap_vol);
+
+ list_for_each_entry (brickinfo, &snap_vol->bricks, brick_list) {
+ if (uuid_compare (brickinfo->uuid, MY_UUID))
+ continue;
+
+ if (brickinfo->snap_status == -1) {
+ gf_log (this->name, GF_LOG_INFO,
+ "not starting snap brick %s:%s for "
+ "for the snap %s (volume: %s)",
+ brickinfo->hostname, brickinfo->path,
+ peer_snap_name, parent_volinfo->volname);
+ continue;
+ }
+
+ ret = glusterd_brick_start (snap_vol, brickinfo, _gf_true);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "starting the "
+ "brick %s:%s for the snap %s (volume: %s) "
+ "failed", brickinfo->hostname, brickinfo->path,
+ peer_snap_name, parent_volinfo->volname);
+ goto out;
+ }
+ }
+
+ snap_vol->status = GLUSTERD_STATUS_STARTED;
+
+ ret = glusterd_store_volinfo (snap_vol, GLUSTERD_VOLINFO_VER_AC_NONE);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to store snap volinfo");
+ goto out;
+ }
+out:
+ gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
+}
+
+/* Import snapshot info from peer_data and add it to priv */
+int32_t
+glusterd_import_friend_snap (dict_t *peer_data, int32_t snap_count,
+ char *peer_snap_name, char *peer_snap_id)
+{
+ char buf[NAME_MAX] = "";
+ char prefix[NAME_MAX] = "";
+ dict_t *dict = NULL;
+ glusterd_snap_t *snap = NULL;
+ glusterd_volinfo_t *snap_vol = NULL;
+ glusterd_conf_t *priv = NULL;
+ int32_t ret = -1;
+ int32_t volcount = -1;
+ int32_t i = -1;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+ GF_ASSERT (peer_data);
+ GF_ASSERT (peer_snap_name);
+ GF_ASSERT (peer_snap_id);
+
+ snprintf (prefix, sizeof(prefix), "snap%d", snap_count);
+
+ snap = glusterd_new_snap_object ();
+ if (!snap) {
+ gf_log (this->name, GF_LOG_ERROR, "Could not create "
+ "the snap object for snap %s", peer_snap_name);
+ goto out;
+ }
+
+ strcpy (snap->snapname, peer_snap_name);
+ uuid_parse (peer_snap_id, snap->snap_id);
+
+ snprintf (buf, sizeof(buf), "%s.snapid", prefix);
+ ret = dict_get_str (peer_data, buf, &snap->description);
+
+ snprintf (buf, sizeof(buf), "%s.time_stamp", prefix);
+ ret = dict_get_int64 (peer_data, buf, &snap->time_stamp);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to get time_stamp for snap %s",
+ peer_snap_name);
+ goto out;
+ }
+
+ snprintf (buf, sizeof(buf), "%s.snap_restored", prefix);
+ ret = dict_get_int8 (peer_data, buf, (int8_t *) &snap->snap_restored);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to get snap_restored for snap %s",
+ peer_snap_name);
+ goto out;
+ }
+
+ snprintf (buf, sizeof(buf), "%s.snap_status", prefix);
+ ret = dict_get_int32 (peer_data, buf, (int32_t *) &snap->snap_status);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to get snap_status for snap %s",
+ peer_snap_name);
+ goto out;
+ }
+
+ snprintf (buf, sizeof(buf), "%s.volcount", prefix);
+ ret = dict_get_int32 (peer_data, buf, &volcount);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to get volcount for snap %s",
+ peer_snap_name);
+ goto out;
+ }
+
+ ret = glusterd_store_create_snap_dir (snap);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to create snap dir");
+ goto out;
+ }
+
+ list_add_order (&snap->snap_list, &priv->snapshots,
+ glusterd_compare_snap_time);
+
+ for (i = 1; i <= volcount; i++) {
+ ret = glusterd_import_volinfo (peer_data, i,
+ &snap_vol, prefix);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to import snap volinfo for "
+ "snap %s", peer_snap_name);
+ goto out;
+ }
+
+ snap_vol->snapshot = snap;
+
+ ret = glusterd_gen_snap_volfiles (snap_vol, peer_snap_name);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to generate snap vol files "
+ "for snap %s", peer_snap_name);
+ goto out;
+ }
+
+ ret = glusterd_import_quota_conf (peer_data, i,
+ snap_vol, prefix);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to import quota conf "
+ "for snap %s", peer_snap_name);
+ goto out;
+ }
+
+ snap_vol = NULL;
+ }
+
+ ret = glusterd_store_snap (snap);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "Could not store snap"
+ "object %s", peer_snap_name);
+ goto out;
+ }
+
+out:
+ if (ret)
+ glusterd_snap_remove (dict, snap,
+ _gf_true, _gf_true);
+
+ if (dict)
+ dict_unref (dict);
+
+ gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
+}
+
+/* During a peer-handshake, after the volumes have synced, and the list of
+ * missed snapshots have synced, the node will perform the pending deletes
+ * and restores on this list. At this point, the current snapshot list in
+ * the node will be updated, and hence in case of conflicts arising during
+ * snapshot handshake, the peer hosting the bricks will be given precedence
+ * Likewise, if there will be a conflict, and both peers will be in the same
+ * state, i.e either both would be hosting bricks or both would not be hosting
+ * bricks, then a decision can't be taken and a peer-reject will happen.
+ *
+ * glusterd_compare_and_update_snap() implements the following algorithm to
+ * perform the above task:
+ * Step 1: Start.
+ * Step 2: Check if the peer is missing a delete on the said snap.
+ * If yes, goto step 6.
+ * Step 3: Check if there is a conflict between the peer's data and the
+ * local snap. If no, goto step 5.
+ * Step 4: As there is a conflict, check if both the peer and the local nodes
+ * are hosting bricks. Based on the results perform the following:
+ * Peer Hosts Bricks Local Node Hosts Bricks Action
+ * Yes Yes Goto Step 7
+ * No No Goto Step 7
+ * Yes No Goto Step 8
+ * No Yes Goto Step 6
+ * Step 5: Check if the local node is missing the peer's data.
+ * If yes, goto step 9.
+ * Step 6: It's a no-op. Goto step 10
+ * Step 7: Peer Reject. Goto step 10
+ * Step 8: Delete local node's data.
+ * Step 9: Accept Peer Data.
+ * Step 10: Stop
+ *
+ */
+int32_t
+glusterd_compare_and_update_snap (dict_t *peer_data, int32_t snap_count,
+ glusterd_peerinfo_t *peerinfo)
+{
+ char buf[NAME_MAX] = "";
+ char prefix[NAME_MAX] = "";
+ char *peer_snap_name = NULL;
+ char *peer_snap_id = NULL;
+ dict_t *dict = NULL;
+ glusterd_snap_t *snap = NULL;
+ gf_boolean_t conflict = _gf_false;
+ gf_boolean_t is_local = _gf_false;
+ gf_boolean_t is_hosted = _gf_false;
+ gf_boolean_t missed_delete = _gf_false;
+ int32_t ret = -1;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ GF_ASSERT (peer_data);
+ GF_ASSERT (peerinfo);
+
+ snprintf (prefix, sizeof(prefix), "snap%d", snap_count);
+
+ /* Fetch the peer's snapname */
+ snprintf (buf, sizeof(buf), "%s.snapname", prefix);
+ ret = dict_get_str (peer_data, buf, &peer_snap_name);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to fetch snapname from peer: %s",
+ peerinfo->hostname);
+ goto out;
+ }
+
+ /* Fetch the peer's snap_id */
+ snprintf (buf, sizeof(buf), "%s.snap_id", prefix);
+ ret = dict_get_str (peer_data, buf, &peer_snap_id);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to fetch snap_id from peer: %s",
+ peerinfo->hostname);
+ goto out;
+ }
+
+ /* Check if the peer has missed a snap delete for the
+ * snap in question
+ */
+ missed_delete = glusterd_peer_has_missed_snap_delete (peerinfo,
+ peer_snap_id);
+ if (missed_delete == _gf_true) {
+ /* Peer has missed delete on the missing/conflicting snap_id */
+ gf_log (this->name, GF_LOG_INFO, "Peer %s has missed a delete "
+ "on snap %s", peerinfo->hostname, peer_snap_name);
+ ret = 0;
+ goto out;
+ }
+
+ /* Check if there is a conflict, and if the
+ * peer data is already present
+ */
+ glusterd_is_peer_snap_conflicting (peer_snap_name, peer_snap_id,
+ &conflict, &snap,
+ peerinfo->hostname);
+ if (conflict == _gf_false) {
+ if (snap) {
+ /* Peer has snap with the same snapname
+ * and snap_id. No need to accept peer data
+ */
+ ret = 0;
+ goto out;
+ } else {
+ /* Peer has snap with the same snapname
+ * and snap_id, which local node doesn't have.
+ */
+ goto accept_peer_data;
+ }
+ }
+
+ /* There is a conflict. Check if the current node is
+ * hosting bricks for the conflicted snap.
+ */
+ is_local = glusterd_are_snap_bricks_local (snap);
+
+ /* Check if the peer is hosting any bricks for the
+ * conflicting snap
+ */
+ snprintf (buf, sizeof(buf), "%s.host_bricks", prefix);
+ ret = dict_get_int8 (peer_data, buf, (int8_t *) &is_hosted);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to fetch host_bricks from peer: %s "
+ "for %s", peerinfo->hostname, peer_snap_name);
+ goto out;
+ }
+
+ /* As there is a conflict at this point of time, the data of the
+ * node that hosts a brick takes precedence. If both the local
+ * node and the peer are in the same state, i.e if both of them
+ * are either hosting or not hosting the bricks, for the snap,
+ * then it's a peer reject
+ */
+ if (is_hosted == is_local) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Conflict in snapshot %s with peer %s",
+ peer_snap_name, peerinfo->hostname);
+ ret = -1;
+ goto out;
+ }
+
+ if (is_hosted == _gf_false) {
+ /* If there was a conflict, and the peer is not hosting
+ * any brick, then don't accept peer data
+ */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Peer doesn't hosts bricks for conflicting "
+ "snap(%s). Not accepting peer data.",
+ peer_snap_name);
+ ret = 0;
+ goto out;
+ }
+
+ /* The peer is hosting a brick in case of conflict
+ * And local node isn't. Hence remove local node's
+ * data and accept peer data
+ */
+
+ gf_log (this->name, GF_LOG_DEBUG, "Peer hosts bricks for conflicting "
+ "snap(%s). Removing local data. Accepting peer data.",
+ peer_snap_name);
+
+ dict = dict_new();
+ if (!dict) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to create dict");
+ ret = -1;
+ goto out;
+ }
+
+ ret = glusterd_snap_remove (dict, snap, _gf_true, _gf_false);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to remove snap %s", snap->snapname);
+ goto out;
+ }
+
+accept_peer_data:
+
+ /* Accept Peer Data */
+ ret = glusterd_import_friend_snap (peer_data, snap_count,
+ peer_snap_name, peer_snap_id);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to import snap %s from peer %s",
+ peer_snap_name, peerinfo->hostname);
+ goto out;
+ }
+
+out:
+ if (dict)
+ dict_unref (dict);
+
+ gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
+}
+
+/* Compare snapshots present in peer_data, with the snapshots in
+ * the current node
+ */
+int32_t
+glusterd_compare_friend_snapshots (dict_t *peer_data,
+ glusterd_peerinfo_t *peerinfo)
+{
+ int32_t ret = -1;
+ int32_t snap_count = 0;
+ int i = 1;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ GF_ASSERT (peer_data);
+ GF_ASSERT (peerinfo);
+
+ ret = dict_get_int32 (peer_data, "snap_count", &snap_count);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to fetch snap_count");
+ goto out;
+ }
+
+ for (i = 1; i <= snap_count; i++) {
+ /* Compare one snapshot from peer_data at a time */
+ ret = glusterd_compare_and_update_snap (peer_data, i, peerinfo);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to compare snapshots with peer %s",
+ peerinfo->hostname);
+ goto out;
+ }
+ }
+
+out:
+ gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
+}
+
+int32_t
+glusterd_compare_friend_data (dict_t *peer_data, int32_t *status,
+ char *hostname)
+{
+ int32_t ret = -1;
+ int32_t count = 0;
+ int i = 1;
+ gf_boolean_t update = _gf_false;
+ gf_boolean_t stale_nfs = _gf_false;
+ gf_boolean_t stale_shd = _gf_false;
+ gf_boolean_t stale_qd = _gf_false;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ GF_ASSERT (peer_data);
GF_ASSERT (status);
- ret = dict_get_int32 (vols, "count", &count);
+ ret = dict_get_int32 (peer_data, "count", &count);
if (ret)
goto out;
while (i <= count) {
- ret = glusterd_compare_friend_volume (vols, i, status,
+ ret = glusterd_compare_friend_volume (peer_data, i, status,
hostname);
if (ret)
goto out;
@@ -4199,10 +5334,10 @@ glusterd_compare_friend_data (dict_t *vols, int32_t *status, char *hostname)
stale_shd = _gf_true;
if (glusterd_is_nodesvc_running ("quotad"))
stale_qd = _gf_true;
- ret = glusterd_import_global_opts (vols);
+ ret = glusterd_import_global_opts (peer_data);
if (ret)
goto out;
- ret = glusterd_import_friend_volumes (vols);
+ ret = glusterd_import_friend_volumes (peer_data);
if (ret)
goto out;
if (_gf_false == glusterd_are_all_volumes_stopped ()) {
@@ -4218,9 +5353,8 @@ glusterd_compare_friend_data (dict_t *vols, int32_t *status, char *hostname)
}
out:
- gf_log ("", GF_LOG_DEBUG, "Returning with ret: %d, status: %d",
- ret, *status);
-
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Returning with ret: %d, status: %d", ret, *status);
return ret;
}
@@ -4522,14 +5656,16 @@ glusterd_nodesvc_start (char *server, gf_boolean_t wait)
"--trace-children=yes", "--track-origins=yes",
NULL);
runner_argprintf (&runner, "--log-file=%s", valgrind_logfile);
- }
+ }
runner_add_args (&runner, SBIN_DIR"/glusterfs",
"-s", "localhost",
"--volfile-id", volfileid,
"-p", pidfile,
"-l", logfile,
- "-S", sockfpath, NULL);
+ "-S", sockfpath,
+ "-L", "DEBUG",
+ NULL);
if (!strcmp (server, "glustershd")) {
snprintf (glusterd_uuid_option, sizeof (glusterd_uuid_option),
@@ -5456,7 +6592,6 @@ out:
return -1;
}
-#ifdef GF_LINUX_HOST_OS
int
glusterd_get_brick_root (char *path, char **mount_point)
{
@@ -5752,7 +6887,6 @@ out:
return device;
}
-#endif
int
glusterd_add_brick_detail_to_dict (glusterd_volinfo_t *volinfo,
@@ -5826,13 +6960,12 @@ glusterd_add_brick_detail_to_dict (glusterd_volinfo_t *volinfo,
if (ret)
goto out;
}
-#ifdef GF_LINUX_HOST_OS
+
ret = glusterd_add_brick_mount_details (brickinfo, dict, count);
if (ret)
goto out;
ret = glusterd_add_inode_size_to_dict (dict, count);
-#endif
out:
if (ret)
gf_log (this->name, GF_LOG_DEBUG, "Error adding brick"
@@ -8830,7 +9963,7 @@ glusterd_snap_config_use_rsp_dict (dict_t *dst, dict_t *src)
}
for (i = 0; i < voldisplaycount; i++) {
- snprintf (buf, sizeof(buf), "volume%ld-volname", i);
+ snprintf (buf, sizeof(buf), "volume%"PRIu64"-volname", i);
ret = dict_get_str (src, buf, &volname);
if (ret) {
gf_log ("", GF_LOG_ERROR,
@@ -8845,7 +9978,7 @@ glusterd_snap_config_use_rsp_dict (dict_t *dst, dict_t *src)
}
snprintf (buf, sizeof(buf),
- "volume%ld-snap-max-hard-limit", i);
+ "volume%"PRIu64"-snap-max-hard-limit", i);
ret = dict_get_uint64 (src, buf, &value);
if (ret) {
gf_log ("", GF_LOG_ERROR,
@@ -8860,7 +9993,7 @@ glusterd_snap_config_use_rsp_dict (dict_t *dst, dict_t *src)
}
snprintf (buf, sizeof(buf),
- "volume%ld-active-hard-limit", i);
+ "volume%"PRIu64"-active-hard-limit", i);
ret = dict_get_uint64 (src, buf, &value);
if (ret) {
gf_log ("", GF_LOG_ERROR,
@@ -8875,7 +10008,7 @@ glusterd_snap_config_use_rsp_dict (dict_t *dst, dict_t *src)
}
snprintf (buf, sizeof(buf),
- "volume%ld-snap-max-soft-limit", i);
+ "volume%"PRIu64"-snap-max-soft-limit", i);
ret = dict_get_uint64 (src, buf, &value);
if (ret) {
gf_log ("", GF_LOG_ERROR,
@@ -9993,7 +11126,6 @@ glusterd_missed_snapinfo_new (glusterd_missed_snap_info **missed_snapinfo)
if (!new_missed_snapinfo)
goto out;
- new_missed_snapinfo->node_snap_info = NULL;
INIT_LIST_HEAD (&new_missed_snapinfo->missed_snaps);
INIT_LIST_HEAD (&new_missed_snapinfo->snap_ops);
@@ -10023,7 +11155,6 @@ glusterd_missed_snap_op_new (glusterd_snap_op_t **snap_op)
if (!new_snap_op)
goto out;
- new_snap_op->brick_path = NULL;
new_snap_op->brick_num = -1;
new_snap_op->op = -1;
new_snap_op->status = -1;
@@ -10376,3 +11507,38 @@ glusterd_compare_volume_name(struct list_head *list1, struct list_head *list2)
volinfo2 = list_entry(list2, glusterd_volinfo_t, vol_list);
return strcmp(volinfo1->volname, volinfo2->volname);
}
+
+int32_t
+glusterd_mount_lvm_snapshot (char *device_path, char *brick_mount_path)
+{
+ char msg[NAME_MAX] = "";
+ int32_t ret = -1;
+ runner_t runner = {0, };
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ GF_ASSERT (brick_mount_path);
+ GF_ASSERT (device_path);
+
+
+ runinit (&runner);
+ snprintf (msg, sizeof (msg), "mount -o nouuid %s %s",
+ device_path, brick_mount_path);
+ runner_add_args (&runner, "mount", "-o", "nouuid", device_path,
+ brick_mount_path, NULL);
+ runner_log (&runner, this->name, GF_LOG_DEBUG, msg);
+ ret = runner_run (&runner);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "mounting the snapshot "
+ "logical device %s failed (error: %s)", device_path,
+ strerror (errno));
+ goto out;
+ } else
+ gf_log (this->name, GF_LOG_DEBUG, "mounting the snapshot "
+ "logical device %s successful", device_path);
+
+out:
+ gf_log (this->name, GF_LOG_TRACE, "Returning with %d", ret);
+ return ret;
+}