From fe5927b6bd1ed795c9e85996e7c54c3abe36ceba Mon Sep 17 00:00:00 2001 From: Vijaikumar M Date: Fri, 14 Feb 2014 20:01:38 +0530 Subject: glusterd/snapshot: store location for snap driven changes Currently snapshot volfiles are stored at: /vols//snaps/ With snap driven approach we need to store the volfiles at: /snaps// Change-Id: I8efdd5db29833b2b06b64a900cbb4c9b9a5d36b6 Signed-off-by: Vijaikumar M Signed-off-by: Sachin Pandit Reviewed-on: http://review.gluster.org/7006 Reviewed-by: Avra Sengupta Reviewed-by: Rajesh Joseph Tested-by: Rajesh Joseph --- xlators/mgmt/glusterd/src/glusterd-store.c | 1407 ++++++++++------------------ 1 file changed, 519 insertions(+), 888 deletions(-) (limited to 'xlators/mgmt/glusterd/src/glusterd-store.c') diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c index c02c2c690..7b45da00f 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -76,26 +76,6 @@ 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) @@ -145,32 +125,6 @@ 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) { @@ -255,24 +209,6 @@ 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) { @@ -366,48 +302,12 @@ glusterd_store_brickinfo (glusterd_volinfo_t *volinfo, 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_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); - if (ret) - goto out; - ret = gf_store_rename_tmppath (brickinfo->shandle); 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) { @@ -736,8 +636,7 @@ glusterd_store_voldirpath_set (glusterd_volinfo_t *volinfo, char *voldirpath, priv = THIS->private; GF_ASSERT (priv); - snprintf (voldirpath, len, "%s/%s/%s", priv->workdir, - GLUSTERD_VOLUME_DIR_PREFIX, volinfo->volname); + GLUSTERD_GET_VOLUME_DIR (voldirpath, volinfo, priv); } static int32_t @@ -751,67 +650,43 @@ glusterd_store_create_volume_dir (glusterd_volinfo_t *volinfo) glusterd_store_voldirpath_set (volinfo, voldirpath, sizeof (voldirpath)); ret = gf_store_mkdir (voldirpath); + gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret); return ret; } -static void -glusterd_store_vol_snaps_cg_dirpath_set (char *cgdirpath, size_t len) +static int32_t +glusterd_store_create_snap_dir (glusterd_snap_t *snap) { - glusterd_conf_t *priv = NULL; + int32_t ret = -1; + char snapdirpath[PATH_MAX] = {0,}; + glusterd_conf_t *priv = NULL; priv = THIS->private; GF_ASSERT (priv); + GF_ASSERT (snap); - snprintf (cgdirpath, len, "%s/%s", priv->workdir, - GLUSTERD_VOL_SNAP_CG_DIR_PREFIX); -} -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, PATH_MAX, "%s/snaps/%s", priv->workdir, + snap->snapname); - snprintf (snapdirpath, len, "%s/%s/%s/%s", priv->workdir, - GLUSTERD_VOLUME_DIR_PREFIX, volinfo->volname, - GLUSTERD_VOL_SNAP_DIR_PREFIX); + ret = mkdir_p (snapdirpath, 0755, _gf_true); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, "Failed to create snaps dir " + "%s", snapdirpath); + } + return ret; } static void -glusterd_store_snap_vol_dirpath_set (glusterd_volinfo_t *volinfo, - char *snapdirpath, size_t len, - char *snap_name) +glusterd_store_vol_snaps_cg_dirpath_set (char *cgdirpath, size_t len) { glusterd_conf_t *priv = NULL; - size_t strlen = 0; - char path[PATH_MAX] = {0,}; - GF_ASSERT (volinfo); priv = THIS->private; GF_ASSERT (priv); - glusterd_store_vol_snaps_dirpath_set (volinfo, path, sizeof (path)); - strlen = sizeof (path) + sizeof (*snap_name); - snprintf (snapdirpath, strlen, "%s/%s", path, 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; + snprintf (cgdirpath, len, "%s/%s", priv->workdir, + GLUSTERD_VOL_SNAP_CG_DIR_PREFIX); } /* creates GLUSTERD_VOLUME_DIR_PREFIX/cg directory */ @@ -827,24 +702,6 @@ glusterd_store_create_snaps_cg_dir () 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) @@ -870,6 +727,49 @@ out: return ret; } +int32_t +glusterd_store_snapinfo_write (glusterd_snap_t *snap) +{ + int32_t ret = -1; + int fd = 0; + char buf[PATH_MAX] = ""; + + GF_ASSERT (snap); + + fd = gf_store_mkstemp (snap->shandle); + if (fd <= 0) + goto out; + + ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_ID, + uuid_utoa (snap->snap_id)); + if (ret) + goto out; + + snprintf (buf, sizeof (buf), "%d", snap->snap_status); + ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_STATUS, buf); + if (ret) + goto out; + + snprintf (buf, sizeof (buf), "%d", snap->snap_restored); + ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_RESTORED, buf); + if (ret) + goto out; + + if (snap->description) { + ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_DESC, + snap->description); + if (ret) + goto out; + } + + snprintf (buf, sizeof (buf), "%ld", snap->time_stamp); + ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_TIMESTAMP, buf); + +out: + gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + static void glusterd_store_rbstatepath_set (glusterd_volinfo_t *volinfo, char *rbstatepath, size_t len) @@ -915,49 +815,19 @@ glusterd_store_node_state_path_set (glusterd_volinfo_t *volinfo, } static void -glusterd_store_snap_list_path_set (glusterd_volinfo_t *volinfo, - char *snap_list_path, size_t len) +glusterd_store_snapfpath_set (glusterd_snap_t *snap, char *snap_fpath, + 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); -} + glusterd_conf_t *priv = NULL; -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); + priv = THIS->private; + GF_ASSERT (priv); + GF_ASSERT (snap); + GF_ASSERT (snap_fpath); 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; + snprintf (snap_fpath, len, "%s/snaps/%s/%s", priv->workdir, + snap->snapname, GLUSTERD_SNAP_INFO_FILE); } static void @@ -1032,19 +902,15 @@ 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) +glusterd_store_create_snap_shandle_on_absence (glusterd_snap_t *snap) { - char snap_list_path[PATH_MAX] = {0}; - int32_t ret = 0; - - GF_ASSERT (volinfo); + char snapfpath[PATH_MAX] = {0}; + int32_t ret = 0; - 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); + GF_ASSERT (snap); + glusterd_store_snapfpath_set (snap, snapfpath, sizeof (snapfpath)); + ret = gf_store_handle_create_on_absence (&snap->shandle, snapfpath); return ret; } @@ -1069,28 +935,6 @@ 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, &snapinfo->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) { @@ -1213,90 +1057,6 @@ 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) { - gf_log ("", GF_LOG_ERROR, "Failed to store snap-name of " - "snap %s", snap->snap_name); - goto out; - } - - if ( strlen(snap->cg_name) > 0 ) { - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_CG_NAME, count); - ret = gf_store_save_value (fd, key, snap->cg_name); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to store cg_name " - "of snap %s", snap->snap_name); - 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) { - gf_log ("", GF_LOG_ERROR, "Failed to store snap-ID of " - "snap %s", snap->snap_name); - 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) { - gf_log ("", GF_LOG_ERROR, "Failed to store CG-ID of snap %s", - snap->snap_name); - 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) { - gf_log ("", GF_LOG_ERROR, "Failed to store snap-status of " - "snap %s", snap->snap_name); - goto out; - } - - if (snap->description) { - snprintf (buf, sizeof (buf), "%s", snap->description); - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_DESC, count); - ret = gf_store_save_value (fd, key, buf); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to store snap-description " - "of snap %s", snap->snap_name); - goto out; - } - } - - snprintf (buf, sizeof (buf), "%ld", snap->time_stamp); - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_TIMESTAMP, count); - ret = gf_store_save_value (fd, key, buf); - if (ret){ - gf_log ("", GF_LOG_ERROR, "Failed to store snap-time of %s", - snap->snap_name); - goto out; - } - -out: - gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret); - return ret; -} - int32_t glusterd_store_snap_cg_write (int fd, glusterd_snap_cg_t *cg) { @@ -1385,79 +1145,28 @@ out: } int32_t -glusterd_store_perform_snap_volume_store (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snap_volinfo) +glusterd_store_snap_volume (glusterd_volinfo_t *volinfo, glusterd_snap_t *snap) { - int fd = -1; - int32_t ret = -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; - - ret = gf_store_rename_tmppath (snap_volinfo->shandle); - 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); + GF_ASSERT (snap); LOCK (&snap->lock); { - snap_volinfo = snap->snap_volume; - - if (!snap_volinfo) - goto unlock; - - ret = glusterd_store_create_snap_vol_dir (volinfo, - snap_volinfo->volname); + 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->snap_name, volinfo->volname); + "%s", snap->snapname, volinfo->volname); goto unlock; } - ret = glusterd_store_perform_snap_volume_store (volinfo, - snap_volinfo); + 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->snap_name, volinfo->volname); + "%s", snap->snapname, volinfo->volname); goto unlock; } } @@ -1468,213 +1177,6 @@ unlock: } -int32_t -glusterd_store_perform_snap_list_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_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; - 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_TRACE, "Returning %d", ret); - return ret; -} - -int32_t -glusterd_store_perform_snap_store (glusterd_volinfo_t *volinfo, char *snapname) -{ - 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,}; - xlator_t *this = NULL; - - GF_ASSERT (volinfo); - GF_ASSERT (snapname); - - this = THIS; - GF_ASSERT (this); - - ret = glusterd_store_create_snaps_dir (volinfo); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "failed to create the snaps " - "directory for the volume %s (snap: %s)", - volinfo->volname, snapname); - 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) { - if (!strcmp (entry->snap_name, snapname)) { - ret = glusterd_store_snap_list_write (fd, entry, - count); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "Failed to write snap list to" - " store"); - goto unlock; - } - ret = glusterd_store_snap_volume (volinfo, - entry); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "Failed to store snap volume"); - goto unlock; - } - } - count++; - } - GF_ASSERT (count == volinfo->snap_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_TRACE, "Returning %d", ret); - return ret; -} - -int32_t -glusterd_store_perform_all_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,}; - xlator_t *this = NULL; - - GF_ASSERT (volinfo); - - this = THIS; - GF_ASSERT (this); - - ret = glusterd_store_create_snaps_dir (volinfo); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "failed to create the snaps " - "directory for the volume %s", volinfo->volname); - 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) { - gf_log (this->name, GF_LOG_ERROR, "Failed to " - "write snap list to store"); - goto unlock; - } - ret = glusterd_store_snap_volume (volinfo, entry); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Failed to " - "store snap volume"); - 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_TRACE, "Returning %d", ret); - return ret; -} - int32_t glusterd_store_snap_cg (glusterd_snap_cg_t *cg) { @@ -1831,8 +1333,14 @@ glusterd_store_volume_cleanup_tmp (glusterd_volinfo_t *volinfo) gf_store_unlink_tmppath (volinfo->rb_shandle); gf_store_unlink_tmppath (volinfo->node_state_shandle); +} - gf_store_unlink_tmppath (volinfo->snap_list_shandle); +void +glusterd_store_snap_cleanup_tmp (glusterd_snap_t *snap) +{ + GF_ASSERT (snap); + + gf_store_unlink_tmppath (snap->shandle); } int32_t @@ -1885,6 +1393,60 @@ out: return ret; } +int32_t +glusterd_store_snap_atomic_update (glusterd_snap_t *snap) +{ + int ret = -1; + GF_ASSERT (snap); + + ret = gf_store_rename_tmppath (snap->shandle); + if (ret) + gf_log (THIS->name, GF_LOG_ERROR, "Couldn't rename " + "temporary file(s): Reason %s", strerror (errno)); + + return ret; +} + +int32_t +glusterd_store_snap (glusterd_snap_t *snap) +{ + int32_t ret = -1; + + GF_ASSERT (snap); + + ret = glusterd_store_create_snap_dir (snap); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, "Failed to create snap dir"); + goto out; + } + + ret = glusterd_store_create_snap_shandle_on_absence (snap); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, "Failed to create snap info " + "file"); + goto out; + } + + ret = glusterd_store_snapinfo_write (snap); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, "Failed to write snap info"); + goto out; + } + + ret = glusterd_store_snap_atomic_update (snap); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR,"Failed to do automic update"); + goto out; + } + +out: + if (ret) + glusterd_store_snap_cleanup_tmp (snap); + + gf_log (THIS->name, GF_LOG_TRACE, "Returning %d", ret); + return ret; +} + int32_t glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t ac) { @@ -1909,9 +1471,6 @@ 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; @@ -1931,12 +1490,8 @@ glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t a if (ret) goto out; - ret = glusterd_store_perform_all_snap_store (volinfo); - if (ret) - goto out; - //checksum should be computed at the end - ret = glusterd_volume_compute_cksum (volinfo, NULL); + ret = glusterd_volume_compute_cksum (volinfo); if (ret) goto out; @@ -2018,8 +1573,7 @@ out: } int32_t -glusterd_store_delete_volume (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snapinfo) +glusterd_store_delete_volume (glusterd_volinfo_t *volinfo) { char pathname[PATH_MAX] = {0,}; int32_t ret = 0; @@ -2041,22 +1595,11 @@ glusterd_store_delete_volume (glusterd_volinfo_t *volinfo, GF_ASSERT (priv); - if (snapinfo) { - GLUSTERD_GET_SNAP_DIR (pathname, volinfo, snapinfo->volname, - priv); - } else { - GLUSTERD_GET_VOLUME_DIR (pathname, volinfo, priv); - } + GLUSTERD_GET_VOLUME_DIR (pathname, volinfo, priv); - if (snapinfo == NULL ) { - snprintf (delete_path, sizeof (delete_path), - "%s/"GLUSTERD_TRASH"/%s.deleted", priv->workdir, - uuid_utoa (volinfo->volume_id)); - } else { - snprintf (delete_path, sizeof (delete_path), - "%s/"GLUSTERD_TRASH"/%s.deleted", priv->workdir, - uuid_utoa (snapinfo->volume_id)); - } + snprintf (delete_path, sizeof (delete_path), + "%s/"GLUSTERD_TRASH"/%s.deleted", priv->workdir, + uuid_utoa (volinfo->volume_id)); snprintf (trashdir, sizeof (trashdir), "%s/"GLUSTERD_TRASH, priv->workdir); @@ -2148,6 +1691,115 @@ out: return ret; } +int32_t +glusterd_store_delete_snap (glusterd_snap_t *snap) +{ + char pathname[PATH_MAX] = {0,}; + int32_t ret = 0; + glusterd_conf_t *priv = NULL; + DIR *dir = NULL; + struct dirent *entry = NULL; + char path[PATH_MAX] = {0,}; + char delete_path[PATH_MAX] = {0,}; + char trashdir[PATH_MAX] = {0,}; + struct stat st = {0, }; + xlator_t *this = NULL; + gf_boolean_t rename_fail = _gf_false; + + this = THIS; + priv = this->private; + GF_ASSERT (priv); + + GF_ASSERT (snap); + GLUSTERD_GET_SNAP_DIR (pathname, snap, priv); + + snprintf (delete_path, sizeof (delete_path), + "%s/"GLUSTERD_TRASH"/snap-%s.deleted", priv->workdir, + uuid_utoa (snap->snap_id)); + + snprintf (trashdir, sizeof (trashdir), "%s/"GLUSTERD_TRASH, + priv->workdir); + + ret = mkdir (trashdir, 0777); + if (ret && errno != EEXIST) { + gf_log (this->name, GF_LOG_ERROR, "Failed to create trash " + "directory, reason : %s", strerror (errno)); + ret = -1; + goto out; + } + + ret = rename (pathname, delete_path); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to rename snap " + "directory %s to %s", snap->snapname, delete_path); + rename_fail = _gf_true; + goto out; + } + + dir = opendir (delete_path); + if (!dir) { + gf_log (this->name, GF_LOG_DEBUG, "Failed to open directory %s." + " Reason : %s", delete_path, strerror (errno)); + ret = 0; + goto out; + } + + glusterd_for_each_entry (entry, dir); + while (entry) { + snprintf (path, PATH_MAX, "%s/%s", delete_path, entry->d_name); + ret = stat (path, &st); + if (ret == -1) { + gf_log (this->name, GF_LOG_DEBUG, "Failed to stat " + "entry %s : %s", path, strerror (errno)); + goto stat_failed; + } + + if (S_ISDIR (st.st_mode)) + ret = rmdir (path); + else + ret = unlink (path); + + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, " Failed to remove " + "%s. Reason : %s", path, strerror (errno)); + } + + gf_log (this->name, GF_LOG_DEBUG, "%s %s", + ret ? "Failed to remove":"Removed", + entry->d_name); +stat_failed: + memset (path, 0, sizeof(path)); + glusterd_for_each_entry (entry, dir); + } + + ret = closedir (dir); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, "Failed to close dir %s. " + "Reason : %s",delete_path, strerror (errno)); + } + + ret = rmdir (delete_path); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, "Failed to rmdir: %s,err: %s", + delete_path, strerror (errno)); + } + ret = rmdir (trashdir); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, "Failed to rmdir: %s, Reason:" + " %s", trashdir, strerror (errno)); + } + +out: + if (snap->shandle) { + gf_store_handle_destroy (snap->shandle); + snap->shandle = NULL; + } + ret = (rename_fail == _gf_true) ? -1: 0; + + gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + int glusterd_store_global_info (xlator_t *this) { @@ -2472,10 +2124,8 @@ out: int32_t -glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo, - glusterd_volinfo_t *snap_volinfo) +glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo) { - int32_t ret = 0; glusterd_brickinfo_t *brickinfo = NULL; gf_store_iter_t *iter = NULL; @@ -2490,34 +2140,19 @@ glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo, char *tmpvalue = NULL; struct pmap_registry *pmap = NULL; gf_store_op_errno_t op_errno = GD_STORE_SUCCESS; - glusterd_volinfo_t *tmp_volinfo = NULL; GF_ASSERT (volinfo); GF_ASSERT (volinfo->volname); priv = THIS->private; - if (snap_volinfo) { - GLUSTERD_GET_SNAP_BRICK_DIR (brickdir, volinfo, - snap_volinfo->volname, priv); - } else { - GLUSTERD_GET_BRICK_DIR (brickdir, volinfo, priv); - } - - if (snap_volinfo) - ret = gf_store_iter_new (snap_volinfo->shandle, &tmpiter); - else - ret = gf_store_iter_new (volinfo->shandle, &tmpiter); + GLUSTERD_GET_BRICK_DIR (brickdir, volinfo, priv); + ret = gf_store_iter_new (volinfo->shandle, &tmpiter); if (ret) goto out; - if (snap_volinfo) - tmp_volinfo = snap_volinfo; - else - tmp_volinfo = volinfo; - - while (brick_count < tmp_volinfo->brick_count) { + while (brick_count < volinfo->brick_count) { ret = glusterd_brickinfo_new (&brickinfo); if (ret) @@ -2619,7 +2254,7 @@ glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo, if (ret) goto out; - list_add_tail (&brickinfo->brick_list, &tmp_volinfo->bricks); + list_add_tail (&brickinfo->brick_list, &volinfo->bricks); brick_count++; } @@ -2634,7 +2269,7 @@ out: int32_t -glusterd_store_retrieve_rbstate (char *volname) +glusterd_store_retrieve_rbstate (char *volname, glusterd_snap_t *snap) { int32_t ret = -1; glusterd_volinfo_t *volinfo = NULL; @@ -2648,11 +2283,15 @@ glusterd_store_retrieve_rbstate (char *volname) 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; + if (snap) { + volinfo = snap->snap_volume; + } else { + 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); @@ -2736,7 +2375,7 @@ out: } int32_t -glusterd_store_retrieve_node_state (char *volname) +glusterd_store_retrieve_node_state (char *volname, glusterd_snap_t *snap) { int32_t ret = -1; glusterd_volinfo_t *volinfo = NULL; @@ -2750,11 +2389,15 @@ glusterd_store_retrieve_node_state (char *volname) 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; + if (snap) { + volinfo = snap->snap_volume; + } else { + 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); @@ -2827,27 +2470,13 @@ glusterd_store_update_volinfo (glusterd_volinfo_t *volinfo, glusterd_conf_t *conf = NULL; gf_store_iter_t *iter = NULL; gf_store_op_errno_t op_errno = GD_STORE_SUCCESS; - glusterd_volinfo_t *parent_vol = NULL; this = THIS; GF_ASSERT (this); conf = THIS->private; GF_ASSERT (volinfo); - if (snap) { - ret = glusterd_volinfo_find (volinfo->parent_volname, - &parent_vol); - if (ret) { - gf_log (this->name, GF_LOG_DEBUG, "Failed to get parent" - " volume for %s snap volume", volinfo->volname); - goto out; - } - - GLUSTERD_GET_SNAP_DIR (volpath, parent_vol, volinfo->volname, - conf); - } else { - GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, conf); - } + GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, conf); snprintf (path, sizeof (path), "%s/%s", volpath, GLUSTERD_VOLUME_INFO_FILE); @@ -3052,11 +2681,10 @@ out: int32_t glusterd_store_retrieve_volume (char *volname, glusterd_snap_t *snap) { - int32_t ret = -1; - char volpath[PATH_MAX] = {0,}; + int32_t ret = -1; glusterd_volinfo_t *volinfo = NULL; + glusterd_volinfo_t *origin_volinfo = NULL; glusterd_conf_t *priv = NULL; - glusterd_volinfo_t *parent_vol = NULL; xlator_t *this = NULL; this = THIS; @@ -3071,19 +2699,10 @@ glusterd_store_retrieve_volume (char *volname, glusterd_snap_t *snap) priv = THIS->private; - if (snap) { - ret = glusterd_volinfo_find (volname, &parent_vol); - if (ret) - goto out; - GLUSTERD_GET_UUID_NOHYPHEN(volinfo->volname, - snap->snap_id); - GLUSTERD_GET_SNAP_DIR (volpath, parent_vol, volinfo->volname, - priv); - strncpy (volinfo->parent_volname, volname, GLUSTERD_MAX_VOLUME_NAME); - } else { - strncpy (volinfo->volname, volname, GLUSTERD_MAX_VOLUME_NAME); - GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, priv); - } + strncpy (volinfo->volname, volname, GLUSTERD_MAX_VOLUME_NAME); + volinfo->snapshot = snap; + if (snap) + volinfo->is_snap_volume = _gf_true; ret = glusterd_store_update_volinfo (volinfo, snap); if (ret) { @@ -3092,32 +2711,29 @@ glusterd_store_retrieve_volume (char *volname, glusterd_snap_t *snap) goto out; } - if (snap) - ret = glusterd_store_retrieve_bricks (parent_vol, volinfo); - else - ret = glusterd_store_retrieve_bricks (volinfo, NULL); + ret = glusterd_store_retrieve_bricks (volinfo); if (ret) goto out; - if (snap) - ret = glusterd_volume_compute_cksum (parent_vol, volinfo); - else - ret = glusterd_volume_compute_cksum (volinfo, NULL); + ret = glusterd_volume_compute_cksum (volinfo); if (ret) goto out; - if (!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->snap_list); + ret = glusterd_volinfo_find (volinfo->parent_volname, + &origin_volinfo); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Parent volinfo " + "not found for %s volume", volname); + goto out; + } + glusterd_list_add_snapvol (origin_volinfo, volinfo); } - - out: + /*TODO: cleanup volinfo pointer on failure */ + gf_log ("", GF_LOG_TRACE, "Returning with %d", ret); return ret; @@ -3325,183 +2941,6 @@ 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; - uint64_t snap_count = 0; - gf_store_handle_t *shandle = NULL; - - 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; - - snap_count = atol(value); - GF_FREE (value); - value = NULL; - - shandle = volinfo->snap_list_shandle; - while (count <= 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_retrieve_value (shandle, key, &value); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to retrieve " - "snap name"); - goto out; - } - - strncpy (snap->snap_name, value, strlen(value)); - GF_FREE (value); - value = NULL; - - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_STATUS, count); - ret = gf_store_retrieve_value (shandle, key, - &value); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to retrieve " - "snap-status of snap %s", snap->snap_name); - 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_retrieve_value (shandle, key, &value); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to retrieve " - "snap-ID of snap %s", snap->snap_name); - goto out; - } - - uuid_parse (value, snap->snap_id); - GF_FREE (value); - value = NULL; - - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_TIMESTAMP, count); - ret = gf_store_retrieve_value (shandle, key, &value); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to retrieve" - " Time-stamp of snap %s", snap->snap_name); - goto out; - } - - snap->time_stamp = atoi (value); - GF_FREE (value); - value = NULL; - - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_CG_ID, count); - ret = gf_store_retrieve_value (shandle, key, &value); - if (ret) { - gf_log ("", GF_LOG_ERROR, "Failed to retrieve" - " snap CG-ID of snap %s", snap->snap_name); - goto out; - } - - uuid_parse (value, snap->cg_id); - GF_FREE (value); - value = NULL; - - if (!uuid_is_null(snap -> cg_id)) { - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_CG_NAME, count); - ret = gf_store_retrieve_value (shandle, key, &value); - if (ret){ - gf_log ("", GF_LOG_ERROR,"Failed to retreive " - "CG name"); - goto out; - } - strcpy (snap->cg_name, value); - GF_FREE (value); - value = NULL; - } - - snprintf (key, sizeof (key), "%s-%"PRIu64, - GLUSTERD_STORE_KEY_SNAP_DESC, count); - ret = gf_store_retrieve_value (shandle, key, &value); - if (!ret) { - if (uuid_is_null (snap -> cg_id)) - snap->description = value; - value = NULL; - } else { - ret = 0; - gf_log (THIS->name, GF_LOG_TRACE, "No desc for %s", - snap->snap_name); - } - - 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_snap_cgs (xlator_t *this) { @@ -3540,9 +2979,9 @@ out: } int32_t -glusterd_store_retrieve_volumes (xlator_t *this) +glusterd_store_retrieve_volumes (xlator_t *this, glusterd_snap_t *snap) { - int32_t ret = 0; + int32_t ret = -1; char path[PATH_MAX] = {0,}; glusterd_conf_t *priv = NULL; DIR *dir = NULL; @@ -3554,60 +2993,248 @@ glusterd_store_retrieve_volumes (xlator_t *this) GF_ASSERT (priv); - snprintf (path, PATH_MAX, "%s/%s", priv->workdir, - GLUSTERD_VOLUME_DIR_PREFIX); + if (snap) + snprintf (path, PATH_MAX, "%s/snaps/%s", priv->workdir, + snap->snapname); + else + snprintf (path, PATH_MAX, "%s/%s", priv->workdir, + GLUSTERD_VOLUME_DIR_PREFIX); dir = opendir (path); if (!dir) { gf_log ("", GF_LOG_ERROR, "Unable to open dir %s", path); - ret = -1; goto out; } glusterd_for_each_entry (entry, dir); while (entry) { - ret = glusterd_store_retrieve_volume (entry->d_name, NULL); + if ( entry->d_type != DT_DIR ) + goto next; + + ret = glusterd_store_retrieve_volume (entry->d_name, snap); if (ret) { gf_log ("", GF_LOG_ERROR, "Unable to restore " "volume: %s", entry->d_name); goto out; } - ret = glusterd_store_retrieve_rbstate (entry->d_name); + ret = glusterd_store_retrieve_rbstate (entry->d_name, snap); if (ret) { /* Backward compatibility */ gf_log ("", GF_LOG_INFO, "Creating a new rbstate " "for volume: %s.", entry->d_name); - ret = glusterd_volinfo_find (entry->d_name, &volinfo); + if (snap) { + volinfo = snap->snap_volume; + } else { + ret = glusterd_volinfo_find (entry->d_name, + &volinfo); + } ret = glusterd_store_create_rbstate_shandle_on_absence (volinfo); ret = glusterd_store_perform_rbstate_store (volinfo); } - ret = glusterd_store_retrieve_node_state (entry->d_name); + ret = glusterd_store_retrieve_node_state (entry->d_name, snap); if (ret) { /* Backward compatibility */ gf_log ("", GF_LOG_INFO, "Creating a new node_state " "for volume: %s.", entry->d_name); - ret = glusterd_volinfo_find (entry->d_name, &volinfo); - ret = + if (snap) { + volinfo = snap->snap_volume; + } else { + ret = glusterd_volinfo_find (entry->d_name, &volinfo); + } 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_all_snap_store (volinfo); - //ret = glusterd_store_perform_snap_list_store (volinfo); TODO: Fix this +next: + glusterd_for_each_entry (entry, dir); + } + + ret = 0; +out: + if (dir) + closedir (dir); + gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); + + return ret; +} + +int +glusterd_store_update_snap (glusterd_snap_t *snap) +{ + int ret = -1; + char *key = NULL; + char *value = NULL; + char snappath[PATH_MAX] = {0,}; + char path[PATH_MAX] = {0,}; + xlator_t *this = NULL; + glusterd_conf_t *conf = NULL; + gf_store_iter_t *iter = NULL; + gf_store_op_errno_t op_errno = GD_STORE_SUCCESS; + + this = THIS; + conf = this->private; + GF_ASSERT (snap); + + GLUSTERD_GET_SNAP_DIR (snappath, snap, conf); + + snprintf (path, sizeof (path), "%s/%s", snappath, + GLUSTERD_SNAP_INFO_FILE); + + ret = gf_store_handle_retrieve (path, &snap->shandle); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "snap handle is NULL"); + goto out; + } + + ret = gf_store_iter_new (snap->shandle, &iter); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get new store " + "iter"); + goto out; + } + + ret = gf_store_iter_get_next (iter, &key, &value, &op_errno); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get next store " + "iter"); + goto out; + } + + while (!ret) { + gf_log (this->name, GF_LOG_DEBUG, "key = %s value = %s", + key, value); + + if (!strncmp (key, GLUSTERD_STORE_KEY_SNAP_ID, + strlen (GLUSTERD_STORE_KEY_SNAP_ID))) { + ret = uuid_parse (value, snap->snap_id); + if (ret) + gf_log (this->name, GF_LOG_WARNING, + "Failed to parse uuid"); + } else if (!strncmp (key, GLUSTERD_STORE_KEY_SNAP_RESTORED, + strlen (GLUSTERD_STORE_KEY_SNAP_RESTORED))) { + snap->snap_restored = atoi (value); + } else if (!strncmp (key, GLUSTERD_STORE_KEY_SNAP_STATUS, + strlen (GLUSTERD_STORE_KEY_SNAP_STATUS))) { + snap->snap_status = atoi (value); + } else if (!strncmp (key, GLUSTERD_STORE_KEY_SNAP_DESC, + strlen (GLUSTERD_STORE_KEY_SNAP_DESC))) { + snap->description = gf_strdup (value); + } else if (!strncmp (key, GLUSTERD_STORE_KEY_SNAP_TIMESTAMP, + strlen (GLUSTERD_STORE_KEY_SNAP_TIMESTAMP))) { + snap->time_stamp = atoi (value); + } + + GF_FREE (key); + GF_FREE (value); + key = NULL; + value = NULL; + + ret = gf_store_iter_get_next (iter, &key, &value, &op_errno); + } + + if (op_errno != GD_STORE_EOF) + goto out; + + ret = gf_store_iter_destroy (iter); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to destroy store " + "iter"); + } + +out: + return ret; +} + +int32_t +glusterd_store_retrieve_snap (char *snapname) +{ + int32_t ret = -1; + glusterd_snap_t *snap = NULL; + glusterd_conf_t *priv = NULL; + xlator_t *this = NULL; + + this = THIS; + priv = this->private; + GF_ASSERT (priv); + GF_ASSERT (snapname); + + snap = glusterd_new_snap_object (); + if (!snap) { + gf_log (this->name, GF_LOG_ERROR, "Failed to create " + " snap object"); + goto out; + } + + strncpy (snap->snapname, snapname, strlen(snapname)); + ret = glusterd_store_update_snap (snap); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to update snapshot " + "for %s snap", snapname); + goto out; + } + + ret = glusterd_store_retrieve_volumes (this, snap); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to retrieve " + "snap volumes for snap %s", snapname); + goto out; + } + + /* TODO: list_add_order can do 'N-square' comparisions and + is not efficient. Find a better solution to store the snap + in order */ + list_add_order (&snap->snap_list, &priv->snapshots, + glusterd_compare_snap_time); + +out: + gf_log ("", GF_LOG_TRACE, "Returning with %d", ret); + + return ret; +} + +int32_t +glusterd_store_retrieve_snaps (xlator_t *this) +{ + int32_t ret = 0; + char path[PATH_MAX] = {0,}; + glusterd_conf_t *priv = NULL; + DIR *dir = NULL; + struct dirent *entry = NULL; + + GF_ASSERT (this); + priv = this->private; + + GF_ASSERT (priv); + + snprintf (path, PATH_MAX, "%s/snaps", priv->workdir); + + dir = opendir (path); + + if (!dir) { + /* If snaps dir doesn't exists ignore the error for + backward compatibility */ + if (errno != ENOENT) { + ret = -1; + gf_log ("", GF_LOG_ERROR, "Unable to open dir %s", path); + } + goto out; + } + + glusterd_for_each_entry (entry, dir); + + while (entry) { + ret = glusterd_store_retrieve_snap (entry->d_name); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to restore " + "snapshot: %s", entry->d_name); + goto out; } + glusterd_for_each_entry (entry, dir); } @@ -4020,7 +3647,11 @@ glusterd_restore () goto out; } - ret = glusterd_store_retrieve_volumes (this); + ret = glusterd_store_retrieve_volumes (this, NULL); + if (ret) + goto out; + + ret = glusterd_store_retrieve_snaps (this); if (ret) goto out; -- cgit