summaryrefslogtreecommitdiffstats
path: root/xlators/features/changelog/src
diff options
context:
space:
mode:
authorVenky Shankar <vshankar@redhat.com>2014-02-19 20:47:46 +0530
committerVenky Shankar <vshankar@redhat.com>2014-05-14 05:10:15 -0700
commitd2db585ce7e26851178104433fa9422482d8719e (patch)
tree2e52f15cf261906debd8ec54106ffe9f84af881e /xlators/features/changelog/src
parentbfde478cedda8267134ee3807c8db5e042115eae (diff)
features/changelog : historical journal consumption.
Facilitates Glusterfs with the ability to detect file-operations happened in past by scanning the back-end(brick-level) glusterfs journal (changelog). Design: * List of changelogs produces in one perfectly running session are stored in htime file which also holds necessary information about the session start and end time. * Involves fixed sized seeks to identify N'th changelog in the list. * Requires O(log n), (where n is number of changelogs in the list), time to identify the end changelog for the given start-end time interval. Currently the background processing of changelogs is sub optimal. BZ 1097041 tracks the development effort. For complete design, refer the below link: http://lists.nongnu.org/archive/html/gluster-devel/2014-02/msg00206.html Change-Id: I27e49f75e492e843084d0ecaf9130224d08462a0 BUG: 1091961 Signed-off-by: Ajeet Jha <ajha@redhat.com> Signed-off-by: Venky Shankar <vshankar@redhat.com> Signed-off-by: Ajeet Jha <ajha@redhat.com> Reviewed-on: http://review.gluster.org/6930 Reviewed-by: Kotresh HR <khiremat@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com>
Diffstat (limited to 'xlators/features/changelog/src')
-rw-r--r--xlators/features/changelog/src/changelog-helpers.c103
-rw-r--r--xlators/features/changelog/src/changelog-helpers.h17
-rw-r--r--xlators/features/changelog/src/changelog-mem-types.h1
-rw-r--r--xlators/features/changelog/src/changelog-misc.h7
-rw-r--r--xlators/features/changelog/src/changelog.c37
5 files changed, 159 insertions, 6 deletions
diff --git a/xlators/features/changelog/src/changelog-helpers.c b/xlators/features/changelog/src/changelog-helpers.c
index 71f2f7a25ad..984106b75e6 100644
--- a/xlators/features/changelog/src/changelog-helpers.c
+++ b/xlators/features/changelog/src/changelog-helpers.c
@@ -17,6 +17,7 @@
#include "defaults.h"
#include "logging.h"
#include "iobuf.h"
+#include "syscall.h"
#include "changelog-helpers.h"
#include "changelog-mem-types.h"
@@ -132,6 +133,49 @@ changelog_write (int fd, char *buffer, size_t len)
return (writen != len);
}
+int
+htime_update (xlator_t *this,
+ changelog_priv_t *priv, unsigned long ts,
+ char * buffer)
+{
+ char changelog_path[PATH_MAX+1] = {0,};
+ int len = -1;
+ char x_value[25] = {0,};
+ /* time stamp(10) + : (1) + rolltime (12 ) + buffer (2) */
+ int ret = 0;
+
+ if (priv->htime_fd ==-1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Htime fd not available for updation");
+ ret = -1;
+ goto out;
+ }
+ strcpy (changelog_path, buffer);
+ len = strlen (changelog_path);
+ changelog_path[len] = '\0'; /* redundant */
+
+ if (changelog_write (priv->htime_fd, (void*) changelog_path, len+1 ) < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Htime file content write failed");
+ ret =-1;
+ goto out;
+ }
+
+ sprintf (x_value,"%lu:%d",ts, priv->rollover_count);
+
+ if (sys_fsetxattr (priv->htime_fd, HTIME_KEY, x_value,
+ strlen (x_value), XATTR_REPLACE)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Htime xattr updation failed");
+ goto out;
+ }
+
+ priv->rollover_count +=1;
+
+out:
+ return ret;
+}
+
static int
changelog_rollover_changelog (xlator_t *this,
changelog_priv_t *priv, unsigned long ts)
@@ -173,6 +217,15 @@ changelog_rollover_changelog (xlator_t *this,
ofile, nfile, strerror (errno));
}
+ if (!ret) {
+ ret = htime_update (this, priv, ts, nfile);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "could not update htime file");
+ goto out;
+ }
+ }
+
if (notify) {
bname = basename (nfile);
gf_log (this->name, GF_LOG_DEBUG, "notifying: %s", bname);
@@ -212,6 +265,54 @@ changelog_rollover_changelog (xlator_t *this,
return ret;
}
+/* Returns 0 on successful creation of htime file
+ * returns -1 on failure or error
+ */
+int
+htime_open (xlator_t *this,
+ changelog_priv_t * priv, unsigned long ts)
+{
+ int fd = -1;
+ int ret = 0;
+ char ht_dir_path[PATH_MAX] = {0,};
+ char ht_file_path[PATH_MAX] = {0,};
+ int flags = 0;
+
+ CHANGELOG_FILL_HTIME_DIR(priv->changelog_dir, ht_dir_path);
+
+ /* get the htime file name in ht_file_path */
+ (void) snprintf (ht_file_path,PATH_MAX,"%s/%s.%lu",ht_dir_path,
+ HTIME_FILE_NAME, ts);
+
+ flags |= (O_CREAT | O_RDWR | O_SYNC);
+ fd = open (ht_file_path, flags,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ if (fd < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "unable to open/create htime file: %s"
+ "(reason: %s)", ht_file_path, strerror (errno));
+ ret = -1;
+ goto out;
+
+ }
+
+ if (sys_fsetxattr (fd, HTIME_KEY, HTIME_INITIAL_VALUE,
+ sizeof (HTIME_INITIAL_VALUE)-1, 0)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Htime xattr initialization failed");
+ ret = -1;
+ goto out;
+ }
+
+ /* save this htime_fd in priv->htime_fd */
+ priv->htime_fd = fd;
+ /* initialize rollover-number in priv to 1 */
+ priv->rollover_count = 1;
+
+out:
+ return ret;
+}
+
int
changelog_open (xlator_t *this,
changelog_priv_t *priv)
@@ -311,7 +412,7 @@ changelog_handle_change (xlator_t *this,
int ret = 0;
if (CHANGELOG_TYPE_IS_ROLLOVER (cld->cld_type)) {
- changelog_encode_change(priv);
+ changelog_encode_change (priv);
ret = changelog_start_next_change (this, priv,
cld->cld_roll_time,
cld->cld_finale);
diff --git a/xlators/features/changelog/src/changelog-helpers.h b/xlators/features/changelog/src/changelog-helpers.h
index ec90f8a13d7..987af190b9c 100644
--- a/xlators/features/changelog/src/changelog-helpers.h
+++ b/xlators/features/changelog/src/changelog-helpers.h
@@ -203,9 +203,18 @@ struct changelog_priv {
/* logging directory */
char *changelog_dir;
+ /* htime directory */
+ char *htime_dir;
+
/* one file for all changelog types */
int changelog_fd;
+ /* htime fd for current changelog session */
+ int htime_fd;
+
+ /* rollover_count used by htime */
+ int rollover_count;
+
gf_lock_t lock;
/* writen end of the pipe */
@@ -393,6 +402,11 @@ void *
changelog_fsync_thread (void *data);
int
changelog_forget (xlator_t *this, inode_t *inode);
+int
+htime_update (xlator_t *this, changelog_priv_t *priv,
+ unsigned long ts, char * buffer);
+int
+htime_open (xlator_t *this, changelog_priv_t * priv, unsigned long ts);
/* Geo-Rep snapshot dependency changes */
void
@@ -549,5 +563,6 @@ call_stub_t *__chlog_barrier_dequeue (xlator_t *this, struct list_head *queue);
goto label; \
} \
} while (0)
+/* End: Geo-Rep snapshot dependency changes */
+
#endif /* _CHANGELOG_HELPERS_H */
-/* End: Geo-Rep snapshot dependency changes */
diff --git a/xlators/features/changelog/src/changelog-mem-types.h b/xlators/features/changelog/src/changelog-mem-types.h
index d72464eab70..e1fa319a715 100644
--- a/xlators/features/changelog/src/changelog-mem-types.h
+++ b/xlators/features/changelog/src/changelog-mem-types.h
@@ -23,6 +23,7 @@ enum gf_changelog_mem_types {
gf_changelog_mt_libgfchangelog_rl_t = gf_common_mt_end + 7,
gf_changelog_mt_libgfchangelog_dirent_t = gf_common_mt_end + 8,
gf_changelog_mt_changelog_buffer_t = gf_common_mt_end + 9,
+ gf_changelog_mt_history_data_t = gf_common_mt_end + 10,
gf_changelog_mt_end
};
diff --git a/xlators/features/changelog/src/changelog-misc.h b/xlators/features/changelog/src/changelog-misc.h
index 127b03e2e1b..257c1f34218 100644
--- a/xlators/features/changelog/src/changelog-misc.h
+++ b/xlators/features/changelog/src/changelog-misc.h
@@ -16,6 +16,9 @@
#define CHANGELOG_MAX_TYPE 3
#define CHANGELOG_FILE_NAME "CHANGELOG"
+#define HTIME_FILE_NAME "HTIME"
+#define HTIME_KEY "trusted.glusterfs.htime"
+#define HTIME_INITIAL_VALUE "0:0"
#define CHANGELOG_VERSION_MAJOR 1
#define CHANGELOG_VERSION_MINOR 1
@@ -64,6 +67,10 @@
} \
} while (0)
+#define CHANGELOG_FILL_HTIME_DIR(changelog_dir, path) do { \
+ strcpy (path, changelog_dir); \
+ strcat (path, "/htime"); \
+ } while(0)
/**
* everything after 'CHANGELOG_TYPE_ENTRY' are internal types
* (ie. none of the fops trigger this type of event), hence
diff --git a/xlators/features/changelog/src/changelog.c b/xlators/features/changelog/src/changelog.c
index 5eb2cd93fd3..0b982148f44 100644
--- a/xlators/features/changelog/src/changelog.c
+++ b/xlators/features/changelog/src/changelog.c
@@ -1661,6 +1661,11 @@ changelog_init (xlator_t *this, changelog_priv_t *priv)
* simple here.
*/
ret = changelog_fill_rollover_data (&cld, _gf_false);
+ if(ret)
+ goto out;
+
+ ret = htime_open (this, priv, cld.cld_roll_time);
+ /* call htime open with cld's rollover_time */
if (ret)
goto out;
@@ -1779,6 +1784,8 @@ reconfigure (xlator_t *this, dict_t *options)
gf_boolean_t active_now = _gf_true;
changelog_time_slice_t *slice = NULL;
changelog_log_data_t cld = {0,};
+ char htime_dir[PATH_MAX] = {0,};
+ struct timeval tv = {0,};
priv = this->private;
if (!priv)
@@ -1803,6 +1810,12 @@ reconfigure (xlator_t *this, dict_t *options)
goto out;
ret = mkdir_p (priv->changelog_dir, 0600, _gf_true);
+
+ if (ret)
+ goto out;
+ CHANGELOG_FILL_HTIME_DIR(priv->changelog_dir, htime_dir);
+ ret = mkdir_p (htime_dir, 0600, _gf_true);
+
if (ret)
goto out;
@@ -1847,6 +1860,15 @@ reconfigure (xlator_t *this, dict_t *options)
goto out;
if (active_now) {
+ if (!active_earlier) {
+ if (gettimeofday(&tv, NULL) ) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "unable to fetch htime");
+ ret = -1;
+ goto out;
+ }
+ htime_open(this, priv, tv.tv_sec);
+ }
ret = changelog_spawn_notifier (this, priv);
if (!ret)
ret = changelog_spawn_helper_threads (this,
@@ -1871,10 +1893,11 @@ reconfigure (xlator_t *this, dict_t *options)
int32_t
init (xlator_t *this)
{
- int ret = -1;
- char *tmp = NULL;
- changelog_priv_t *priv = NULL;
- gf_boolean_t cond_lock_init = _gf_false;
+ int ret = -1;
+ char *tmp = NULL;
+ changelog_priv_t *priv = NULL;
+ gf_boolean_t cond_lock_init = _gf_false;
+ char htime_dir[PATH_MAX] = {0,};
GF_VALIDATE_OR_GOTO ("changelog", this, out);
@@ -1932,6 +1955,12 @@ init (xlator_t *this)
* so that consumers can _look_ into it (finding nothing...)
*/
ret = mkdir_p (priv->changelog_dir, 0600, _gf_true);
+
+ if (ret)
+ goto out;
+
+ CHANGELOG_FILL_HTIME_DIR(priv->changelog_dir, htime_dir);
+ ret = mkdir_p (htime_dir, 0600, _gf_true);
if (ret)
goto out;