diff options
author | Venky Shankar <vshankar@redhat.com> | 2014-02-19 20:47:46 +0530 |
---|---|---|
committer | Venky Shankar <vshankar@redhat.com> | 2014-05-14 05:10:15 -0700 |
commit | d2db585ce7e26851178104433fa9422482d8719e (patch) | |
tree | 2e52f15cf261906debd8ec54106ffe9f84af881e /xlators/features/changelog/src | |
parent | bfde478cedda8267134ee3807c8db5e042115eae (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.c | 103 | ||||
-rw-r--r-- | xlators/features/changelog/src/changelog-helpers.h | 17 | ||||
-rw-r--r-- | xlators/features/changelog/src/changelog-mem-types.h | 1 | ||||
-rw-r--r-- | xlators/features/changelog/src/changelog-misc.h | 7 | ||||
-rw-r--r-- | xlators/features/changelog/src/changelog.c | 37 |
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; |