summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra Bhat <raghavendra@redhat.com>2013-11-29 12:13:28 +0530
committerRaghavendra Bhat <raghavendra@redhat.com>2013-12-02 18:20:52 +0530
commit30228525ee04694eb4e2fd367cab6779ffb769dc (patch)
tree51519c8f429dce671185fe9db861e2757fe31dc3
parent16edf27198de7efca8a0eff3955d36dee9edde67 (diff)
mgmt/glusterd: handle issues present in snapshot create and snap management
Change-Id: I94b5f6e00be7d1ff0c454e291c779dae7b423748 Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com>
-rw-r--r--libglusterfs/src/run.c2
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handshake.c6
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mgmt.c34
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c447
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.c48
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.h4
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c62
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h13
8 files changed, 322 insertions, 294 deletions
diff --git a/libglusterfs/src/run.c b/libglusterfs/src/run.c
index ebe7f39..4fd2a3a 100644
--- a/libglusterfs/src/run.c
+++ b/libglusterfs/src/run.c
@@ -187,7 +187,7 @@ runner_log (runner_t *runner, const char *dom, gf_loglevel_t lvl,
if (len > 0)
buf[len - 1] = '\0';
- gf_log (dom, lvl, "%s: %s", msg, buf);
+ gf_log_callingfn (dom, lvl, "%s: %s", msg, buf);
GF_FREE (buf);
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c
index 714695b..bea5540 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c
@@ -105,9 +105,9 @@ build_volfile_path (const char *volname, char *path,
ret = snprintf (path, path_len, "%s/vols/%s/%s.vol",
priv->workdir, volinfo->volname, volname);
else
- ret = snprintf (path, path_len, "%s/vols/%s/snaps/%s/%s.vol",
- priv->workdir, tmp_volname, volinfo->volname,
- volname);
+ ret = snprintf (path, path_len, "%s/vols/%s.vol",
+ priv->workdir, volname);
+
if (ret == -1)
goto out;
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
index 066b1de..5397050 100644
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.c
+++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
@@ -140,46 +140,24 @@ gd_mgmt_v3_brick_op_fn (glusterd_op_t op, dict_t *dict,
{
int ret = -1;
xlator_t *this = THIS;
- int64_t vol_count = 0;
- int64_t count = 1;
- char key[1024] = {0,};
- char *volname = NULL;
switch (op) {
case GD_OP_SNAP:
{
-
- ret = dict_get_int64 (dict, "volcount", &vol_count);
- if (ret)
+ ret = glusterd_snapshot_brickop (dict, op_errstr, rsp_dict);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "snapshot brickop "
+ "failed");
goto out;
- while (count <= vol_count) {
- snprintf (key, 1024, "volname%"PRId64, count);
- ret = dict_get_str (dict, key, &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get"
- " volname");
- goto out;
- }
- ret = dict_set_str (dict, "volname", volname);
- if (ret)
- goto out;
-
- ret = gd_brick_op_phase (op, NULL, dict, op_errstr);
- if (ret)
- goto out;
- volname = NULL;
- count++;
}
-
- dict_del (dict, "volname");
-
break;
}
default:
break;
}
+ ret = 0;
out:
- gf_log (this->name, GF_LOG_DEBUG, "OP = %d. Returning %d", op, ret);
+ gf_log (this->name, GF_LOG_TRACE, "OP = %d. Returning %d", op, ret);
return ret;
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index eacda05..ea26059 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -34,6 +34,7 @@
#include "run.h"
#include "glusterd-volgen.h"
#include "glusterd-mgmt.h"
+#include "glusterd-syncop.h"
#include "syscall.h"
#include "cli1-xdr.h"
@@ -391,7 +392,6 @@ out:
return ret;
}
-
int
glusterd_snapshot_config_limit_prevalidate (dict_t *dict, char **op_errstr,
int config_command)
@@ -542,7 +542,7 @@ out:
int
glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
+ dict_t *rsp_dict)
{
char *volname = NULL;
glusterd_volinfo_t *volinfo = NULL;
@@ -577,6 +577,13 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
"the volume %s", volname);
goto out;
}
+ if (!glusterd_is_volume_started (volinfo)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "volume %s is not started",
+ volinfo->volname);
+ ret = -1;
+ goto out;
+ }
if (glusterd_is_defrag_on (volinfo)) {
ret = -1;
gf_log (this->name, GF_LOG_WARNING,
@@ -590,53 +597,6 @@ out:
return ret;
}
-int
-glusterd_snapshot_prevalidate (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int snap_command = 0;
- xlator_t *this = NULL;
- int ret = -1;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict); //not sure if this is needed, verify.
-
- ret = dict_get_int32 (dict, "type", &snap_command);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "unable to get the type of "
- "the snapshot command");
- goto out;
- }
-
- switch (snap_command) {
- case (GF_SNAP_OPTION_TYPE_CREATE):
- ret = glusterd_snapshot_create_prevalidate (dict, op_errstr,
- rsp_dict);
- break;
-
- case (GF_SNAP_OPTION_TYPE_CONFIG):
- ret = glusterd_snapshot_config_prevalidate (dict, op_errstr);
- break;
-
- case GF_SNAP_OPTION_TYPE_RESTORE:
- ret = glusterd_snapshot_restore_prevalidate (dict, op_errstr);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Snapshot restore "
- "validation failed");
- goto out;
- }
- break;
- default:
- gf_log (this->name, GF_LOG_WARNING, "invalid snap command");
- goto out;
- }
-out:
- return ret;
-}
-
glusterd_snap_t*
glusterd_new_snap_object()
{
@@ -666,7 +626,7 @@ glusterd_new_snap_cg_object(int64_t volume_count)
}
cg = GF_CALLOC (1, (sizeof (*cg) +
- (volume_count * sizeof (*volinfo))),
+ (volume_count * sizeof (volinfo))),
gf_gld_mt_snap_cg_t);
if (cg) {
@@ -845,6 +805,7 @@ glusterd_remove_snap_by_name (glusterd_volinfo_t *volinfo, char *snap_name)
{
entry->snap_status = GD_SNAP_STATUS_DECOMMISSION;
list_del_init (&entry->snap_list);
+ volinfo->snap_count--;
}
UNLOCK (&volinfo->lock);
}
@@ -1577,6 +1538,7 @@ glusterd_snapshot_cg_get_snaplist_lk (dict_t *dict, glusterd_snap_cg_t *cg,
xlator_t *this = NULL;
int64_t i = 0;
char key[256]= {0,};
+ glusterd_volinfo_t *volinfo = NULL;
this = THIS;
@@ -1646,16 +1608,17 @@ glusterd_snapshot_cg_get_snaplist_lk (dict_t *dict, glusterd_snap_cg_t *cg,
/* Get snap list for all volumes present in the CG */
for (i = 0; i < cg->volume_count; ++i) {
+ volinfo = cg->volumes[i];
ret = snprintf (key, sizeof (key), "%s.vol%ld", keyprefix, i);
if (ret < 0) { /* Only negative value is error */
goto out;
}
ret = glusterd_snapshot_vol_get_snaplist (dict, key,
- &(cg->volumes[i]), NULL, detail);
+ volinfo, NULL,
+ detail);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "snaplist for %s volume",
- cg->volumes[i].volname);
+ gf_log (this->name, GF_LOG_ERROR, "Failed to get "
+ "snaplist for %s volume", volinfo->volname);
goto out;
}
}
@@ -2064,6 +2027,7 @@ glusterd_get_cg_snap_name_lk (dict_t *dict, glusterd_snap_cg_t *cg)
char *snapname = NULL;
glusterd_snap_t *snap = NULL;
xlator_t *this = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
this = THIS;
@@ -2076,18 +2040,27 @@ glusterd_get_cg_snap_name_lk (dict_t *dict, glusterd_snap_cg_t *cg)
/* TODO: As of now only one snap is supported per CG When CG
* management module comes in then this restriction can be removed.
*/
- snap_count = cg->volumes[0].snap_count;
+
+ /* TODO: As of now, consistency group can be created out of some volumes,
+ even though the volumes already have snapshots taken. But the
+ future plan is to have consistency group where past or future
+ individual snapshots are not allowed. So this below check
+ of snap count of the first volume of the CG to 1, is in accordance
+ with that.
+ */
+ volinfo = cg->volumes[0];
+ snap_count = volinfo->snap_count;
if (1 != snap_count) {
gf_log (this->name, GF_LOG_ERROR, "More than one snap is "
- "associated with the cg (%s)", cg->cg_name);
+ "associated with the cg (%s)", cg->cg_name);
ret = -1;
goto out;
}
- snap = glusterd_find_snap_by_index (&(cg->volumes[0]), 0);
+ snap = glusterd_find_snap_by_index (volinfo, 0);
if (NULL == snap) {
gf_log (this->name, GF_LOG_ERROR, "Failed to get snap for "
- "%s CG", cg->cg_name);
+ "%s CG", cg->cg_name);
ret = -1;
goto out;
}
@@ -2126,6 +2099,7 @@ glusterd_get_cg_volume_names_lk (dict_t *dict, glusterd_snap_cg_t *cg)
char *volname = NULL;
xlator_t *this = NULL;
char key[PATH_MAX] = {0,};
+ glusterd_volinfo_t *volinfo = NULL;
this = THIS;
@@ -2145,11 +2119,12 @@ glusterd_get_cg_volume_names_lk (dict_t *dict, glusterd_snap_cg_t *cg)
* present in the CG.
*/
for (i = 0; i < cg->volume_count; ++i) {
+ volinfo = cg->volumes[i];
/* TODO: When Jarvis framework is fixed change the index
* to start from 0 instead of 1
*/
snprintf (key, sizeof (key), "volname%ld", i+1);
- volname = gf_strdup (cg->volumes[i].volname);
+ volname = gf_strdup (volinfo->volname);
if (NULL == volname) {
ret = -1;
goto out;
@@ -2268,6 +2243,7 @@ unlock:
}
ret = 0; /* Success */
+
out:
return ret;
}
@@ -2287,7 +2263,6 @@ glusterd_snap_create (glusterd_volinfo_t *volinfo,
xlator_t *this = NULL;
glusterd_conf_t *priv = NULL;
int ret = -1;
- uuid_t snap_uuid;
this = THIS;
priv = this->private;
@@ -2310,12 +2285,10 @@ glusterd_snap_create (glusterd_volinfo_t *volinfo,
if (description)
snap->description = gf_strdup (description);
snap->time_stamp = time (NULL);
- uuid_generate (snap_uuid);
- uuid_copy (snap->snap_id, snap_uuid);
+ uuid_copy (snap->snap_id, snap_volinfo->volume_id);
if (!uuid_is_null (cg_id))
uuid_copy (snap->cg_id, cg_id);
snap->snap_volume = snap_volinfo;
- uuid_copy (snap_volinfo->volume_id, snap_uuid);
strcpy (snap->snap_name, snap_volinfo->volname);
//TODO: replace strcpy with strncpy
@@ -2343,106 +2316,6 @@ out:
return ret;
}
-int
-glusterd_remove_snapshot (glusterd_brickinfo_t *brickinfo, char *volname,
- char *snapname, const char *snap_device)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- runner_t runner = {0,};
- char msg[1024] = {0, };
-
- this = THIS;
- priv = this->private;
-
- if (!brickinfo) {
- gf_log (this->name, GF_LOG_ERROR, "brickinfo NULL");
- goto out;
- }
-
- snprintf (msg, sizeof(msg), "remove snapshot of the brick %s:%s, "
- "device: %s", brickinfo->hostname, brickinfo->path,
- snap_device);
- runner_add_args (&runner, "/sbin/lvmremove", snap_device, NULL);
- runner_log (&runner, "", GF_LOG_DEBUG, msg);
-
- //let glusterd get blocked till snapshot is over
- synclock_unlock (&priv->big_lock);
- ret = runner_run (&runner);
- synclock_lock (&priv->big_lock);
-
- 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) {
- ret = glusterd_get_brick_root (brickinfo->path, &mnt_pt);
- if (ret)
- goto out;
-
- entry = glusterd_get_mnt_entry_info (mnt_pt, mtab);
- if (!entry) {
- ret = -1;
- goto out;
- }
- ret = glusterd_remove_snapshot (brickinfo,
- actual_volinfo->volname,
- name, entry->mnt_fsname);
- 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:
- if (mtab)
- endmntent (mtab);
- return ret;
-}
-
/* This function is called to get the device path of the snap lvm. Usually
if /dev/<group-name>/<group-name>-<lvm-name> is the device for the lvm,
then the snap device will be /dev/<group-name>/<group-name>-<snap-name>.
@@ -2591,6 +2464,8 @@ glusterd_snap_brick_create (char *device, glusterd_volinfo_t *snap_volinfo,
FILE *mtab = NULL;
char *snap_brick_dir = NULL;
char snap_brick_path[PATH_MAX] = {0, };
+ struct stat statbuf = {0, };
+
this = THIS;
priv = this->private;
@@ -2660,7 +2535,7 @@ glusterd_snap_brick_create (char *device, glusterd_volinfo_t *snap_volinfo,
goto out;
}
/* mount the snap logical device on the directory inside
- /var/run/gluster/snaps/<snapname>/@snap_brick_mount_path
+ /run/gluster/snaps/<snapname>/@snap_brick_mount_path
*/
ret = mount (device, snap_brick_mount_path, entry->mnt_type, MS_MGC_VAL,
"nouuid");
@@ -2669,7 +2544,9 @@ glusterd_snap_brick_create (char *device, glusterd_volinfo_t *snap_volinfo,
"logical device %s failed (error: %s)", device,
strerror (errno));
goto out;
- }
+ } else
+ gf_log (this->name, GF_LOG_DEBUG, "mounting the snapshot "
+ "logical device %s successful", device);
ret = glusterd_brickinfo_new (&snap_brickinfo);
if (ret) {
@@ -2687,9 +2564,32 @@ glusterd_snap_brick_create (char *device, glusterd_volinfo_t *snap_volinfo,
&snap_volinfo->bricks);
}
UNLOCK (&snap_volinfo->lock);
+
+ ret = stat (snap_brick_path, &statbuf);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "stat of the brick %s"
+ "(brick mount: %s) failed (%s)", snap_brick_path,
+ snap_brick_mount_path, strerror (errno));
+ goto out;
+ }
+ ret = sys_lsetxattr (snap_brickinfo->path,
+ GF_XATTR_VOL_ID_KEY,
+ snap_volinfo->volume_id, 16,
+ XATTR_REPLACE);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to set "
+ "extended attribute %s on %s. Reason: "
+ "%s, snap: %s", GF_XATTR_VOL_ID_KEY,
+ snap_brickinfo->path, strerror (errno),
+ snap_volinfo->volname);
+ goto out;
+ }
+
out:
GF_FREE (tmp);
if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "unmounting the snap brick"
+ " mount %s", snap_brick_mount_path);
umount (snap_brick_mount_path);
if (snap_brickinfo)
glusterd_brickinfo_delete (snap_brickinfo);
@@ -2719,6 +2619,7 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *name, dict_t *dict,
char tmp[2046] = {0, };
glusterd_volinfo_t *snap_volume = NULL;
char *description = NULL;
+ uuid_t snap_uuid = {0, };
this = THIS;
GF_ASSERT (this);
@@ -2736,6 +2637,8 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *name, dict_t *dict,
ret = glusterd_volinfo_dup (volinfo, &snap_volume);
strcpy (snap_volume->volname, snapname);
snap_volume->is_snap_volume = _gf_true;
+ uuid_generate (snap_uuid);
+ uuid_copy (snap_volume->volume_id, snap_uuid);
list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
if (uuid_compare (brickinfo->uuid, MY_UUID)) {
@@ -2771,7 +2674,7 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *name, dict_t *dict,
gf_log (this->name, GF_LOG_ERROR, "not able to"
" create the brickinfo for the snap %s"
", volume %s", snapname,
- volinfo->volname);
+ volinfo->volname);
goto out;
}
}
@@ -2827,6 +2730,9 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *name, dict_t *dict,
list_add_tail (&snap_volume->vol_list, &priv->volumes);
list_for_each_entry (brickinfo, &snap_volume->bricks, brick_list) {
+ if (uuid_compare (brickinfo->uuid, MY_UUID))
+ continue;
+
ret = glusterd_snap_brick_start (volinfo, snap_volume, brickinfo,
_gf_true);
if (ret) {
@@ -2848,72 +2754,6 @@ out:
return ret;
}
-int32_t
-glusterd_do_snap_remove (glusterd_volinfo_t *volinfo, char *name, dict_t *dict)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_snap_t *snap = NULL;
- glusterd_snap_cg_t *cg = NULL;
- int i = 0;
-
- this = THIS;
- priv = this->private;
-
- 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 (volinfo, name);
- if (!snap) {
- cg = glusterd_find_snap_cg_by_name (priv, volinfo->volname);
- if (!cg) {
- gf_log (this->name, GF_LOG_ERROR, "could not find "
- "the snap or the cg object by the name %s",
- name);
- goto out;
- }
- }
-
- if (snap) {
- ret = glusterd_brick_snapshot_remove (snap->snap_volume,
- 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);
- goto out;
- }
- }
-
- if (cg) {
- for (i = 0; i < cg->volume_count ; i++) {
- ret = glusterd_brick_snapshot_remove (&cg->volumes[i],
- 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);
- goto out;
- }
- }
- }
-
- ret = 0;
-out:
- 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
@@ -3000,7 +2840,9 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
char err_str[PATH_MAX] = {0, };
this = THIS;
+ GF_ASSERT (this);
priv = this->private;
+ GF_ASSERT (priv);
ret = dict_get_int64 (dict, "volcount", &volume_count);
if (ret) {
@@ -3018,6 +2860,13 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
is_cg = _gf_true;
ret = dict_get_str (dict, "cg-name", &name);
uuid_generate (cg_id);
+ cg = glusterd_new_snap_cg_object (volume_count);
+ if (!cg) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "cannot create the consistency"
+ " group %s", name);
+ goto out;
+ }
} else if (volume_count == 1) {
ret = dict_get_str (dict, "snap-name", &name);
}
@@ -3032,6 +2881,15 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
volname);
goto out;
}
+ /* If the user has not provided the snapname/cg-name, then
+ one is generated by glusterd itself. Put it into the
+ dict, so that cli displays the name of the snap/cg that
+ was created.
+ */
+ if (is_cg)
+ ret = dict_set_str (rsp_dict, "cg-name", name);
+ else
+ ret = dict_set_str (rsp_dict, "snap-name", name);
}
for (i = 1; i < volume_count + 1; i++) {
@@ -3083,6 +2941,8 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
"snapshot of the volume %s failed", volname);
goto out;
}
+ if (cg)
+ cg->volumes[i-1] = volinfo;
}
if (volume_count > 1) {
@@ -3092,6 +2952,7 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
"consistency group %s", name);
goto out;
}
+
uuid_copy (cg->cg_id, cg_id);
strncpy (cg->cg_name, name, sizeof (cg->cg_name));
ret = glusterd_add_snap_cg (priv, cg);
@@ -3105,7 +2966,16 @@ glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
"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:
gf_log ("", GF_LOG_TRACE, "Returning %d", ret);
return ret;
@@ -3321,6 +3191,118 @@ glusterd_snapshot (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
}
ret = 0;
+
+out:
+ return ret;
+}
+
+int
+glusterd_snapshot_brickop (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
+{
+ int ret = -1;
+ int64_t vol_count = 0;
+ int64_t count = 1;
+ char key[1024] = {0,};
+ char *volname = NULL;
+ int32_t snap_command = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ GF_ASSERT (this);
+ GF_ASSERT (dict);
+ GF_ASSERT (rsp_dict); //not sure if this is needed, verify.
+ ret = dict_get_int32 (dict, "type", &snap_command);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "unable to get the type of "
+ "the snapshot command");
+ goto out;
+ }
+
+ switch (snap_command) {
+ case GF_SNAP_OPTION_TYPE_CREATE:
+ {
+ ret = dict_get_int64 (dict, "volcount", &vol_count);
+ if (ret)
+ goto out;
+ while (count <= vol_count) {
+ snprintf (key, 1024, "volname%"PRId64, count);
+ ret = dict_get_str (dict, key, &volname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to get volname");
+ goto out;
+ }
+ ret = dict_set_str (dict, "volname", volname);
+ if (ret)
+ goto out;
+
+ ret = gd_brick_op_phase (GD_OP_SNAP, NULL, dict,
+ op_errstr);
+ if (ret)
+ goto out;
+ volname = NULL;
+ count++;
+ }
+
+ dict_del (dict, "volname");
+ ret = 0;
+ break;
+ }
+ case GF_SNAP_OPTION_TYPE_DELETE:
+ break;
+ default:
+ break;
+ }
+
+out:
+ return ret;
+}
+
+int
+glusterd_snapshot_prevalidate (dict_t *dict, char **op_errstr,
+ dict_t *rsp_dict)
+{
+ int snap_command = 0;
+ xlator_t *this = NULL;
+ int ret = -1;
+
+ this = THIS;
+
+ GF_ASSERT (this);
+ GF_ASSERT (dict);
+ GF_ASSERT (rsp_dict); //not sure if this is needed, verify.
+
+ ret = dict_get_int32 (dict, "type", &snap_command);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "unable to get the type of "
+ "the snapshot command");
+ goto out;
+ }
+
+ switch (snap_command) {
+ case (GF_SNAP_OPTION_TYPE_CREATE):
+ ret = glusterd_snapshot_create_prevalidate (dict, op_errstr,
+ rsp_dict);
+ break;
+
+ case (GF_SNAP_OPTION_TYPE_CONFIG):
+ ret = glusterd_snapshot_config_prevalidate (dict, op_errstr);
+ break;
+
+ case GF_SNAP_OPTION_TYPE_RESTORE:
+ ret = glusterd_snapshot_restore_prevalidate (dict, op_errstr);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "Snapshot restore "
+ "validation failed");
+ goto out;
+ }
+ break;
+ default:
+ gf_log (this->name, GF_LOG_WARNING, "invalid snap command");
+ goto out;
+ }
+
out:
gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
return ret;
@@ -3422,7 +3404,6 @@ glusterd_handle_snapshot_fn (rpcsvc_request_t *req)
case GF_SNAP_OPTION_TYPE_CONFIG:
ret = glusterd_mgmt_v3_initiate_all_phases (req, cli_op, dict);
break;
- case GF_SNAP_OPTION_TYPE_DELETE:
case GF_SNAP_OPTION_TYPE_START:
case GF_SNAP_OPTION_TYPE_STOP:
case GF_SNAP_OPTION_TYPE_STATUS:
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c
index 8a673cc..37bf8bd 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.c
+++ b/xlators/mgmt/glusterd/src/glusterd-store.c
@@ -1249,17 +1249,18 @@ glusterd_store_snap_cg_write (int fd, glusterd_snap_cg_t *cg)
int ret = -1;
char buf[PATH_MAX] = {0, };
uint64_t count = 0;
+ glusterd_volinfo_t *volinfo = NULL;
GF_ASSERT (fd > 0);
GF_ASSERT (cg);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_NAME,
- cg->cg_name);
+ snprintf (buf, sizeof (buf), "%"PRIu64, cg->volume_count);
+ ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_CG_VOL_COUNT, buf);
if (ret)
goto out;
- snprintf (buf, sizeof (buf), "%"PRIu64, cg->volume_count);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_CG_VOL_COUNT, buf);
+ ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_NAME,
+ cg->cg_name);
if (ret)
goto out;
@@ -1281,8 +1282,9 @@ glusterd_store_snap_cg_write (int fd, glusterd_snap_cg_t *cg)
goto out;
}
while (count < cg->volume_count) {
+ volinfo = cg->volumes[count];
ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_ID,
- uuid_utoa (cg->volumes[count].volume_id));
+ uuid_utoa (volinfo->volume_id));
if (ret)
goto out;
@@ -1314,6 +1316,11 @@ glusterd_store_perform_snap_cg_store (glusterd_snap_cg_t *cg)
ret = glusterd_store_snap_cg_write (fd, cg);
if (ret)
goto out;
+
+ ret = gf_store_rename_tmppath (cg->shandle);
+ if (ret)
+ goto out;
+
out:
if (ret && (fd > 0))
gf_store_unlink_tmppath (cg->shandle);
@@ -1822,7 +1829,7 @@ glusterd_store_delete_snap_cg (glusterd_snap_cg_t *cg)
snprintf (trashdir, sizeof (trashdir), "%s/"GLUSTERD_TRASH"/%s",
priv->workdir, GLUSTERD_VOL_SNAP_CG_DIR_PREFIX);
- ret = mkdir (trashdir, 0777);
+ ret = mkdir_p (trashdir, 0777, _gf_true);
if (ret && errno != EEXIST) {
gf_log (this->name, GF_LOG_ERROR, "Failed to create trash "
"directory, reason : %s", strerror (errno));
@@ -1861,6 +1868,7 @@ out:
gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
+
int32_t
glusterd_store_delete_volume (glusterd_volinfo_t *volinfo,
glusterd_volinfo_t *snapinfo)
@@ -1986,7 +1994,6 @@ out:
return ret;
}
-
int
glusterd_store_global_info (xlator_t *this)
{
@@ -2847,6 +2854,7 @@ glusterd_store_retrieve_volume (char *volname, glusterd_snap_t *snap)
list_add_tail (&volinfo->vol_list, &priv->volumes);
} else {
// as of now snap volume are also added to the list of volume
+ volinfo->is_snap_volume = _gf_true;
snap->snap_volume = volinfo;
list_add_tail (&volinfo->vol_list, &priv->volumes);
}
@@ -2955,7 +2963,7 @@ out:
}
int32_t
-glusterd_store_retrieve_snap_cg (char *cg_name, glusterd_conf_t *priv)
+glusterd_store_retrieve_snap_cg (char *cg_store_name, glusterd_conf_t *priv)
{
int32_t ret = -1;
gf_store_iter_t *iter = NULL;
@@ -2969,13 +2977,13 @@ glusterd_store_retrieve_snap_cg (char *cg_name, glusterd_conf_t *priv)
gf_store_handle_t *tmp_shandle = NULL;
uint64_t count = 0;
glusterd_volinfo_t *volinfo = NULL;
- glusterd_volinfo_t *tmpinfo = NULL;
uuid_t vol_id = {0, };
- GF_ASSERT (cg_name);
+ GF_ASSERT (cg_store_name);
GF_ASSERT (priv);
- glusterd_store_snap_cgfpath_set (cg_name, path, sizeof (path));
+ snprintf (path, sizeof (path), "%s/%s/%s", priv->workdir,
+ GLUSTERD_VOL_SNAP_CG_DIR_PREFIX, cg_store_name);
ret = gf_store_handle_retrieve (path, &tmp_shandle);
if (ret)
goto out;
@@ -2983,6 +2991,7 @@ glusterd_store_retrieve_snap_cg (char *cg_name, glusterd_conf_t *priv)
ret = gf_store_iter_new (tmp_shandle, &iter);
if (ret)
goto out;
+
ret = gf_store_iter_get_matching (iter,
GLUSTERD_STORE_KEY_CG_VOL_COUNT,
&value);
@@ -3000,20 +3009,18 @@ glusterd_store_retrieve_snap_cg (char *cg_name, glusterd_conf_t *priv)
"Failed to create snap cg object");
goto out;
}
-
cg->shandle = tmp_shandle;
GLUSTERD_GET_SNAP_CG_DIR (cg_path, priv);
snprintf (path, sizeof (path), "%s/%s", cg_path,
- cg_name);
- cg->volume_count = atoi (value);
+ cg_store_name);
ret = gf_store_iter_get_next (iter, &key, &value, &op_errno);
while (!ret) {
if (!strncmp(key, GLUSTERD_STORE_KEY_SNAP_NAME,
sizeof (*key))) {
- strncpy (cg->cg_name, value, sizeof (*value));
+ strncpy (cg->cg_name, value, sizeof (value));
} else if (!strncmp(key, GLUSTERD_STORE_KEY_SNAP_STATUS,
sizeof (*key))) {
cg->cg_status = atoi (value);
@@ -3024,26 +3031,26 @@ glusterd_store_retrieve_snap_cg (char *cg_name, glusterd_conf_t *priv)
sizeof (*key))) {
cg->description = gf_strdup (value);
} else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_ID,
- sizeof (*key))) {
- uuid_parse (key, vol_id);
+ sizeof (*key))) {
+ uuid_parse (value, vol_id);
ret = glusterd_volinfo_find_by_volume_id (vol_id, &volinfo);
if (ret)
break;
if (count < vol_count) {
- tmpinfo = &cg->volumes[count];
- tmpinfo = volinfo;
+ cg->volumes[count] = volinfo;
count++;
}
}
GF_FREE (value);
value = NULL;
+ ret = gf_store_iter_get_next (iter, &key, &value, &op_errno);
}
ret = glusterd_add_snap_cg (priv, cg);
if (ret) {
gf_log (THIS->name, GF_LOG_ERROR, "Failed to add %s to"
- " cg_list", cg_name);
+ " cg_list", cg_store_name);
goto out;
}
@@ -3060,6 +3067,7 @@ out:
return ret;
}
+
int32_t
glusterd_store_retrieve_snap_list (char *volname)
{
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h
index 927ca82..a5a4bfd 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.h
+++ b/xlators/mgmt/glusterd/src/glusterd-store.h
@@ -148,4 +148,8 @@ int32_t
glusterd_store_perform_snap_store (glusterd_volinfo_t *volinfo);
int32_t
glusterd_store_perform_snap_list_store (glusterd_volinfo_t *volinfo);
+int32_t
+glusterd_store_snap_cg (glusterd_snap_cg_t *cg);
+int32_t
+glusterd_store_delete_snap_cg (glusterd_snap_cg_t *cg);
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index dd64867..f7b117b 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -484,6 +484,10 @@ glusterd_volinfo_dup (glusterd_volinfo_t *volinfo,
int32_t ret = -1;
glusterd_volinfo_t *new_volinfo = NULL;
xlator_t *this = NULL;
+ uuid_t username_id = {0, };
+ uuid_t password_id = {0, };
+ char *username = NULL;
+ char *password = NULL;
this = THIS;
GF_ASSERT (this);
@@ -512,12 +516,31 @@ glusterd_volinfo_dup (glusterd_volinfo_t *volinfo,
for authentication of trusted clients. If its not working,
generate new username and passowd (uuid-generate) and use.
*/
- glusterd_auth_set_username (new_volinfo, volinfo->auth.username);
- glusterd_auth_set_password (new_volinfo, volinfo->auth.password);
+ uuid_generate (username_id);
+ username = uuid_utoa (username_id);
+ if (!username) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_WARNING, "could not get the "
+ "username");
+ goto out;
+ }
+ uuid_generate (password_id);
+ password = uuid_utoa (password_id);
+ if (!password) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_WARNING, "could not get the "
+ "password");
+ goto out;
+ }
+ glusterd_auth_set_username (new_volinfo, username);
+ glusterd_auth_set_password (new_volinfo, password);
*dup_volinfo = new_volinfo;
out:
+ if (ret)
+ GF_FREE (new_volinfo);
+
return ret;
}
@@ -1504,12 +1527,12 @@ glusterd_snap_volume_start_glusterfs (glusterd_volinfo_t *volinfo,
priv = this->private;
GF_ASSERT (priv);
- ret = _mk_snap_rundir_p (volinfo, snap_volinfo);
+ ret = _mk_rundir_p (volinfo);
if (ret)
goto out;
GLUSTERD_GET_SNAP_BRICK_PIDFILE (pidfile, volinfo,
- snap_volinfo->volname, brickinfo,
- priv);
+ snap_volinfo->volname,
+ brickinfo, priv);
if (glusterd_is_service_running (pidfile, NULL))
goto connect;
@@ -1596,12 +1619,12 @@ glusterd_snap_volume_start_glusterfs (glusterd_volinfo_t *volinfo,
runner_argprintf (&runner, "%d,%d", port, rdma_port);
runner_add_arg (&runner, "--xlator-option");
runner_argprintf (&runner, "%s-server.transport.rdma.listen-port=%d",
- volinfo->volname, rdma_port);
+ snap_volinfo->volname, rdma_port);
}
runner_add_arg (&runner, "--xlator-option");
runner_argprintf (&runner, "%s-server.listen-port=%d",
- volinfo->volname, port);
+ snap_volinfo->volname, port);
if (volinfo->memory_accounting)
runner_add_arg (&runner, "--mem-accounting");
@@ -4403,16 +4426,38 @@ glusterd_restart_bricks (glusterd_conf_t *conf)
glusterd_brickinfo_t *brickinfo = NULL;
gf_boolean_t start_nodesvcs = _gf_false;
int ret = 0;
+ glusterd_snap_t *snap = NULL;
+ glusterd_volinfo_t *snap_volume = NULL;
list_for_each_entry (volinfo, &conf->volumes, vol_list) {
if (volinfo->status != GLUSTERD_STATUS_STARTED)
continue;
+ if (volinfo->is_snap_volume)
+ continue;
start_nodesvcs = _gf_true;
+ gf_log (THIS->name, GF_LOG_DEBUG, "starting the volume %s",
+ volinfo->volname);
list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
glusterd_brick_start (volinfo, brickinfo, _gf_false);
}
}
+ list_for_each_entry (volinfo, &conf->volumes, vol_list) {
+ if (volinfo->is_snap_volume)
+ continue;
+ list_for_each_entry (snap, &volinfo->snaps, snap_list) {
+ snap_volume = snap->snap_volume;
+ GF_ASSERT (snap_volume);
+ list_for_each_entry (brickinfo, &snap_volume->bricks,
+ brick_list) {
+ glusterd_snap_brick_start (volinfo, snap_volume,
+ brickinfo, _gf_false);
+ }
+ }
+ }
+
+ //TODO: start consistency groups also
+
if (start_nodesvcs)
glusterd_nodesvcs_handle_graph_change (NULL);
@@ -7650,6 +7695,9 @@ glusterd_snap_use_rsp_dict (dict_t *dst, dict_t *src)
}
break;
default:
+ // copy the response dictinary's contents to the dict to be
+ // sent back to the cli
+ dict_copy (src, dst);
break;
}
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index fb4f32a..19c05c4 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -359,7 +359,7 @@ struct glusterd_snap_cg_ {
int64_t volume_count;
struct list_head cg_list;
gf_store_handle_t *shandle;
- glusterd_volinfo_t volumes[0];
+ glusterd_volinfo_t *volumes[0];
};
typedef struct glusterd_snap_cg_ glusterd_snap_cg_t;
@@ -412,7 +412,14 @@ enum glusterd_vol_comp_status_ {
#define GLUSTERD_VOL_SNAP_DIR_PREFIX "snaps"
#define GLUSTERD_VOL_SNAP_CG_DIR_PREFIX "cgs"
-#define GLUSTERD_DEFAULT_SNAPS_BRICK_DIR "/var/run/gluster/snaps"
+/* TODO: It was supposed to be /var/run/gluster. But /var/run seems
+ to be a symbolic link to /run/gluster which creates problems
+ as the entry point in the mtab for the mount point and
+ glusterd maintained entry point will be different. Verify
+ properly on which path should be used for creating the
+ brick directories of snap volumes
+*/
+#define GLUSTERD_DEFAULT_SNAPS_BRICK_DIR "/run/gluster/snaps"
/* definitions related to replace brick */
#define RB_CLIENT_MOUNTPOINT "rb_mount"
@@ -899,6 +906,8 @@ int
glusterd_snapshot_prevalidate (dict_t *dict, char **op_errstr,
dict_t *rsp_dict);
int
+glusterd_snapshot_brickop (dict_t *dict, char **op_errstr, dict_t *rsp_dict);
+int
glusterd_snapshot (dict_t *dict, char **op_errstr, dict_t *rsp_dict);
char *
glusterd_build_snap_device_path (char *device, char *snapname);