summaryrefslogtreecommitdiffstats
path: root/xlators/features/changelog/lib
diff options
context:
space:
mode:
authorKotresh HR <khiremat@redhat.com>2018-08-21 06:09:44 -0400
committerAmar Tumballi <amarts@redhat.com>2018-08-31 13:28:43 +0000
commit35aa67001c8fac99b040fbc61f36ef4f1b1590ac (patch)
tree2d0e75b469b37738a7a61c2171aadc5a58956b5d /xlators/features/changelog/lib
parent052849983e51a061d7fb2c3ffd74fa78bb257084 (diff)
libgfchangelog: Fix changelog history API
Problem: If requested start time and end time doesn't fall into first HTIME file, then history API fails even though continuous changelogs are avaiable for the requested range in other HTIME files. This is induced by changelog disable and enable which creates fresh HTIME index file. Cause and Analysis: Each HTIME index file represents the availability of continuous changelogs. If changelog is disabled and enabled, a new HTIME index file is created represents non availability of continuous changelogs. So as long as the requested start and end falls into single HTIME index file and not across, history API should succeed. But History API checks for the changelogs only in first HTIME index file and errors out if not available. Fix: Check in all HTIME index files for availability of continuous changelogs for requested change. fixes: bz#1622549 Change-Id: I80eeceb5afbd1b89f86a9dc4c320e161907d3559 Signed-off-by: Kotresh HR <khiremat@redhat.com>
Diffstat (limited to 'xlators/features/changelog/lib')
-rw-r--r--xlators/features/changelog/lib/src/gf-history-changelog.c51
1 files changed, 46 insertions, 5 deletions
diff --git a/xlators/features/changelog/lib/src/gf-history-changelog.c b/xlators/features/changelog/lib/src/gf-history-changelog.c
index fd92dd7ed0b..5259ae3893b 100644
--- a/xlators/features/changelog/lib/src/gf-history-changelog.c
+++ b/xlators/features/changelog/lib/src/gf-history-changelog.c
@@ -780,6 +780,15 @@ gf_changelog_extract_min_max (const char *dname, const char *htime_dir,
return ret;
}
+/* gf_history_changelog returns actual_end and spawns threads to
+ * parse historical changelogs. The return values are as follows.
+ * 0 : On success
+ * 1 : Successful, but partial historical changelogs available,
+ * end time falls into different htime file or future time
+ * -2 : Error, requested historical changelog not available, not
+ * even partial
+ * -1 : On any error
+ */
int
gf_history_changelog (char* changelog_dir, unsigned long start,
unsigned long end, int n_parallel,
@@ -807,6 +816,7 @@ gf_history_changelog (char* changelog_dir, unsigned long start,
pthread_t consume_th = 0;
char htime_dir[PATH_MAX] = {0,};
char buffer[PATH_MAX] = {0,};
+ gf_boolean_t partial_history = _gf_false;
pthread_attr_t attr;
@@ -836,6 +846,11 @@ gf_history_changelog (char* changelog_dir, unsigned long start,
goto out;
}
+ gf_smsg (this->name, GF_LOG_INFO, 0,
+ CHANGELOG_LIB_MSG_TOTAL_LOG_INFO,
+ "Requesting historical changelogs",
+ "start=%lu", start, "end=%lu", end, NULL);
+
/* basic sanity check */
if (start > end || n_parallel <= 0) {
gf_smsg (this->name, GF_LOG_ERROR, errno,
@@ -871,8 +886,14 @@ gf_history_changelog (char* changelog_dir, unsigned long start,
entry = sys_readdir (dirp, scratch);
- if (!entry || errno != 0)
+ if (!entry || errno != 0) {
+ gf_smsg (this->name, GF_LOG_ERROR, errno,
+ CHANGELOG_LIB_MSG_HIST_FAILED,
+ "Requested changelog range is not availbale",
+ "start=%lu", start, "end=%lu", end, NULL);
+ ret = -2;
break;
+ }
ret = gf_changelog_extract_min_max (entry->d_name, htime_dir,
&fd, &total_changelog,
@@ -919,6 +940,23 @@ gf_history_changelog (char* changelog_dir, unsigned long start,
end2 = (end <= max_ts) ? end : max_ts;
+ /* Check if end falls out of same HTIME file. The end
+ * falling to a different htime file or changelog
+ * disable-enable is detected only after 20 seconds.
+ * This is required because, applications generally
+ * asks historical changelogs till current time and
+ * it is possible changelog is not rolled over yet.
+ * So, buffer time of default rollover time plus 5
+ * seconds is subtracted. If the application requests
+ * the end time with in half a minute of changelog
+ * disable, it's not detected as changelog disable and
+ * it's application's responsibility to retry after
+ * 20 seconds before confirming it as partial history.
+ */
+ if ((end - 20) > max_ts) {
+ partial_history = _gf_true;
+ }
+
/**
* search @end2 in htime file returning it's index (@to)
*/
@@ -992,14 +1030,13 @@ gf_history_changelog (char* changelog_dir, unsigned long start,
} else {/* end of range check */
gf_smsg (this->name, GF_LOG_ERROR, errno,
CHANGELOG_LIB_MSG_HIST_FAILED,
- "Requested changelog "
- "range is not available.",
+ "Requested changelog range is not "
+ "available. Retrying next HTIME",
"start=%lu", start,
+ "end=%lu", end,
"chlog_min=%lu", min_ts,
"chlog_max=%lu", max_ts,
NULL);
- ret = -2;
- goto out;
}
} /* end of readdir() */
@@ -1019,5 +1056,9 @@ out:
hist_jnl->hist_done = 1;
*actual_end = ts2;
+ if (partial_history) {
+ ret = 1;
+ }
+
return ret;
}