Wednesday, July 12, 2017

[389-commits] [389-ds-base] 01/01: Ticket 49316 - Fix clock unsafety in DS

This is an automated email from the git hooks/post-receive script.

firstyear pushed a commit to branch master
in repository 389-ds-base.

commit 680a1a54c22d8f190c298645c8e36c5556c14e1f
Author: William Brown <firstyear@redhat.com>
Date: Mon Jul 10 14:51:49 2017 +1000

Ticket 49316 - Fix clock unsafety in DS

Bug Description: DS is heavily reliant on correct working time
for a variety of aspects. In almost every aspect of the server
we found a way to misuse time somehow. From timeouts only
checking second boundaries which would lead to timeouts of
less that 1 second in some cases, to enforcing 32bit times on
64bit platforms, confusion of absolute utc times and relative
offsets, incorrect time types (not time_t), wrapping thread
safe functions in mutexs causing import perf issues, and finally,
using not-threadsafe polling function to update an int
representing the current time, which may never be flushed
to the cache, nor other threads reading it.

tl;dr - what didn't we do wrong with time?

Fix Description: This fix has to cover a lot of ground:

* make clock_gettime a requirement of the server
* deprecate broken api's to create noise when people use them
* remove the clock thread
* replace access to clocks with clock_gettime
* add a clock_monotonic interface for timeouts which is
not affected by admin clock changes
* update search/add etc to use timespec timeouts rather
than time_t
* replace calls to the broken "current_time()" function
with a properly labeled utc or rel time function
* fix checkpoint thread to run compact indepedent to
checkpoints
* remove incorrectly defined gmtime_r functions
* remove incorrect documentation about atomicity of statics
in the server
* fix locations that used time as an int to time_t (2038 work)
* deprecate long and long long value parser for time replacing
with time_t to prevent 2038 issues

https://pagure.io/389-ds-base/issue/49316

Author: wibrown

Review by: mreynolds (Thank you so much!)
---
configure.ac | 5 +-
.../plugins/acct_usability/acct_usability.c | 2 +-
ldap/servers/plugins/acctpolicy/acct_plugin.c | 4 +-
ldap/servers/plugins/acctpolicy/acct_util.c | 6 +-
ldap/servers/plugins/automember/automember.c | 4 +-
ldap/servers/plugins/chainingdb/cb.h | 3 +-
ldap/servers/plugins/chainingdb/cb_add.c | 5 +-
ldap/servers/plugins/chainingdb/cb_compare.c | 7 +-
.../servers/plugins/chainingdb/cb_conn_stateless.c | 69 +++----
ldap/servers/plugins/chainingdb/cb_delete.c | 5 +-
ldap/servers/plugins/chainingdb/cb_modify.c | 5 +-
ldap/servers/plugins/chainingdb/cb_modrdn.c | 5 +-
ldap/servers/plugins/chainingdb/cb_search.c | 124 ++++++------
ldap/servers/plugins/dna/dna.c | 2 +-
ldap/servers/plugins/replication/cl5_api.c | 10 +-
ldap/servers/plugins/replication/repl5_backoff.c | 4 +-
.../servers/plugins/replication/repl5_connection.c | 10 +-
.../plugins/replication/repl5_inc_protocol.c | 16 +-
ldap/servers/plugins/replication/repl5_replica.c | 19 +-
ldap/servers/plugins/replication/repl5_ruv.c | 8 +-
.../plugins/replication/repl5_tot_protocol.c | 14 +-
ldap/servers/plugins/replication/repl_objset.c | 4 +-
.../plugins/replication/windows_connection.c | 2 +-
.../plugins/replication/windows_inc_protocol.c | 6 +-
.../plugins/replication/windows_tot_protocol.c | 6 +-
ldap/servers/plugins/retrocl/retrocl_po.c | 2 +-
ldap/servers/plugins/retrocl/retrocl_trim.c | 2 +-
ldap/servers/plugins/rootdn_access/rootdn_access.c | 14 +-
ldap/servers/plugins/syntaxes/string.c | 34 ++--
ldap/servers/slapd/abandon.c | 6 +-
ldap/servers/slapd/add.c | 8 +-
ldap/servers/slapd/auditlog.c | 4 +-
ldap/servers/slapd/back-ldbm/dblayer.c | 212 +++++++++++---------
ldap/servers/slapd/back-ldbm/idl_new.c | 20 +-
ldap/servers/slapd/back-ldbm/import-merge.c | 13 +-
ldap/servers/slapd/back-ldbm/import-threads.c | 8 +-
ldap/servers/slapd/back-ldbm/import.c | 8 +-
ldap/servers/slapd/back-ldbm/index.c | 25 +--
ldap/servers/slapd/back-ldbm/ldbm_search.c | 30 ++-
ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 2 +-
ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 6 +-
ldap/servers/slapd/back-ldbm/sort.c | 12 +-
ldap/servers/slapd/back-ldbm/vlv.c | 10 +-
ldap/servers/slapd/back-ldbm/vlv_srch.c | 23 +--
ldap/servers/slapd/back-ldbm/vlv_srch.h | 2 +-
ldap/servers/slapd/connection.c | 6 +-
ldap/servers/slapd/conntable.c | 2 +-
ldap/servers/slapd/csngen.c | 31 +--
ldap/servers/slapd/daemon.c | 73 +------
ldap/servers/slapd/eventq.c | 38 ++--
ldap/servers/slapd/generation.c | 4 +-
ldap/servers/slapd/getfilelist.c | 2 +-
ldap/servers/slapd/libglobs.c | 78 ++++----
ldap/servers/slapd/log.c | 14 +-
ldap/servers/slapd/main.c | 2 +-
ldap/servers/slapd/monitor.c | 2 +-
ldap/servers/slapd/operation.c | 28 ++-
ldap/servers/slapd/opshared.c | 16 +-
ldap/servers/slapd/pagedresults.c | 20 +-
ldap/servers/slapd/pblock.c | 5 +-
ldap/servers/slapd/pw.c | 50 ++---
ldap/servers/slapd/pw_mgmt.c | 2 +-
ldap/servers/slapd/pw_retry.c | 5 +-
ldap/servers/slapd/regex.c | 48 ++++-
ldap/servers/slapd/result.c | 13 +-
ldap/servers/slapd/sasl_map.c | 4 +-
ldap/servers/slapd/schema.c | 4 +-
ldap/servers/slapd/slap.h | 18 +-
ldap/servers/slapd/slapi-plugin.h | 187 ++++++++++++++++--
ldap/servers/slapd/slapi-private.h | 12 +-
ldap/servers/slapd/time.c | 213 +++++++++++----------
ldap/servers/slapd/uuid.c | 2 +-
ldap/servers/slapd/value.c | 21 +-
73 files changed, 921 insertions(+), 765 deletions(-)

diff --git a/configure.ac b/configure.ac
index 03c1eea..19986c0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -70,7 +70,10 @@ AC_FUNC_STAT
AC_FUNC_STRERROR_R
AC_FUNC_STRFTIME
AC_FUNC_VPRINTF
-AC_CHECK_FUNCS([clock_gettime endpwent ftruncate getcwd gethostbyname inet_ntoa localtime_r memmove memset mkdir munmap putenv rmdir setrlimit socket strcasecmp strchr strcspn strdup strerror strncasecmp strpbrk strrchr strstr strtol tzset])
+AC_CHECK_FUNCS([endpwent ftruncate getcwd gethostbyname inet_ntoa localtime_r memmove memset mkdir munmap putenv rmdir setrlimit socket strcasecmp strchr strcspn strdup strerror strncasecmp strpbrk strrchr strstr strtol tzset])
+
+# These functions are *required* without option.
+AC_CHECK_FUNCS([clock_gettime], [], AC_MSG_ERROR([unable to locate required symbol clock_gettime]))

# This will detect if we need to add the LIBADD_DL value for us.
LT_LIB_DLLOAD
diff --git a/ldap/servers/plugins/acct_usability/acct_usability.c b/ldap/servers/plugins/acct_usability/acct_usability.c
index fc8c53a..06d7ea9 100644
--- a/ldap/servers/plugins/acct_usability/acct_usability.c
+++ b/ldap/servers/plugins/acct_usability/acct_usability.c
@@ -197,7 +197,7 @@ static LDAPControl *auc_create_response_ctrl(Slapi_Entry *e)
Slapi_PWPolicy *pwpolicy = NULL;
time_t expire_time = (time_t)0;
time_t unlock_time = (time_t)0;
- time_t now = slapi_current_time();
+ time_t now = slapi_current_utc_time();

