summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src
diff options
context:
space:
mode:
authorVijaikumar M <vmallika@redhat.com>2014-03-04 13:02:52 +0530
committerRajesh Joseph <rjoseph@redhat.com>2014-03-06 01:31:23 -0800
commit40497ba922667abbc20dda635cb0ef0abe5f51eb (patch)
tree3755c4d52ff5ed4a6d6f0d1cff0dcd80cef52ba1 /xlators/mgmt/glusterd/src
parentfabee8f75c56f18c949b79dcc751c2855b5c7514 (diff)
glusterd/snapshot: Snapshot create and delete changes
With the snap driven approach, While creating the snapshot, We have to mention the snap-name first and then the volumes to be associated with that. Corresponding changes has been made in glusterd. While deleting the snapshot, we have to mention only the snapname. Corresponding changes has been made in glusterd. CLI changes for the same can be found here: http://review.gluster.org/#/c/6947/ Change-Id: I8bd8f471da5b728165da5f331faad3dde3486823 Signed-off-by: Vijaikumar M <vmallika@redhat.com> Reviewed-on: http://review.gluster.org/7123 Reviewed-by: Avra Sengupta <asengupt@redhat.com> Reviewed-by: Rajesh Joseph <rjoseph@redhat.com> Tested-by: Rajesh Joseph <rjoseph@redhat.com>
Diffstat (limited to 'xlators/mgmt/glusterd/src')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c1744
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.c33
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h25
4 files changed, 656 insertions, 1147 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index ee077e7bc..e59aaa9ff 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -44,10 +44,6 @@
#include <mntent.h>
#endif
-char *
-generate_snapname (char *volname, char *name, gf_boolean_t volume_from_cg);
-
-
/* This function will restore a snapshot for the entire
* volume or the entire CG (Consistency Group)
*
@@ -574,29 +570,23 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
dict_t *rsp_dict)
{
char *volname = NULL;
- char *name = NULL;
+ char *snapname = NULL;
char *device = NULL;
char *tmpstr = NULL;
char *snap_brick_dir = NULL;
char snap_brick_path[PATH_MAX] = "";
char *mnt_pt = NULL;
- char snapname[PATH_MAX] = "";
- char tmp[2046] = "";
char key[PATH_MAX] = "";
char snap_mount[PATH_MAX] = "";
- char snapmntname[PATH_MAX] = "";
- char snapbrckcnt[PATH_MAX] = "";
- char snapbrckord[PATH_MAX] = "";
char snap_volname[64] = "";
char err_str[PATH_MAX] = "";
int ret = -1;
int64_t i = 0;
- int64_t volume_count = 0;
+ int64_t volcount = 0;
int64_t brick_count = 0;
int64_t brick_order = 0;
glusterd_brickinfo_t *brickinfo = NULL;
glusterd_volinfo_t *volinfo = NULL;
- gf_boolean_t is_cg = _gf_false;
xlator_t *this = NULL;
uuid_t *snap_volid = NULL;
gf_loglevel_t loglevel = GF_LOG_ERROR;
@@ -604,34 +594,34 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
this = THIS;
GF_ASSERT (op_errstr);
- ret = dict_get_int64 (dict, "volcount", &volume_count);
+ ret = dict_get_int64 (dict, "volcount", &volcount);
if (ret) {
- snprintf (err_str, sizeof (err_str), "failed to "
+ snprintf (err_str, sizeof (err_str), "Failed to "
"get the volume count");
goto out;
}
- GF_ASSERT (volume_count);
+ if (volcount <= 0) {
+ snprintf (err_str, sizeof (err_str), "Invalid volume count %ld "
+ "supplied", volcount);
+ ret = -1;
+ goto out;
+ }
- if (volume_count > 1) {
- is_cg = _gf_true;
- ret = dict_get_str (dict, "cg-name", &name);
- if (ret) {
- snprintf (err_str, sizeof (err_str),
- "failed to get cg-name");
- goto out;
- }
- } else {
- ret = dict_get_str (dict, "snap-name", &name);
- if (ret) {
- snprintf (err_str, sizeof (err_str),
- "failed to get snap-name");
- goto out;
- }
+ ret = dict_get_str (dict, "snapname", &snapname);
+ if (ret) {
+ snprintf (err_str, sizeof (err_str), "Failed to get snapname");
+ goto out;
}
- snprintf (snapname, sizeof (snapname), "%s", name);
- for (i = 0; i < volume_count; i++) {
- snprintf (key, sizeof (key), "volname%ld", i+1);
+ if (glusterd_find_snap_by_name (snapname)) {
+ ret = -1;
+ snprintf (err_str, sizeof (err_str), "Snap %s already exist",
+ snapname);
+ goto out;
+ }
+
+ for (i = 1; i <= volcount; i++) {
+ snprintf (key, sizeof (key), "volname%ld", i);
ret = dict_get_str (dict, key, &volname);
if (ret) {
snprintf (err_str, sizeof (err_str),
@@ -645,30 +635,30 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
"%s", volname);
goto out;
}
+
+ ret = -1;
if (!glusterd_is_volume_started (volinfo)) {
- ret = -1;
snprintf (err_str, sizeof (err_str),
"volume %s is not started",volinfo->volname);
loglevel = GF_LOG_WARNING;
goto out;
}
if (glusterd_is_defrag_on (volinfo)) {
- ret = -1;
snprintf (err_str, sizeof (err_str),
"rebalance process is running for the "
"volume %s", volname);
loglevel = GF_LOG_WARNING;
goto out;
}
+ /* TODO: Also check whether geo replication is running */
+
if (volinfo->is_snap_volume == _gf_true) {
- ret = -1;
snprintf (err_str, sizeof (err_str),
"Volume %s is a snap volume", volname);
loglevel = GF_LOG_WARNING;
goto out;
}
if (volinfo->snap_count >= volinfo->snap_max_hard_limit) {
- ret = -1;
snprintf (err_str, sizeof (err_str),
"The number of existing snaps has reached the "
"maximum limit of %"PRIu64" ,for the volume %s",
@@ -677,7 +667,7 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
goto out;
}
- snprintf (key, sizeof(key) - 1, "vol%ld_volid", i+1);
+ snprintf (key, sizeof(key) - 1, "vol%ld_volid", i);
ret = dict_get_bin (dict, key, (void **)&snap_volid);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
@@ -685,22 +675,11 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
goto out;
}
- /* snap uuid is used as lvm snapshot name.
+ /* snap volume uuid is used as lvm snapshot name.
This will avoid restrictions on snapshot names
provided by user */
GLUSTERD_GET_UUID_NOHYPHEN (snap_volname, *snap_volid);
- if (is_cg) {
- memset(snapname, '\0', sizeof (snapname));
- snprintf (tmp, sizeof (tmp), "%s_snap",
- volinfo->volname);
- snprintf (snapname, sizeof (snapname), "%s_%s",
- name, tmp);
- strcpy(snap_volname, snapname);
- }
-
- //Also check whether geo replication is running
-
brick_count = 0;
brick_order = 0;
/* Adding snap bricks mount paths to the dict */
@@ -710,10 +689,6 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
continue;
}
- memset (snapmntname, '\0', sizeof(snapmntname));
- memset (snapbrckord, '\0', sizeof(snapbrckord));
- memset (snap_mount, '\0', sizeof(snap_mount));
-
device = glusterd_get_brick_mount_details (brickinfo);
if (!device) {
snprintf (err_str, sizeof (err_str),
@@ -769,16 +744,15 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
snprintf (snap_brick_path, sizeof (snap_brick_path),
"%s/%s", snap_mount, snap_brick_dir);
- ret = snprintf (snapmntname, sizeof(snapmntname) - 1,
- "vol%ld.brick%ld", i+1, brick_count);
- snapmntname[ret] = '\0';
tmpstr = gf_strdup (snap_brick_path);
if (!tmpstr) {
ret = -1;
goto out;
}
- ret = dict_set_dynstr (rsp_dict, snapmntname, tmpstr);
+ snprintf (key, sizeof(key), "vol%ld.brick%ld", i,
+ brick_count);
+ ret = dict_set_dynstr (rsp_dict, key, tmpstr);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"Failed to set %s", snap_mount);
@@ -787,34 +761,28 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
}
tmpstr = NULL;
- ret = snprintf (snapbrckord, sizeof(snapbrckord) - 1,
- "vol%ld.brick%ld.order",
- i+1, brick_count);
- snapbrckord[ret] = '\0';
-
- ret = dict_set_int64 (rsp_dict, snapbrckord, brick_order);
+ snprintf (key, sizeof(key) - 1, "vol%ld.brick%ld.order",
+ i, brick_count);
+ ret = dict_set_int64 (rsp_dict, key, brick_order);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
- "Failed to set brick order");
+ "Failed to set %s", key);
goto out;
}
brick_count++;
brick_order++;
}
- memset (snapbrckcnt, '\0', sizeof(snapbrckcnt));
- ret = snprintf (snapbrckcnt, sizeof(snapbrckcnt) - 1,
- "vol%ld_brickcount", i+1);
-
- ret = dict_set_int64 (rsp_dict, snapbrckcnt, brick_count);
+ snprintf (key, sizeof(key) - 1, "vol%ld_brickcount", i);
+ ret = dict_set_int64 (rsp_dict, key, brick_count);
if (ret) {
gf_log ("", GF_LOG_ERROR, "Failed to set %s",
- snapbrckcnt);
+ key);
goto out;
}
}
- ret = dict_set_int64 (rsp_dict, "volcount", volume_count);
+ ret = dict_set_int64 (rsp_dict, "volcount", volcount);
if (ret) {
gf_log ("", GF_LOG_ERROR, "Failed to set volcount");
goto out;
@@ -842,9 +810,16 @@ glusterd_new_snap_object()
snap = GF_CALLOC (1, sizeof (*snap), gf_gld_mt_snap_t);
if (snap) {
- LOCK_INIT (&snap->lock);
+ if (LOCK_INIT (&snap->lock)) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed initiating"
+ " snap lock");
+ GF_FREE (snap);
+ return NULL;
+ }
+
INIT_LIST_HEAD (&snap->snap_list);
INIT_LIST_HEAD (&snap->volumes);
+ snap->snapname[0] = 0;
snap->snap_status = GD_SNAP_STATUS_INIT;
}
@@ -962,41 +937,6 @@ out:
return snap;
}
-glusterd_snap_t*
-glusterd_remove_snap_by_id (uuid_t snap_id)
-{
- glusterd_snap_t *snap = NULL;
-
- if (uuid_is_null(snap_id))
- goto out;
-
- snap = glusterd_find_snap_by_id (snap_id);
-
- if (snap) {
- snap->snap_status = GD_SNAP_STATUS_DECOMMISSION;
- list_del_init (&snap->snap_list);
- }
-out:
- return snap;
-}
-
-glusterd_snap_t*
-glusterd_remove_snap_by_name (char *snapname)
-{
- glusterd_snap_t *snap = NULL;
-
- GF_VALIDATE_OR_GOTO ("glusterd", snapname, out);
-
- snap = glusterd_find_snap_by_name (snapname);
-
- if (snap) {
- snap->snap_status = GD_SNAP_STATUS_DECOMMISSION;
- list_del_init (&snap->snap_list);
- }
-out:
- return snap;
-}
-
// Big lock should already acquired before this is called
int32_t
glusterd_add_snap_cg (glusterd_conf_t *conf, glusterd_snap_cg_t *cg)
@@ -1111,23 +1051,294 @@ out:
return entry;
}
+int
+glusterd_do_lvm_snapshot_remove (glusterd_volinfo_t *snap_vol,
+ glusterd_brickinfo_t *brickinfo,
+ const char *mount_pt, const char *snap_device)
+{
+ int ret = -1;
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+ runner_t runner = {0,};
+ char msg[1024] = {0, };
+ char pidfile[PATH_MAX] = {0, };
+ pid_t pid = -1;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ if (!brickinfo) {
+ gf_log (this->name, GF_LOG_ERROR, "brickinfo NULL");
+ goto out;
+ }
+
+ GF_ASSERT (snap_vol);
+ GF_ASSERT (mount_pt);
+ GF_ASSERT (snap_device);
+
+ GLUSTERD_GET_BRICK_PIDFILE (pidfile, snap_vol, brickinfo, priv);
+ if (glusterd_is_service_running (pidfile, &pid)) {
+ ret = kill (pid, SIGKILL);
+ if (ret && errno != ESRCH) {
+ gf_log (this->name, GF_LOG_ERROR, "Unable to kill pid "
+ "%d reason : %s", pid, strerror(errno));
+ goto out;
+ }
+ }
+
+ runinit (&runner);
+ snprintf (msg, sizeof (msg), "umount the snapshot mounted path %s",
+ mount_pt);
+ runner_add_args (&runner, "umount", mount_pt, NULL);
+ runner_log (&runner, "", GF_LOG_DEBUG, msg);
+
+ /* We need not do synclock_unlock => runner_run => synclock_lock here.
+ Because it is needed if we are running a glusterfs process in
+ runner_run, so that when the glusterfs process started wants to
+ communicate to glusterd, glusterd wont be able to respond if it
+ has held the big lock. So we do unlock, run glusterfs process
+ (thus communicate to glusterd), lock. But since this is not a
+ glusterfs command that is being run, unlocking and then relocking
+ is not needed.
+ */
+ ret = runner_run (&runner);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "unmounting the "
+ "path %s (brick: %s) failed (%s)", mount_pt,
+ brickinfo->path, strerror (errno));
+ goto out;
+ }
+
+ runinit (&runner);
+ snprintf (msg, sizeof(msg), "remove snapshot of the brick %s:%s, "
+ "device: %s", brickinfo->hostname, brickinfo->path,
+ snap_device);
+ runner_add_args (&runner, "/sbin/lvremove", "-f", snap_device, NULL);
+ runner_log (&runner, "", GF_LOG_DEBUG, msg);
+
+ ret = runner_run (&runner);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "removing snapshot of the "
+ "brick (%s:%s) of device %s failed",
+ brickinfo->hostname, brickinfo->path, snap_device);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
int32_t
-glusterd_delete_snap_volume (glusterd_volinfo_t *snapinfo)
+glusterd_lvm_snapshot_remove (glusterd_volinfo_t *snap_vol)
{
- int ret = -1;
- GF_ASSERT (snapinfo);
+ char *mnt_pt = NULL;
+ struct mntent *entry = NULL;
+ int32_t ret = -1;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ xlator_t *this = NULL;
+ FILE *mtab = NULL;
- ret = glusterd_store_delete_volume (snapinfo);
+ this = THIS;
+ GF_ASSERT (this);
- if (ret)
+ if (!snap_vol) {
+ gf_log (this->name, GF_LOG_ERROR, "snap volinfo is NULL");
goto out;
+ }
+
+ list_for_each_entry (brickinfo, &snap_vol->bricks, brick_list) {
+ if (uuid_compare (brickinfo->uuid, MY_UUID))
+ continue;
+
+ ret = glusterd_get_brick_root (brickinfo->path, &mnt_pt);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "getting the root "
+ "of the brick for volume %s (snap %s) failed ",
+ snap_vol->volname, snap_vol->snapshot->snapname);
+ goto out;
+ }
+
+ entry = glusterd_get_mnt_entry_info (mnt_pt, mtab);
+ if (!entry) {
+ gf_log (this->name, GF_LOG_WARNING, "getting the mount"
+ " entry for the brick %s:%s of the snap %s "
+ "(volume: %s) failed", brickinfo->hostname,
+ brickinfo->path, snap_vol->snapshot->snapname,
+ snap_vol->volname);
+ ret = -1;
+ goto out;
+ }
+ ret = glusterd_do_lvm_snapshot_remove (snap_vol, brickinfo,
+ mnt_pt, entry->mnt_fsname);
+ if (mtab)
+ endmntent (mtab);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to "
+ "remove the snapshot %s (%s)",
+ brickinfo->path, entry->mnt_fsname);
+ goto out;
+ }
+ }
- ret = glusterd_volinfo_delete (snapinfo);
+ ret = 0;
out:
- gf_log (THIS->name, GF_LOG_DEBUG, "returning %d", ret);
return ret;
}
+int32_t
+glusterd_snap_volume_remove (glusterd_volinfo_t *snap_vol,
+ gf_boolean_t force)
+{
+ int ret = -1;
+ int ret_1 = 0;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ glusterd_volinfo_t *origin_vol = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ if (!snap_vol) {
+ gf_log(this->name, GF_LOG_WARNING, "snap_vol in NULL");
+ ret_1 = -1;
+ goto out;
+ }
+
+ list_for_each_entry (brickinfo, &snap_vol->bricks, brick_list) {
+ if (uuid_compare (brickinfo->uuid, MY_UUID))
+ continue;
+
+ ret = glusterd_brick_stop (snap_vol, brickinfo, _gf_false);
+ if (ret) {
+ gf_log(this->name, GF_LOG_WARNING, "Failed to stop "
+ "brick for volume %s", snap_vol->volname);
+ ret_1 = ret;
+
+ /* Continue to cleaning up the snap in case of error
+ if force flag is enabled */
+ if (!force)
+ goto out;
+ }
+ }
+ ret = glusterd_lvm_snapshot_remove (snap_vol);
+ if (ret) {
+ gf_log(this->name, GF_LOG_WARNING, "Failed to remove "
+ "lvm snapshot volume %s", snap_vol->volname);
+ ret_1 = ret;
+ if (!force)
+ goto out;
+ }
+
+ ret = glusterd_store_delete_volume (snap_vol);
+ if (ret) {
+ gf_log(this->name, GF_LOG_WARNING, "Failed to remove volume %s "
+ "from store", snap_vol->volname);
+ ret_1 = ret;
+ if (!force)
+ goto out;
+ }
+
+ if (!list_empty(&snap_vol->snapvol_list) ) {
+ ret = glusterd_volinfo_find (snap_vol->parent_volname,
+ &origin_vol);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to get "
+ "parent volinfo %s for volume %s",
+ snap_vol->parent_volname, snap_vol->volname);
+ ret_1 = ret;
+ if (!force)
+ goto out;
+ }
+ origin_vol->snap_count--;
+ }
+
+ ret = glusterd_volinfo_delete (snap_vol);
+ if (ret) {
+ gf_log(this->name, GF_LOG_WARNING, "Failed to remove volinfo "
+ "%s ", snap_vol->volname);
+ ret_1 = ret;
+ if (!force)
+ goto out;
+ }
+
+out:
+ gf_log (this->name, GF_LOG_TRACE, "returning %d", ret_1);
+ return ret_1;
+}
+
+int32_t
+glusterd_snapobject_delete (glusterd_snap_t *snap)
+{
+ if (snap == NULL) {
+ gf_log(THIS->name, GF_LOG_WARNING, "snap in NULL");
+ return -1;
+ }
+
+ list_del_init (&snap->snap_list);
+ list_del_init (&snap->volumes);
+ if (LOCK_DESTROY(&snap->lock))
+ gf_log (THIS->name, GF_LOG_WARNING, "Failed destroying lock"
+ "of snap %s", snap->snapname);
+
+ GF_FREE (snap->description);
+ GF_FREE (snap);
+
+ return 0;
+}
+
+int32_t
+glusterd_snap_remove (glusterd_snap_t *snap,
+ gf_boolean_t force)
+{
+ int ret = -1;
+ int ret_1 = 0;
+ glusterd_volinfo_t *snap_vol = NULL;
+ glusterd_volinfo_t *tmp = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ if (!snap) {
+ gf_log(this->name, GF_LOG_WARNING, "snap in NULL");
+ ret_1 = -1;
+ goto out;
+ }
+
+ list_for_each_entry_safe (snap_vol, tmp, &snap->volumes, vol_list) {
+ ret = glusterd_snap_volume_remove (snap_vol, force);
+ if (ret) {
+ gf_log(this->name, GF_LOG_WARNING, "Failed to remove "
+ "volinfo %s for snap %s", snap_vol->volname,
+ snap->snapname);
+ ret_1 = ret;
+
+ /* Continue to cleaning up the snap in case of error
+ if force flag is enabled */
+ if (!force)
+ goto out;
+ }
+ }
+
+ ret = glusterd_store_delete_snap (snap);
+ if (ret) {
+ gf_log(this->name, GF_LOG_WARNING, "Failed to remove snap %s "
+ "from store", snap->snapname);
+ ret_1 = ret;
+ if (!force)
+ goto out;
+ }
+
+ ret = glusterd_snapobject_delete (snap);
+ if (ret)
+ gf_log (this->name, GF_LOG_WARNING, "Failed to delete "
+ "snap object %s", snap->snapname);
+
+out:
+ gf_log (THIS->name, GF_LOG_TRACE, "returning %d", ret_1);
+ return ret_1;
+}
+
/* This function will retrieve the details of a single snap
* and then serialize them to dictionary (dict)
* This function is called under snap lock
@@ -2345,15 +2556,13 @@ glusterd_handle_snapshot_create (rpcsvc_request_t *req, glusterd_op_t op,
{
int ret = -1;
char *volname = NULL;
- char *name = NULL;
+ char *snapname = NULL;
int64_t volcount = 0;
xlator_t *this = NULL;
char key[PATH_MAX] = "";
char *username = NULL;
char *password = NULL;
- gf_boolean_t is_cg = _gf_false;
- uuid_t *cg_id = NULL;
- uuid_t *snap_volid = NULL;
+ uuid_t *uuid_ptr = NULL;
uuid_t tmp_uuid = {0};
int i = 0;
@@ -2369,54 +2578,39 @@ glusterd_handle_snapshot_create (rpcsvc_request_t *req, glusterd_op_t op,
"get the volume count");
goto out;
}
- GF_ASSERT (volcount);
-
- if (volcount > 1) {
- is_cg = _gf_true;
- ret = dict_get_str (dict, "cg-name", &name);
- } else {
- ret = dict_get_str (dict, "snap-name", &name);
+ if (volcount <= 0) {
+ gf_log (this->name, GF_LOG_ERROR, "Invalid volume count %ld "
+ "supplied", volcount);
+ ret = -1;
+ goto out;
}
- if (!name) {
- name = generate_snapname (NULL, NULL, is_cg);
- if (!name) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to generate snapname");
- goto out;
- }
+ ret = dict_get_str (dict, "snapname", &snapname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to get the snapname");
+ goto out;
+ }
- if (!is_cg)
- ret = dict_set_dynstr (dict, "snap-name", name);
- else
- ret = dict_set_dynstr (dict, "cg-name", name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to set %s",
- is_cg?"cg name":"snap name");
- ret = -1;
- GF_FREE (name);
- goto out;
- }
+ uuid_ptr = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
+ if (!uuid_ptr) {
+ gf_log (this->name, GF_LOG_ERROR, "Out Of Memory");
+ ret = -1;
+ goto out;
}
- if (volcount > 1) {
- /* Generate a cg-id for this operation and
- * save it in the dict */
- cg_id = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
- if (!cg_id) {
- gf_log (this->name, GF_LOG_ERROR, "Out Of Memory");
- ret = -1;
- goto out;
- }
+ uuid_generate (*uuid_ptr);
+ ret = dict_set_bin (dict, "snap-id", uuid_ptr, sizeof(uuid_t));
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Unable to set snap-id");
+ GF_FREE (uuid_ptr);
+ goto out;
+ }
+ uuid_ptr = NULL;
- uuid_generate (*cg_id);
- ret = dict_set_bin (dict, "cg-id", cg_id, sizeof(uuid_t));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set cg-id");
- GF_FREE (cg_id);
- goto out;
- }
+ ret = dict_set_int64 (dict, "snap-time", (int64_t)time(NULL));
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Unable to set snap-time");
+ goto out;
}
for (i = 1; i <= volcount; i++) {
@@ -2451,20 +2645,20 @@ glusterd_handle_snapshot_create (rpcsvc_request_t *req, glusterd_op_t op,
goto out;
}
- snap_volid = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
- if (!snap_volid) {
+ uuid_ptr = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
+ if (!uuid_ptr) {
gf_log (this->name, GF_LOG_ERROR, "Out Of Memory");
ret = -1;
goto out;
}
snprintf (key, sizeof(key) - 1, "vol%d_volid", i);
- uuid_generate (*snap_volid);
- ret = dict_set_bin (dict, key, snap_volid, sizeof(uuid_t));
+ uuid_generate (*uuid_ptr);
+ ret = dict_set_bin (dict, key, uuid_ptr, sizeof(uuid_t));
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"Unable to set snap_volid");
- GF_FREE (snap_volid);
+ GF_FREE (uuid_ptr);
goto out;
}
}
@@ -2585,32 +2779,6 @@ out:
}
int32_t
-glusterd_snap_delete (glusterd_snap_t *snap)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- if (!snap) {
- gf_log (this->name, GF_LOG_WARNING, "snap object is NULL");
- goto out;
- }
-
- ret = glusterd_store_delete_snap (snap);
- if (ret)
- goto out;
-
- GF_FREE (snap->description);
- GF_FREE (snap);
- ret = 0;
-
-out:
- return ret;
-}
-
-int32_t
glusterd_cg_delete (glusterd_snap_cg_t *cg)
{
int32_t ret = -1;
@@ -2633,88 +2801,105 @@ out:
return ret;
}
-/* this should be the last thing to be done.
- 1. Do op stage related checks such as whether volume is there or not etc
- 2. Do quorum checks.
- 3. Then do this and take the snapshot OR take the snapshot and build the
- snap object (Can be decided later)
-*/
glusterd_snap_t*
-glusterd_snap_create (glusterd_volinfo_t *volinfo,
- char *snapname, uuid_t *snap_id,
- char *description, uuid_t *cg_id,
- glusterd_snap_cg_t *cg, char *cg_name)
+glusterd_create_snap_object (dict_t *dict)
{
- glusterd_snap_t *snap = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- int ret = -1;
+ char *snapname = NULL;
+ uuid_t *snap_id = NULL;
+ char *description = NULL;
+ glusterd_snap_t *snap = NULL;
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+ int ret = -1;
+ int64_t time_stamp = 0;
this = THIS;
priv = this->private;
- GF_ASSERT (snap_id);
- GF_ASSERT (snapname);
- if (cg_id)
- GF_ASSERT (cg_name);
+ GF_ASSERT (dict);
- if (!volinfo) {
- gf_log (this->name, GF_LOG_ERROR, "volinfo is NULL");
+ /* Fetch snapname, description, id and time from dict */
+ ret = dict_get_str (dict, "snapname", &snapname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Unable to fetch snapname");
+ goto out;
+ }
+
+ /* Ignore ret value for description*/
+ ret = dict_get_str (dict, "description", &description);
+
+ ret = dict_get_bin (dict, "snap-id", (void **)&snap_id);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Unable to fetch snap_id");
+ goto out;
+ }
+
+ ret = dict_get_int64 (dict, "snap-time", &time_stamp);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Unable to fetch snap-time");
+ goto out;
+ }
+ if (time_stamp <= 0) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_ERROR, "Invalid time-stamp: %ld",
+ time_stamp);
+ goto out;
+ }
+
+ list_for_each_entry (snap, &priv->snapshots, snap_list) {
+ if (!strcmp (snap->snapname, snapname) ||
+ !uuid_compare (snap->snap_id, *snap_id)) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Found duplicate snap %s (%s)",
+ snap->snapname, uuid_utoa (snap->snap_id));
+ ret = -1;
+ break;
+ }
+ }
+ if (ret) {
+ snap = NULL;
goto out;
}
snap = glusterd_new_snap_object ();
if (!snap) {
- gf_log (this->name, GF_LOG_ERROR, "could not create "
- "the snap object fot the volume %s (snap: %s)",
- volinfo->volname, snapname);
+ gf_log (this->name, GF_LOG_ERROR, "Could not create "
+ "the snap object for snap %s", snapname);
goto out;
}
-
- // for now ignore if description is not strduped
+ strcpy (snap->snapname, snapname);
+ uuid_copy (snap->snap_id, *snap_id);
+ snap->time_stamp = (time_t)time_stamp;
+ snap->snap_status = GD_SNAP_STATUS_IN_USE;
if (description) {
- if (cg_id) {
- cg->description = gf_strdup (description);
- if (cg->description == NULL) {
- gf_log ("", GF_LOG_ERROR,
- "Saving the CG Description Failed");
- ret = -1;
- goto out;
- }
- }
- else {
- snap->description = gf_strdup (description);
- if (snap->description == NULL) {
- gf_log ("", GF_LOG_ERROR,
- "Saving the Snap Description Failed");
- ret = -1;
- goto out;
- }
+ snap->description = gf_strdup (description);
+ if (snap->description == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Saving the Snap Description Failed");
+ ret = -1;
+ goto out;
}
}
- snap->time_stamp = time (NULL);
- uuid_copy (snap->snap_id, *snap_id);
- if (cg_id){
- uuid_copy (snap->cg_id, *cg_id);
- strncpy (snap->cg_name, cg_name,
- sizeof (snap->cg_name) - 1);
+
+ ret = glusterd_store_snap (snap);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "Could not store snap"
+ "object %s", snap->snapname);
+ goto out;
}
- strcpy (snap->snapname, snapname);
- snap->snap_status = GD_SNAP_STATUS_IN_USE;
+ list_add_order (&snap->snap_list, &priv->snapshots,
+ glusterd_compare_snap_time);
+ gf_log (this->name, GF_LOG_TRACE, "Snap %s added to the list",
+ snap->snapname);
ret = 0;
+
out:
if (ret) {
- if (snap) {
- list_del_init (&snap->snap_list);
- list_del_init (&snap->volumes);
- LOCK_DESTROY (&snap->lock);
- GF_FREE (snap->description);
- GF_FREE (snap->snap_volume);
- GF_FREE (snap);
- }
- snap = NULL;
+ if (snap)
+ glusterd_snap_remove (snap, _gf_true);
+ snap=NULL;
}
return snap;
@@ -2722,7 +2907,7 @@ out:
/* This function is called to get the device path of the snap lvm. Usually
if /dev/mapper/<group-name>-<lvm-name> is the device for the lvm,
- then the snap device will be /dev/<group-name>/<snap-name>.
+ then the snap device will be /dev/<group-name>/<snapname>.
This function takes care of building the path for the snap device.
*/
char *
@@ -2792,23 +2977,21 @@ out:
then call the glusterd_snap_create function to create the snap object
for glusterd
*/
-int
-glusterd_take_snapshot (glusterd_brickinfo_t *brickinfo, char *volname,
- char *snapname, char **snap_device)
+char *
+glusterd_take_lvm_snapshot (glusterd_volinfo_t *snap_vol,
+ glusterd_brickinfo_t *brickinfo)
{
char msg[NAME_MAX] = "";
char buf[PATH_MAX] = "";
- char *tmp = NULL;
+ char *snap_device = NULL;
char *ptr = NULL;
char *device = NULL;
int ret = -1;
gf_boolean_t match = _gf_false;
- glusterd_conf_t *priv = NULL;
runner_t runner = {0,};
xlator_t *this = NULL;
this = THIS;
- priv = this->private;
if (!brickinfo) {
gf_log (this->name, GF_LOG_ERROR, "brickinfo NULL");
@@ -2857,10 +3040,10 @@ glusterd_take_snapshot (glusterd_brickinfo_t *brickinfo, char *volname,
if (match == _gf_true)
runner_add_args (&runner, "/sbin/lvcreate", "-s", device,
"--setactivationskip", "n", "--name",
- snapname, NULL);
+ snap_vol->volname, NULL);
else
runner_add_args (&runner, "/sbin/lvcreate", "-s", device,
- "--name", snapname, NULL);
+ "--name", snap_vol->volname, NULL);
runner_log (&runner, "", GF_LOG_DEBUG, msg);
ret = runner_start (&runner);
if (ret) {
@@ -2872,22 +3055,18 @@ glusterd_take_snapshot (glusterd_brickinfo_t *brickinfo, char *volname,
}
runner_end (&runner);
- gf_log (this->name, GF_LOG_INFO, "device: %s", device);
- if (device) {
- tmp = glusterd_build_snap_device_path (device, snapname);
- *snap_device = tmp;
- if (!*snap_device) {
- gf_log (this->name, GF_LOG_WARNING, "cannot copy the "
- "snapshot device name (volname: %s, "
- "snapname: %s)", volname, snapname);
- ret = -1;
- goto out;
- }
+ snap_device = glusterd_build_snap_device_path (device,
+ snap_vol->volname);
+ if (!snap_device) {
+ gf_log (this->name, GF_LOG_WARNING, "Cannot copy the snapshot "
+ "device name for snap %s (volume id: %s)",
+ snap_vol->snapshot->snapname, snap_vol->volname);
+ ret = -1;
+ goto out;
}
out:
- gf_log ("", GF_LOG_TRACE, "Returning %d", ret);
- return ret;
+ return snap_device;
}
int32_t
@@ -3036,27 +3215,20 @@ out:
return ret;
}
-/* TODO: lvm uses '-' as the delimter for differentiating the logical volume
- name and the volume group name. So as of now, if the snapname given from
- cli contains '-', it confuses lvm. Handle it.
-*/
-int32_t
-glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict,
- glusterd_snap_cg_t *cg, uuid_t *cg_id, int volcount,
- uuid_t *snap_volid, char *cg_name)
+glusterd_volinfo_t *
+glusterd_do_snap_vol (glusterd_volinfo_t *origin_vol, glusterd_snap_t *snap,
+ dict_t *dict, int64_t volcount)
{
char *snap_brick_mount_path = "";
- char snapmntname[PATH_MAX] = "";
- char tmpname[PATH_MAX] = "";
+ char key[PATH_MAX] = "";
char *device = NULL;
- char *description = NULL;
char *username = NULL;
char *password = NULL;
glusterd_brickinfo_t *snap_brickinfo = NULL;
glusterd_brickinfo_t *brickinfo = NULL;
glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *snap_volume = NULL;
- glusterd_snap_t *snap = NULL;
+ glusterd_volinfo_t *snap_vol = NULL;
+ uuid_t *snap_volid = NULL;
int32_t ret = -1;
int32_t brick_count = 0;
xlator_t *this = NULL;
@@ -3066,82 +3238,72 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict,
priv = this->private;
GF_ASSERT (priv);
- GF_ASSERT (volinfo);
- GF_ASSERT (snapname);
+ GF_ASSERT (origin_vol);
GF_ASSERT (dict);
- if (cg_id)
- GF_ASSERT (cg_name);
- snap = glusterd_snap_create (volinfo, snapname, snap_volid,
- description, cg_id, cg, cg_name);
- if (!snap) {
- gf_log (this->name, GF_LOG_ERROR, "creating the "
- "snap object failed for the volume %s",
- volinfo->volname);
- ret = -1;
+ /* fetch username, password and vol_id from dict*/
+
+ snprintf (key, sizeof(key), "volume%ld_username", volcount);
+ ret = dict_get_str (dict, key, &username);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to get %s for "
+ "snap %s", key, snap->snapname);
goto out;
}
- ret = glusterd_volinfo_dup (volinfo, &snap_volume);
+ snprintf (key, sizeof(key), "volume%ld_password", volcount);
+ ret = dict_get_str (dict, key, &password);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to duplicate volinfo "
- "for the snapshot %s", snapname);
+ gf_log (this->name, GF_LOG_ERROR, "Failed to get %s for "
+ "snap %s", key, snap->snapname);
goto out;
}
-
- /* snap uuid is used as lvm snapshot name.
- This will avoid restrictions on snapshot names provided by user */
- GLUSTERD_GET_UUID_NOHYPHEN (snap_volume->volname, *snap_volid);
- snap_volume->snapshot = snap;
- snap_volume->is_snap_volume = _gf_true;
- strncpy (snap_volume->parent_volname, volinfo->volname,
- sizeof(snap_volume->parent_volname) - 1);
- uuid_copy (snap_volume->volume_id, *snap_volid);
- snap->snap_volume = snap_volume;
-
- /* fetch internal username and password for the snap*/
-
- snprintf (tmpname, sizeof(tmpname), "volume%d_username", volcount);
- ret = dict_get_str (dict, tmpname, &username);
+ snprintf (key, sizeof(key) - 1, "vol%ld_volid", volcount);
+ ret = dict_get_bin (dict, key, (void **)&snap_volid);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get snap username for "
- "volume %s", volinfo->volname);
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to fetch snap_volid");
goto out;
}
- snprintf (tmpname, sizeof(tmpname), "volume%d_password", volcount);
- ret = dict_get_str (dict, tmpname, &password);
+ ret = glusterd_volinfo_dup (origin_vol, &snap_vol);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get snap password for "
- "volume %s", volinfo->volname);
+ gf_log (this->name, GF_LOG_ERROR, "Failed to duplicate volinfo "
+ "for the snapshot %s", snap->snapname);
goto out;
}
- glusterd_auth_set_username (snap_volume, username);
- glusterd_auth_set_password (snap_volume, password);
+ /* uuid is used as lvm snapshot name.
+ This will avoid restrictions on snapshot names provided by user */
+ GLUSTERD_GET_UUID_NOHYPHEN (snap_vol->volname, *snap_volid);
+ uuid_copy (snap_vol->volume_id, *snap_volid);
+ snap_vol->is_snap_volume = _gf_true;
+ strcpy (snap_vol->parent_volname, origin_vol->volname);
+ snap_vol->snapshot = snap;
+ snap->snap_volume = snap_vol;
+
+ glusterd_auth_set_username (snap_vol, username);
+ glusterd_auth_set_password (snap_vol, password);
/* Adding snap brickinfos to the snap volinfo */
brick_count = 0;
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ list_for_each_entry (brickinfo, &origin_vol->bricks, brick_list) {
snap_brickinfo = NULL;
device = NULL;
ret = glusterd_brickinfo_new (&snap_brickinfo);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"initializing the brick for the snap "
- "volume failed (snapname: %s)", snap_volume->volname);
+ "volume failed (snapname: %s)", snap->snapname);
goto out;
}
- memset (snapmntname, '\0', sizeof(snapmntname));
- ret = snprintf (snapmntname, sizeof(snapmntname) - 1,
- "vol%d.brick%d", volcount, brick_count);
- snapmntname[ret] = '\0';
-
- ret = dict_get_ptr (dict, snapmntname, (void **)&snap_brick_mount_path);
+ snprintf (key, sizeof(key) - 1, "vol%ld.brick%d", volcount,
+ brick_count);
+ ret = dict_get_ptr (dict, key, (void **)&snap_brick_mount_path);
if (ret) {
gf_log ("", GF_LOG_ERROR, "Unable to fetch "
- "snap mount path (%s)", snapmntname);
+ "snap mount path (%s)", key);
GF_FREE (snap_brickinfo);
goto out;
}
@@ -3149,39 +3311,30 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict,
strcpy (snap_brickinfo->hostname, brickinfo->hostname);
strcpy (snap_brickinfo->path, snap_brick_mount_path);
uuid_copy (snap_brickinfo->uuid, brickinfo->uuid);
- LOCK (&snap_volume->lock);
- {
- list_add_tail (&snap_brickinfo->brick_list,
- &snap_volume->bricks);
- }
- UNLOCK (&snap_volume->lock);
+ list_add_tail (&snap_brickinfo->brick_list, &snap_vol->bricks);
brick_count++;
}
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (uuid_compare (brickinfo->uuid, MY_UUID)) {
+ list_for_each_entry (brickinfo, &origin_vol->bricks, brick_list) {
+ if (uuid_compare (brickinfo->uuid, MY_UUID))
continue;
- }
if (!glusterd_is_brick_started (brickinfo)) {
gf_log (this->name, GF_LOG_WARNING, "brick %s:%s is not"
" started (volume: %s snap: %s)",
brickinfo->hostname, brickinfo->path,
- volinfo->volname, snapname);
+ origin_vol->volname, snap->snapname);
continue;
}
- ret = glusterd_take_snapshot (brickinfo,
- volinfo->volname,
- snap_volume->volname, &device);
+ device = glusterd_take_lvm_snapshot (snap_vol, brickinfo);
/* Fail the snapshot even though snapshot on one of
the bricks fails. At the end when we check whether
the snapshot volume meets quorum or not, then the
the snapshot can either be treated as success, or
in case of failure we can undo the changes and return
- failure to cli.
- */
- if (ret) {
+ failure to cli. */
+ if (!device) {
gf_log (this->name, GF_LOG_ERROR,
"Failed to take snapshot of %s:%s",
brickinfo->hostname, brickinfo->path);
@@ -3189,165 +3342,85 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict,
}
/* create the complete brick here */
- ret = glusterd_snap_brick_create (device, snap_volume,
- brickinfo);
+ ret = glusterd_snap_brick_create (device, snap_vol, brickinfo);
+ GF_FREE (device);
+ device = NULL;
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "not able to"
" create the brickinfo for the snap %s"
- ", volume %s", snapname,
- volinfo->volname);
+ ", volume %s", snap->snapname,
+ origin_vol->volname);
goto out;
}
}
- //TODO: the quorum check of the snap volume here
-
- ret = glusterd_store_snap (snap);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Could not store snap"
- "object after taking the snapshot (volume: %s)",
- volinfo->volname);
- goto out;
- }
+ /*TODO: the quorum check of the snap volume here */
- ret = glusterd_store_volinfo (snap_volume,
+ ret = glusterd_store_volinfo (snap_vol,
GLUSTERD_VOLINFO_VER_AC_INCREMENT);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "Failed to store snapshot "
- "volinfo (%s) for volume %s", snap_volume->volname,
- volinfo->volname);
+ "volinfo (%s) for snap %s", snap_vol->volname,
+ snap->snapname);
goto out;
}
- ret = generate_snap_brick_volfiles (volinfo, snap_volume);
+ ret = generate_snap_brick_volfiles (origin_vol, snap_vol);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "generating the brick "
"volfiles for the snap %s (volume: %s) failed",
- snapname, volinfo->volname);
+ snap->snapname, origin_vol->volname);
goto out;
}
- ret = generate_snap_client_volfiles (volinfo, snap_volume,
+ ret = generate_snap_client_volfiles (origin_vol, snap_vol,
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",
- snapname, volinfo->volname);
+ snap->snapname, origin_vol->volname);
goto out;
}
-
- ret = generate_snap_client_volfiles (volinfo, snap_volume,
+ ret = generate_snap_client_volfiles (origin_vol, snap_vol,
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",
- snapname, volinfo->volname);
+ snap->snapname, origin_vol->volname);
goto out;
}
- list_add_tail (&snap->snap_list, &priv->snapshots);
- ret = glusterd_list_add_snapvol (volinfo, snap_volume);
+ ret = glusterd_list_add_snapvol (origin_vol, snap_vol);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "could not add the snap "
- "volume %s to the list",
- snap_volume->volname);
+ "volume %s to the list", snap_vol->volname);
goto out;
}
- list_for_each_entry (brickinfo, &snap_volume->bricks, brick_list) {
+ list_for_each_entry (brickinfo, &snap_vol->bricks, brick_list) {
if (uuid_compare (brickinfo->uuid, MY_UUID))
continue;
- ret = glusterd_brick_start (snap_volume, brickinfo,
- _gf_true);
+ 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, snapname, volinfo->volname);
+ "failed", brickinfo->hostname, brickinfo->path,
+ snap->snapname, origin_vol->volname);
goto out;
}
}
- snap_volume->status = GLUSTERD_STATUS_STARTED;
+ snap_vol->status = GLUSTERD_STATUS_STARTED;
out:
if (ret) {
- if (snap_volume) {
- list_del_init (&snap_volume->vol_list);
- list_del_init (&snap_volume->snapvol_list);
- glusterd_delete_snap_volume (snap_volume);
- }
-
- if (snap) {
- glusterd_remove_snap_by_name (snap->snapname);
- glusterd_snap_delete (snap);
- }
+ if (snap_vol)
+ glusterd_snap_volume_remove (snap_vol, _gf_true);
+ snap_vol = NULL;
}
- gf_log ("", GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* This function helps in generating the names for either the snapshot
- (if only one volume name is given in the snap create command) or
- the consistency group (if multiple volume names are given in the snaap
- create command). Apart from that, it also helps in generating the names
- for the snaps of the individual volumes in a consistency group.
-*/
-char *
-generate_snapname (char *volname, char *name, gf_boolean_t volume_from_cg)
-{
- char internal_snapname[PATH_MAX] = {0, };
- char timestr[256] = {0, };
- int ret = -1;
- char *snapname = NULL;
- struct timeval tv = {0, };
- xlator_t *this = NULL;
- int i = 0;
-
- this = THIS;
- GF_ASSERT (this);
-
- if (name) {
- GF_ASSERT (volname);
- if (volume_from_cg) {
- snprintf (internal_snapname, sizeof (internal_snapname),
- "%s_%s_snap", name, volname);
- } else {
- snprintf (internal_snapname, sizeof (internal_snapname),
- "%s", name);
- }
- } else {
- ret = gettimeofday (&tv, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "getting time failed. snapname is not given via"
- "cli. ");
- goto out;
- }
- gf_time_fmt (timestr, sizeof (timestr),
- tv.tv_sec, gf_timefmt_FT);
- snprintf (timestr + strlen (timestr),
- sizeof timestr - strlen (timestr),
- ".%"GF_PRI_SUSECONDS,
- tv.tv_usec);
-
- for (i = 0; i < strlen (timestr); i++) {
- if (timestr[i] == ' ' || timestr[i] == ':' ||
- timestr[i] == '.' || timestr[i] == '-')
- timestr[i] = '_';
- }
-
- snprintf (internal_snapname,
- sizeof (internal_snapname), "%s%s",
- (volume_from_cg)?"cg_":"",
- timestr);
- }
-
- snapname = gf_strdup (internal_snapname);
-out:
- return snapname;
+ return snap_vol;
}
/* This is a snapshot remove handler function. This function will be
@@ -3366,72 +3439,59 @@ int
glusterd_handle_snapshot_remove (rpcsvc_request_t *req, glusterd_op_t op,
dict_t *dict, char *err_str, size_t len)
{
- int ret = -1;
- int64_t vol_count = 0;
- char *volname = NULL;
+ int ret = -1;
+ int64_t volcount = 0;
char *snapname = NULL;
- char *cgname = NULL;
- glusterd_conf_t *conf = NULL;
- glusterd_snap_cg_t *cg = NULL;
+ char *volname = NULL;
+ char key[PATH_MAX] = "";
+ glusterd_snap_t *snap = NULL;
+ glusterd_volinfo_t *snap_vol = NULL;
+ glusterd_volinfo_t *tmp = NULL;
xlator_t *this = NULL;
this = THIS;
- GF_ASSERT (this);
- conf = this->private;
-
- GF_ASSERT (conf);
GF_ASSERT (req);
GF_ASSERT (dict);
GF_ASSERT (err_str);
- /* If volume name is provided then volcount will be set */
- ret = dict_get_int64 (dict, "volcount", &vol_count);
+ ret = dict_get_str (dict, "snapname", &snapname);
if (ret) {
- /* If volcount is not provided then cgname must be there */
- ret = dict_get_str (dict, "cgname", &cgname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "get neither volcount nor cgname");
- goto out;
- }
- } else {
- /* TODO: Change the index to 0 when mgmt v3 code is fixed */
- ret = dict_get_str (dict, "volname1", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "get volname");
- goto out;
- }
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "get snapname");
- goto out;
- }
+ gf_log (this->name, GF_LOG_ERROR, "Failed to get snapname");
+ goto out;
}
- if (NULL != cgname) {
- cg = glusterd_find_snap_cg_by_name (conf, cgname);
+ snap = glusterd_find_snap_by_name (snapname);
+ if (!snap){
+ gf_log (this->name, GF_LOG_ERROR, "Snap %s does not exist",
+ snapname);
+ ret = -1;
+ goto out;
+ }
- if (NULL == cg) {
- snprintf (err_str, len, "CG %s does not exist", cgname);
- gf_log (this->name, GF_LOG_WARNING, "%s", err_str);
+ /* Set volnames in the dict to get volume lock */
+ list_for_each_entry_safe (snap_vol, tmp, &snap->volumes, vol_list) {
+ volcount++;
+ volname = gf_strdup (snap_vol->parent_volname);
+ if (!volname) {
ret = -1;
+ gf_log (this->name, GF_LOG_ERROR, "strdup failed");
goto out;
}
- LOCK (&cg->lock);
- {
- /* Get the volumes belong to CG */
- ret = glusterd_get_cg_volume_names_lk (dict, cg);
- }
- UNLOCK (&cg->lock);
-
+ snprintf (key, sizeof (key), "volname%ld", volcount);
+ ret = dict_set_dynstr (dict, key, volname);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "volume names of %s CG", cgname);
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set "
+ "volume name in dictionary");
+ GF_FREE (volname);
goto out;
}
+ volname = NULL;
+ }
+ ret = dict_set_int64 (dict, "volcount", volcount);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set volcount");
+ goto out;
}
ret = glusterd_mgmt_v3_initiate_snap_phases (req, op, dict);
@@ -3442,7 +3502,6 @@ glusterd_handle_snapshot_remove (rpcsvc_request_t *req, glusterd_op_t op,
}
ret = 0; /* Success */
-
out:
return ret;
}
@@ -3451,368 +3510,32 @@ int
glusterd_snapshot_remove_prevalidate (dict_t *dict, char **op_errstr,
dict_t *rsp_dict)
{
- int32_t ret = -1;
- char *volname = NULL;
- char *name = NULL;
+ int32_t ret = -1;
+ char *snapname = NULL;
xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
glusterd_snap_t *snap = NULL;
- glusterd_snap_cg_t *cg = NULL;
- char volname_buf[PATH_MAX] = {0, };
- glusterd_volinfo_t *volinfo = NULL;
- char err_str[PATH_MAX] = {0, };
- int64_t volcount = 0;
- int64_t i = 0;
- int64_t j = 0;
- gf_boolean_t volume_found = _gf_false;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
- GF_ASSERT (op_errstr);
-
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR, "input dict is NULL");
- goto out;
- }
-
- ret = dict_get_int64 (dict, "volcount", &volcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "getting volcount failed");
- goto out;
- }
-
- /* TODO: The policy for the snapshot create is not decided on
- whether to start the snap volume upon the execution of the
- snapshot create command. Once the policy is decided, check
- here whether the volume is in use before delete command is
- executed. (May be a force option to delete forcefully even
- when the snap volume is in use.)
- */
-
- if (volcount > 1) {
- ret = dict_get_str (dict, "cgname", &name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "getting the cg name"
- " failed");
- goto out;
- }
- cg = glusterd_find_snap_cg_by_name (conf, name);
- if (!cg) {
- snprintf (err_str, sizeof (err_str), "consistency group"
- "%s does not exist", name);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- *op_errstr = gf_strdup (err_str);
- goto out;
- }
- GF_ASSERT (volcount == cg->volume_count);
-
- for (i = 0; i < volcount; i++) {
- volume_found = _gf_false;
- snprintf (volname_buf, sizeof (volname_buf),
- "volname%ld", i+1);
- ret = dict_get_str (dict, volname_buf, &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "volume name "
- "is notgiven");
- goto out;
- }
- for (j = 0; j < volcount; j++) {
- volinfo = cg->volumes[j];
- if (!strcmp (volinfo->volname, volname)) {
- volume_found = _gf_true;
- break;
- }
- }
- if (!volume_found) {
- gf_log (this->name, GF_LOG_ERROR, "volume %s"
- " is not found in the consistency "
- "group %s", volname, name);
- goto out;
- }
- }
- } else {
- snprintf (volname_buf, sizeof (volname_buf), "volname1");
- ret = dict_get_str (dict, volname_buf, &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "volume name is not "
- "given");
- goto out;
- }
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Volume %s does "
- "not exist", volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- *op_errstr = gf_strdup (err_str);
- goto out;
- }
- ret = dict_get_str (dict, "snapname", &name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "getting snap name "
- "failed (volume: %s)", volname);
- goto out;
- }
- snap = glusterd_find_snap_by_name (name);
- if (!snap) {
- ret = -1;
- snprintf (err_str, sizeof (err_str), "snap %s does "
- "not exist", name);
- gf_log (this->name, GF_LOG_ERROR, "%s, (volume: %s)",
- err_str, volinfo->volname);
- *op_errstr = gf_strdup (err_str);
- goto out;
- }
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-glusterd_remove_snap (glusterd_volinfo_t *snap_vol,
- glusterd_brickinfo_t *brickinfo, const char *mount_pt,
- const char *snap_device)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- runner_t runner = {0,};
- char msg[1024] = {0, };
- char pidfile[PATH_MAX] = {0, };
- pid_t pid = -1;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- if (!brickinfo) {
- gf_log (this->name, GF_LOG_ERROR, "brickinfo NULL");
- goto out;
- }
-
- GF_ASSERT (snap_vol);
- GF_ASSERT (mount_pt);
- GF_ASSERT (snap_device);
-
- /* sleep for some time so that the glusterfsd process associated
- with the snap lvm does not have any reference to the snap and
- has been stopped completely
- TODO: find the issue because of which umount fails and fix it.
- */
- //usleep (24007);
-
- //ret = umount2 (mount_pt, MNT_FORCE);
-
- GLUSTERD_GET_BRICK_PIDFILE (pidfile, snap_vol, brickinfo, priv);
- if (glusterd_is_service_running (pidfile, &pid)) {
- ret = kill (pid, SIGKILL);
- if (ret && errno != ESRCH) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to kill pid "
- "%d reason : %s", pid, strerror(errno));
- goto out;
- }
- }
-
- runinit (&runner);
- snprintf (msg, sizeof (msg), "umount the snapshot mounted path %s",
- mount_pt);
- runner_add_args (&runner, "umount", mount_pt, NULL);
- runner_log (&runner, "", GF_LOG_DEBUG, msg);
-
- /* We need not do synclock_unlock => runner_run => synclock_lock here.
- Because it is needed if we are running a glusterfs process in
- runner_run, so that when the glusterfs process started wants to
- communicate to glusterd, glusterd wont be able to respond if it
- has held the big lock. So we do unlock, run glusterfs process
- (thus communicate to glusterd), lock. But since this is not a
- glusterfs command that is being run, unlocking and then relocking
- is not needed.
- */
- ret = runner_run (&runner);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "unmounting the "
- "path %s (brick: %s) failed (%s)", mount_pt,
- brickinfo->path, strerror (errno));
- goto out;
- }
-
- runinit (&runner);
- snprintf (msg, sizeof(msg), "remove snapshot of the brick %s:%s, "
- "device: %s", brickinfo->hostname, brickinfo->path,
- snap_device);
- runner_add_args (&runner, "/sbin/lvremove", "-f", snap_device, NULL);
- runner_log (&runner, "", GF_LOG_DEBUG, msg);
-
- ret = runner_run (&runner);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "removing snapshot of the "
- "brick (%s:%s) of device %s failed",
- brickinfo->hostname, brickinfo->path, snap_device);
- goto out;
- }
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_brick_snapshot_remove (glusterd_volinfo_t *snap_volinfo,
- glusterd_volinfo_t *actual_volinfo, char *name)
-{
- char *mnt_pt = NULL;
- struct mntent *entry = NULL;
- int32_t ret = -1;
- glusterd_brickinfo_t *brickinfo = NULL;
- xlator_t *this = NULL;
- FILE *mtab = NULL;
this = THIS;
- GF_ASSERT (this);
-
- if (!snap_volinfo) {
- gf_log (this->name, GF_LOG_ERROR, "snap volinfo is NULL");
- goto out;
- }
-
- if (!actual_volinfo) {
- gf_log (this->name, GF_LOG_ERROR, "volinfo for the volume "
- "is NULL");
- goto out;
- }
-
- if (!name) {
- gf_log (this->name, GF_LOG_ERROR, "snapname is NULL "
- "(volume: %s)", actual_volinfo->volname);
- goto out;
- }
-
- list_for_each_entry (brickinfo, &snap_volinfo->bricks, brick_list) {
- if (uuid_compare (brickinfo->uuid, MY_UUID))
- continue;
-
- ret = glusterd_get_brick_root (brickinfo->path, &mnt_pt);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "getting the root "
- "of the brick for snap volume %s faile", name);
- goto out;
- }
- entry = glusterd_get_mnt_entry_info (mnt_pt, mtab);
- if (!entry) {
- gf_log (this->name, GF_LOG_WARNING, "getting the mount"
- " entry for the brick %s:%s of the snap %s "
- "(volume: %s) failed", brickinfo->hostname,
- brickinfo->path, name, actual_volinfo->volname);
- ret = -1;
- goto out;
- }
- ret = glusterd_remove_snap (snap_volinfo, brickinfo, mnt_pt,
- entry->mnt_fsname);
- if (mtab)
- endmntent (mtab);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "remove the snapshot %s (%s)",
- brickinfo->path, entry->mnt_fsname);
- goto out;
- }
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_do_snap_remove (glusterd_volinfo_t *volinfo, char *name)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_snap_t *snap = NULL;
- glusterd_volinfo_t *snap_volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- if (!volinfo) {
- gf_log (this->name, GF_LOG_ERROR, "volinfo NULL");
- goto out;
- }
-
- if (!name) {
- gf_log (this->name, GF_LOG_ERROR, "name is NULL (volume: %s)",
- volinfo->volname);
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (name);
- if (!snap) {
- gf_log (this->name, GF_LOG_ERROR, "could not find "
- "the snap object by the name %s",
- name);
+ if (!dict || !op_errstr) {
+ gf_log (this->name, GF_LOG_ERROR, "input parameters NULL");
goto out;
- } else {
- gf_log (this->name, GF_LOG_DEBUG, "found the snap %s "
- "(volume: %s)", name, volinfo->volname);
}
- snap_volinfo = snap->snap_volume;
- GF_ASSERT (snap_volinfo);
- list_for_each_entry (brickinfo, &snap_volinfo->bricks, brick_list) {
- if (uuid_compare (brickinfo->uuid, MY_UUID))
- continue;
-
- /* TODO: The policy for the snapshot create is not
- decided on whether to start the snap volume upon
- the execution of the snapshot create command. Once
- the policy is decided, check here whether the volume
- is in use before delete command is executed.
- (May be a force option to delete forcefully even
- when the snap volume is in use.)
- */
- ret = glusterd_brick_stop (snap_volinfo, brickinfo, _gf_false);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "stopping "
- "the brick %s:%s for the snap %s "
- "(volume: %s) failed",
- brickinfo->hostname,
- brickinfo->path, snap_volinfo->volname,
- volinfo->volname);
- //goto out;
- }
- }
- ret = glusterd_brick_snapshot_remove (snap_volinfo, volinfo,
- name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "removing the bricks"
- " snapshots for the snap %s (volume: %s) "
- "failed", name, volinfo->volname);
+ ret = dict_get_str (dict, "snapname", &snapname);
+ if (ret){
+ gf_log (this->name, GF_LOG_ERROR, "Getting the snap name "
+ "failed");
goto out;
}
- list_del_init (&snap->snap_volume->vol_list);
- list_del_init (&snap->snap_volume->snapvol_list);
- ret = glusterd_delete_snap_volume (snap->snap_volume);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "removing the snap "
- "store for the snap %s (volume %s) failed",
- snap->snapname, volinfo->volname);
+ snap = glusterd_find_snap_by_name (snapname);
+ if (!snap){
+ gf_log (this->name, GF_LOG_ERROR, "Snap %s does not exist",
+ snapname);
+ ret = -1;
goto out;
}
-
- snap = glusterd_remove_snap_by_name (snap->snapname);
- GF_ASSERT (snap); //snap cannot be NULL;
- glusterd_snap_delete (snap); //deletes in memory snap object
-
ret = 0;
out:
return ret;
@@ -3860,236 +3583,127 @@ int32_t
glusterd_snapshot_remove_commit (dict_t *dict, char **op_errstr,
dict_t *rsp_dict)
{
- int32_t ret = -1;
- char *cg_name = NULL;
- char *name = NULL;
- glusterd_snap_cg_t *cg = NULL;
+ int32_t ret = -1;
+ char *snapname = NULL;
+ char *dup_snapname = NULL;
+ glusterd_snap_t *snap = NULL;
xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int64_t volcount = -1;
- char volname_buf[PATH_MAX] = {0, };
- int i = 0;
- gf_boolean_t free_name = _gf_false;
this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
if (!dict || !op_errstr) {
gf_log (this->name, GF_LOG_ERROR, "input parameters NULL");
goto out;
}
- ret = dict_get_int64 (dict, "volcount", &volcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "volume count not given");
+ ret = dict_get_str (dict, "snapname", &snapname);
+ if (ret){
+ gf_log (this->name, GF_LOG_ERROR, "Getting the snap name "
+ "failed");
goto out;
}
- if (volcount > 1) {
- ret = dict_get_str (dict, "cgname", &cg_name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "getting the cg name"
- " failed");
- goto out;
- }
- cg = glusterd_find_snap_cg_by_name (conf, cg_name);
- if (!cg) {
- gf_log (this->name, GF_LOG_ERROR, "consistency group "
- "%s not found", cg_name);
- goto out;
- }
- GF_ASSERT (volcount == cg->volume_count);
+ snap = glusterd_find_snap_by_name (snapname);
+ if (!snap){
+ gf_log (this->name, GF_LOG_ERROR, "Snap %s does not exist",
+ snapname);
+ ret = -1;
+ goto out;
}
- for (i = 0; i < volcount; i++) {
- snprintf (volname_buf, sizeof (volname_buf), "volname%d", i+1);
- ret = dict_get_str (dict, volname_buf, &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "getting volume name"
- "failed");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "getting the volinfo"
- " failed for the volume %s", volname);
- goto out;
- }
- ret = dict_get_str (dict, "snapname", &name);
- if (ret && volcount == 1) {
- gf_log (this->name, GF_LOG_ERROR, "getting the snap "
- "name failed (volume: %s)", volinfo->volname);
- goto out;
- }
+ ret = glusterd_snap_remove (snap, _gf_false);
+ if (ret){
+ gf_log (this->name, GF_LOG_ERROR, "Failed to remove snap %s",
+ snapname);
+ goto out;
+ }
- if (!name) {
- name = glusterd_get_snap_from_cg (volinfo, cg);
- if (!name) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "get the snap name "
- "(volname: %s, cg name: %s)",
- volinfo->volname, cg->cg_name);
- goto out;
- }
- free_name = _gf_true;
- }
+ dup_snapname = gf_strdup (snapname);
+ if (!dup_snapname) {
+ gf_log (this->name, GF_LOG_ERROR, "Strdup failed");
+ ret = -1;
+ goto out;
+ }
- ret = glusterd_do_snap_remove (volinfo, name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "removing the %s %s failed",
- (volinfo)?"snap":"cg", name);
- goto out;
- }
- volinfo->snap_count--;
- if (free_name)
- GF_FREE (name);
- name = NULL;
- }
-
- if (volcount > 1) {
- ret = glusterd_store_delete_snap_cg (cg);
- /* TODO: Handle the errors of deleting store handle of cg.
- For now, the error is ignored and we proceed with the
- deletion of the in memory cg object.
- */
- if (ret)
- gf_log (this->name, GF_LOG_WARNING, "removing the "
- "store handle for the consistency group %s "
- "failed", cg->cg_name);
- cg = glusterd_remove_snap_cg_by_name (conf, cg_name);
- ret = glusterd_cg_delete (cg);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "removing the cg "
- "object failed");
- goto out;
- }
+ ret = dict_set_dynstr (rsp_dict, "snapname", dup_snapname);
+ if (ret){
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set the snapname");
+ GF_FREE (dup_snapname);
+ goto out;
}
ret = 0;
out:
- if (free_name)
- GF_FREE (name);
return ret;
}
-/* name can be either the snapname if @volnames contains only one volume or
- cg name if there are multiple volume names in volnames string
-*/
-
int32_t
glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
dict_t *rsp_dict)
{
int ret = -1;
- int i = 0;
- int64_t volume_count = 0;
- gf_boolean_t is_cg = _gf_false;
- char *name = NULL;
+ int64_t i = 0;
+ int64_t volcount = 0;
+ char *snapname = NULL;
char *volname = NULL;
char *tmp_name = NULL;
- char volname_buf[PATH_MAX] = "";
char key[PATH_MAX] = "";
xlator_t *this = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_snap_cg_t *cg = NULL;
- glusterd_conf_t *priv = NULL;
- uuid_t *cg_id = NULL;
- uuid_t *snap_volid = NULL;
glusterd_snap_t *snap = NULL;
- char err_str[PATH_MAX] = "";
+ glusterd_volinfo_t *origin_vol = NULL;
+ glusterd_volinfo_t *snap_vol = NULL;
+ glusterd_conf_t *priv = NULL;
this = THIS;
- GF_ASSERT (this);
priv = this->private;
- GF_ASSERT (priv);
+ GF_ASSERT(priv);
- ret = dict_get_int64 (dict, "volcount", &volume_count);
+ ret = dict_get_int64 (dict, "volcount", &volcount);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "failed to "
"get the volume count");
goto out;
}
- if (volume_count == 1) {
- ret = dict_get_str (dict, "snap-name", &name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to fetch snap-name");
- goto out;
- }
- tmp_name = gf_strdup (name);
- if (!tmp_name) {
- gf_log (this->name, GF_LOG_ERROR, "Out of memory");
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr (rsp_dict, "snap-name", tmp_name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set snap-name in rsp_dict");
- GF_FREE (tmp_name);
- tmp_name = NULL;
- goto out;
- }
- } else {
- ret = dict_get_str (dict, "cg-name", &name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to fetch cg-name");
- goto out;
- }
- tmp_name = gf_strdup (name);
- if (!tmp_name) {
- gf_log (this->name, GF_LOG_ERROR, "Out of memory");
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr (rsp_dict, "cg-name", tmp_name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set cg-name in rsp_dict");
- GF_FREE (tmp_name);
- tmp_name = NULL;
- goto out;
- }
+ ret = dict_get_str (dict, "snapname", &snapname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Unable to fetch snapname");
+ goto out;
+ }
+ tmp_name = gf_strdup (snapname);
+ if (!tmp_name) {
+ gf_log (this->name, GF_LOG_ERROR, "Out of memory");
+ ret = -1;
+ goto out;
}
- tmp_name = NULL;
- ret = dict_get_bin (dict, "cg-id", (void **)&cg_id);
- if (ret)
- gf_log (this->name, GF_LOG_DEBUG, "Not a cg.");
- else {
- is_cg = _gf_true;
- gf_log (this->name, GF_LOG_DEBUG, "cg-id = %s", uuid_utoa(*cg_id));
+ ret = dict_set_dynstr (rsp_dict, "snapname", tmp_name);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set snapname in rsp_dict");
+ GF_FREE (tmp_name);
+ goto out;
}
+ tmp_name = NULL;
- if (volume_count > 1) {
- cg = glusterd_new_snap_cg_object (volume_count);
- if (!cg) {
- gf_log (this->name, GF_LOG_ERROR, "cannot create the "
- "consistency group %s", name);
- ret = -1;
- goto out;
- }
+ snap = glusterd_create_snap_object (dict);
+ if (!snap) {
+ gf_log (this->name, GF_LOG_ERROR, "creating the"
+ "snap object %s failed", snapname);
+ ret = -1;
+ goto out;
}
- for (i = 1; i < volume_count + 1; i++) {
- snprintf (volname_buf, sizeof (volname_buf),
- "volname%d", i);
- ret = dict_get_str (dict, volname_buf,
- &volname);
+ for (i = 1; i <= volcount; i++) {
+ snprintf (key, sizeof (key), "volname%ld", i);
+ ret = dict_get_str (dict, key, &volname);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"failed to get volume name");
goto out;
}
- ret = glusterd_volinfo_find (volname, &volinfo);
+ ret = glusterd_volinfo_find (volname, &origin_vol);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"failed to get the volinfo for "
@@ -4097,86 +3711,26 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
goto out;
}
- tmp_name = generate_snapname (volname, name, is_cg);
- if (!tmp_name) {
- gf_log (this->name,
- GF_LOG_ERROR, "strdup failed (%s)", name);
- ret = -1;
- goto out;
- }
-
- list_for_each_entry (snap, &priv->snapshots, snap_list) {
- if (!strcmp (snap->snapname, tmp_name)) {
- snprintf (err_str, sizeof (err_str), "snap with"
- " name %s already exists", tmp_name);
- gf_log (this->name, GF_LOG_ERROR, "%s",
- err_str);
- ret = -1;
- *op_errstr = gf_strdup (err_str);
- goto out;
- }
- }
-
- snprintf (key, sizeof(key) - 1, "vol%d_volid", i);
- ret = dict_get_bin (dict, key, (void **)&snap_volid);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch snap_volid");
- goto out;
- }
-
/* TODO: Create a stub where the bricks are
added parallely by worker threads so that
- the snap creating happens parallely.
- */
- if (is_cg) {
- ret = glusterd_do_snap (volinfo, tmp_name, dict,
- cg, cg_id, i, snap_volid, name);
- }
- else {
- ret = glusterd_do_snap (volinfo, tmp_name, dict,
- cg, cg_id, i, snap_volid, NULL);
- }
- if (ret) {
+ the snap creating happens parallely. */
+ snap_vol = glusterd_do_snap_vol (origin_vol, snap, dict, i);
+ if (!snap_vol) {
+ ret = -1;
gf_log (this->name, GF_LOG_WARNING, "taking the "
"snapshot of the volume %s failed", volname);
goto out;
}
- if (cg)
- cg->volumes[i-1] = volinfo;
-
- GF_FREE (tmp_name);
- tmp_name = NULL;
- }
-
- if (volume_count > 1) {
- uuid_copy (cg->cg_id, *cg_id);
- strncpy (cg->cg_name, name, sizeof (cg->cg_name));
- ret = glusterd_add_snap_cg (priv, cg);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "could not add the"
- " consistency group %s to the glusterd list ",
- name);
- cg = glusterd_remove_snap_cg_by_name (priv, name);
- if (!cg)
- gf_log (this->name, GF_LOG_WARNING, "cannot "
- "find the consistency group %s", name);
- goto out;
- }
- ret = glusterd_store_snap_cg (cg);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "storing the cg "
- "failed (cg: %s)", cg->cg_name);
- goto out;
- }
}
ret = 0;
out:
-
- if (ret)
- GF_FREE (tmp_name);
+ if (ret) {
+ if (snap)
+ glusterd_snap_remove (snap, _gf_true);
+ snap=NULL;
+ }
gf_log ("", GF_LOG_TRACE, "Returning %d", ret);
return ret;
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c
index 7b45da00f..ae20b60db 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.c
+++ b/xlators/mgmt/glusterd/src/glusterd-store.c
@@ -1145,39 +1145,6 @@ out:
}
int32_t
-glusterd_store_snap_volume (glusterd_volinfo_t *volinfo, glusterd_snap_t *snap)
-{
- int32_t ret = -1;
- GF_ASSERT (volinfo);
- GF_ASSERT (snap);
-
-
- LOCK (&snap->lock);
- {
- ret = glusterd_store_create_volume_dir (volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Failed create snapshot dir (%s) for volume "
- "%s", snap->snapname, volinfo->volname);
- goto unlock;
- }
-
- ret = glusterd_store_perform_volume_store (volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Failed store snapshot volinfo (%s) for volume "
- "%s", snap->snapname, volinfo->volname);
- goto unlock;
- }
- }
-unlock:
- UNLOCK (&snap->lock);
-
- return 0;
-
-}
-
-int32_t
glusterd_store_snap_cg (glusterd_snap_cg_t *cg)
{
int32_t ret = -1;
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 63adbb75f..7b4e454cb 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -636,6 +636,7 @@ glusterd_volinfo_delete (glusterd_volinfo_t *volinfo)
GF_ASSERT (volinfo);
list_del_init (&volinfo->vol_list);
+ list_del_init (&volinfo->snapvol_list);
ret = glusterd_volume_brickinfos_delete (volinfo);
if (ret)
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index e2654e6f8..1ef5685eb 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -143,11 +143,6 @@ int32_t
glusterd_volume_start_glusterfs (glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t *brickinfo,
gf_boolean_t wait);
-int32_t
-glusterd_snap_volume_start_glusterfs (glusterd_volinfo_t *volinfo,
- glusterd_volinfo_t *snap_volinfo,
- glusterd_brickinfo_t *brickinfo,
- gf_boolean_t wait);
int32_t
glusterd_volume_stop_glusterfs (glusterd_volinfo_t *volinfo,
@@ -293,21 +288,13 @@ int
glusterd_brick_stop (glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t *brickinfo,
gf_boolean_t del_brick);
-int
-glusterd_snap_brick_start (glusterd_volinfo_t *volinfo,
- glusterd_volinfo_t *snap_volinfo,
- glusterd_brickinfo_t *brickinfo,
- gf_boolean_t wait);
-int
-glusterd_snap_brick_stop (glusterd_volinfo_t *volinfo,
- glusterd_volinfo_t *snap_volinfo,
- glusterd_brickinfo_t *brickinfo,
- gf_boolean_t del_brick);
+
int
glusterd_is_defrag_on (glusterd_volinfo_t *volinfo);
int32_t
glusterd_volinfo_bricks_delete (glusterd_volinfo_t *volinfo);
+
int
glusterd_friend_find_by_uuid (uuid_t uuid,
glusterd_peerinfo_t **peerinfo);
@@ -385,16 +372,16 @@ glusterd_delete_volume (glusterd_volinfo_t *volinfo);
int32_t
glusterd_delete_brick (glusterd_volinfo_t* volinfo,
glusterd_brickinfo_t *brickinfo);
-int32_t
-glusterd_delete_snap_brick (glusterd_volinfo_t *volinfo,
- glusterd_volinfo_t *snap_volinfo,
- glusterd_brickinfo_t *brickinfo);
+
int32_t
glusterd_delete_all_bricks (glusterd_volinfo_t* volinfo);
+
int
glusterd_spawn_daemons (void *opaque);
+
int
glusterd_restart_gsyncds (glusterd_conf_t *conf);
+
int
glusterd_start_gsync (glusterd_volinfo_t *master_vol, char *slave,
char *path_list, char *conf_path,