glusterd/snapshot: Compare and update snapshots during peer handshake

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

Change-Id: I79be0f0f5f2a4f5c72277a4e77c2be732af432e1
BUG: 1061685
Signed-off-by: Avra Sengupta <asengupt@redhat.com>
Reviewed-on: http://review.gluster.org/7525
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com>
Reviewed-by: Rajesh Joseph <rjoseph@redhat.com>
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
This commit is contained in:
Avra Sengupta 2014-04-22 00:52:57 +00:00 committed by Vijay Bellur
parent a7c8d514c0
commit 54a5a42848
8 changed files with 985 additions and 126 deletions

View File

@ -109,6 +109,7 @@ enum gf_probe_resp {
GF_PROBE_ADD_FAILED,
GF_PROBE_QUORUM_NOT_MET,
GF_PROBE_MISSED_SNAP_CONFLICT,
GF_PROBE_SNAP_CONFLICT,
};
enum gf_deprobe_resp {

View File

@ -3409,6 +3409,12 @@ set_probe_error_str (int op_ret, int op_errno, char *op_errstr, char *errstr,
"peer %s", hostname);
break;
case GF_PROBE_SNAP_CONFLICT:
snprintf (errstr, len, "Conflict in comparing "
"list of snapshots from "
"peer %s", hostname);
break;
default:
snprintf (errstr, len, "Probe returned with "
"unknown errno %d", op_errno);

View File

@ -2082,12 +2082,12 @@ glusterd_op_sync_volume (dict_t *dict, char **op_errstr,
if (volname) {
ret = glusterd_add_volume_to_dict (volinfo, rsp_dict,
1);
1, "volume");
vol_count = 1;
} else {
list_for_each_entry (volinfo, &priv->volumes, vol_list) {
ret = glusterd_add_volume_to_dict (volinfo,
rsp_dict, count);
ret = glusterd_add_volume_to_dict (volinfo, rsp_dict,
count, "volume");
if (ret)
goto out;

View File

@ -1278,6 +1278,14 @@ glusterd_rpc_friend_add (call_frame_t *frame, xlator_t *this,
"in the peer_data dict for handshake");
goto out;
}
ret = glusterd_add_snapshots_to_export_dict (peer_data);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"Unable to add list of snapshots "
"in the peer_data dict for handshake");
goto out;
}
}
uuid_copy (req.uuid, MY_UUID);

View File

@ -694,6 +694,16 @@ glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx)
op_errno = GF_PROBE_MISSED_SNAP_CONFLICT;
op_ret = -1;
}
ret = glusterd_compare_friend_snapshots (ev_ctx->vols,
peerinfo);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"Conflict in comparing peer's snapshots");
event_type = GD_FRIEND_EVENT_LOCAL_RJT;
op_errno = GF_PROBE_SNAP_CONFLICT;
op_ret = -1;
}
}
ret = glusterd_friend_sm_new_event (event_type, &new_event);

View File

@ -677,7 +677,7 @@ glusterd_store_create_volume_dir (glusterd_volinfo_t *volinfo)
return ret;
}
static int32_t
int32_t
glusterd_store_create_snap_dir (glusterd_snap_t *snap)
{
int32_t ret = -1;

File diff suppressed because it is too large Load Diff

View File

@ -281,7 +281,8 @@ int32_t
glusterd_volume_count_get (void);
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);
int
glusterd_get_brickinfo (xlator_t *this, const char *brickname,
int port, gf_boolean_t localhost,
@ -735,4 +736,23 @@ gd_restore_snap_volume (dict_t *rsp_dict,
int32_t
glusterd_mount_lvm_snapshot (char *device_path, char *brick_mount_path);
int32_t
glusterd_add_snapshots_to_export_dict (dict_t *peer_data);
int32_t
glusterd_compare_friend_snapshots (dict_t *peer_data,
glusterd_peerinfo_t *peerinfo);
int32_t
glusterd_snapobject_delete (glusterd_snap_t *snap);
int32_t
glusterd_snap_volume_remove (dict_t *rsp_dict,
glusterd_volinfo_t *snap_vol,
gf_boolean_t remove_lvm,
gf_boolean_t force);
int32_t
glusterd_store_create_snap_dir (glusterd_snap_t *snap);
#endif