From 727a63c3a5f9cab5af6089826d81df2035e1c0b6 Mon Sep 17 00:00:00 2001 From: Rajesh Joseph Date: Fri, 13 Dec 2013 11:53:21 +0530 Subject: Snapshot: Gluster snapshot restore feature Implemented gluster snapshot restore feature. The restore is done by replacing the origin volume with the snap volume. TODO: After the restore the snapshot volume should be deleted. As of now the deletion work is pending. Change-Id: Ib137fb6bb84a74030607ffa47f89cd705dc7e1ff Signed-off-by: Rajesh Joseph --- xlators/mgmt/glusterd/src/glusterd-snapshot.c | 171 +++++--------------------- 1 file changed, 33 insertions(+), 138 deletions(-) (limited to 'xlators/mgmt/glusterd/src/glusterd-snapshot.c') diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c index acc8bef16..8419cfb25 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c @@ -48,139 +48,6 @@ char * generate_snapname (char *volname, char *name, gf_boolean_t volume_from_cg); -/* This function will do the actual snapshot restore on the brick. - * - * @param brickinfo brickinfo structure - * @param snapname name of the snap which will be restored - * - * @return Negative value on Failure and 0 in success - */ -int -glusterd_snapshot_restore_brick_snap (glusterd_brickinfo_t *brickinfo, - char *snapname) -{ - int ret = -1; - char *device = NULL; - xlator_t *this = NULL; - runner_t runner = {0,}; - glusterd_conf_t *conf = NULL; - char msg[PATH_MAX] = {0,}; - - this = THIS; - GF_ASSERT (this); - conf = this->private; - - GF_ASSERT (conf); - GF_ASSERT (brickinfo); - GF_ASSERT (snapname); - - /* Using the brickinfo get the actual device name */ - device = glusterd_get_brick_mount_details (brickinfo); - - runinit (&runner); - snprintf (msg, sizeof (msg), "Restoring snapshot of the brick %s:%s " - "to %s snap", brickinfo->hostname, brickinfo->path, snapname); - - /* Command for restoring the snapshot */ - runner_add_args (&runner, "/sbin/lvconvert", "--merge", device, NULL); - runner_log (&runner, "", GF_LOG_DEBUG, msg); - - synclock_unlock (&conf->big_lock); - /* Run the actual command */ - ret = runner_run (&runner); - synclock_lock (&conf->big_lock); - - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "snapshot restore of the " - "brick (%s:%s) of device %s failed", - brickinfo->hostname, brickinfo->path, device); - goto out; - } - -out: - return ret; -} - -/* This function will restore the snapshot for the entire volume. - * - * @param snap snap object which needs to be restored - * @param op_errstr In case of any failure error message will be returned - * in this variable - * @return Negative value on Failure and 0 in success - */ -int -glusterd_snapshot_restore_snap (glusterd_snap_t *snap, char **op_errstr) -{ - int ret = -1; - xlator_t *this = NULL; - glusterd_volinfo_t *volinfo = NULL; - glusterd_brickinfo_t *brickinfo = NULL; - - this = THIS; - - GF_ASSERT (this); - GF_ASSERT (snap); - GF_ASSERT (snap->snap_volume); - GF_ASSERT (op_errstr); - - /* For restore always take volinfo stored in snap. Do not use - * volinfo of the original volume*/ - volinfo = snap->snap_volume; - - list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { - /* This code is executed on each node of the volume. We need - * to run the restore only on those bricks which are present - * in this node. Therefore check if node belongs to this node - * or not. - */ - if (uuid_compare (brickinfo->uuid, MY_UUID)) { - continue; /* Bricks not present in this node */ - } - - /* This case should never occur as volume is already stopped. - * Just to avoid a case where the brick is explicitly started - * by the user we have this check here. - */ - if (glusterd_is_brick_started (brickinfo)) { - ret = gf_asprintf (op_errstr, "Brick (%s: %s) is " - "running therefore snapshot cannot " - "be restored", brickinfo->hostname, - brickinfo->path); - if (ret < 0) { - goto out; - } - - gf_log (this->name, GF_LOG_ERROR, "%s", *op_errstr); - ret = -1; - goto out; - } - - /* Do the actual snapshot restore */ - ret = glusterd_snapshot_restore_brick_snap (brickinfo, - snap->snap_name); - if (ret) { - ret = gf_asprintf (op_errstr, "Snapshot restore failed" - " for %s:%s", brickinfo->hostname, - brickinfo->path); - if (ret < 0) { - goto out; - } - - gf_log (this->name, GF_LOG_ERROR, "%s", *op_errstr); - ret = -1; - goto out; - } - - } - - /* TODO: Move this code to postvalidate */ - snap->snap_restored = _gf_true; - /* TODO: persist the change in store */ - -out: - return ret; -} - /* This function will restore a snapshot for the entire * volume or the entire CG (Consistency Group) * @@ -260,7 +127,7 @@ glusterd_snapshot_restore (dict_t *dict, char **op_errstr) } /* Restore the snap for the entire volume */ - ret = glusterd_snapshot_restore_snap (snap, op_errstr); + ret = gd_restore_snap_volume (volinfo, snap->snap_volume); if (ret) { /* No need to update op_errstr because it is assumed * that the called function will do that in case of @@ -289,10 +156,12 @@ out: * @param dict dictionary containing snapshot restore request * @param op_errstr In case of any failure error message will be returned * in this variable + * @param rsp_dict response dictionary * @return Negative value on Failure and 0 in success */ int -glusterd_snapshot_restore_prevalidate (dict_t *dict, char **op_errstr) +glusterd_snapshot_restore_prevalidate (dict_t *dict, char **op_errstr, + dict_t *rsp_dict) { int ret = -1; int64_t i = 0; @@ -300,6 +169,7 @@ glusterd_snapshot_restore_prevalidate (dict_t *dict, char **op_errstr) gf_boolean_t snap_restored = _gf_false; char *volname = NULL; char *snapname = NULL; + char *cgname = NULL; glusterd_volinfo_t *volinfo = NULL; glusterd_snap_t *snap = NULL; xlator_t *this = NULL; @@ -310,6 +180,30 @@ glusterd_snapshot_restore_prevalidate (dict_t *dict, char **op_errstr) GF_ASSERT (this); GF_ASSERT (dict); GF_ASSERT (op_errstr); + GF_ASSERT (rsp_dict); + + ret = dict_get_str (dict, "cgname", &cgname); + if (ret) { + ret = dict_get_str (dict, "snapname", &snapname); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get " + "neither snapname nor cgname"); + goto out; + } + ret = dict_set_str (rsp_dict, "snapname", snapname); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to set " + "snap name"); + goto out; + } + } else { + ret = dict_set_str (rsp_dict, "cgname", cgname); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to set " + "CG name"); + goto out; + } + } ret = dict_get_int64 (dict, "volcount", &volcount); @@ -3234,7 +3128,7 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict, } ret = generate_snap_client_volfiles (volinfo, snap_volume, - GF_CLIENT_TRUSTED); + GF_CLIENT_TRUSTED, _gf_false); if (ret) { gf_log (this->name, GF_LOG_ERROR, "generating the trusted " "client volfiles for the snap %s (volume: %s) failed", @@ -3243,7 +3137,7 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict, } ret = generate_snap_client_volfiles (volinfo, snap_volume, - GF_CLIENT_OTHER); + GF_CLIENT_OTHER, _gf_false); if (ret) { gf_log (this->name, GF_LOG_ERROR, "generating the client " "volfiles for the snap %s (volume: %s) failed", @@ -4657,7 +4551,8 @@ glusterd_snapshot_prevalidate (dict_t *dict, char **op_errstr, break; case GF_SNAP_OPTION_TYPE_RESTORE: - ret = glusterd_snapshot_restore_prevalidate (dict, op_errstr); + ret = glusterd_snapshot_restore_prevalidate (dict, op_errstr, + rsp_dict); if (ret) { gf_log (this->name, GF_LOG_WARNING, "Snapshot restore " "validation failed"); -- cgit