if (!e) {
slapi_log_err(SLAPI_LOG_PLUGIN, AUC_PLUGIN_SUBSYSTEM,
diff --git a/ldap/servers/plugins/acctpolicy/acct_plugin.c b/ldap/servers/plugins/acctpolicy/acct_plugin.c
index 27c27bc..b24c746 100644
--- a/ldap/servers/plugins/acctpolicy/acct_plugin.c
+++ b/ldap/servers/plugins/acctpolicy/acct_plugin.c
@@ -99,7 +99,7 @@ acct_inact_limit( Slapi_PBlock *pb, const char *dn, Slapi_Entry *target_entry, a
}

last_t = gentimeToEpochtime( lasttimestr );
- cur_t = time( (time_t*)0 );
+ cur_t = slapi_current_utc_time();
lim_t = policy->inactivitylimit;

/* Finally do the time comparison */
@@ -159,7 +159,7 @@ acct_record_login( const char *dn )

plugin_id = get_identity();

- timestr = epochtimeToGentime( time( (time_t*)0 ) );
+ timestr = epochtimeToGentime( slapi_current_utc_time() );
val.bv_val = timestr;
val.bv_len = strlen( val.bv_val );

diff --git a/ldap/servers/plugins/acctpolicy/acct_util.c b/ldap/servers/plugins/acctpolicy/acct_util.c
index 35e8b41..0e5ce8e 100644
--- a/ldap/servers/plugins/acctpolicy/acct_util.c
+++ b/ldap/servers/plugins/acctpolicy/acct_util.c
@@ -221,7 +221,7 @@ gentimeToEpochtime( char *gentimestr ) {

/* Find the local offset from GMT */
cur_gm_time = (struct tm*)slapi_ch_calloc( 1, sizeof( struct tm ) );
- cur_local_epochtime = time( (time_t *)0 );
+ cur_local_epochtime = slapi_current_utc_time();
gmtime_r( &cur_local_epochtime, cur_gm_time );
cur_gm_epochtime = mktime( cur_gm_time );
free( cur_gm_time );
@@ -255,9 +255,9 @@ epochtimeToGentime( time_t epochtime ) {
struct tm t;

gmtime_r( &epochtime, &t );
- gentimestr = slapi_ch_malloc( 20 );
+ gentimestr = slapi_ch_malloc(SLAPI_TIMESTAMP_BUFSIZE);
/* Format is YYYYmmddHHMMSSZ (15+1 chars) */
- strftime( gentimestr, 16, "%Y%m%d%H%M%SZ", &t );
+ strftime( gentimestr, SLAPI_TIMESTAMP_BUFSIZE, "%Y%m%d%H%M%SZ", &t );

return( gentimestr );
}
diff --git a/ldap/servers/plugins/automember/automember.c b/ldap/servers/plugins/automember/automember.c
index a74d48c..67cb8c4 100644
--- a/ldap/servers/plugins/automember/automember.c
+++ b/ldap/servers/plugins/automember/automember.c
@@ -1398,7 +1398,7 @@ automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileD
vals = slapi_entry_attr_get_charray(e, curr_rule->attr);
for (i = 0; vals && vals[i]; ++i) {
/* Evaluate the regex. */
- if (slapi_re_exec(curr_rule->regex, vals[i], -1) == 1) {
+ if (slapi_re_exec_nt(curr_rule->regex, vals[i]) == 1) {
/* Found a match. Add to end of the exclusion list
* and set last as a hint to ourselves. */
slapi_log_err(SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM,
@@ -1473,7 +1473,7 @@ automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileD
vals = slapi_entry_attr_get_charray(e, curr_rule->attr);
for (i = 0; vals && vals[i]; ++i) {
/* Evaluate the regex. */
- if (slapi_re_exec(curr_rule->regex, vals[i], -1) == 1) {
+ if (slapi_re_exec_nt(curr_rule->regex, vals[i]) == 1) {
/* Found a match. Add to the end of the targets list
* and set last as a hint to ourselves. */
slapi_log_err(SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM,
diff --git a/ldap/servers/plugins/chainingdb/cb.h b/ldap/servers/plugins/chainingdb/cb.h
index 5fc76df..60a4d83 100644
--- a/ldap/servers/plugins/chainingdb/cb.h
+++ b/ldap/servers/plugins/chainingdb/cb.h
@@ -381,7 +381,7 @@ typedef struct _cb_searchContext {
#define CB_UPDATE_CONTROLS_ISABANDON 2


-int cb_get_connection(cb_conn_pool * pool, LDAP ** ld, cb_outgoing_conn ** cnx, struct timeval * tmax, char **errmsg);
+int cb_get_connection(cb_conn_pool * pool, LDAP ** ld, cb_outgoing_conn ** cnx, struct timespec *expire_time, char **errmsg);
int cb_config(cb_backend_instance * cb, int argc, char ** argv );
int cb_update_controls( Slapi_PBlock *pb, LDAP * ld, LDAPControl *** controls, int ctrl_flags);
int cb_is_control_forwardable(cb_backend * cb, char *controloid);
@@ -469,7 +469,6 @@ void cb_update_failed_conn_cpt ( cb_backend_instance *cb ) ;
void cb_reset_conn_cpt( cb_backend_instance *cb ) ;
int cb_check_availability( cb_backend_instance *cb, Slapi_PBlock *pb ) ;

-time_t current_time(void);
char* get_localhost_DNS(void);

/* this function is called when state of a backend changes */
diff --git a/ldap/servers/plugins/chainingdb/cb_add.c b/ldap/servers/plugins/chainingdb/cb_add.c
index 9c772ac..7dc3871 100644
--- a/ldap/servers/plugins/chainingdb/cb_add.c
+++ b/ldap/servers/plugins/chainingdb/cb_add.c
@@ -129,8 +129,9 @@ chaining_back_add ( Slapi_PBlock *pb )
}

/* heart-beat management */
- if (cb->max_idle_time>0)
- endtime=current_time() + cb->max_idle_time;
+ if (cb->max_idle_time>0) {
+ endtime=slapi_current_utc_time() + cb->max_idle_time;
+ }

/* Send LDAP operation to the remote host */
rc = ldap_add_ext( ld, dn, mods, ctrls, NULL, &msgid );
diff --git a/ldap/servers/plugins/chainingdb/cb_compare.c b/ldap/servers/plugins/chainingdb/cb_compare.c
index a54225a..a7cfd35 100644
--- a/ldap/servers/plugins/chainingdb/cb_compare.c
+++ b/ldap/servers/plugins/chainingdb/cb_compare.c
@@ -123,10 +123,11 @@ chaining_back_compare ( Slapi_PBlock *pb )
ldap_controls_free(ctrls);
return -1;
}
-
+
/* heart-beat management */
- if (cb->max_idle_time>0)
- endtime=current_time() + cb->max_idle_time;
+ if (cb->max_idle_time>0) {
+ endtime=slapi_current_utc_time() + cb->max_idle_time;
+ }

/*
* Send LDAP operation to the remote host
diff --git a/ldap/servers/plugins/chainingdb/cb_conn_stateless.c b/ldap/servers/plugins/chainingdb/cb_conn_stateless.c
index 499b3a7..6e54b41 100644
--- a/ldap/servers/plugins/chainingdb/cb_conn_stateless.c
+++ b/ldap/servers/plugins/chainingdb/cb_conn_stateless.c
@@ -130,14 +130,13 @@ int
cb_get_connection(cb_conn_pool * pool,
LDAP ** lld,
cb_outgoing_conn ** cc,
- struct timeval * maxtime,
+ struct timespec *expire_time,
char **errmsg)
{
int rc=LDAP_SUCCESS; /* optimistic */
cb_outgoing_conn *conn=NULL;
cb_outgoing_conn *connprev=NULL;
LDAP *ld=NULL;
- time_t endbefore=0;
int checktime=0;
struct timeval bind_to, op_to;
unsigned int maxconcurrency,maxconnections;
@@ -147,6 +146,8 @@ cb_get_connection(cb_conn_pool * pool,
char *mech = NULL;;
static char *error1="Can't contact remote server : %s";
int isMultiThread = ENABLE_MULTITHREAD_PER_CONN ; /* by default, we enable multiple operations per connection */
+
+ struct timespec cb_expire_time;

/*
** return an error if we can't get a connection
@@ -204,23 +205,27 @@ cb_get_connection(cb_conn_pool * pool,
return LDAP_CONNECT_ERROR;
}

- if (maxtime) {
- if (maxtime->tv_sec != 0) {
+ if (expire_time) {
+ if (expire_time->tv_sec > 0) {
checktime=1;
- endbefore = current_time() + maxtime->tv_sec;
+
+ cb_expire_time.tv_sec = expire_time->tv_sec;
+ cb_expire_time.tv_nsec = expire_time->tv_nsec;

/* make sure bind to <= operation timeout */
- if ((bind_to.tv_sec==0) || (bind_to.tv_sec > maxtime->tv_sec))
- bind_to.tv_sec=maxtime->tv_sec;
+ if ((bind_to.tv_sec==0) || (bind_to.tv_sec > expire_time->tv_sec)) {
+ bind_to.tv_sec=expire_time->tv_sec;
+ }
}
} else {
if (op_to.tv_sec != 0) {
checktime=1;
- endbefore = current_time() + op_to.tv_sec;
+ slapi_timespec_expire_at(op_to.tv_sec, &cb_expire_time);

/* make sure bind to <= operation timeout */
- if ((bind_to.tv_sec==0) || (bind_to.tv_sec > op_to.tv_sec))
+ if ((bind_to.tv_sec==0) || (bind_to.tv_sec > op_to.tv_sec)) {
bind_to.tv_sec=op_to.tv_sec;
+ }
}
}

@@ -238,31 +243,29 @@ cb_get_connection(cb_conn_pool * pool,
slapi_lock_mutex( pool->conn.conn_list_mutex );

if (cb_debug_on()) {
- slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
- "cb_get_connection - server %s conns: %d maxconns: %d\n",
- hostname, pool->conn.conn_list_count, maxconnections );
+ slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
+ "cb_get_connection - server %s conns: %d maxconns: %d\n",
+ hostname, pool->conn.conn_list_count, maxconnections );
}

for (;;) {

/* time limit mgmt */
- if (checktime) {
- if (current_time() > endbefore ) {
- slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
- "cb_get_connection - server %s expired.\n", hostname );
- if ( errmsg ) {
- *errmsg = PR_smprintf(error1,"timelimit exceeded");
- }
- rc=LDAP_TIMELIMIT_EXCEEDED;
- conn=NULL;
- ld=NULL;
- goto unlock_and_return;
+ if (checktime && slapi_timespec_expire_check(&cb_expire_time) == TIMER_EXPIRED) {
+ slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
+ "cb_get_connection - server %s expired.\n", hostname );
+ if ( errmsg ) {
+ *errmsg = PR_smprintf(error1,"timelimit exceeded");
}
+ rc=LDAP_TIMELIMIT_EXCEEDED;
+ conn=NULL;
+ ld=NULL;
+ goto unlock_and_return;
}

- /*
- * First, look for an available, already open/bound connection
- */
+ /*
+ * First, look for an available, already open/bound connection
+ */

if (secure) {
for (conn = pool->connarray[PR_ThreadSelf()]; conn != NULL; conn = conn->next) {
@@ -456,7 +459,7 @@ cb_get_connection(cb_conn_pool * pool,
conn->ld=ld;
conn->status=CB_CONNSTATUS_OK;
conn->refcount=0; /* incremented below */
- conn->opentime=current_time();
+ conn->opentime=slapi_current_utc_time();
conn->ThreadId=PR_MyThreadId(); /* store the thread id */
conn->next=NULL;
if (secure) {
@@ -639,7 +642,7 @@ static void cb_check_for_stale_connections(cb_conn_pool * pool) {
slapi_lock_mutex(pool->conn.conn_list_mutex);

if (connlifetime > 0)
- curtime=current_time();
+ curtime=slapi_current_utc_time();

if (pool->secure) {
myself = PR_ThreadSelf();
@@ -859,7 +862,7 @@ int cb_ping_farm(cb_backend_instance *cb, cb_outgoing_conn * cnx,time_t end_time
if (cnx && (cnx->status != CB_CONNSTATUS_OK )) /* Known problem */
return LDAP_SERVER_DOWN;

- now = current_time();
+ now = slapi_current_utc_time();
if (end_time && ((now <= end_time) || (end_time <0))) return LDAP_SUCCESS;

secure = cb->pool->secure;
@@ -902,7 +905,7 @@ void cb_update_failed_conn_cpt ( cb_backend_instance *cb ) {
slapi_unlock_mutex(cb->monitor_availability.cpt_lock);
if (cb->monitor_availability.cpt >= CB_NUM_CONN_BEFORE_UNAVAILABILITY ) {
/* we reach the limit of authorized failed connections => we setup the chaining BE state to unavailable */
- now = current_time();
+ now = slapi_current_utc_time();
slapi_lock_mutex(cb->monitor_availability.lock_timeLimit);
cb->monitor_availability.unavailableTimeLimit = now + CB_UNAVAILABLE_PERIOD ;
slapi_unlock_mutex(cb->monitor_availability.lock_timeLimit);
@@ -932,7 +935,7 @@ int cb_check_availability( cb_backend_instance *cb, Slapi_PBlock *pb ) {
time_t now ;
if ( cb->monitor_availability.farmserver_state == FARMSERVER_UNAVAILABLE ){
slapi_lock_mutex(cb->monitor_availability.lock_timeLimit);
- now = current_time();
+ now = slapi_current_utc_time();
if (now >= cb->monitor_availability.unavailableTimeLimit) {
cb->monitor_availability.unavailableTimeLimit = now + CB_INFINITE_TIME ; /* to be sure only one thread can do the test */
slapi_unlock_mutex(cb->monitor_availability.lock_timeLimit);
@@ -946,7 +949,7 @@ int cb_check_availability( cb_backend_instance *cb, Slapi_PBlock *pb ) {
"cb_check_availability - ping the farm server and check if it's still unavailable");
if (cb_ping_farm(cb, NULL, 0) != LDAP_SUCCESS) { /* farm still unavailable... Just change the timelimit */
slapi_lock_mutex(cb->monitor_availability.lock_timeLimit);
- now = current_time();
+ now = slapi_current_utc_time();
cb->monitor_availability.unavailableTimeLimit = now + CB_UNAVAILABLE_PERIOD ;
slapi_unlock_mutex(cb->monitor_availability.lock_timeLimit);
cb_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, "FARM SERVER TEMPORARY UNAVAILABLE", 0, NULL) ;
@@ -957,7 +960,7 @@ int cb_check_availability( cb_backend_instance *cb, Slapi_PBlock *pb ) {
else {
/* farm is back !*/
slapi_lock_mutex(cb->monitor_availability.lock_timeLimit);
- now = current_time();
+ now = slapi_current_utc_time();
cb->monitor_availability.unavailableTimeLimit = now ; /* the unavailable period is finished */
slapi_unlock_mutex(cb->monitor_availability.lock_timeLimit);
/* The farmer server state backs to FARMSERVER_AVAILABLE, but this already done in cb_ping_farm, and also the reset of cpt*/
diff --git a/ldap/servers/plugins/chainingdb/cb_delete.c b/ldap/servers/plugins/chainingdb/cb_delete.c
index 7761b94..92333f5 100644
--- a/ldap/servers/plugins/chainingdb/cb_delete.c
+++ b/ldap/servers/plugins/chainingdb/cb_delete.c
@@ -116,8 +116,9 @@ chaining_back_delete ( Slapi_PBlock *pb )
}

/* heart-beat management */
- if (cb->max_idle_time>0)
- endtime=current_time() + cb->max_idle_time;
+ if (cb->max_idle_time>0) {
+ endtime=slapi_current_utc_time() + cb->max_idle_time;
+ }

/*
* Call the backend preoperation plugins
diff --git a/ldap/servers/plugins/chainingdb/cb_modify.c b/ldap/servers/plugins/chainingdb/cb_modify.c
index 411980d..b084bc2 100644
--- a/ldap/servers/plugins/chainingdb/cb_modify.c
+++ b/ldap/servers/plugins/chainingdb/cb_modify.c
@@ -124,8 +124,9 @@ chaining_back_modify ( Slapi_PBlock *pb )
cb_remove_illegal_mods(cb,mods);

/* heart-beat management */
- if (cb->max_idle_time>0)
- endtime=current_time() + cb->max_idle_time;
+ if (cb->max_idle_time>0) {
+ endtime=slapi_current_utc_time() + cb->max_idle_time;
+ }

/*
* Call the backend preoperation plugins
diff --git a/ldap/servers/plugins/chainingdb/cb_modrdn.c b/ldap/servers/plugins/chainingdb/cb_modrdn.c
index 00c598c..912104b 100644
--- a/ldap/servers/plugins/chainingdb/cb_modrdn.c
+++ b/ldap/servers/plugins/chainingdb/cb_modrdn.c
@@ -128,8 +128,9 @@ chaining_back_modrdn ( Slapi_PBlock *pb )
}

/* heart-beat management */
- if (cb->max_idle_time>0)
- endtime=current_time() + cb->max_idle_time;
+ if (cb->max_idle_time>0) {
+ endtime=slapi_current_utc_time() + cb->max_idle_time;
+ }

/*
* Call the backend preoperation plugins
diff --git a/ldap/servers/plugins/chainingdb/cb_search.c b/ldap/servers/plugins/chainingdb/cb_search.c
index dad2785..cc72e75 100644
--- a/ldap/servers/plugins/chainingdb/cb_search.c
+++ b/ldap/servers/plugins/chainingdb/cb_search.c
@@ -40,9 +40,8 @@ chainingdb_build_candidate_list ( Slapi_PBlock *pb )
const char *target = NULL;
char *filter;
char **attrs = NULL;
+ struct timespec expire_time;
struct timeval timeout;
- time_t optime;
- time_t endbefore = 0;
time_t endtime = 0;
char *matched_msg, *error_msg;
char **referrals = NULL;
@@ -56,7 +55,6 @@ chainingdb_build_candidate_list ( Slapi_PBlock *pb )
slapi_pblock_get( pb, SLAPI_OPERATION, &op );
slapi_pblock_get( pb, SLAPI_SEARCH_STRFILTER, &filter );
slapi_pblock_get( pb, SLAPI_SEARCH_SCOPE, &scope );
- slapi_pblock_get( pb, SLAPI_OPINITIATED_TIME, &optime );
slapi_pblock_get( pb, SLAPI_SEARCH_TARGET_SDN, &target_sdn );

target = slapi_sdn_get_dn(target_sdn);
@@ -94,8 +92,9 @@ chainingdb_build_candidate_list ( Slapi_PBlock *pb )
slapi_pblock_get( pb, SLAPI_SEARCH_ATTRS, &attrs );
slapi_pblock_get( pb, SLAPI_SEARCH_ATTRSONLY, &attrsonly );
slapi_pblock_get( pb, SLAPI_REQCONTROLS, &controls );
- slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &timelimit );
slapi_pblock_get( pb, SLAPI_SEARCH_SIZELIMIT, &sizelimit );
+ slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &timelimit );
+ slapi_operation_time_expiry(op, (time_t)timelimit, &expire_time);
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET,NULL);

if ((scope != LDAP_SCOPE_BASE) && (scope != LDAP_SCOPE_ONELEVEL) && (scope != LDAP_SCOPE_SUBTREE)) {
@@ -143,20 +142,25 @@ chainingdb_build_candidate_list ( Slapi_PBlock *pb )
** Time limit management.
** Make sure the operation has not expired
*/
-
- if ( timelimit == -1 ) {
- timeout.tv_sec = timeout.tv_usec = 0;
+ if (slapi_timespec_expire_check(&expire_time) == TIMER_EXPIRED) {
+ cb_send_ldap_result( pb, LDAP_TIMELIMIT_EXCEEDED, NULL,NULL, 0, NULL);
+ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY, NULL );
+ return 1;
+ }
+ /* Set the timeout for ldap_search_ext */
+ /* for some reasons, it is an error to pass in a zero'd timeval */
+ /* to ldap_search_ext() */
+ if ( timelimit == -1 || timelimit == 0) {
+ timeout.tv_sec = -1;
+ timeout.tv_usec = -1;
} else {
- time_t now=current_time();
- endbefore=optime + timelimit;
- if (now >= endbefore) {
- cb_send_ldap_result( pb, LDAP_TIMELIMIT_EXCEEDED, NULL,NULL, 0, NULL);
- slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY, NULL );
- return 1;
- }
- timeout.tv_sec=(time_t)timelimit-(now-optime);
+ /* Get the elapsed op time to fix our time limit */
+ struct timespec elapsed;
+ slapi_operation_time_elapsed(op, &elapsed);
+ timeout.tv_sec = ((time_t)timelimit) - elapsed.tv_sec;
timeout.tv_usec=0;
}
+

/* Operational attribute support for internal searches: */
/* The front-end relies on the fact that operational attributes */
@@ -179,7 +183,7 @@ chainingdb_build_candidate_list ( Slapi_PBlock *pb )
}

/* Grab a connection handle */
- rc = cb_get_connection(cb->pool, &ld, &cnx, &timeout, &cnxerrbuf);
+ rc = cb_get_connection(cb->pool, &ld, &cnx, &expire_time, &cnxerrbuf);
if (LDAP_SUCCESS != rc) {
static int warned_get_conn = 0;
if (!warned_get_conn) {
@@ -230,14 +234,10 @@ chainingdb_build_candidate_list ( Slapi_PBlock *pb )
ctx->ld=ld;
ctx->cnx=cnx;

- /* for some reasons, it is an error to pass in a zero'd timeval */
- /* to ldap_search_ext() */
- if ((timeout.tv_sec==0) && (timeout.tv_usec==0))
- timeout.tv_sec=timeout.tv_usec=-1;
-
/* heart-beat management */
- if (cb->max_idle_time>0)
- endtime=current_time() + cb->max_idle_time;
+ if (cb->max_idle_time>0) {
+ endtime=slapi_current_utc_time() + cb->max_idle_time;
+ }

rc = ldap_search_ext(ld ,target,scope,filter,attrs,attrsonly,
ctrls, NULL, &timeout,sizelimit, &(ctx->msgid) );
@@ -282,18 +282,16 @@ chainingdb_build_candidate_list ( Slapi_PBlock *pb )

case 0:
/* Local timeout management */
- if (timelimit != -1) {
- if (current_time() > endbefore) {
- slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
- "chainingdb_build_candidate_list - Local timeout expiration\n");
- cb_send_ldap_result(pb,LDAP_TIMELIMIT_EXCEEDED,
- NULL,NULL, 0, NULL);
- /* Force connection close */
- cb_release_op_connection(cb->pool,ld,1);
- ldap_msgfree(res);
- slapi_ch_free((void **)&ctx);
- return 1;
- }
+ if (slapi_timespec_expire_check(&expire_time) == TIMER_EXPIRED) {
+ slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
+ "chainingdb_build_candidate_list - Local timeout expiration\n");
+ cb_send_ldap_result(pb,LDAP_TIMELIMIT_EXCEEDED,
+ NULL,NULL, 0, NULL);
+ /* Force connection close */
+ cb_release_op_connection(cb->pool,ld,1);
+ ldap_msgfree(res);
+ slapi_ch_free((void **)&ctx);
+ return 1;
}
/* heart-beat management */
if ((rc=cb_ping_farm(cb,cnx,endtime)) != LDAP_SUCCESS) {
@@ -399,7 +397,7 @@ chainingdb_next_search_entry ( Slapi_PBlock *pb )
int sizelimit, timelimit;
int rc, parse_rc, retcode;
int i, attrsonly;
- time_t optime;
+ struct timespec expire_time;
LDAPMessage *res=NULL;
char *matched_msg,*error_msg;
cb_searchContext *ctx=NULL;
@@ -409,6 +407,7 @@ chainingdb_next_search_entry ( Slapi_PBlock *pb )
cb_backend_instance * cb=NULL;
Slapi_Backend * be;
time_t endtime = 0;
+ Slapi_Operation *op;

matched_msg=error_msg=NULL;

@@ -417,7 +416,8 @@ chainingdb_next_search_entry ( Slapi_PBlock *pb )
slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &timelimit );
slapi_pblock_get( pb, SLAPI_SEARCH_SIZELIMIT, &sizelimit );
slapi_pblock_get( pb, SLAPI_SEARCH_TARGET_SDN, &target_sdn );
- slapi_pblock_get( pb, SLAPI_OPINITIATED_TIME, &optime );
+ slapi_pblock_get( pb, SLAPI_OPERATION, &op);
+ slapi_operation_time_expiry(op, (time_t)timelimit, &expire_time);
slapi_pblock_get( pb, SLAPI_SEARCH_ATTRSONLY, &attrsonly );

cb = cb_get_instance(be);
@@ -452,23 +452,20 @@ chainingdb_next_search_entry ( Slapi_PBlock *pb )

int n;
Slapi_Entry ** ptr;
- if ( (timelimit != -1) && (timelimit != 0)) {
- time_t now=current_time();
-
- if (now > (optime + timelimit)) {
- cb_send_ldap_result( pb, LDAP_TIMELIMIT_EXCEEDED, NULL,NULL, 0, NULL);
- slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET,NULL );
- slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY,NULL);
+ if (slapi_timespec_expire_check(&expire_time) == TIMER_EXPIRED) {
+ cb_send_ldap_result( pb, LDAP_TIMELIMIT_EXCEEDED, NULL,NULL, 0, NULL);
+ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET,NULL );
+ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY,NULL);

- for ( n = 0, ptr=(Slapi_Entry **)ctx->data; ptr != NULL && ptr[n] != NULL; n++ ) {
- slapi_entry_free(ptr[n]);
- }
- if (ctx->data)
- slapi_ch_free((void **)&ctx->data);
- slapi_ch_free((void **)&ctx);
- return -1;
+ for ( n = 0, ptr=(Slapi_Entry **)ctx->data; ptr != NULL && ptr[n] != NULL; n++ ) {
+ slapi_entry_free(ptr[n]);
}
- }
+ if (ctx->data) {
+ slapi_ch_free((void **)&ctx->data);
+ }
+ slapi_ch_free((void **)&ctx);
+ return -1;
+ }

/*
** Return the Slapi_Entry of the result set one
@@ -497,15 +494,16 @@ chainingdb_next_search_entry ( Slapi_PBlock *pb )
* the context.
*/

- /* Poll the server for the results of the search operation.
- * Passing LDAP_MSG_ONE indicates that you want to receive
- * the entries one at a time, as they come in. If the next
- * entry that you retrieve is NULL, there are no more entries.
+ /* Poll the server for the results of the search operation.
+ * Passing LDAP_MSG_ONE indicates that you want to receive
+ * the entries one at a time, as they come in. If the next
+ * entry that you retrieve is NULL, there are no more entries.
*/

/* heart-beat management */
- if (cb->max_idle_time>0)
- endtime=current_time() + cb->max_idle_time;
+ if (cb->max_idle_time>0) {
+ endtime=slapi_current_utc_time() + cb->max_idle_time;
+ }

while (1) {

@@ -579,8 +577,9 @@ chainingdb_next_search_entry ( Slapi_PBlock *pb )
case LDAP_RES_SEARCH_ENTRY:

/* heart-beat management */
- if (cb->max_idle_time>0)
- endtime=current_time() + cb->max_idle_time;
+ if (cb->max_idle_time>0) {
+ endtime=slapi_current_utc_time() + cb->max_idle_time;
+ }

/* The server sent one of the entries found by the search */
if ((entry = cb_LDAPMessage2Entry(ctx->ld,res,attrsonly)) == NULL) {
@@ -610,8 +609,9 @@ chainingdb_next_search_entry ( Slapi_PBlock *pb )
*/

/* heart-beat management */
- if (cb->max_idle_time>0)
- endtime=current_time() + cb->max_idle_time;
+ if (cb->max_idle_time>0) {
+ endtime=slapi_current_utc_time() + cb->max_idle_time;
+ }

parse_rc = ldap_parse_reference( ctx->ld, res, &referrals, NULL, 1 );
if ( parse_rc != LDAP_SUCCESS ) {
diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c
index 1ae29dd..50840ac 100644
--- a/ldap/servers/plugins/dna/dna.c
+++ b/ldap/servers/plugins/dna/dna.c
@@ -894,7 +894,7 @@ dna_load_plugin_config(Slapi_PBlock *pb, int use_eventq)
* performing the operation at this point when
* starting up would cause the change to not
* get changelogged. */
- time(&now);
+ now = slapi_current_utc_time();
eq_ctx = slapi_eq_once(dna_update_config_event, NULL, now + 30);
} else {
dna_update_config_event(0, NULL);
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
index f11e903..3c6870a 100644
--- a/ldap/servers/plugins/replication/cl5_api.c
+++ b/ldap/servers/plugins/replication/cl5_api.c
@@ -3388,15 +3388,15 @@ static void _cl5TrimCleanup(void)

static int _cl5TrimMain (void *param __attribute__((unused)))
{
- time_t timePrev = current_time ();
- time_t timeCompactPrev = current_time ();
+ time_t timePrev = slapi_current_utc_time();
+ time_t timeCompactPrev = slapi_current_utc_time();
time_t timeNow;

PR_AtomicIncrement (&s_cl5Desc.threadCount);

while (s_cl5Desc.dbState != CL5_STATE_CLOSING)
{
- timeNow = current_time ();
+ timeNow = slapi_current_utc_time();
if (timeNow - timePrev >= s_cl5Desc.dbTrim.trimInterval)
{
/* time to trim */
@@ -4094,7 +4094,7 @@ static PRBool _cl5CanTrim (time_t time, long *numToTrim)
}

if (time) {
- return (current_time () - time > s_cl5Desc.dbTrim.maxAge);
+ return (slapi_current_utc_time() - time > s_cl5Desc.dbTrim.maxAge);
} else {
return PR_TRUE;
}
@@ -4972,7 +4972,7 @@ static int _cl5WriteOperationTxn(const char *replName, const char *replGen,
}

/* assign entry time - used for trimming */
- entry.time = current_time ();
+ entry.time = slapi_current_utc_time();
entry.op = (slapi_operation_parameters *)op;

/* construct the key */
diff --git a/ldap/servers/plugins/replication/repl5_backoff.c b/ldap/servers/plugins/replication/repl5_backoff.c
index 0fded96..8e349be 100644
--- a/ldap/servers/plugins/replication/repl5_backoff.c
+++ b/ldap/servers/plugins/replication/repl5_backoff.c
@@ -114,7 +114,7 @@ backoff_reset(Backoff_Timer *bt, slapi_eq_fn_t callback, void *callback_data)
bt->next_interval = bt->initial_interval;
}
/* Schedule the callback */
- time(&bt->last_fire_time);
+ bt->last_fire_time = slapi_current_utc_time();
return_value = bt->last_fire_time + bt->next_interval;
bt->pending_event = slapi_eq_once(bt->callback, bt->callback_arg,
return_value);
@@ -184,7 +184,7 @@ backoff_expired(Backoff_Timer *bt, int margin)

PR_ASSERT(NULL != bt);
PR_Lock(bt->lock);
- return_value = (current_time() >= (bt->last_fire_time + bt->next_interval + margin));
+ return_value = (slapi_current_utc_time() >= (bt->last_fire_time + bt->next_interval + margin));
PR_Unlock(bt->lock);
return return_value;
}
diff --git a/ldap/servers/plugins/replication/repl5_connection.c b/ldap/servers/plugins/replication/repl5_connection.c
index 55ebd54..dacef9f 100644
--- a/ldap/servers/plugins/replication/repl5_connection.c
+++ b/ldap/servers/plugins/replication/repl5_connection.c
@@ -389,7 +389,7 @@ conn_read_result_ex(Repl_Connection *conn, char **retoidp, struct berval **retda
if (block)
{
/* Did the connection's timeout expire ? */
- time_now = time( NULL );
+ time_now = slapi_current_utc_time();
if (conn->timeout.tv_sec <= ( time_now - start_time ))
{
/* We timed out */
@@ -756,7 +756,7 @@ conn_is_available(Repl_Connection *conn)
{
time_t poll_timeout_sec = 1; /* Polling for 1sec */
time_t yield_delay_msec = 100; /* Delay to wait */
- time_t start_time = time( NULL );
+ time_t start_time = slapi_current_utc_time();
time_t time_now;
ConnResult return_value = CONN_OPERATION_SUCCESS;

@@ -766,7 +766,7 @@ conn_is_available(Repl_Connection *conn)
/* in case of timeout we return CONN_TIMEOUT only
* if the RA.timeout is exceeded
*/
- time_now = time(NULL);
+ time_now = slapi_current_utc_time();
if (conn->timeout.tv_sec <= (time_now - start_time)) {
break;
} else {
@@ -1141,7 +1141,7 @@ conn_start_linger(Repl_Connection *conn)
agmt_get_long_name(conn->agmt));
return;
}
- time(&now);
+ now = slapi_current_utc_time();
PR_Lock(conn->lock);
if (conn->linger_active)
{
@@ -2185,7 +2185,7 @@ repl5_start_debug_timeout(int *setlevel)
{
Slapi_Eq_Context eqctx = 0;
if (s_debug_timeout && s_debug_level) {
- time_t now = time(NULL);
+ time_t now = slapi_current_utc_time();
eqctx = slapi_eq_once(repl5_debug_timeout_callback, setlevel,
s_debug_timeout + now);
}
diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c
index 90491fd..68185bf 100644
--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c
@@ -259,7 +259,7 @@ repl5_inc_result_threadmain(void *param)
char *uniqueid = NULL;
char *ldap_error_string = NULL;
time_t time_now = 0;
- time_t start_time = time( NULL );
+ time_t start_time = slapi_current_utc_time();
int connection_error = 0;
int operation_code = 0;
int backoff_time = 1;
@@ -282,7 +282,7 @@ repl5_inc_result_threadmain(void *param)
/* We need to a) check that the 'real' timeout hasn't expired and
* b) implement a backoff sleep to avoid spinning */
/* Did the connection's timeout expire ? */
- time_now = time( NULL );
+ time_now = slapi_current_utc_time();
if (conn_get_timeout(conn) <= ( time_now - start_time ))
{
/* We timed out */
@@ -373,7 +373,7 @@ repl5_inc_result_threadmain(void *param)
/* Should we stop ? */
PR_Lock(rd->lock);
if (!finished && yield_session && rd->abort != SESSION_ABORTED && rd->abort_time == 0) {
- rd->abort_time = time( NULL );
+ rd->abort_time = slapi_current_utc_time();
rd->abort = SESSION_ABORTED; /* only set the abort time once */
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "repl5_inc_result_threadmain - "
"Abort control detected, setting abort time...(%s)\n",
@@ -932,7 +932,7 @@ repl5_inc_run(Private_Repl_Protocol *prp)
*/
if (STATE_BACKOFF == next_state){
/* Step the backoff timer */
- time(&now);
+ now = slapi_current_utc_time();
next_fire_time = backoff_step(prp_priv->backoff);
/* And go back to sleep */
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
@@ -978,7 +978,7 @@ repl5_inc_run(Private_Repl_Protocol *prp)
release_replica (prp);
done = 1;
agmt_set_update_in_progress(prp->agmt, PR_FALSE);
- agmt_set_last_update_end(prp->agmt, current_time());
+ agmt_set_last_update_end(prp->agmt, slapi_current_utc_time());
/* MAB: I don't find the following status correct. How do we know it has
* been stopped by an admin and not by a total update request, for instance?
* In any case, how is this protocol shutdown situation different from all the
@@ -1074,7 +1074,7 @@ repl5_inc_run(Private_Repl_Protocol *prp)
/*
* Reset our update times and status
*/
- agmt_set_last_update_start(prp->agmt, current_time());
+ agmt_set_last_update_start(prp->agmt, slapi_current_utc_time());
agmt_set_last_update_end(prp->agmt, 0);
agmt_set_update_in_progress(prp->agmt, PR_TRUE);
/*
@@ -1122,7 +1122,7 @@ repl5_inc_run(Private_Repl_Protocol *prp)
/* Set the updates times based off the result of send_updates() */
if(rc == UPDATE_NO_MORE_UPDATES){
/* update successful, set the end time */
- agmt_set_last_update_end(prp->agmt, current_time());
+ agmt_set_last_update_end(prp->agmt, slapi_current_utc_time());
} else {
/* Failed to send updates, reset the start time to zero */
agmt_set_last_update_start(prp->agmt, 0);
@@ -1973,7 +1973,7 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
/* See if the result thread has hit a problem */

if(!finished && rd->abort_time){
- time_t current_time = time ( NULL );
+ time_t current_time = slapi_current_utc_time ();
if ((current_time - rd->abort_time) >= release_timeout){
rd->result = UPDATE_YIELD;
return_value = UPDATE_YIELD;
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 55c270f..cf44bfd 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -246,7 +246,7 @@ replica_new_from_entry (Slapi_Entry *e, char *errortext, PRBool is_add_operation
In that case the updated would fail but nothing bad would happen. The next
scheduled update would save the state */
r->repl_eqcxt_rs = slapi_eq_repeat(replica_update_state, r->repl_name,
- current_time () + START_UPDATE_DELAY, RUV_SAVE_INTERVAL);
+ slapi_current_utc_time() + START_UPDATE_DELAY, RUV_SAVE_INTERVAL);

if (r->tombstone_reap_interval > 0)
{
@@ -255,7 +255,7 @@ replica_new_from_entry (Slapi_Entry *e, char *errortext, PRBool is_add_operation
* This will allow the server to fully start before consuming resources.
*/
r->repl_eqcxt_tr = slapi_eq_repeat(eq_cb_reap_tombstones, r->repl_name,
- current_time() + r->tombstone_reap_interval,
+ slapi_current_utc_time() + r->tombstone_reap_interval,
1000 * r->tombstone_reap_interval);
}

@@ -516,17 +516,14 @@ replica_subentry_update(Slapi_DN *repl_root, ReplicaId rid)
LDAPMod * mods[2];
LDAPMod mod;
struct berval * vals[2];
- char buf[20];
- time_t curtime;
- struct tm ltm;
+ char buf[SLAPI_TIMESTAMP_BUFSIZE];
struct berval val;
Slapi_PBlock *modpb = NULL;
char *dn;

replica_subentry_check(repl_root, rid);
- curtime = current_time();
- gmtime_r(&curtime, &ltm);
- strftime(buf, sizeof (buf), "%Y%m%d%H%M%SZ", &ltm);
+
+ slapi_timestamp_utc_hr(buf, SLAPI_TIMESTAMP_BUFSIZE);

slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "subentry_update called at %s\n", buf);

@@ -1214,7 +1211,7 @@ replica_is_updatedn (Replica *r, const Slapi_DN *sdn)
if (r->groupdn_list) {
/* check and rebuild groupdns */
if (r->updatedn_group_check_interval > -1) {
- time_t now = time(NULL);
+ time_t now = slapi_current_utc_time();
if (now - r->updatedn_group_last_check > r->updatedn_group_check_interval) {
Slapi_ValueSet *updatedn_groups_copy = NULL;
ReplicaUpdateDNList groupdn_list = replica_updatedn_list_new(NULL);
@@ -1652,7 +1649,7 @@ replica_set_enabled (Replica *r, PRBool enable)
if (r->repl_eqcxt_rs == NULL) /* event is not already registered */
{
r->repl_eqcxt_rs = slapi_eq_repeat(replica_update_state, r->repl_name,
- current_time() + START_UPDATE_DELAY, RUV_SAVE_INTERVAL);
+ slapi_current_utc_time() + START_UPDATE_DELAY, RUV_SAVE_INTERVAL);
}
}
else /* disable */
@@ -3907,7 +3904,7 @@ replica_set_tombstone_reap_interval (Replica *r, long interval)
if ( interval > 0 && r->repl_eqcxt_tr == NULL )
{
r->repl_eqcxt_tr = slapi_eq_repeat (eq_cb_reap_tombstones, r->repl_name,
- current_time() + r->tombstone_reap_interval,
+ slapi_current_utc_time() + r->tombstone_reap_interval,
1000 * r->tombstone_reap_interval);
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
"replica_set_tombstone_reap_interval - tombstone_reap event (interval=%ld) was %s\n",
diff --git a/ldap/servers/plugins/replication/repl5_ruv.c b/ldap/servers/plugins/replication/repl5_ruv.c
index d59e6d2..25f61e2 100644
--- a/ldap/servers/plugins/replication/repl5_ruv.c
+++ b/ldap/servers/plugins/replication/repl5_ruv.c
@@ -666,7 +666,7 @@ set_max_csn_nolock_ext(RUV *ruv, const CSN *max_csn, const char *replica_purl, P
if (!must_be_greater || (csn_compare(replica->csn, max_csn) < 0)) {
csn_free(&replica->csn);
replica->csn = csn_dup(max_csn);
- replica->last_modified = current_time();
+ replica->last_modified = slapi_current_utc_time();
} else {
char csn1[CSN_STRSIZE+1];
char csn2[CSN_STRSIZE+1];
@@ -748,7 +748,7 @@ ruv_set_csns(RUV *ruv, const CSN *csn, const char *replica_purl)
{
replica->csn = csn_dup(csn);
}
- replica->last_modified = current_time();
+ replica->last_modified = slapi_current_utc_time();
if (replica_purl && (NULL == replica->replica_purl ||
strcmp(replica->replica_purl, replica_purl) != 0))
{
@@ -810,7 +810,7 @@ ruv_set_csns_keep_smallest(RUV *ruv, const CSN *csn)
{
csn_free(&replica->csn);
replica->csn = csn_dup(csn);
- replica->last_modified = current_time();
+ replica->last_modified = slapi_current_utc_time();
}

return_value = RUV_SUCCESS;
@@ -1891,7 +1891,7 @@ ruvAddReplica (RUV *ruv, const CSN *csn, const char *replica_purl)
/* PR_ASSERT(replica->rid != READ_ONLY_REPLICA_ID); */

replica->csn = csn_dup (csn);
- replica->last_modified = current_time();
+ replica->last_modified = slapi_current_utc_time();
replica->min_csn = csn_dup (csn);

replica->replica_purl = slapi_ch_strdup(replica_purl);
diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c
index cb10b16..ab113d3 100644
--- a/ldap/servers/plugins/replication/repl5_tot_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c
@@ -114,7 +114,7 @@ static void repl5_tot_result_threadmain(void *param)
{
int message_id = 0;
time_t time_now = 0;
- time_t start_time = time( NULL );
+ time_t start_time = slapi_current_utc_time();
int backoff_time = 1;

/* Read the next result */
@@ -133,7 +133,7 @@ static void repl5_tot_result_threadmain(void *param)
/* We need to a) check that the 'real' timeout hasn't expired and
* b) implement a backoff sleep to avoid spinning */
/* Did the connection's timeout expire ? */
- time_now = time( NULL );
+ time_now = slapi_current_utc_time();
if (conn_get_timeout(conn) <= ( time_now - start_time ))
{
/* We timed out */
@@ -347,7 +347,7 @@ repl5_tot_run(Private_Repl_Protocol *prp)
conn_set_timeout(prp->conn, agmt_get_timeout(prp->agmt));

/* acquire remote replica */
- agmt_set_last_init_start(prp->agmt, current_time());
+ agmt_set_last_init_start(prp->agmt, slapi_current_utc_time());
retry:
rc = acquire_replica (prp, REPL_NSDS50_TOTAL_PROTOCOL_OID, NULL /* ruv */);
/* We never retry total protocol, even in case a transient error.
@@ -455,7 +455,7 @@ retry:
cb_data.rc = 0;
cb_data.num_entries = 1UL;
cb_data.sleep_on_busy = 0UL;
- cb_data.last_busy = current_time ();
+ cb_data.last_busy = slapi_current_utc_time ();
cb_data.flowcontrol_detection = 0;
cb_data.lock = PR_NewLock();

@@ -514,7 +514,7 @@ retry:
cb_data.rc = 0;
cb_data.num_entries = 0UL;
cb_data.sleep_on_busy = 0UL;
- cb_data.last_busy = current_time ();
+ cb_data.last_busy = slapi_current_utc_time ();
cb_data.flowcontrol_detection = 0;
cb_data.lock = PR_NewLock();

@@ -575,7 +575,7 @@ retry:
* suitable messages will have been logged to the error log about the failure.
*/

- agmt_set_last_init_end(prp->agmt, current_time());
+ agmt_set_last_init_end(prp->agmt, slapi_current_utc_time());
rc = cb_data.rc;
agmt_set_update_in_progress(prp->agmt, PR_FALSE);
agmt_update_done(prp->agmt, 1);
@@ -883,7 +883,7 @@ int send_entry (Slapi_Entry *e, void *cb_data)
}

if (rc == CONN_BUSY) {
- time_t now = current_time ();
+ time_t now = slapi_current_utc_time ();
if ((now - *last_busyp) < (*sleep_on_busyp + 10)) {
*sleep_on_busyp +=5;
}
diff --git a/ldap/servers/plugins/replication/repl_objset.c b/ldap/servers/plugins/replication/repl_objset.c
index 405914d..b81881c 100644
--- a/ldap/servers/plugins/replication/repl_objset.c
+++ b/ldap/servers/plugins/replication/repl_objset.c
@@ -97,7 +97,7 @@ repl_objset_destroy(Repl_Objset **o, time_t maxwait, FNFree panic_fn)
PR_ASSERT(NULL != o);
PR_ASSERT(NULL != *o);

- time(&now);
+ now = slapi_current_utc_time();
stop_time = now + maxwait;

/*
@@ -133,7 +133,7 @@ repl_objset_destroy(Repl_Objset **o, time_t maxwait, FNFree panic_fn)
co = llistGetNext((*o)->objects, &cookie);
}
PR_Unlock((*o)->lock);
- time(&now);
+ now = slapi_current_utc_time();
if (loopcount > 0)
{
DS_Sleep(PR_TicksPerSecond());
diff --git a/ldap/servers/plugins/replication/windows_connection.c b/ldap/servers/plugins/replication/windows_connection.c
index c5486e3..d819ba9 100644
--- a/ldap/servers/plugins/replication/windows_connection.c
+++ b/ldap/servers/plugins/replication/windows_connection.c
@@ -1223,7 +1223,7 @@ windows_conn_start_linger(Repl_Connection *conn)
agmt_get_long_name(conn->agmt));
return;
}
- time(&now);
+ now = slapi_current_utc_time();
PR_Lock(conn->lock);
if (conn->linger_active)
{
diff --git a/ldap/servers/plugins/replication/windows_inc_protocol.c b/ldap/servers/plugins/replication/windows_inc_protocol.c
index b878f2b..94a2933 100644
--- a/ldap/servers/plugins/replication/windows_inc_protocol.c
+++ b/ldap/servers/plugins/replication/windows_inc_protocol.c
@@ -739,7 +739,7 @@ windows_inc_run(Private_Repl_Protocol *prp)
dev_debug("windows_inc_run(STATE_SENDING_UPDATES)");
agmt_set_update_in_progress(prp->agmt, PR_TRUE);
num_changes_sent = 0;
- last_start_time = current_time();
+ last_start_time = slapi_current_utc_time();
agmt_set_last_update_start(prp->agmt, last_start_time);
/*
* We've acquired the replica, and are ready to send any
@@ -750,7 +750,7 @@ windows_inc_run(Private_Repl_Protocol *prp)
windows_release_replica (prp);
done = 1;
agmt_set_update_in_progress(prp->agmt, PR_FALSE);
- agmt_set_last_update_end(prp->agmt, current_time());
+ agmt_set_last_update_end(prp->agmt, slapi_current_utc_time());
/* MAB: I don't find the following status correct. How do we know it has
been stopped by an admin and not by a total update request, for instance?
In any case, how is this protocol shutdown situation different from all the
@@ -892,7 +892,7 @@ windows_inc_run(Private_Repl_Protocol *prp)
run_dirsync = PR_FALSE;
}

- agmt_set_last_update_end(prp->agmt, current_time());
+ agmt_set_last_update_end(prp->agmt, slapi_current_utc_time());
agmt_set_update_in_progress(prp->agmt, PR_FALSE);
agmt_update_done(prp->agmt, 0);
/* If timed out, close the connection after released the replica */
diff --git a/ldap/servers/plugins/replication/windows_tot_protocol.c b/ldap/servers/plugins/replication/windows_tot_protocol.c
index ad6c4f8..6de0e93 100644
--- a/ldap/servers/plugins/replication/windows_tot_protocol.c
+++ b/ldap/servers/plugins/replication/windows_tot_protocol.c
@@ -142,7 +142,7 @@ windows_tot_run(Private_Repl_Protocol *prp)
windows_conn_set_timeout(prp->conn, agmt_get_timeout(prp->agmt));

/* acquire remote replica */
- agmt_set_last_init_start(prp->agmt, current_time());
+ agmt_set_last_init_start(prp->agmt, slapi_current_utc_time());

rc = windows_acquire_replica (prp, &ruv, 0 /* don't check RUV for total protocol */);
/* We never retry total protocol, even in case a transient error.
@@ -204,7 +204,7 @@ windows_tot_run(Private_Repl_Protocol *prp)
cb_data.rc = 0;
cb_data.num_entries = 0UL;
cb_data.sleep_on_busy = 0UL;
- cb_data.last_busy = current_time ();
+ cb_data.last_busy = slapi_current_utc_time ();

/* Don't send anything if one-way (ONE_WAY_SYNC_FROM_AD) is set. */
if ((one_way == ONE_WAY_SYNC_DISABLED) || (one_way == ONE_WAY_SYNC_TO_AD)) {
@@ -253,7 +253,7 @@ windows_tot_run(Private_Repl_Protocol *prp)
/* Save the dirsync cookie. */
windows_private_save_dirsync_cookie(prp->agmt);

- agmt_set_last_init_end(prp->agmt, current_time());
+ agmt_set_last_init_end(prp->agmt, slapi_current_utc_time());
agmt_set_update_in_progress(prp->agmt, PR_FALSE);
agmt_update_done(prp->agmt, 1);

diff --git a/ldap/servers/plugins/retrocl/retrocl_po.c b/ldap/servers/plugins/retrocl/retrocl_po.c
index 1d85ea4..4631c76 100644
--- a/ldap/servers/plugins/retrocl/retrocl_po.c
+++ b/ldap/servers/plugins/retrocl/retrocl_po.c
@@ -619,7 +619,7 @@ int retrocl_postob (Slapi_PBlock *pb, int optype)
return SLAPI_PLUGIN_SUCCESS;
}

- curtime = current_time();
+ curtime = slapi_current_utc_time();

(void)slapi_pblock_get( pb, SLAPI_ORIGINAL_TARGET_DN, &dn );

diff --git a/ldap/servers/plugins/retrocl/retrocl_trim.c b/ldap/servers/plugins/retrocl/retrocl_trim.c
index 5f30217..4f1b57a 100644
--- a/ldap/servers/plugins/retrocl/retrocl_trim.c
+++ b/ldap/servers/plugins/retrocl/retrocl_trim.c
@@ -238,7 +238,7 @@ static int trim_changelog(void)
int me,lt;


- now = current_time();
+ now = slapi_current_utc_time();

PR_Lock( ts.ts_s_trim_mutex );
me = ts.ts_c_max_age;
diff --git a/ldap/servers/plugins/rootdn_access/rootdn_access.c b/ldap/servers/plugins/rootdn_access/rootdn_access.c
index 3450ce2..a8933f9 100644
--- a/ldap/servers/plugins/rootdn_access/rootdn_access.c
+++ b/ldap/servers/plugins/rootdn_access/rootdn_access.c
@@ -63,8 +63,8 @@ char * strToLower(char *str);
*/
static void *_PluginID = NULL;
static char *_PluginDN = NULL;
-static int open_time = 0;
-static int close_time = 0;
+static time_t open_time = 0;
+static time_t close_time = 0;
static char *daysAllowed = NULL;
static char **hosts = NULL;
static char **hosts_to_deny = NULL;
@@ -289,7 +289,7 @@ rootdn_load_config(Slapi_PBlock *pb)
*/
strncpy(hour, openTime,2);
strncpy(min, openTime+2,2);
- open_time = (atoi(hour) * 3600) + (atoi(min) * 60);
+ open_time = (time_t)(atoi(hour) * 3600) + (atoi(min) * 60);
}
if(closeTime){
end = strspn(closeTime, "0123456789");
@@ -317,7 +317,7 @@ rootdn_load_config(Slapi_PBlock *pb)
*/
strncpy(hour, closeTime,2);
strncpy(min, closeTime+2,2);
- close_time = (atoi(hour) * 3600) + (atoi(min) * 60);
+ close_time = (time_t)(atoi(hour) * 3600) + (atoi(min) * 60);
}
if((openTime && closeTime == NULL) || (openTime == NULL && closeTime)){
/* If you are using TOD access control, you must have a open and close time */
@@ -461,16 +461,16 @@ rootdn_check_access(Slapi_PBlock *pb){
* grab the current time/info if we need it
*/
if(open_time || daysAllowed){
- time(&curr_time);
+ curr_time = slapi_current_utc_time();
timeinfo = localtime(&curr_time);
}
/*
* First check TOD restrictions, continue through if we are in the open "window"
*/
if(open_time){
- int curr_total;
+ time_t curr_total;

- curr_total = (timeinfo->tm_hour * 3600) + (timeinfo->tm_min * 60);
+ curr_total = (time_t)(timeinfo->tm_hour * 3600) + (timeinfo->tm_min * 60);

if((curr_total < open_time) || (curr_total >= close_time)){
slapi_log_err(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access - Bind not in the "
diff --git a/ldap/servers/plugins/syntaxes/string.c b/ldap/servers/plugins/syntaxes/string.c
index ac3d532..753a369 100644
--- a/ldap/servers/plugins/syntaxes/string.c
+++ b/ldap/servers/plugins/syntaxes/string.c
@@ -197,10 +197,7 @@ string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
size_t tmpbufsize;
char pat[BUFSIZ];
char buf[BUFSIZ];
- time_t curtime = 0;
- time_t time_up = 0;
- time_t optime = 0; /* time op was initiated */
- int timelimit = 0; /* search timelimit */
+ struct timespec expire_time = {0};
Operation *op = NULL;
Slapi_Regex *re = NULL;
const char *re_result = NULL;
@@ -214,17 +211,10 @@ string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
slapi_pblock_get( pb, SLAPI_OPERATION, &op );
}
if (NULL != op) {
+ int32_t timelimit = -1; /* search timelimit */
slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &timelimit );
- slapi_pblock_get( pb, SLAPI_OPINITIATED_TIME, &optime );
- } else {
- /* timelimit is not passed via pblock */
- timelimit = -1;
+ slapi_operation_time_expiry(op, (time_t)timelimit, &expire_time);
}
- /*
- * (timelimit==-1) means no time limit
- */
- time_up = ( timelimit==-1 ? -1 : optime + timelimit);
-
if (pb) {
slapi_pblock_get( pb, SLAPI_PLUGIN_SYNTAX_FILTER_NORMALIZED, &filter_normalized );
slapi_pblock_get( pb, SLAPI_PLUGIN_SYNTAX_FILTER_DATA, &sf );
@@ -335,8 +325,8 @@ string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
}
}

- curtime = current_time();
- if ( time_up != -1 && curtime > time_up ) {
+ if (slapi_timespec_expire_check(&expire_time) == TIMER_EXPIRED) {
+ slapi_log_err(SLAPI_LOG_TRACE, SYNTAX_PLUGIN_SUBSYSTEM, "LDAP_TIMELIMIT_EXCEEDED\n");
rc = LDAP_TIMELIMIT_EXCEEDED;
goto bailout;
}
@@ -371,10 +361,20 @@ string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
slapi_dn_ignore_case(realval);
}
if (alt) {
- tmprc = slapi_re_exec( re, alt, time_up );
+ if (slapi_timespec_expire_check(&expire_time) == TIMER_EXPIRED) {
+ slapi_log_err(SLAPI_LOG_TRACE, SYNTAX_PLUGIN_SUBSYSTEM, "LDAP_TIMELIMIT_EXCEEDED\n");
+ rc = LDAP_TIMELIMIT_EXCEEDED;
+ goto bailout;
+ }
+ tmprc = slapi_re_exec_nt(re, alt);
slapi_ch_free_string(&alt);
} else {
- tmprc = slapi_re_exec( re, realval, time_up );
+ if (slapi_timespec_expire_check(&expire_time) == TIMER_EXPIRED) {
+ slapi_log_err(SLAPI_LOG_TRACE, SYNTAX_PLUGIN_SUBSYSTEM, "LDAP_TIMELIMIT_EXCEEDED\n");
+ rc = LDAP_TIMELIMIT_EXCEEDED;
+ goto bailout;
+ }
+ tmprc = slapi_re_exec_nt(re, realval);
}

if (slapi_is_loglevel_set(SLAPI_LOG_TRACE)) {
diff --git a/ldap/servers/slapd/abandon.c b/ldap/servers/slapd/abandon.c
index 581b6d2..2abb96a 100644
--- a/ldap/servers/slapd/abandon.c
+++ b/ldap/servers/slapd/abandon.c
@@ -137,10 +137,12 @@ do_abandon( Slapi_PBlock *pb )
" targetop=SUPPRESSED-BY-PLUGIN msgid=%d\n",
pb_conn->c_connid, pb_op->o_opid, id );
} else {
+ struct timespec o_hr_time_end;
+ slapi_operation_time_elapsed(o, &o_hr_time_end);
slapi_log_access( LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d ABANDON"
- " targetop=%d msgid=%d nentries=%d etime=%ld\n",
+ " targetop=%d msgid=%d nentries=%d etime=%"PRId64".%010"PRId64"\n",
pb_conn->c_connid, pb_op->o_opid, o->o_opid, id,
- o->o_results.r.r_search.nentries, current_time() - o->o_time );
+ o->o_results.r.r_search.nentries, o_hr_time_end.tv_sec, o_hr_time_end.tv_nsec);
}

PR_ExitMonitor(pb_conn->c_mutex);
diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c
index 7fa5444..eb9a9fc 100644
--- a/ldap/servers/slapd/add.c
+++ b/ldap/servers/slapd/add.c
@@ -780,13 +780,11 @@ done:
static int
add_created_attrs(Slapi_PBlock *pb, Slapi_Entry *e)
{
- char buf[20];
+ char buf[SLAPI_TIMESTAMP_BUFSIZE];
char *binddn = NULL;
char *plugin_dn = NULL;
struct berval bv;
struct berval *bvals[2];
- time_t curtime;
- struct tm ltm;
Operation *op;
struct slapdplugin *plugin = NULL;
struct slapi_componentid *cid = NULL;
@@ -848,9 +846,7 @@ add_created_attrs(Slapi_PBlock *pb, Slapi_Entry *e)
slapi_entry_attr_replace(e, "creatorsname", bvals);
slapi_entry_attr_replace(e, "modifiersname", bvals);

- curtime = current_time();
- gmtime_r(&curtime, &ltm);
- strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &ltm);
+ slapi_timestamp_utc_hr(buf, SLAPI_TIMESTAMP_BUFSIZE);

bv.bv_val = buf;
bv.bv_len = strlen(bv.bv_val);
diff --git a/ldap/servers/slapd/auditlog.c b/ldap/servers/slapd/auditlog.c
index 59ba476..d065669 100644
--- a/ldap/servers/slapd/auditlog.c
+++ b/ldap/servers/slapd/auditlog.c
@@ -95,7 +95,7 @@ write_audit_log_entry( Slapi_PBlock *pb )
default:
return; /* Unsupported operation type. */
}
- curtime = current_time();
+ curtime = slapi_current_utc_time();
/* log the raw, unnormalized DN */
dn = slapi_sdn_get_udn(sdn);
write_audit_file(SLAPD_AUDIT_LOG, operation_get_type(op), dn, change, flag, curtime, LDAP_SUCCESS, SLAPD_AUDIT_LOG);
@@ -164,7 +164,7 @@ write_auditfail_log_entry( Slapi_PBlock *pb )
default:
return; /* Unsupported operation type. */
}
- curtime = current_time();
+ curtime = slapi_current_utc_time();
/* log the raw, unnormalized DN */
dn = slapi_sdn_get_udn(sdn);
auditfail_config = config_get_auditfaillog();
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 3290052..b96a8a3 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -4301,19 +4301,21 @@ dblayer_start_checkpoint_thread(struct ldbminfo *li)
*/
static int checkpoint_threadmain(void *param)
{
- time_t time_of_last_checkpoint_completion = 0; /* seconds since epoch */
PRIntervalTime interval;
int rval = -1;
dblayer_private *priv = NULL;
struct ldbminfo *li = NULL;
int debug_checkpointing = 0;
- int checkpoint_interval;
char *home_dir = NULL;
char **list = NULL;
char **listp = NULL;
struct dblayer_private_env *penv = NULL;
- time_t time_of_last_comapctdb_completion = current_time(); /* seconds since epoch */
- int compactdb_interval = 0;
+ struct timespec checkpoint_expire;
+ struct timespec compactdb_expire;
+ time_t compactdb_interval_update = 0;
+ time_t checkpoint_interval_update = 0;
+ time_t compactdb_interval = 0;
+ time_t checkpoint_interval = 0;
back_txn txn;

PR_ASSERT(NULL != param);
@@ -4324,8 +4326,7 @@ static int checkpoint_threadmain(void *param)

INCR_THREAD_COUNT(priv);

- compactdb_interval = priv->dblayer_compactdb_interval;
- interval = PR_MillisecondsToInterval(DBLAYER_SLEEP_INTERVAL);
+ interval = PR_MillisecondsToInterval(DBLAYER_SLEEP_INTERVAL * 10);
home_dir = dblayer_get_home_dir(li, NULL);
if (NULL == home_dir || '\0' == *home_dir)
{
@@ -4337,76 +4338,113 @@ static int checkpoint_threadmain(void *param)
/* work around a problem with newly created environments */
dblayer_force_checkpoint(li);

+ PR_Lock(li->li_config_mutex);
+ checkpoint_interval = (time_t)priv->dblayer_checkpoint_interval;
+ compactdb_interval = (time_t)priv->dblayer_compactdb_interval;
penv = priv->dblayer_env;
debug_checkpointing = priv->db_debug_checkpointing;
+ PR_Unlock(li->li_config_mutex);
+
/* assumes dblayer_force_checkpoint worked */
- time_of_last_checkpoint_completion = current_time();
+ /*
+ * Importantly, the use of this api is not affected by backwards time steps
+ * and the like. Because this use relative system time, rather than utc,
+ * it makes it much more reliable to run.
+ */
+ slapi_timespec_expire_at(compactdb_interval, &compactdb_expire);
+ slapi_timespec_expire_at(checkpoint_interval, &checkpoint_expire);
+
while (!priv->dblayer_stop_threads)
{
/* sleep for a while */
/* why aren't we sleeping exactly the right amount of time ? */
/* answer---because the interval might be changed after the server
* starts up */
+
DS_Sleep(interval);

- if (0 == priv->dblayer_enable_transactions)
+ if (0 == priv->dblayer_enable_transactions) {
continue;
+ }

PR_Lock(li->li_config_mutex);
- checkpoint_interval = priv->dblayer_checkpoint_interval;
+ checkpoint_interval_update = (time_t)priv->dblayer_checkpoint_interval;
+ compactdb_interval_update = (time_t)priv->dblayer_compactdb_interval;
PR_Unlock(li->li_config_mutex);

- /* Check to see if the checkpoint interval has elapsed */
- if (current_time() - time_of_last_checkpoint_completion <
- checkpoint_interval)
- continue;
+ /* If the checkpoint has been updated OR we have expired */
+ if (checkpoint_interval != checkpoint_interval_update &&
+ slapi_timespec_expire_check(&checkpoint_expire) == TIMER_EXPIRED) {

- if (!dblayer_db_uses_transactions(priv->dblayer_env->dblayer_DB_ENV))
- continue;
+ /* If our interval has changed, update it. */
+ checkpoint_interval = checkpoint_interval_update;

- /* now checkpoint */
- checkpoint_debug_message(debug_checkpointing,
- "checkpoint_threadmain - Starting checkpoint\n");
- rval = dblayer_txn_checkpoint(li, priv->dblayer_env,
- PR_TRUE, PR_FALSE);
- checkpoint_debug_message(debug_checkpointing,
- "checkpoint_threadmain - Checkpoint Done\n");
- if (rval != 0) {
- /* bad error */
- slapi_log_err(SLAPI_LOG_CRIT,
- "checkpoint_threadmain", "Serious Error---Failed to checkpoint database, "
- "err=%d (%s)\n", rval, dblayer_strerror(rval));
- if (LDBM_OS_ERR_IS_DISKFULL(rval)) {
- operation_out_of_disk_space();
- goto error_return;
+ if (!dblayer_db_uses_transactions(priv->dblayer_env->dblayer_DB_ENV)) {
+ continue;
}
- } else {
- time_of_last_checkpoint_completion = current_time();
- }

- checkpoint_debug_message(debug_checkpointing,
- "checkpoint_threadmain - Starting checkpoint\n");
- rval = dblayer_txn_checkpoint(li, priv->dblayer_env,
- PR_TRUE, PR_FALSE);
- checkpoint_debug_message(debug_checkpointing,
- "checkpoint_threadmain - Checkpoint Done\n");
- if (rval != 0) {
- /* bad error */
- slapi_log_err(SLAPI_LOG_CRIT,
- "checkpoint_threadmain", "Serious Error---Failed to checkpoint database, "
- "err=%d (%s)\n", rval, dblayer_strerror(rval));
- if (LDBM_OS_ERR_IS_DISKFULL(rval)) {
- operation_out_of_disk_space();
- goto error_return;
+ /* now checkpoint */
+ checkpoint_debug_message(debug_checkpointing,
+ "checkpoint_threadmain - Starting checkpoint\n");
+ rval = dblayer_txn_checkpoint(li, priv->dblayer_env,
+ PR_TRUE, PR_FALSE);
+ checkpoint_debug_message(debug_checkpointing,
+ "checkpoint_threadmain - Checkpoint Done\n");
+ if (rval != 0) {
+ /* bad error */
+ slapi_log_err(SLAPI_LOG_CRIT,
+ "checkpoint_threadmain", "Serious Error---Failed to checkpoint database, "
+ "err=%d (%s)\n", rval, dblayer_strerror(rval));
+ if (LDBM_OS_ERR_IS_DISKFULL(rval)) {
+ operation_out_of_disk_space();
+ goto error_return;
+ }
}
- } else {
- time_of_last_checkpoint_completion = current_time();
+
+ rval = LOG_ARCHIVE(penv->dblayer_DB_ENV, &list,
+ DB_ARCH_ABS, (void *)slapi_ch_malloc);
+ if (rval) {
+ slapi_log_err(SLAPI_LOG_ERR, "checkpoint_threadmain",
+ "log archive failed - %s (%d)\n",
+ dblayer_strerror(rval), rval);
+ } else {
+ for (listp = list; listp && *listp != NULL; ++listp) {
+ if (priv->dblayer_circular_logging) {
+ checkpoint_debug_message(debug_checkpointing,
+ "Deleting %s\n", *listp);
+ unlink(*listp);
+ } else {
+ char new_filename[MAXPATHLEN];
+ PR_snprintf(new_filename, sizeof(new_filename),
+ "%s.old", *listp);
+ checkpoint_debug_message(debug_checkpointing,
+ "Renaming %s -> %s\n",*listp, new_filename);
+ if(rename(*listp, new_filename) != 0){
+ slapi_log_err(SLAPI_LOG_ERR, "checkpoint_threadmain", "Failed to rename log (%s) to (%s)\n",
+ *listp, new_filename);
+ rval = -1;
+ goto error_return;
+ }
+ }
+ }
+ slapi_ch_free((void**)&list);
+ /* Note: references inside the returned memory need not be
+ * individually freed. */
+ }
+ slapi_timespec_expire_at(checkpoint_interval, &checkpoint_expire);
}
- /* find out which log files don't contain active txns */

/* Compacting DB borrowing the timing of the log flush */
- if ((compactdb_interval > 0) &&
- (current_time() - time_of_last_comapctdb_completion > compactdb_interval)) {
+
+ /*
+ * Remember that if compactdb_interval is 0, timer_expired can
+ * never occur unless the value in compctdb_interval changes.
+ *
+ * this could have been a bug infact, where compactdb_interval
+ * was 0, if you change while running it would never take effect ....
+ */
+ if (compactdb_interval_update != compactdb_interval ||
+ slapi_timespec_expire_check(&compactdb_expire) == TIMER_EXPIRED) {
int rc = 0;
Object *inst_obj;
ldbm_instance *inst;
@@ -4422,17 +4460,45 @@ static int checkpoint_threadmain(void *param)
if (!db || rc ) {
continue;
}
- slapi_log_err(SLAPI_LOG_BACKLDBM, "checkpoint_threadmain", "Compacting DB start: %s\n",
+ slapi_log_err(SLAPI_LOG_NOTICE, "checkpoint_threadmain", "Compacting DB start: %s\n",
inst->inst_name);
+
+ /*
+ * It's possible for this to heap us after free because when we access db
+ * *just* as the server shut's down, we don't know it. So we should probably
+ * do something like wrapping access to the db var in a rwlock, and have "read"
+ * to access, and take writes to change the state. This would prevent the issue.
+ */
+ DBTYPE type;
+ rc = db->get_type(db, &type);
+ if (rc) {
+ slapi_log_err(SLAPI_LOG_ERR, "checkpoint_threadmain",
+ "compactdb: failed to determine db type for %s: db error - %d %s\n",
+ inst->inst_name, rc, db_strerror(rc));
+ continue;
+ }
+
rc = dblayer_txn_begin(inst->inst_be, NULL, &txn);
if (rc) {
slapi_log_err(SLAPI_LOG_ERR, "checkpoint_threadmain", "compactdb: transaction begin failed: %d\n", rc);
break;
}
+ /*
+ * https://docs.oracle.com/cd/E17275_01/html/api_reference/C/BDB-C_APIReference.pdf
+ * "DB_FREELIST_ONLY
+ * Do no page compaction, only returning pages to the filesystem that are already free and at the end
+ * of the file. This flag must be set if the database is a Hash access method database."
+ *
+ */
+
+ uint32_t compact_flags = DB_FREE_SPACE;
+ if (type == DB_HASH) {
+ compact_flags |= DB_FREELIST_ONLY;
+ }
rc = db->compact(db, txn.back_txn_txn, NULL/*start*/, NULL/*stop*/,
- &c_data, DB_FREE_SPACE, NULL/*end*/);
+ &c_data, compact_flags, NULL/*end*/);
if (rc) {
- slapi_log_err(SLAPI_LOG_ERR,
+ slapi_log_err(SLAPI_LOG_ERR, "checkpoint_threadmain",
"compactdb: failed to compact %s; db error - %d %s\n",
inst->inst_name, rc, db_strerror(rc));
if((rc = dblayer_txn_abort(inst->inst_be, &txn))){
@@ -4441,7 +4507,7 @@ static int checkpoint_threadmain(void *param)
break;
}
} else {
- slapi_log_err(SLAPI_LOG_BACKLDBM,
+ slapi_log_err(SLAPI_LOG_NOTICE, "checkpoint_threadmain",
"compactdb: compact %s - %d pages freed\n",
inst->inst_name, c_data.compact_pages_free);
if((rc = dblayer_txn_commit(inst->inst_be, &txn))){
@@ -4451,40 +4517,10 @@ static int checkpoint_threadmain(void *param)
}
}
}
- time_of_last_comapctdb_completion = current_time(); /* seconds since epoch */
- compactdb_interval = priv->dblayer_compactdb_interval;
+ compactdb_interval = compactdb_interval_update;
+ slapi_timespec_expire_at(compactdb_interval, &compactdb_expire);
}

- rval = LOG_ARCHIVE(penv->dblayer_DB_ENV, &list,
- DB_ARCH_ABS, (void *)slapi_ch_malloc);
- if (rval) {
- slapi_log_err(SLAPI_LOG_ERR, "checkpoint_threadmain",
- "log archive failed - %s (%d)\n",
- dblayer_strerror(rval), rval);
- } else {
- for (listp = list; listp && *listp != NULL; ++listp) {
- if (priv->dblayer_circular_logging) {
- checkpoint_debug_message(debug_checkpointing,
- "Deleting %s\n", *listp);
- unlink(*listp);
- } else {
- char new_filename[MAXPATHLEN];
- PR_snprintf(new_filename, sizeof(new_filename),
- "%s.old", *listp);
- checkpoint_debug_message(debug_checkpointing,
- "Renaming %s -> %s\n",*listp, new_filename);
- if(rename(*listp, new_filename) != 0){
- slapi_log_err(SLAPI_LOG_ERR, "checkpoint_threadmain", "Failed to rename log (%s) to (%s)\n",
- *listp, new_filename);
- rval = -1;
- goto error_return;
- }
- }
- }
- slapi_ch_free((void**)&list);
- /* Note: references inside the returned memory need not be
- * individually freed. */
- }
}
slapi_log_err(SLAPI_LOG_TRACE, "checkpoint_threadmain", "Check point before leaving\n");
rval = dblayer_force_checkpoint(li);
diff --git a/ldap/servers/slapd/back-ldbm/idl_new.c b/ldap/servers/slapd/back-ldbm/idl_new.c
index 1ffdc03..0c680aa 100644
--- a/ldap/servers/slapd/back-ldbm/idl_new.c
+++ b/ldap/servers/slapd/back-ldbm/idl_new.c
@@ -325,7 +325,7 @@ idl_new_range_fetch(
int *flag_err,
int allidslimit,
int sizelimit,
- time_t stoptime,
+ struct timespec *expire_time,
int lookthrough_limit,
int operator
)
@@ -344,7 +344,6 @@ idl_new_range_fetch(
DBT dataret;
back_txn s_txn;
struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private;
- time_t curtime;
void *saved_key = NULL;
int coreop = operator & SLAPI_OP_RANGE;
ID key = 0xff; /* random- to suppress compiler warning */
@@ -436,14 +435,15 @@ idl_new_range_fetch(
}
}
/* timelimit check */
- if (stoptime > 0) { /* timelimit is set */
- curtime = current_time();
- if (curtime >= stoptime) {
- slapi_log_err(SLAPI_LOG_TRACE,
- "idl_new_range_fetch", "timelimit exceeded\n");
- *flag_err = LDAP_TIMELIMIT_EXCEEDED;
- goto error;
- }
+ /*
+ * A future improvement could be to check this only every X iterations
+ * to prevent overwhelming the clock?
+ */
+ if (slapi_timespec_expire_check(expire_time) == TIMER_EXPIRED) {
+ slapi_log_err(SLAPI_LOG_TRACE,
+ "idl_new_range_fetch", "timelimit exceeded\n");
+ *flag_err = LDAP_TIMELIMIT_EXCEEDED;
+ goto error;
}
if (operator & SLAPI_OP_RANGE_NO_IDL_SORT) {
key = (ID)strtol((char *)cur_key.data+1 , (char **)NULL, 10);
diff --git a/ldap/servers/slapd/back-ldbm/import-merge.c b/ldap/servers/slapd/back-ldbm/import-merge.c
index b657507..385494d 100644
--- a/ldap/servers/slapd/back-ldbm/import-merge.c
+++ b/ldap/servers/slapd/back-ldbm/import-merge.c
@@ -647,7 +647,7 @@ int import_mega_merge(ImportJob *job)
passes, (long unsigned int)job->number_indexers);
}

- time(&beginning);
+ beginning = slapi_current_utc_time();
/* Iterate over the files */
for (current_worker = job->worker_list;
(ret == 0) && (current_worker != NULL);
@@ -660,9 +660,9 @@ int import_mega_merge(ImportJob *job)
time_t file_end = 0;
int key_count = 0;

- time(&file_beginning);
+ file_beginning = slapi_current_utc_time();
ret = import_merge_one_file(current_worker,passes,&key_count);
- time(&file_end);
+ file_end = slapi_current_utc_time();
if (key_count == 0) {
import_log_notice(job, SLAPI_LOG_INFO, "import_mega_merge", "No files to merge for \"%s\".",
current_worker->index_info->name);
@@ -679,12 +679,11 @@ int import_mega_merge(ImportJob *job)
}
}

- time(&end);
+ end = slapi_current_utc_time();
if (0 == ret) {
int seconds_to_merge = end - beginning;
-
- import_log_notice(job, SLAPI_LOG_INFO, "import_mega_merge", "Merging completed in %d seconds.",
- seconds_to_merge);
+ import_log_notice(job, SLAPI_LOG_INFO, "import_mega_merge", "Merging completed in %d seconds.",
+ seconds_to_merge);
}

return ret;
diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c
index c45a358..f2fe50d 100644
--- a/ldap/servers/slapd/back-ldbm/import-threads.c
+++ b/ldap/servers/slapd/back-ldbm/import-threads.c
@@ -295,11 +295,9 @@ import_get_version(char *str)
static void
import_add_created_attrs(Slapi_Entry *e)
{
- char buf[20];
+ char buf[SLAPI_TIMESTAMP_BUFSIZE];
struct berval bv;
struct berval *bvals[2];
- time_t curtime;
- struct tm ltm;

bvals[0] = &bv;
bvals[1] = NULL;
@@ -313,9 +311,7 @@ import_add_created_attrs(Slapi_Entry *e)
slapi_entry_attr_replace(e, "modifiersname", bvals);
}

- curtime = current_time();
- gmtime_r(&curtime, &ltm);
- strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &ltm);
+ slapi_timestamp_utc_hr(buf, SLAPI_TIMESTAMP_BUFSIZE);

bv.bv_val = buf;
bv.bv_len = strlen(bv.bv_val);
diff --git a/ldap/servers/slapd/back-ldbm/import.c b/ldap/servers/slapd/back-ldbm/import.c
index 3839337..f035a71 100644
--- a/ldap/servers/slapd/back-ldbm/import.c
+++ b/ldap/servers/slapd/back-ldbm/import.c
@@ -761,7 +761,7 @@ static int import_monitor_threads(ImportJob *job, int *status)
goto error_abort;
}

- time(&last_time);
+ last_time = slapi_current_utc_time();
job->start_time = last_time;
import_clear_progress_history(job);

@@ -773,7 +773,7 @@ static int import_monitor_threads(ImportJob *job, int *status)

/* First calculate the time interval since last reported */
if (0 == (count % display_interval)) {
- time(&time_now);
+ time_now = slapi_current_utc_time();
time_interval = time_now - last_time;
last_time = time_now;
/* Now calculate our rate of progress overall for this chunk */
@@ -1212,7 +1212,7 @@ int import_main_offline(void *arg)
opstr = "Reindexing";
}
PR_ASSERT(inst != NULL);
- time(&beginning);
+ beginning = slapi_current_utc_time();

/* Decide which indexes are needed */
if (job->flags & FLAG_INDEX_ATTRS) {
@@ -1496,7 +1496,7 @@ error:
if (!(job->flags & FLAG_ONLINE))
dblayer_close(job->inst->inst_li, DBLAYER_IMPORT_MODE);

- time(&end);
+ end = slapi_current_utc_time();
if (verbose && (0 == ret)) {
int seconds_to_import = end - beginning;
size_t entries_processed = job->lead_ID - (job->starting_ID - 1);
diff --git a/ldap/servers/slapd/back-ldbm/index.c b/ldap/servers/slapd/back-ldbm/index.c
index 4d74484..2ba82d2 100644
--- a/ldap/servers/slapd/back-ldbm/index.c
+++ b/ldap/servers/slapd/back-ldbm/index.c
@@ -1227,7 +1227,7 @@ index_range_read_ext(
int lookthrough_limit = -1; /* default no limit */
int is_and = 0;
int sizelimit = 0;
- time_t curtime, stoptime = 0;
+ struct timespec expire_time;
int timelimit = -1;
back_search_result_set *sr = NULL;
int isroot = 0;
@@ -1252,11 +1252,9 @@ index_range_read_ext(
slapi_pblock_get(pb, SLAPI_SEARCH_SIZELIMIT, &sizelimit);
}
slapi_pblock_get(pb, SLAPI_SEARCH_TIMELIMIT, &timelimit);
- if (timelimit != -1) {
- time_t optime;
- slapi_pblock_get(pb, SLAPI_OPINITIATED_TIME, &optime);
- stoptime = optime + timelimit;
- }
+ Slapi_Operation *op;
+ slapi_pblock_get( pb, SLAPI_OPERATION, &op );
+ slapi_operation_time_expiry(op, (time_t)timelimit, &expire_time);

/*
* Determine the lookthrough_limit from the PBlock.
@@ -1472,7 +1470,7 @@ index_range_read_ext(
}
if (idl_get_idl_new()) { /* new idl */
idl = idl_new_range_fetch(be, db, &cur_key, &upperkey, db_txn,
- ai, err, allidslimit, sizelimit, stoptime,
+ ai, err, allidslimit, sizelimit, &expire_time,
lookthrough_limit, operator);
} else { /* old idl */
int retry_count = 0;
@@ -1509,14 +1507,11 @@ index_range_read_ext(
}
}
/* check time limit */
- if (timelimit != -1) {
- curtime = current_time();
- if (curtime >= stoptime) {
- slapi_log_err(SLAPI_LOG_TRACE,
- "index_range_read_ext", "timelimit exceeded\n");
- *err = LDAP_TIMELIMIT_EXCEEDED;
- break;
- }
+ if (slapi_timespec_expire_check(&expire_time) == TIMER_EXPIRED) {
+ slapi_log_err(SLAPI_LOG_TRACE,
+ "index_range_read_ext", "timelimit exceeded\n");
+ *err = LDAP_TIMELIMIT_EXCEEDED;
+ break;
}
/* Check to see if the operation has been abandoned (also happens
* when the connection is closed by the client).
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c
index 3b3b5b2..5ce4cf3 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_search.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c
@@ -603,7 +603,7 @@ ldbm_back_search( Slapi_PBlock *pb )
}
else
{
- time_t time_up= 0;
+ struct timespec expire_time = {0};
int lookthrough_limit = 0;
struct vlv_response vlv_response_control;
int abandoned= 0;
@@ -670,16 +670,10 @@ ldbm_back_search( Slapi_PBlock *pb )
*/
if (sort && (NULL != candidates))
{
- time_t optime = 0;
int tlimit = 0;

slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &tlimit );
- slapi_pblock_get( pb, SLAPI_OPINITIATED_TIME, &optime );
- /*
- * (tlimit==-1) means no time limit
- */
- time_up = (tlimit==-1 ? -1 : optime + tlimit);
-
+ slapi_operation_time_expiry(operation, (time_t)tlimit, &expire_time);
lookthrough_limit = compute_lookthrough_limit( pb, li );
}

@@ -695,7 +689,7 @@ ldbm_back_search( Slapi_PBlock *pb )
if (filter) {
rc = vlv_filter_candidates(be, pb, candidates, basesdn,
scope, filter, &idl,
- lookthrough_limit, time_up);
+ lookthrough_limit, &expire_time);
}
switch (rc) {
case LDAP_SUCCESS: /* Everything OK */
@@ -761,7 +755,7 @@ ldbm_back_search( Slapi_PBlock *pb )
sort_log_access(pb,sort_control,candidates);
}
sort_return_value = sort_candidates( be, lookthrough_limit,
- time_up, pb, candidates,
+ &expire_time, pb, candidates,
sort_control,
&sort_error_type );
/* Fix for bugid # 394184, SD, 20 Jul 00 */
@@ -1426,7 +1420,7 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
ID id;
struct backentry *e;
int nentries;
- time_t curtime, stoptime, optime;
+ struct timespec expire_time;
int tlimit, llimit, slimit, isroot;
struct berval **urls = NULL;
int err;
@@ -1458,7 +1452,6 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
slapi_pblock_get( pb, SLAPI_NENTRIES, &nentries );
slapi_pblock_get( pb, SLAPI_SEARCH_SIZELIMIT, &slimit );
slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &tlimit );
- slapi_pblock_get( pb, SLAPI_OPINITIATED_TIME, &optime );
slapi_pblock_get( pb, SLAPI_REQUESTOR_ISROOT, &isroot );
slapi_pblock_get( pb, SLAPI_SEARCH_REFERRALS, &urls );
slapi_pblock_get( pb, SLAPI_TARGET_UNIQUEID, &target_uniqueid );
@@ -1528,7 +1521,7 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
sr->sr_vlventry = NULL;
}

- stoptime = optime + tlimit;
+ slapi_operation_time_expiry(op, (time_t)tlimit, &expire_time);
llimit = sr->sr_lookthroughlimit;

/* Find the next candidate entry and return it. */
@@ -1548,10 +1541,12 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
goto bail;
}

+ /*
+ * Check this only every few iters to prevent smashing the clock api?
+ */
/* check time limit */
- curtime = current_time();
- if ( tlimit != -1 && curtime > stoptime )
- {
+ if (slapi_timespec_expire_check(&expire_time) == TIMER_EXPIRED) {
+ slapi_log_err(SLAPI_LOG_TRACE, "ldbm_back_next_search_entry_ext", "LDAP_TIMELIMIT_EXCEEDED\n");
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate );
if ( use_extension ) {
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY_EXT, NULL );
@@ -1562,7 +1557,6 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
slapi_send_ldap_result( pb, LDAP_TIMELIMIT_EXCEEDED, NULL, NULL, nentries, urls );
goto bail;
}
-
/* check lookthrough limit */
if ( llimit != -1 && sr->sr_lookthroughcount >= llimit )
{
@@ -1576,7 +1570,7 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
slapi_send_ldap_result( pb, LDAP_ADMINLIMIT_EXCEEDED, NULL, NULL, nentries, urls );
goto bail;
}
-
+
/*
* Get the entry ID
*/
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index 6d897ed..641fcde 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -2865,7 +2865,7 @@ int ldbm_back_upgradedb(Slapi_PBlock *pb)
{
if (PR_FILE_DIRECTORY == info.type) /* directory exists */
{
- time_t tm = time(0); /* long */
+ time_t tm = slapi_current_utc_time();

char *tmpname = slapi_ch_smprintf("%s/%ld", dest_dir, tm);
dest_dir = tmpname;
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
index ca2ff7b..1fc8c08 100644
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
@@ -278,7 +278,7 @@ int idl_new_compare_dups(
);
IDList *idl_new_range_fetch(backend *be, DB* db, DBT *lowerkey, DBT *upperkey,
DB_TXN *txn, struct attrinfo *a, int *flag_err,
- int allidslimit, int sizelimit, time_t stoptime,
+ int allidslimit, int sizelimit, struct timespec *expire_time,
int lookthrough_limit, int operator);

/*
@@ -451,7 +451,7 @@ typedef struct sort_spec_thing sort_spec_thing;
typedef struct sort_spec_thing sort_spec;

void sort_spec_free(sort_spec *s);
-int sort_candidates(backend *be, int lookthrough_limit, time_t time_up, Slapi_PBlock *pb, IDList *candidates, sort_spec_thing *sort_spec, char **sort_error_type) ;
+int sort_candidates(backend *be, int lookthrough_limit, struct timespec *expire_time, Slapi_PBlock *pb, IDList *candidates, sort_spec_thing *sort_spec, char **sort_error_type) ;
int make_sort_response_control ( Slapi_PBlock *pb, int code, char *error_type);
int parse_sort_spec(struct berval *sort_spec_ber, sort_spec **ps);
struct berval* attr_value_lowest(struct berval **values, value_compare_fn_type compare_fn);
@@ -541,7 +541,7 @@ int vlv_search_build_candidate_list(Slapi_PBlock *pb, const Slapi_DN *base, int
const struct vlv_request *vlv_request_control, IDList** candidates, struct vlv_response *vlv_response_control);
int vlv_update_index(struct vlvIndex* p, back_txn *txn, struct ldbminfo *li, Slapi_PBlock *pb, struct backentry* oldEntry, struct backentry* newEntry);
int vlv_update_all_indexes(back_txn *txn, backend *be, Slapi_PBlock *pb, struct backentry* oldEntry, struct backentry* newEntry);
-int vlv_filter_candidates(backend *be, Slapi_PBlock *pb, const IDList *candidates, const Slapi_DN *base, int scope, Slapi_Filter *filter, IDList** filteredCandidates,int lookthrough_limit, time_t time_up);
+int vlv_filter_candidates(backend *be, Slapi_PBlock *pb, const IDList *candidates, const Slapi_DN *base, int scope, Slapi_Filter *filter, IDList** filteredCandidates,int lookthrough_limit, struct timespec *expire_time);
int vlv_trim_candidates_txn(backend *be, const IDList *candidates, const sort_spec* sort_control, const struct vlv_request *vlv_request_control, IDList** filteredCandidates,struct vlv_response *pResponse, back_txn *txn);
int vlv_trim_candidates(backend *be, const IDList *candidates, const sort_spec* sort_control, const struct vlv_request *vlv_request_control, IDList** filteredCandidates,struct vlv_response *pResponse);
int vlv_parse_request_control(backend *be, struct berval *vlv_spec_ber, struct vlv_request* vlvp);
diff --git a/ldap/servers/slapd/back-ldbm/sort.c b/ldap/servers/slapd/back-ldbm/sort.c
index 0650472..3b7221a 100644
--- a/ldap/servers/slapd/back-ldbm/sort.c
+++ b/ldap/servers/slapd/back-ldbm/sort.c
@@ -21,7 +21,7 @@
struct baggage_carrier {
backend *be; /* For id2entry */
Slapi_PBlock *pb; /* For slapi_op_abandoned */
- time_t stoptime; /* For timelimit policing */
+ struct timespec *expire_time;
int lookthrough_limit;
int check_counter; /* Used to avoid checking every 100ns */
};
@@ -137,7 +137,7 @@ void sort_log_access(Slapi_PBlock *pb,sort_spec_thing *s,IDList *candidates)
* Plan C: We determine that sorting these suckers is
* far too hard for us to even try, so we refuse.
*/
-int sort_candidates(backend *be,int lookthrough_limit,time_t time_up, Slapi_PBlock *pb,
+int sort_candidates(backend *be,int lookthrough_limit, struct timespec *expire_time, Slapi_PBlock *pb,
IDList *candidates, sort_spec_thing *s, char **sort_error_type)
{
int return_value = LDAP_SUCCESS;
@@ -185,7 +185,7 @@ int sort_candidates(backend *be,int lookthrough_limit,time_t time_up, Slapi_PBlo

bc.be = be;
bc.pb = pb;
- bc.stoptime = time_up;
+ bc.expire_time = expire_time;
bc.lookthrough_limit = lookthrough_limit;
bc.check_counter = 1;

@@ -580,7 +580,6 @@ static int compare_entries_sv(ID *id_a, ID *id_b, sort_spec *s,baggage_carrier *
*/
static int sort_check(baggage_carrier *bc)
{
- time_t curtime = 0;
/* check for abandon */
if ( slapi_op_abandoned( bc->pb)) {
return LDAP_OTHER;
@@ -590,9 +589,8 @@ static int sort_check(baggage_carrier *bc)

if (0 == ((bc->check_counter)++ % CHECK_INTERVAL) ) {

- /* check time limit */
- curtime = current_time();
- if ( bc->stoptime != -1 && curtime > bc->stoptime ) {
+ if (slapi_timespec_expire_check(bc->expire_time) == TIMER_EXPIRED) {
+ slapi_log_err(SLAPI_LOG_TRACE, "sort_check", "LDAP_TIMELIMIT_EXCEEDED\n");
return LDAP_TIMELIMIT_EXCEEDED;
}

diff --git a/ldap/servers/slapd/back-ldbm/vlv.c b/ldap/servers/slapd/back-ldbm/vlv.c
index 37cf25d..a299341 100644
--- a/ldap/servers/slapd/back-ldbm/vlv.c
+++ b/ldap/servers/slapd/back-ldbm/vlv.c
@@ -1355,7 +1355,7 @@ vlv_build_candidate_list( backend *be, struct vlvIndex* p, const struct vlv_requ
* other (80)
*/
int
-vlv_filter_candidates(backend *be, Slapi_PBlock *pb, const IDList *candidates, const Slapi_DN *base, int scope, Slapi_Filter *filter, IDList** filteredCandidates, int lookthrough_limit, time_t time_up)
+vlv_filter_candidates(backend *be, Slapi_PBlock *pb, const IDList *candidates, const Slapi_DN *base, int scope, Slapi_Filter *filter, IDList** filteredCandidates, int lookthrough_limit, struct timespec *expire_time)
{
IDList* resultIdl= NULL;
int return_value = LDAP_SUCCESS;
@@ -1424,12 +1424,20 @@ vlv_filter_candidates(backend *be, Slapi_PBlock *pb, const IDList *candidates, c
if ( counter++ % 10 == 0 )
{
/* check time limit */
+#ifdef HAVE_CLOCK_GETTIME
+ if (slapi_timespec_expire_check(expire_time) == TIMER_EXPIRED) {
+ slapi_log_err(SLAPI_LOG_TRACE, "vlv_filter_candidates", "LDAP_TIMELIMIT_EXCEEDED\n");
+ return_value= LDAP_TIMELIMIT_EXCEEDED;
+ done= 1;
+ }
+#else
time_t curtime = current_time();
if ( time_up != -1 && curtime > time_up )
{
return_value= LDAP_TIMELIMIT_EXCEEDED;
done= 1;
}
+

No comments:

Post a Comment