summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-snapshot.c
diff options
context:
space:
mode:
authorRajesh Joseph <rjoseph@redhat.com>2013-12-13 11:53:21 +0530
committerRajesh Joseph <rjoseph@redhat.com>2014-01-15 13:53:32 +0530
commit727a63c3a5f9cab5af6089826d81df2035e1c0b6 (patch)
tree25c37ce129a65ed5af8ec9b52272bd98916fa206 /xlators/mgmt/glusterd/src/glusterd-snapshot.c
parent33c45ff71cb43eec7cdcee054a6a55b7c3aaa8fb (diff)
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 <rjoseph@redhat.com>
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-snapshot.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c171
1 files changed, 33 insertions, 138 deletions
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");