From 6726c1617daeb783053a15d12189a64c27343f8c Mon Sep 17 00:00:00 2001 From: shishir gowda Date: Wed, 9 Oct 2013 10:42:56 +0530 Subject: mgmt/glusterd: Store for snapshot Introduced a new store for storing snapshot list for a given volume. $GLUSTERD_INSTALL_PATH/vols//snap_list.info $GLUSTERD_INSTALL_PATH/vols//snaps/ $GLUSTERD_INSTALL_PATH/vols//snaps//info <-snapshot volume info $GLUSTERD_INSTALL_PATH/vols//snaps//bricks <-snapshot volume brick dir $GLUSTERD_INSTALL_PATH/vols//snaps//bricks/ <-snapshot volume brick info files store delete options TODO - $GLUSTERD_INSTALL_PATH/CG/ <-place holder for all cg's .../CG//info <- per cg information placeholder Change-Id: I1f9fd8ff7cc0682d05b33965736a43dca6adb3e9 Signed-off-by: shishir gowda --- xlators/mgmt/glusterd/src/glusterd-snapshot.c | 19 +- xlators/mgmt/glusterd/src/glusterd-store.c | 604 +++++++++++++++++++++++- xlators/mgmt/glusterd/src/glusterd-store.h | 14 +- xlators/mgmt/glusterd/src/glusterd-utils.c | 2 +- xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 2 +- xlators/mgmt/glusterd/src/glusterd.h | 16 + 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) { @@ -209,6 +255,24 @@ glusterd_store_create_brick_shandle_on_absence (glusterd_volinfo_t *volinfo, return ret; } +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) { @@ -307,6 +371,39 @@ out: return ret; } +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) { @@ -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//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//snaps/ 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) { @@ -742,6 +951,23 @@ glusterd_store_create_nodestate_sh_on_absence (glusterd_volinfo_t *volinfo) return ret; } +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) { @@ -763,6 +989,28 @@ out: return ret; } +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) { @@ -885,6 +1133,184 @@ out: return ret; } +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) { @@ -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); @@ -2080,6 +2533,128 @@ out: return ret; } +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) { @@ -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); @@ -2136,6 +2711,17 @@ glusterd_store_retrieve_volumes (xlator_t *this) glusterd_store_create_nodestate_sh_on_absence (volinfo); 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); -- cgit