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.c118
1 files changed, 76 insertions, 42 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index d508e74f510..b955fd9de9d 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -647,10 +647,13 @@ out:
* TODO: Duplicate all members of volinfo, e.g. geo-rep sync slaves
*/
int32_t
-glusterd_snap_volinfo_restore (dict_t *rsp_dict,
+glusterd_snap_volinfo_restore (dict_t *dict, dict_t *rsp_dict,
glusterd_volinfo_t *new_volinfo,
- glusterd_volinfo_t *snap_volinfo)
+ glusterd_volinfo_t *snap_volinfo,
+ int32_t volcount)
{
+ char *value = NULL;
+ char key[PATH_MAX] = "";
int32_t brick_count = -1;
int32_t ret = -1;
xlator_t *this = NULL;
@@ -659,6 +662,7 @@ glusterd_snap_volinfo_restore (dict_t *rsp_dict,
this = THIS;
GF_ASSERT (this);
+ GF_ASSERT (dict);
GF_ASSERT (rsp_dict);
GF_VALIDATE_OR_GOTO (this->name, new_volinfo, out);
@@ -666,6 +670,7 @@ glusterd_snap_volinfo_restore (dict_t *rsp_dict,
brick_count = 0;
list_for_each_entry (brickinfo, &snap_volinfo->bricks, brick_list) {
+ brick_count++;
ret = glusterd_brickinfo_new (&new_brickinfo);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "Failed to create "
@@ -681,6 +686,28 @@ glusterd_snap_volinfo_restore (dict_t *rsp_dict,
goto out;
}
+ /* Fetch values if present in dict These values won't
+ * be present in case of a missed restore. In that case
+ * it's fine to use the local node's value
+ */
+ snprintf (key, sizeof (key), "snap%d.brick%d.path",
+ volcount, brick_count);
+ ret = dict_get_str (dict, key, &value);
+ if (!ret)
+ strncpy (new_brickinfo->path, value,
+ sizeof(new_brickinfo->path));
+
+ snprintf (key, sizeof (key), "snap%d.brick%d.snap_status",
+ volcount, brick_count);
+ ret = dict_get_int32 (dict, key, &new_brickinfo->snap_status);
+
+ snprintf (key, sizeof (key), "snap%d.brick%d.device_path",
+ volcount, brick_count);
+ ret = dict_get_str (dict, key, &value);
+ if (!ret)
+ strncpy (new_brickinfo->device_path, value,
+ sizeof(new_brickinfo->device_path));
+
/* If the brick is not of this peer, or snapshot is missed *
* for the brick do not replace the xattr for it */
if ((!uuid_compare (brickinfo->uuid, MY_UUID)) &&
@@ -713,7 +740,7 @@ glusterd_snap_volinfo_restore (dict_t *rsp_dict,
(rsp_dict,
snap_volinfo,
brickinfo,
- brick_count + 1,
+ brick_count,
GF_SNAP_OPTION_TYPE_RESTORE);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
@@ -729,7 +756,6 @@ glusterd_snap_volinfo_restore (dict_t *rsp_dict,
&new_volinfo->bricks);
/* ownership of new_brickinfo is passed to new_volinfo */
new_brickinfo = NULL;
- brick_count++;
}
/* Regenerate all volfiles */
@@ -2336,7 +2362,8 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
if (ret)
goto out;
- snprintf (key, sizeof (key), "volume%d.restored_from_snap", count);
+ snprintf (key, sizeof (key), "%s%d.restored_from_snap",
+ prefix, count);
ret = dict_set_dynstr_with_alloc
(dict, key,
uuid_utoa (volinfo->restored_from_snap));
@@ -4562,6 +4589,7 @@ glusterd_perform_missed_op (glusterd_snap_t *snap, int32_t op)
glusterd_conf_t *priv = NULL;
glusterd_volinfo_t *snap_volinfo = NULL;
glusterd_volinfo_t *volinfo = NULL;
+ glusterd_volinfo_t *tmp = NULL;
xlator_t *this = NULL;
uuid_t null_uuid = {0};
@@ -4590,35 +4618,37 @@ glusterd_perform_missed_op (glusterd_snap_t *snap, int32_t op)
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;
- }
+ list_for_each_entry_safe (snap_volinfo, tmp,
+ &snap->volumes, vol_list) {
+ 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);
+ 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;
+ /* gd_restore_snap_volume() uses the dict and volcount
+ * to fetch snap brick info from other nodes, which were
+ * collected during prevalidation. As this is an ad-hoc
+ * op and only local node's data matter, hence sending
+ * volcount as 0 and re-using the same dict because we
+ * need not record any missed creates in the rsp_dict.
+ */
+ ret = gd_restore_snap_volume (dict, dict, volinfo,
+ snap_volinfo, 0);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to restore snap for %s",
+ snap->snapname);
+ volinfo->version++;
+ goto out;
+ }
}
break;
@@ -4851,7 +4881,9 @@ out:
return is_local;
}
-/* Check if the peer has missed any snap delete for the given snap_id */
+/* Check if the peer has missed any snap delete
+ * or restore for the given snap_id
+ */
gf_boolean_t
glusterd_peer_has_missed_snap_delete (glusterd_peerinfo_t *peerinfo,
char *peer_snap_id)
@@ -4885,8 +4917,10 @@ glusterd_peer_has_missed_snap_delete (glusterd_peerinfo_t *peerinfo,
list_for_each_entry (snap_opinfo,
&missed_snapinfo->snap_ops,
snap_ops_list) {
- if ((snap_opinfo->op ==
- GF_SNAP_OPTION_TYPE_DELETE) &&
+ if (((snap_opinfo->op ==
+ GF_SNAP_OPTION_TYPE_DELETE) ||
+ (snap_opinfo->op ==
+ GF_SNAP_OPTION_TYPE_RESTORE)) &&
(snap_opinfo->status ==
GD_MISSED_SNAP_PENDING)) {
missed_delete = _gf_true;
@@ -5141,7 +5175,7 @@ out:
* 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.
+ * Step 2: Check if the peer is missing a delete or restore 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.
@@ -5205,8 +5239,8 @@ glusterd_compare_and_update_snap (dict_t *peer_data, int32_t snap_count,
goto out;
}
- /* Check if the peer has missed a snap delete for the
- * snap in question
+ /* Check if the peer has missed a snap delete or restore
+ * resulting in stale data for the snap in question
*/
missed_delete = glusterd_peer_has_missed_snap_delete (peerinfo,
peer_snap_id);
@@ -6983,7 +7017,7 @@ glusterd_add_brick_mount_details (glusterd_brickinfo_t *brickinfo,
}
char*
-glusterd_get_brick_mount_details (glusterd_brickinfo_t *brickinfo)
+glusterd_get_brick_mount_details (char *brick_path)
{
int ret = -1;
char *mnt_pt = NULL;
@@ -6994,12 +7028,12 @@ glusterd_get_brick_mount_details (glusterd_brickinfo_t *brickinfo)
this = THIS;
GF_ASSERT (this);
- GF_ASSERT (brickinfo);
+ GF_ASSERT (brick_path);
- ret = glusterd_get_brick_root (brickinfo->path, &mnt_pt);
+ ret = glusterd_get_brick_root (brick_path, &mnt_pt);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "Failed to get mount point "
- "for %s brick", brickinfo->path);
+ "for %s brick", brick_path);
goto out;
}