summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c19
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.c604
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.h14
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c2
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-ops.c2
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h16
6 files changed, 644 insertions, 13 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index 896fbe03b..1c0ea0859 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -258,7 +258,6 @@ out:
}
-
glusterd_snap_cg_t*
glusterd_find_snap_cg_by_name (glusterd_conf_t *conf, char *cg_name)
{
@@ -428,3 +427,21 @@ glusterd_handle_snapshot (rpcsvc_request_t *req)
{
return glusterd_big_locked_handler (req, glusterd_handle_snapshot_fn);
}
+
+int32_t
+glusterd_delete_snap_volume (glusterd_volinfo_t *volinfo,
+ glusterd_volinfo_t *snapinfo)
+{
+ int ret = -1;
+ GF_ASSERT (volinfo);
+
+ ret = glusterd_store_delete_volume (volinfo, snapinfo);
+
+ if (ret)
+ goto out;
+
+ ret = glusterd_volinfo_delete (snapinfo);
+out:
+ gf_log (THIS->name, GF_LOG_DEBUG, "returning %d", ret);
+ return ret;
+}
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c
index 5902589f4..97c8a5d4f 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.c
+++ b/xlators/mgmt/glusterd/src/glusterd-store.c
@@ -76,6 +76,26 @@ glusterd_store_create_brick_dir (glusterd_volinfo_t *volinfo)
return ret;
}
+int32_t
+glusterd_store_create_snap_brick_dir (glusterd_volinfo_t *volinfo,
+ glusterd_volinfo_t *snapinfo)
+{
+ int32_t ret = -1;
+ char brickdirpath[PATH_MAX] = {0,};
+ glusterd_conf_t *priv = NULL;
+
+ GF_ASSERT (volinfo);
+ GF_ASSERT (snapinfo);
+
+ priv = THIS->private;
+ GF_ASSERT (priv);
+
+ GLUSTERD_GET_SNAP_BRICK_DIR (brickdirpath, volinfo, snapinfo->volname,
+ priv);
+ ret = gf_store_mkdir (brickdirpath);
+
+ return ret;
+}
static void
glusterd_store_key_vol_brick_set (glusterd_brickinfo_t *brickinfo,
char *key_vol_brick, size_t len)
@@ -125,6 +145,32 @@ glusterd_store_brickinfopath_set (glusterd_volinfo_t *volinfo,
snprintf (brickpath, len, "%s/%s", brickdirpath, brickfname);
}
+static void
+glusterd_store_snap_brickinfopath_set (glusterd_volinfo_t *volinfo,
+ glusterd_volinfo_t *snapinfo,
+ glusterd_brickinfo_t *brickinfo,
+ char *brickpath, size_t len)
+{
+ char brickfname[PATH_MAX] = {0};
+ char brickdirpath[PATH_MAX] = {0,};
+ glusterd_conf_t *priv = NULL;
+
+ GF_ASSERT (volinfo);
+ GF_ASSERT (snapinfo);
+ GF_ASSERT (brickpath);
+ GF_ASSERT (brickinfo);
+ GF_ASSERT (len >= PATH_MAX);
+
+ priv = THIS->private;
+ GF_ASSERT (priv);
+
+ GLUSTERD_GET_SNAP_BRICK_DIR (brickdirpath, volinfo,
+ snapinfo->volname, priv);
+ glusterd_store_brickinfofname_set (brickinfo, brickfname,
+ sizeof (brickfname));
+ snprintf (brickpath, len, "%s/%s", brickdirpath, brickfname);
+}
+
gf_boolean_t
glusterd_store_is_valid_brickpath (char *volname, char *brick)
{
@@ -210,6 +256,24 @@ glusterd_store_create_brick_shandle_on_absence (glusterd_volinfo_t *volinfo,
}
int32_t
+glusterd_store_create_snap_brick_shandle_on_absence(glusterd_volinfo_t *volinfo,
+ glusterd_volinfo_t *snapinfo,
+ glusterd_brickinfo_t *brickinfo)
+{
+ char brickpath[PATH_MAX] = {0,};
+ int32_t ret = 0;
+
+ GF_ASSERT (volinfo);
+ GF_ASSERT (snapinfo);
+ GF_ASSERT (brickinfo);
+
+ glusterd_store_snap_brickinfopath_set (volinfo, snapinfo, brickinfo,
+ brickpath, sizeof (brickpath));
+ ret = gf_store_handle_create_on_absence (&brickinfo->shandle,
+ brickpath);
+ return ret;
+}
+int32_t
glusterd_store_brickinfo_write (int fd, glusterd_brickinfo_t *brickinfo)
{
char value[256] = {0,};
@@ -308,6 +372,39 @@ out:
}
int32_t
+glusterd_store_snap_brickinfo (glusterd_volinfo_t *volinfo,
+ glusterd_volinfo_t *snapinfo,
+ glusterd_brickinfo_t *brickinfo,
+ int32_t brick_count,
+ int vol_fd)
+{
+ int32_t ret = -1;
+
+ GF_ASSERT (volinfo);
+ GF_ASSERT (snapinfo);
+ GF_ASSERT (brickinfo);
+
+ ret = glusterd_store_volinfo_brick_fname_write (vol_fd, brickinfo,
+ brick_count);
+ if (ret)
+ goto out;
+
+ ret = glusterd_store_create_snap_brick_dir (volinfo, snapinfo);
+ if (ret)
+ goto out;
+
+ ret = glusterd_store_create_snap_brick_shandle_on_absence (volinfo,
+ snapinfo,
+ brickinfo);
+ if (ret)
+ goto out;
+
+ ret = glusterd_store_perform_brick_store (brickinfo);
+out:
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret);
+ return ret;
+}
+int32_t
glusterd_store_delete_brick (glusterd_brickinfo_t *brickinfo, char *delete_path)
{
int32_t ret = -1;
@@ -630,6 +727,73 @@ glusterd_store_create_volume_dir (glusterd_volinfo_t *volinfo)
return ret;
}
+static void
+glusterd_store_vol_snaps_dirpath_set (glusterd_volinfo_t *volinfo,
+ char *snapdirpath, size_t len)
+{
+ glusterd_conf_t *priv = NULL;
+
+ GF_ASSERT (volinfo);
+ priv = THIS->private;
+ GF_ASSERT (priv);
+
+ snprintf (snapdirpath, len, "%s/%s/%s/%s", priv->workdir,
+ GLUSTERD_VOLUME_DIR_PREFIX, volinfo->volname,
+ GLUSTERD_VOL_SNAP_DIR_PREFIX);
+}
+
+static void
+glusterd_store_snap_vol_dirpath_set (glusterd_volinfo_t *volinfo,
+ char *snapdirpath, size_t len,
+ char *snap_name)
+{
+ glusterd_conf_t *priv = NULL;
+ size_t strlen = 0;
+
+ GF_ASSERT (volinfo);
+ priv = THIS->private;
+ GF_ASSERT (priv);
+
+ glusterd_store_vol_snaps_dirpath_set (volinfo, snapdirpath, len);
+ strlen = sizeof (snapdirpath) + sizeof (*snap_name);
+ snprintf (snapdirpath, strlen, "%s/%s", snapdirpath, snap_name);
+}
+/* creates GLUSTERD_VOLUME_DIR_PREFIX/<volname>/snaps directory */
+static int32_t
+glusterd_store_create_snaps_dir (glusterd_volinfo_t *volinfo)
+{
+ int32_t ret = -1;
+ char snapdirpath[PATH_MAX] = {0,};
+
+ GF_ASSERT (volinfo);
+
+ glusterd_store_vol_snaps_dirpath_set (volinfo, snapdirpath,
+ sizeof (snapdirpath));
+ ret = gf_store_mkdir (snapdirpath);
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret);
+ return ret;
+}
+
+
+/* creates GLUSTERD_VOLUME_DIR_PREFIX/<volname>/snaps/<snap-name> directory */
+static int32_t
+glusterd_store_create_snap_vol_dir (glusterd_volinfo_t *volinfo, char *snap_name)
+{
+ int32_t ret = -1;
+ char snapdirpath[PATH_MAX] = {0,};
+
+ GF_ASSERT (volinfo);
+ GF_ASSERT (snap_name);
+
+ glusterd_store_snap_vol_dirpath_set (volinfo, snapdirpath,
+ sizeof (snapdirpath),
+ snap_name);
+
+ ret = gf_store_mkdir (snapdirpath);
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret);
+ return ret;
+}
+
int32_t
glusterd_store_volinfo_write (int fd, glusterd_volinfo_t *volinfo)
{
@@ -698,6 +862,51 @@ glusterd_store_node_state_path_set (glusterd_volinfo_t *volinfo,
GLUSTERD_NODE_STATE_FILE);
}
+static void
+glusterd_store_snap_list_path_set (glusterd_volinfo_t *volinfo,
+ char *snap_list_path, size_t len)
+{
+ char voldirpath[PATH_MAX] = {0,};
+ GF_ASSERT (volinfo);
+ GF_ASSERT (snap_list_path);
+ GF_ASSERT (len <= PATH_MAX);
+
+ glusterd_store_voldirpath_set (volinfo, voldirpath,
+ sizeof (voldirpath));
+ snprintf (snap_list_path, len, "%s/%s", voldirpath,
+ GLUSTERD_VOL_SNAP_FILE);
+}
+
+static void
+glusterd_store_snap_volfpath_set (glusterd_volinfo_t *volinfo,
+ glusterd_volinfo_t *snapinfo,
+ char *volfpath, size_t len)
+{
+ char voldirpath[PATH_MAX] = {0,};
+ GF_ASSERT (volinfo);
+ GF_ASSERT (volfpath);
+ GF_ASSERT (len <= PATH_MAX);
+
+ glusterd_store_snap_vol_dirpath_set (volinfo, voldirpath,
+ sizeof (voldirpath),
+ snapinfo->volname);
+ snprintf (volfpath, len, "%s/%s", voldirpath, GLUSTERD_VOLUME_INFO_FILE);
+}
+
+int32_t
+glusterd_store_create_snap_vol_shandle_on_absence (glusterd_volinfo_t *volinfo,
+ glusterd_volinfo_t *snapinfo)
+{
+ char volfpath[PATH_MAX] = {0};
+ int32_t ret = 0;
+
+ GF_ASSERT (volinfo);
+
+ glusterd_store_snap_volfpath_set (volinfo, snapinfo,
+ volfpath, sizeof (volfpath));
+ ret = gf_store_handle_create_on_absence (&snapinfo->shandle, volfpath);
+ return ret;
+}
int32_t
glusterd_store_create_rbstate_shandle_on_absence (glusterd_volinfo_t *volinfo)
{
@@ -743,6 +952,23 @@ glusterd_store_create_nodestate_sh_on_absence (glusterd_volinfo_t *volinfo)
}
int32_t
+glusterd_store_create_snap_list_sh_on_absence (glusterd_volinfo_t *volinfo)
+{
+ char snap_list_path[PATH_MAX] = {0};
+ int32_t ret = 0;
+
+ GF_ASSERT (volinfo);
+
+ glusterd_store_snap_list_path_set (volinfo, snap_list_path,
+ sizeof (snap_list_path));
+ ret =
+ gf_store_handle_create_on_absence (&volinfo->snap_list_shandle,
+ snap_list_path);
+
+ return ret;
+}
+
+int32_t
glusterd_store_brickinfos (glusterd_volinfo_t *volinfo, int vol_fd)
{
int32_t ret = 0;
@@ -764,6 +990,28 @@ out:
}
int32_t
+glusterd_store_snap_brickinfos (glusterd_volinfo_t *volinfo,
+ glusterd_volinfo_t *snapinfo, int vol_fd)
+{
+ int32_t ret = 0;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ int32_t brick_count = 0;
+
+ GF_ASSERT (volinfo);
+
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ ret = glusterd_store_snap_brickinfo (volinfo, snapinfo,
+ brickinfo, brick_count,
+ vol_fd);
+ if (ret)
+ goto out;
+ brick_count++;
+ }
+out:
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+int32_t
glusterd_store_rbstate_write (int fd, glusterd_volinfo_t *volinfo)
{
int ret = -1;
@@ -886,6 +1134,184 @@ out:
}
int32_t
+glusterd_store_snap_list_write (int fd, glusterd_snap_t *snap, uint64_t count)
+{
+ int ret = -1;
+ char key[256] = {0, };
+ char buf[PATH_MAX] = {0, };
+
+ GF_ASSERT (fd > 0);
+ GF_ASSERT (snap);
+
+ snprintf (key, sizeof (key), "%s-%"PRIu64, GLUSTERD_STORE_KEY_SNAP_NAME,
+ count);
+ ret = gf_store_save_value (fd, key, snap->snap_name);
+ if (ret)
+ goto out;
+
+ snprintf (key, sizeof (key), "%s-%"PRIu64, GLUSTERD_STORE_KEY_SNAP_ID,
+ count);
+ ret = gf_store_save_value (fd, key, uuid_utoa(snap->snap_id));
+ if (ret)
+ goto out;
+
+ snprintf (key, sizeof (key), "%s-%"PRIu64,
+ GLUSTERD_STORE_KEY_SNAP_CG_ID, count);
+ ret = gf_store_save_value (fd, key, uuid_utoa(snap->cg_id));
+ if (ret)
+ goto out;
+
+ snprintf (buf, sizeof (buf), "%d", snap->snap_status);
+ snprintf (key, sizeof (key), "%s-%"PRIu64,
+ GLUSTERD_STORE_KEY_SNAP_STATUS, count);
+ ret = gf_store_save_value (fd, key, buf);
+ if (ret)
+ goto out;
+out:
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int32_t
+glusterd_store_perform_snap_volume_store (glusterd_volinfo_t *volinfo,
+ glusterd_volinfo_t *snap_volinfo)
+{
+ int fd = -1;
+ int32_t ret = -1;
+ GF_ASSERT (volinfo);
+ GF_ASSERT (snap_volinfo);
+
+ ret = glusterd_store_create_snap_vol_shandle_on_absence (volinfo,
+ snap_volinfo);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to create "
+ " shandle for snap %s of volume %s", volinfo->volname,
+ snap_volinfo->volname);
+ goto out;
+ }
+ fd = gf_store_mkstemp (snap_volinfo->shandle);
+ if (fd <= 0) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = glusterd_store_volinfo_write (fd, snap_volinfo);
+ if (ret)
+ goto out;
+ ret = glusterd_store_snap_brickinfos (volinfo, snap_volinfo, fd);
+ if (ret)
+ goto out;
+out:
+ if (ret && (fd > 0))
+ gf_store_unlink_tmppath (volinfo->shandle);
+ if (fd > 0)
+ close (fd);
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int32_t
+glusterd_store_snap_volume (glusterd_volinfo_t *volinfo, glusterd_snap_t *snap)
+{
+ int32_t ret = -1;
+ glusterd_volinfo_t *snap_volinfo = NULL;
+
+ GF_ASSERT (volinfo);
+ GF_ASSERT (snap);
+
+
+ LOCK (&snap->lock);
+ {
+ snap_volinfo = snap->snap_volume;
+
+ ret = glusterd_store_create_snap_vol_dir (volinfo,
+ snap->snap_name);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed create snapshot dir (%s) for volume "
+ "%s", snap->snap_name, volinfo->volname);
+ goto unlock;
+ }
+
+ ret = glusterd_store_perform_snap_volume_store (volinfo,
+ snap_volinfo);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed store snapshot volinfo (%s) for volume "
+ "%s", snap->snap_name, volinfo->volname);
+ goto unlock;
+ }
+ }
+unlock:
+ UNLOCK (&snap->lock);
+
+ return 0;
+
+}
+
+int32_t
+glusterd_store_perform_snap_store (glusterd_volinfo_t *volinfo)
+{
+ int fd = -1;
+ int32_t ret = -1;
+ glusterd_snap_t *entry = NULL;
+ glusterd_snap_t *tmp = NULL;
+ uint64_t count = 0;
+ char buf[PATH_MAX] = {0,};
+
+ GF_ASSERT (volinfo);
+
+ ret = glusterd_store_create_snaps_dir (volinfo);
+ if (ret)
+ goto out;
+
+ ret = glusterd_store_create_snap_list_sh_on_absence (volinfo);
+ if (ret)
+ goto out;
+ fd = gf_store_mkstemp (volinfo->snap_list_shandle);
+ if (fd <= 0) {
+ ret = -1;
+ goto out;
+ }
+
+ LOCK (&volinfo->lock);
+ {
+ list_for_each_entry_safe (entry, tmp, &volinfo->snaps,
+ snap_list) {
+ ret = glusterd_store_snap_list_write (fd, entry, count);
+ if (ret)
+ goto unlock;
+ ret = glusterd_store_snap_volume (volinfo, entry);
+ if (ret)
+ goto unlock;
+ count++;
+ }
+ snprintf (buf, sizeof(buf), "%"PRIu64, count);
+ ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_COUNT,
+ buf);
+ if (ret)
+ goto unlock;
+ }
+unlock:
+ UNLOCK (&volinfo->lock);
+
+ ret = gf_store_rename_tmppath (volinfo->snap_list_shandle);
+ if (ret)
+ goto out;
+
+out:
+ if (ret && (fd > 0))
+ gf_store_unlink_tmppath (volinfo->snap_list_shandle);
+ if (fd > 0)
+ close (fd);
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+
+
+
+int32_t
glusterd_store_perform_node_state_store (glusterd_volinfo_t *volinfo)
{
int fd = -1;
@@ -1063,6 +1489,9 @@ glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t a
if (ret)
goto out;
+ ret = glusterd_store_create_snap_list_sh_on_absence (volinfo);
+ if (ret)
+ goto out;
ret = glusterd_store_perform_volume_store (volinfo);
if (ret)
goto out;
@@ -1082,6 +1511,10 @@ glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t a
if (ret)
goto out;
+ ret = glusterd_store_perform_snap_store (volinfo);
+ if (ret)
+ goto out;
+
//checksum should be computed at the end
ret = glusterd_volume_compute_cksum (volinfo);
if (ret)
@@ -1098,7 +1531,8 @@ out:
int32_t
-glusterd_store_delete_volume (glusterd_volinfo_t *volinfo)
+glusterd_store_delete_volume (glusterd_volinfo_t *volinfo,
+ glusterd_volinfo_t *snapinfo)
{
char pathname[PATH_MAX] = {0,};
int32_t ret = 0;
@@ -1120,7 +1554,12 @@ glusterd_store_delete_volume (glusterd_volinfo_t *volinfo)
GF_ASSERT (priv);
- GLUSTERD_GET_VOLUME_DIR (pathname, volinfo, priv);
+ if (snapinfo) {
+ GLUSTERD_GET_SNAP_DIR (pathname, volinfo, snapinfo->volname,
+ priv);
+ } else {
+ GLUSTERD_GET_VOLUME_DIR (pathname, volinfo, priv);
+ }
snprintf (delete_path, sizeof (delete_path),
"%s/"GLUSTERD_TRASH"/%s.deleted", priv->workdir,
@@ -1444,7 +1883,7 @@ out:
int32_t
-glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo)
+glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo, char *snap_name)
{
int32_t ret = 0;
@@ -1467,7 +1906,12 @@ glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo)
priv = THIS->private;
- GLUSTERD_GET_BRICK_DIR (brickdir, volinfo, priv)
+ if (snap_name) {
+ GLUSTERD_GET_SNAP_BRICK_DIR (brickdir, volinfo, snap_name,
+ priv);
+ } else {
+ GLUSTERD_GET_BRICK_DIR (brickdir, volinfo, priv);
+ }
ret = gf_store_iter_new (volinfo->shandle, &tmpiter);
@@ -1770,7 +2214,7 @@ out:
}
int32_t
-glusterd_store_retrieve_volume (char *volname)
+glusterd_store_retrieve_volume (char *volname, glusterd_snap_t *snap)
{
int32_t ret = -1;
glusterd_volinfo_t *volinfo = NULL;
@@ -1791,7 +2235,11 @@ glusterd_store_retrieve_volume (char *volname)
priv = THIS->private;
- GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, priv);
+ if (snap) {
+ GLUSTERD_GET_SNAP_DIR (volpath, volinfo, snap->snap_name, priv);
+ } else {
+ GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, priv);
+ }
snprintf (path, sizeof (path), "%s/%s", volpath,
GLUSTERD_VOLUME_INFO_FILE);
@@ -1967,7 +2415,7 @@ glusterd_store_retrieve_volume (char *volname)
if (ret)
goto out;
- ret = glusterd_store_retrieve_bricks (volinfo);
+ ret = glusterd_store_retrieve_bricks (volinfo, snap->snap_name);
if (ret)
goto out;
@@ -1976,7 +2424,12 @@ glusterd_store_retrieve_volume (char *volname)
goto out;
- list_add_tail (&volinfo->vol_list, &priv->volumes);
+ if (!snap) {
+ list_add_tail (&volinfo->vol_list, &priv->volumes);
+ } else {
+ snap->snap_volume = volinfo;
+ }
+
out:
gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
@@ -2081,6 +2534,128 @@ out:
}
int32_t
+glusterd_store_retrieve_snap_list (char *volname)
+{
+ int32_t ret = -1;
+ glusterd_volinfo_t *volinfo = NULL;
+ gf_store_iter_t *iter = NULL;
+ char key[256] = {0, };
+ char *value = NULL;
+ char volpath[PATH_MAX] = {0,};
+ glusterd_conf_t *priv = NULL;
+ char path[PATH_MAX] = {0,};
+ gf_store_op_errno_t op_errno = GD_STORE_SUCCESS;
+ glusterd_snap_t *snap = NULL;
+ uint64_t count = 0;
+
+ priv = THIS->private;
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Couldn't get"
+ "volinfo for %s.", volname);
+ goto out;
+ }
+
+ GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, priv);
+ snprintf (path, sizeof (path), "%s/%s", volpath,
+ GLUSTERD_VOL_SNAP_FILE);
+
+ ret = gf_store_handle_retrieve (path, &volinfo->snap_list_shandle);
+ if (ret)
+ goto out;
+
+ ret = gf_store_iter_new (volinfo->snap_list_shandle, &iter);
+ if (ret)
+ goto out;
+
+ ret = gf_store_iter_get_matching (iter, GLUSTERD_STORE_KEY_SNAP_COUNT,
+ &value);
+ if(ret)
+ goto out;
+
+ volinfo->snap_count = atol(value);
+ GF_FREE (value);
+ value = NULL;
+
+ while (count <= volinfo->snap_count) {
+ snap = glusterd_new_snap_object ();
+ if (!snap) {
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "Failed to create snap object");
+ goto out;
+ }
+
+ snprintf (key, sizeof (key), "%s-%"PRIu64,
+ GLUSTERD_STORE_KEY_SNAP_NAME, count);
+ ret = gf_store_iter_get_matching (iter, key, &value);
+ if (ret)
+ goto out;
+
+ strncpy (snap->snap_name, value, sizeof (*value));
+ GF_FREE (value);
+ value = NULL;
+
+ snprintf (key, sizeof (key), "%s-%"PRIu64,
+ GLUSTERD_STORE_KEY_SNAP_STATUS, count);
+ ret = gf_store_iter_get_matching (iter, key,
+ &value);
+ if (ret)
+ goto out;
+
+ snap->snap_status = atoi (value);
+ GF_FREE (value);
+ value = NULL;
+
+ snprintf (key, sizeof (key), "%s-%"PRIu64,
+ GLUSTERD_STORE_KEY_SNAP_ID, count);
+ ret = gf_store_iter_get_matching (iter, key, &value);
+ if (ret)
+ goto out;
+
+ uuid_parse (value, snap->snap_id);
+ GF_FREE (value);
+ value = NULL;
+
+ snprintf (key, sizeof (key), "%s-%"PRIu64,
+ GLUSTERD_STORE_KEY_SNAP_CG_ID, count);
+ ret = gf_store_iter_get_matching (iter, key, &value);
+ if (ret)
+ goto out;
+
+ uuid_parse (value, snap->cg_id);
+ GF_FREE (value);
+ value = NULL;
+
+ ret = glusterd_add_snap (volinfo, snap);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to add %s to"
+ " snap_list", value);
+ goto out;
+ }
+ ret = glusterd_store_retrieve_volume (volname, snap);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to retrieve "
+ "snap %s for volume %s", snap->snap_name, volname);
+ goto out;
+ }
+ count++;
+ }
+
+ if (op_errno != GD_STORE_EOF)
+ goto out;
+
+ ret = gf_store_iter_destroy (iter);
+
+ if (ret)
+ goto out;
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
+
+ return ret;
+}
+int32_t
glusterd_store_retrieve_volumes (xlator_t *this)
{
int32_t ret = 0;
@@ -2109,7 +2684,7 @@ glusterd_store_retrieve_volumes (xlator_t *this)
glusterd_for_each_entry (entry, dir);
while (entry) {
- ret = glusterd_store_retrieve_volume (entry->d_name);
+ ret = glusterd_store_retrieve_volume (entry->d_name, NULL);
if (ret) {
gf_log ("", GF_LOG_ERROR, "Unable to restore "
"volume: %s", entry->d_name);
@@ -2137,6 +2712,17 @@ glusterd_store_retrieve_volumes (xlator_t *this)
ret = glusterd_store_perform_node_state_store (volinfo);
}
+ ret = glusterd_store_retrieve_snap_list (entry->d_name);
+ if (ret) {
+ /* Backward compatibility */
+ gf_log ("", GF_LOG_INFO, "Creating a new snap_list "
+ "for volume: %s.", entry->d_name);
+ ret = glusterd_volinfo_find (entry->d_name, &volinfo);
+ ret =
+ glusterd_store_create_snap_list_sh_on_absence (volinfo);
+ ret = glusterd_store_perform_snap_list_store (volinfo);
+
+ }
glusterd_for_each_entry (entry, dir);
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h
index ce1f766b1..2bf14a743 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.h
+++ b/xlators/mgmt/glusterd/src/glusterd-store.h
@@ -59,6 +59,14 @@ typedef enum glusterd_store_ver_ac_{
#define GLUSTERD_STORE_KEY_VOL_OP_VERSION "op-version"
#define GLUSTERD_STORE_KEY_VOL_CLIENT_OP_VERSION "client-op-version"
+#define GLUSTERD_STORE_KEY_SNAP_NAME "name"
+#define GLUSTERD_STORE_KEY_SNAP_ID "snap-id"
+#define GLUSTERD_STORE_KEY_SNAP_CG_ID "cg-id"
+#define GLUSTERD_STORE_KEY_SNAP_DESC "desc"
+#define GLUSTERD_STORE_KEY_SNAP_TIMESTAMP "time-stamp"
+#define GLUSTERD_STORE_KEY_SNAP_STATUS "status"
+#define GLUSTERD_STORE_KEY_SNAP_COUNT "count"
+
#define GLUSTERD_STORE_KEY_BRICK_HOSTNAME "hostname"
#define GLUSTERD_STORE_KEY_BRICK_PATH "path"
#define GLUSTERD_STORE_KEY_BRICK_PORT "listen-port"
@@ -90,7 +98,8 @@ int32_t
glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t ac);
int32_t
-glusterd_store_delete_volume (glusterd_volinfo_t *volinfo);
+glusterd_store_delete_volume (glusterd_volinfo_t *volinfo,
+ glusterd_volinfo_t *snapinfo);
int32_t
glusterd_retrieve_uuid ();
@@ -128,4 +137,7 @@ glusterd_store_retrieve_options (xlator_t *this);
int32_t
glusterd_store_options (xlator_t *this, dict_t *opts);
+
+int32_t
+glusterd_store_perform_snap_list_store (glusterd_volinfo_t *volinfo);
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 15924cc30..177b65710 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -5604,7 +5604,7 @@ glusterd_delete_volume (glusterd_volinfo_t *volinfo)
int ret = -1;
GF_ASSERT (volinfo);
- ret = glusterd_store_delete_volume (volinfo);
+ ret = glusterd_store_delete_volume (volinfo, NULL);
if (ret)
goto out;
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
index 561ff652d..c467945de 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
@@ -1646,7 +1646,7 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr)
ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
if (ret) {
- glusterd_store_delete_volume (volinfo);
+ glusterd_store_delete_volume (volinfo, NULL);
*op_errstr = gf_strdup ("Failed to store the Volume information");
goto out;
}
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 823c845c1..724618b0e 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -271,8 +271,10 @@ typedef struct glusterd_replace_brick_ glusterd_replace_brick_t;
struct glusterd_volinfo_ {
gf_lock_t lock;
char volname[GLUSTERD_MAX_VOLUME_NAME];
+ gf_boolean_t is_snap_volume;
int type;
int brick_count;
+ uint64_t snap_count;
struct list_head vol_list;
struct list_head bricks;
struct list_head snaps;
@@ -288,6 +290,7 @@ struct glusterd_volinfo_ {
gf_store_handle_t *shandle;
gf_store_handle_t *rb_shandle;
gf_store_handle_t *node_state_shandle;
+ gf_store_handle_t *snap_list_shandle;
/* Defrag/rebalance related */
glusterd_rebalance_t rebal;
@@ -336,6 +339,7 @@ struct glusterd_snap_ {
char *description;
time_t time_stamp;
gd_snap_status_t snap_status;
+ gf_store_handle_t *shandle;
};
typedef struct glusterd_snap_ glusterd_snap_t;
@@ -348,6 +352,7 @@ struct glusterd_snap_cg_ {
gd_snap_status_t cg_status;
int64_t volume_count;
struct list_head cg_list;
+ gf_store_handle_t *shandle;
glusterd_volinfo_t volumes[0];
};
@@ -397,6 +402,8 @@ enum glusterd_vol_comp_status_ {
#define GLUSTERD_CKSUM_FILE "cksum"
#define GLUSTERD_TRASH "trash"
#define GLUSTERD_NODE_STATE_FILE "node_state.info"
+#define GLUSTERD_VOL_SNAP_FILE "snap_list.info"
+#define GLUSTERD_VOL_SNAP_DIR_PREFIX "snaps"
/* definitions related to replace brick */
#define RB_CLIENT_MOUNTPOINT "rb_mount"
@@ -413,11 +420,20 @@ typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args);
snprintf (path, PATH_MAX, "%s/vols/%s", priv->workdir,\
volinfo->volname);
+#define GLUSTERD_GET_SNAP_DIR(path, volinfo, snap_name, priv) \
+ snprintf (path, PATH_MAX, "%s/vols/%s/snaps/%s", priv->workdir,\
+ volinfo->volname, snap_name);
+
#define GLUSTERD_GET_BRICK_DIR(path, volinfo, priv) \
snprintf (path, PATH_MAX, "%s/%s/%s/%s", priv->workdir,\
GLUSTERD_VOLUME_DIR_PREFIX, volinfo->volname, \
GLUSTERD_BRICK_INFO_DIR);
+#define GLUSTERD_GET_SNAP_BRICK_DIR(path, volinfo, snap_name, priv) \
+ snprintf (path, PATH_MAX, "%s/%s/%s/snaps/%s/%s", priv->workdir,\
+ GLUSTERD_VOLUME_DIR_PREFIX, volinfo->volname, \
+ snap_name, GLUSTERD_BRICK_INFO_DIR);
+
#define GLUSTERD_GET_NFS_DIR(path, priv) \
snprintf (path, PATH_MAX, "%s/nfs", priv->workdir);