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(a)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, <m);
- strftime(buf, sizeof (buf), "%Y%m%d%H%M%SZ", <m);
+
+ 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, <m);
- strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", <m);
+ 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_APIRefere...
+ * "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, <m);
- strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", <m);
+ 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;
}
+#endif
/* check lookthrough limit */
if ( lookthrough_limit != -1 && lookedat>lookthrough_limit )
{
diff --git a/ldap/servers/slapd/back-ldbm/vlv_srch.c
b/ldap/servers/slapd/back-ldbm/vlv_srch.c
index 5bdf4f7..3f3b00a 100644
--- a/ldap/servers/slapd/back-ldbm/vlv_srch.c
+++ b/ldap/servers/slapd/back-ldbm/vlv_srch.c
@@ -289,10 +289,10 @@ struct vlvIndex*
vlvSearch_findenabled(backend *be,struct vlvSearch* plist, const Slapi_DN *base, int
scope, const char *filter, const sort_spec* sort_control)
{
struct vlvSearch *t= plist;
- struct vlvIndex *pi= NULL;
+ struct vlvIndex *pi= NULL;
for(; (t!=NULL) && (pi == NULL); t= t->vlv_next)
{
- pi= vlvSearch_equal(t,base,scope,filter,sort_control);
+ pi= vlvSearch_equal(t,base,scope,filter,sort_control);
if(pi!=NULL)
{
if(!vlvIndex_enabled(pi))
@@ -302,11 +302,9 @@ vlvSearch_findenabled(backend *be,struct vlvSearch* plist, const
Slapi_DN *base,
* But it hasn't been enabled yet. Check to see if the
* index is there. But, only check once every 60 seconds.
*/
- time_t curtime = current_time();
- if(curtime>pi->vlv_lastchecked+60)
- {
+ if (slapi_timespec_expire_check(&(pi->vlv_nextcheck)) ==
TIMER_EXPIRED) {
vlvIndex_checkforindex(pi, be);
- pi->vlv_lastchecked= current_time();
+ slapi_timespec_expire_at(60, &(pi->vlv_nextcheck));
}
}
if(!vlvIndex_enabled(pi))
@@ -505,20 +503,9 @@ vlvIndex_new()
struct vlvIndex* p = (struct vlvIndex*)slapi_ch_calloc(1,sizeof(struct vlvIndex));
if(p!=NULL)
{
- p->vlv_sortspec= NULL;
p->vlv_attrinfo= attrinfo_new();
- p->vlv_sortkey= NULL;
- p->vlv_filename= NULL;
- p->vlv_mrpb= NULL;
p->vlv_indexlength_lock= PR_NewLock();
- p->vlv_indexlength_cached= 0;
- p->vlv_indexlength= 0;
p->vlv_online = 1;
- p->vlv_enabled = 0;
- p->vlv_lastchecked= 0;
- p->vlv_uses= 0;
- p->vlv_search= NULL;
- p->vlv_next= NULL;
}
return p;
}
@@ -611,7 +598,7 @@ vlvIndex_init(struct vlvIndex* p, backend *be, struct vlvSearch*
pSearch, const
{
vlvIndex_checkforindex(p, be);
}
- p->vlv_lastchecked= current_time();
+ slapi_timespec_expire_at(60, &(p->vlv_nextcheck));
}
slapi_ch_free((void**)&filename);
}
diff --git a/ldap/servers/slapd/back-ldbm/vlv_srch.h
b/ldap/servers/slapd/back-ldbm/vlv_srch.h
index 6322f80..67cc495 100644
--- a/ldap/servers/slapd/back-ldbm/vlv_srch.h
+++ b/ldap/servers/slapd/back-ldbm/vlv_srch.h
@@ -89,7 +89,7 @@ struct vlvIndex
int vlv_online; /* turned off when generating index */
/* The last time we checked to see if the index file was available */
- time_t vlv_lastchecked;
+ struct timespec vlv_nextcheck;
/* The number of uses this search has received since start up */
uint64_t vlv_uses;
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
index ccd70ad..e099e69 100644
--- a/ldap/servers/slapd/connection.c
+++ b/ldap/servers/slapd/connection.c
@@ -415,7 +415,7 @@ connection_reset(Connection* conn, int ns, PRNetAddr * from, int
fromLen __attri
/* initialize the remaining connection fields */
conn->c_ldapversion = LDAP_VERSION3;
- conn->c_starttime = current_time();
+ conn->c_starttime = slapi_current_utc_time();
conn->c_idlesince = conn->c_starttime;
conn->c_flags = is_SSL ? CONN_FLAG_SSL : 0;
conn->c_authtype = slapi_ch_strdup(SLAPD_AUTH_NONE);
@@ -1386,7 +1386,7 @@ void connection_check_activity_level(Connection *conn)
/* store current count in the previous count slot */
conn->c_private->previous_op_count = current_count;
/* update the last checked time */
- conn->c_private->previous_count_check_time = current_time();
+ conn->c_private->previous_count_check_time = slapi_current_utc_time();
PR_ExitMonitor(conn->c_mutex);
slapi_log_err(SLAPI_LOG_CONNS,"connection_check_activity_level", "conn
%" PRIu64 " activity level = %d\n",conn->c_connid,delta_count);
}
@@ -1623,7 +1623,7 @@ connection_threadmain()
conn->c_opsinitiated, conn->c_refcnt, conn->c_flags);
}
- curtime = current_time();
+ curtime = slapi_current_utc_time();
#define DB_PERF_TURBO 1
#if defined(DB_PERF_TURBO)
/* If it's been a while since we last did it ... */
diff --git a/ldap/servers/slapd/conntable.c b/ldap/servers/slapd/conntable.c
index e36b94e..262ba5d 100644
--- a/ldap/servers/slapd/conntable.c
+++ b/ldap/servers/slapd/conntable.c
@@ -390,7 +390,7 @@ connection_table_as_entry(Connection_Table *ct, Slapi_Entry *e)
}
gmtime_r( &ct->c[i].c_starttime, &utm );
- strftime( buf2, sizeof(buf2), "%Y%m%d%H%M%SZ", &utm );
+ strftime( buf2, SLAPI_TIMESTAMP_BUFSIZE, "%Y%m%d%H%M%SZ", &utm );
/*
* Max threads per connection stats
diff --git a/ldap/servers/slapd/csngen.c b/ldap/servers/slapd/csngen.c
index 468979a..3313019 100644
--- a/ldap/servers/slapd/csngen.c
+++ b/ldap/servers/slapd/csngen.c
@@ -69,14 +69,6 @@ struct csngen
/*
* **************************************************************************
- * global data
- * **************************************************************************
- */
-
-static time_t g_sampled_time; /* time obtained from time() call */
-
-/*
- * **************************************************************************
* forward declarations of helper functions
* **************************************************************************
*/
@@ -143,7 +135,7 @@ csngen_new (ReplicaId rid, Slapi_Attr *state)
else
{
/* new generator */
- gen->state.sampled_time = current_time ();
+ gen->state.sampled_time = slapi_current_utc_time();
gen->state.local_offset = 0;
gen->state.remote_offset = 0;
gen->state.seq_num = 0;
@@ -199,13 +191,10 @@ csngen_new_csn (CSNGen *gen, CSN **csn, PRBool notify)
slapi_rwlock_wrlock (gen->lock);
- if (g_sampled_time == 0)
- csngen_update_time ();
-
- cur_time = g_sampled_time;
+ cur_time = slapi_current_utc_time();
/* check if the time should be adjusted */
- delta = cur_time - gen->state.sampled_time;
+ delta = cur_time - gen->state.sampled_time;
if (delta > 0)
{
rc = _csngen_adjust_local_time (gen, cur_time);
@@ -311,8 +300,7 @@ int csngen_adjust_time(CSNGen *gen, const CSN* csn)
gen->state.remote_offset);
}
/* make sure we have the current time */
- csngen_update_time();
- cur_time = g_sampled_time;
+ cur_time = slapi_current_utc_time();
/* make sure sampled_time is current */
/* must only call adjust_local_time if the current time is greater than
@@ -460,13 +448,6 @@ void csngen_unregister_callbacks(CSNGen *gen, void *cookie)
}
}
-/* this functions is periodically called from daemon.c to
- update time used by all generators */
-void csngen_update_time ()
-{
- g_sampled_time = current_time ();
-}
-
/* debugging function */
void csngen_dump_state (const CSNGen *gen)
{
@@ -881,7 +862,9 @@ _csngen_local_tester_main (void *data)
/* sleep for 30 seconds */
DS_Sleep (PR_SecondsToInterval(60));
- g_sampled_time -= slapi_rand () % 100;
+ /*
+ * g_sampled_time -= slapi_rand () % 100;
+ */
csngen_dump_state (gen);
}
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
index 37eb5e7..e6e3836 100644
--- a/ldap/servers/slapd/daemon.c
+++ b/ldap/servers/slapd/daemon.c
@@ -150,7 +150,6 @@ accept_and_configure(int s __attribute__((unused)), PRFileDesc
*pr_acceptfd, PRN
/*
* This is the shiny new re-born daemon function, without all the hair
*/
-/* GGOODREPL static void handle_timeout( void ); */
static int handle_new_connection(Connection_Table *ct, int tcps, PRFileDesc *pr_acceptfd,
int secure, int local, Connection **newconn );
static void ns_handle_new_connection(struct ns_job_t *job);
static void handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll);
@@ -259,23 +258,6 @@ int daemon_pre_setuid_init(daemon_ports_t *ports)
*/
static int time_shutdown = 0;
-void *
-time_thread(void *nothing __attribute__((unused)))
-{
- PRIntervalTime interval;
-
- interval = PR_SecondsToInterval(1);
-
- while(!time_shutdown) {
- poll_current_time();
- csngen_update_time ();
- DS_Sleep(interval);
- }
-
- /*NOTREACHED*/
- return(NULL);
-}
-
/*
* Return a copy of the mount point for the specified directory
*/
@@ -666,7 +648,7 @@ disk_monitoring_thread(void *nothing __attribute__((unused)))
slapi_log_err(SLAPI_LOG_ALERT, "disk_monitoring_thread", "Disk
space on (%s) is too far below the threshold(%" PRIu64 " bytes). "
"Waiting %d minutes for disk space to be cleaned up before shutting
slapd down...\n",
dirstr, threshold, (grace_period / 60));
- time(&start);
+ start = slapi_current_utc_time();
now = start;
while( (now - start) < grace_period ){
if(g_get_shutdown()){
@@ -715,7 +697,7 @@ disk_monitoring_thread(void *nothing __attribute__((unused)))
g_set_shutdown( SLAPI_SHUTDOWN_DISKFULL );
return;
}
- time(&now);
+ now = slapi_current_utc_time();
}
if(ok_now){
@@ -921,7 +903,6 @@ void slapd_daemon( daemon_ports_t *ports, ns_thrpool_t *tp )
PRFileDesc **fdesp = NULL;
PRIntn num_poll = 0;
PRIntervalTime pr_timeout = PR_MillisecondsToInterval(slapd_wakeup_timer);
- PRThread *time_thread_p;
uint64_t threads;
int in_referral_mode = config_check_referral_mode();
int connection_table_size = get_configured_connection_table_size();
@@ -968,20 +949,6 @@ void slapd_daemon( daemon_ports_t *ports, ns_thrpool_t *tp )
init_op_threads();
- /* Start the time thread */
- time_thread_p = PR_CreateThread(PR_SYSTEM_THREAD,
- (VFP) (void *) time_thread, NULL,
- PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
- PR_JOINABLE_THREAD,
- SLAPD_DEFAULT_THREAD_STACKSIZE);
- if ( NULL == time_thread_p ) {
- PRErrorCode errorCode = PR_GetError();
- slapi_log_err(SLAPI_LOG_EMERG, "slapd_daemon", "Unable to create time
thread - Shutting Down ("
- SLAPI_COMPONENT_NAME_NSPR " error %d - %s)\n",
- errorCode, slapd_pr_strerror(errorCode));
- g_set_shutdown( SLAPI_SHUTDOWN_EXIT );
- }
-
/*
* If we are monitoring disk space, then create the mutex, the cvar,
* and the monitoring thread.
@@ -1135,7 +1102,6 @@ void slapd_daemon( daemon_ports_t *ports, ns_thrpool_t *tp )
select_return = POLL_FN(the_connection_table->fd, num_poll, pr_timeout);
switch (select_return) {
case 0: /* Timeout */
- /* GGOODREPL handle_timeout(); */
break;
case -1: /* Error */
prerr = PR_GetError();
@@ -1305,7 +1271,6 @@ void slapd_daemon( daemon_ports_t *ports, ns_thrpool_t *tp )
/* tell the time thread to shutdown and then wait for it */
time_shutdown = 1;
- PR_JoinThread( time_thread_p );
if ( g_get_shutdown() == SLAPI_SHUTDOWN_DISKFULL ){
/* This is a server-induced shutdown, we need to manually remove the pid file */
@@ -1563,38 +1528,6 @@ setup_pr_read_pds(Connection_Table *ct, PRFileDesc **n_tcps,
PRFileDesc **s_tcps
}
-#ifdef notdef /* GGOODREPL */
-static void
-handle_timeout( void )
-{
- static time_t prevtime = 0;
- static time_t housekeeping_fire_time = 0;
- time_t curtime = current_time();
-
- if (0 == prevtime) {
- prevtime = time (&housekeeping_fire_time);
- }
-
- if ( difftime(curtime, prevtime) >=
- slapd_housekeeping_timer ) {
- uint64_t num_active_threads;
-
- snmp_collator_update();
-
- prevtime = curtime;
- num_active_threads = g_get_active_threadcnt();
- if ( (num_active_threads == 0) ||
- (difftime(curtime, housekeeping_fire_time) >=
- slapd_housekeeping_timer*3) ) {
- housekeeping_fire_time = curtime;
- housekeeping_start(curtime);
- }
- }
-
-}
-#endif /* notdef */
-
-
static int idletimeout_reslimit_handle = -1;
/*
@@ -1612,7 +1545,7 @@ static void
handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll __attribute__((unused)))
{
Connection *c;
- time_t curtime = current_time();
+ time_t curtime = slapi_current_utc_time();
int maxthreads = config_get_maxthreadsperconn();
#if LDAP_ERROR_LOGGING
diff --git a/ldap/servers/slapd/eventq.c b/ldap/servers/slapd/eventq.c
index 8c6fca5..64c1d6b 100644
--- a/ldap/servers/slapd/eventq.c
+++ b/ldap/servers/slapd/eventq.c
@@ -202,16 +202,20 @@ slapi_eq_cancel(Slapi_Eq_Context ctx)
static slapi_eq_context *
eq_new(slapi_eq_fn_t fn, void *arg, time_t when, unsigned long interval)
{
- slapi_eq_context *retptr = (slapi_eq_context *)slapi_ch_calloc(1,
sizeof(slapi_eq_context));
- time_t now;
-
- retptr->ec_fn = fn;
- retptr->ec_arg = arg;
- now = current_time();
- retptr->ec_when = when < now ? now : when;
- retptr->ec_interval = interval == 0UL ? 0UL : (interval + 999) / 1000;
- retptr->ec_id = (Slapi_Eq_Context)retptr;
- return retptr;
+ slapi_eq_context *retptr = (slapi_eq_context *)slapi_ch_calloc(1,
sizeof(slapi_eq_context));
+
+ retptr->ec_fn = fn;
+ retptr->ec_arg = arg;
+ /*
+ * retptr->ec_when = when < now ? now : when;
+ * we used to amke this check, but it make no sense: when queued, if when
+ * has expired, we'll be executed anyway. save the cycles, and just set
+ * ec_when.
+ */
+ retptr->ec_when = when;
+ retptr->ec_interval = interval == 0UL ? 0UL : (interval + 999) / 1000;
+ retptr->ec_id = (Slapi_Eq_Context)retptr;
+ return retptr;
}
@@ -277,18 +281,19 @@ static void
eq_call_all(void)
{
slapi_eq_context *p;
+ time_t curtime = slapi_current_utc_time();
- while ((p = eq_dequeue(current_time())) != NULL) {
+ while ((p = eq_dequeue(curtime)) != NULL) {
/* Call the scheduled function */
p->ec_fn(p->ec_when, p->ec_arg);
slapi_log_err(SLAPI_LOG_HOUSE, NULL,
"Event id %p called at %ld (scheduled for %ld)\n",
- p->ec_id, current_time(), p->ec_when);
+ p->ec_id, curtime, p->ec_when);
if (0UL != p->ec_interval) {
/* This is a repeating event. Requeue it. */
do {
p->ec_when += p->ec_interval;
- } while (p->ec_when < current_time());
+ } while (p->ec_when < curtime);
eq_enqueue(p);
} else {
slapi_ch_free((void **)&p);
@@ -302,23 +307,22 @@ eq_call_all(void)
/*
* The main event queue loop.
*/
-#define WORK_AVAILABLE ((NULL != eq->eq_queue) && (eq->eq_queue->ec_when
<= current_time()))
-
static void
eq_loop(void *arg __attribute__((unused)))
{
while (eq_running) {
+ time_t curtime = slapi_current_utc_time();
PRIntervalTime timeout;
int until;
PR_Lock(eq->eq_lock);
- while (!WORK_AVAILABLE) {
+ while (!(NULL != eq->eq_queue) && (eq->eq_queue->ec_when <=
curtime)) {
if (!eq_running) {
PR_Unlock(eq->eq_lock);
goto bye;
}
/* Compute new timeout */
if (NULL != eq->eq_queue) {
- until = eq->eq_queue->ec_when - current_time();
+ until = eq->eq_queue->ec_when - curtime;
timeout = PR_SecondsToInterval(until);
} else {
timeout = PR_INTERVAL_NO_TIMEOUT;
diff --git a/ldap/servers/slapd/generation.c b/ldap/servers/slapd/generation.c
index 76dffda..19c4422 100644
--- a/ldap/servers/slapd/generation.c
+++ b/ldap/servers/slapd/generation.c
@@ -25,11 +25,11 @@ new_dataversion(void)
{
struct tm t;
char* dataversion;
- time_t curtime = current_time();
+ time_t curtime = slapi_current_utc_time();
gmtime_r (&curtime, &t);
dataversion = slapi_ch_smprintf("0%.4li%.2i%.2i%.2i%.2i%.2i", 1900L +
t.tm_year, 1 + t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
- return dataversion;
+ return dataversion;
}
/* ---------------- Database Data Version ---------------- */
diff --git a/ldap/servers/slapd/getfilelist.c b/ldap/servers/slapd/getfilelist.c
index 3b3f02f..81ca802 100644
--- a/ldap/servers/slapd/getfilelist.c
+++ b/ldap/servers/slapd/getfilelist.c
@@ -127,7 +127,7 @@ matches(const char *filename, const char *pattern)
re = slapi_re_comp( pattern, &error );
if (re) {
/* Matches the compiled pattern against the filename */
- match = slapi_re_exec( re, filename, -1 /* no time limit */ );
+ match = slapi_re_exec_nt( re, filename);
slapi_re_free( re );
}
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index 77da741..7cff150 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -3078,37 +3078,41 @@ config_set_pw_inhistory( const char *attrname, char *value, char
*errorbuf, int
int
config_set_pw_lockduration( const char *attrname, char *value, char *errorbuf, int apply
) {
- int retVal = LDAP_SUCCESS;
- long duration = 0; /* in minutes */
+ int retVal = LDAP_SUCCESS;
+ time_t duration = 0; /* in seconds */
- slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
-
- if ( config_value_is_null( attrname, value, errorbuf, 0 )) {
- return LDAP_OPERATIONS_ERROR;
- }
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
- errno = 0;
- /* in seconds */
- duration = parse_duration(value);
+ if ( config_value_is_null( attrname, value, errorbuf, 0 )) {
+ return LDAP_OPERATIONS_ERROR;
+ }
- if ( errno == ERANGE || duration <= 0 || duration > (MAX_ALLOWED_TIME_IN_SECS -
current_time()) ) {
- slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "password lockout
duration \"%s\" is invalid. ", value);
- retVal = LDAP_OPERATIONS_ERROR;
- return retVal;
- }
+ errno = 0;
+ /* in seconds */
+ duration = parse_duration_time_t(value);
- if ( apply ) {
- slapdFrontendConfig->pw_policy.pw_lockduration = duration;
- }
-
- return retVal;
+ /*
+ * If the duration set is larger than time_t max - current time, we probably have
+ * made it to the heat death of the universe. Congratulations on finding this bug.
+ */
+ if ( errno == ERANGE || duration <= 0 || duration >
(MAX_ALLOWED_TIME_IN_SECS_64 - slapi_current_utc_time()) ) {
+ slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "password lockout
duration \"%s\" is invalid. ", value);
+ retVal = LDAP_OPERATIONS_ERROR;
+ return retVal;
+ }
+
+ if ( apply ) {
+ slapdFrontendConfig->pw_policy.pw_lockduration = duration;
+ }
+
+ return retVal;
}
int
config_set_pw_resetfailurecount( const char *attrname, char *value, char *errorbuf, int
apply ) {
int retVal = LDAP_SUCCESS;
- long duration = 0; /* in minutes */
+ time_t duration = 0; /* in seconds */
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
@@ -3118,9 +3122,9 @@ config_set_pw_resetfailurecount( const char *attrname, char *value,
char *errorb
errno = 0;
/* in seconds */
- duration = parse_duration(value);
+ duration = parse_duration_time_t(value);
- if ( errno == ERANGE || duration < 0 || duration > (MAX_ALLOWED_TIME_IN_SECS -
current_time()) ) {
+ if ( errno == ERANGE || duration <= 0 || duration > (MAX_ALLOWED_TIME_IN_SECS_64
- slapi_current_utc_time()) ) {
slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "password reset count
duration \"%s\" is invalid. ", value);
retVal = LDAP_OPERATIONS_ERROR;
return retVal;
@@ -4293,7 +4297,7 @@ config_set_auditfaillog( const char *attrname, char *value, char
*errorbuf, int
int
config_set_pw_maxage( const char *attrname, char *value, char *errorbuf, int apply ) {
int retVal = LDAP_SUCCESS;
- long long age;
+ time_t age = 0;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
@@ -4303,15 +4307,9 @@ config_set_pw_maxage( const char *attrname, char *value, char
*errorbuf, int app
errno = 0;
/* age in seconds */
- age = slapi_parse_duration_longlong(value);
+ age = parse_duration_time_t(value);
- if (age <= 0 ||
-#if defined(CPU_x86_64)
- age > (MAX_ALLOWED_TIME_IN_SECS_64 - current_time())
-#else
- age > (MAX_ALLOWED_TIME_IN_SECS - current_time())
-#endif
- ) {
+ if (age <= 0 || age > (MAX_ALLOWED_TIME_IN_SECS_64 - slapi_current_utc_time()) )
{
slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "%s: password maximum
age \"%s\" is invalid.", attrname, value);
retVal = LDAP_OPERATIONS_ERROR;
return retVal;
@@ -4326,7 +4324,7 @@ config_set_pw_maxage( const char *attrname, char *value, char
*errorbuf, int app
int
config_set_pw_minage( const char *attrname, char *value, char *errorbuf, int apply ) {
int retVal = LDAP_SUCCESS;
- long long age;
+ time_t age = 0;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
if ( config_value_is_null( attrname, value, errorbuf, 1 )) {
@@ -4335,14 +4333,8 @@ config_set_pw_minage( const char *attrname, char *value, char
*errorbuf, int app
errno = 0;
/* age in seconds */
- age = slapi_parse_duration_longlong(value);
- if (age < 0 ||
-#if defined(CPU_x86_64)
- age > (MAX_ALLOWED_TIME_IN_SECS_64 - current_time())
-#else
- age > (MAX_ALLOWED_TIME_IN_SECS - current_time())
-#endif
- ) {
+ age = parse_duration_time_t(value);
+ if (age < 0 || age > (MAX_ALLOWED_TIME_IN_SECS_64 - slapi_current_utc_time()) )
{
slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "%s: password minimum
age \"%s\" is invalid.", attrname, value);
retVal = LDAP_OPERATIONS_ERROR;
return retVal;
@@ -4357,7 +4349,7 @@ config_set_pw_minage( const char *attrname, char *value, char
*errorbuf, int app
int
config_set_pw_warning( const char *attrname, char *value, char *errorbuf, int apply ) {
int retVal = LDAP_SUCCESS;
- long long sec;
+ time_t sec;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
@@ -4367,7 +4359,7 @@ config_set_pw_warning( const char *attrname, char *value, char
*errorbuf, int ap
errno = 0;
/* in seconds */
- sec = slapi_parse_duration_longlong(value);
+ sec = parse_duration_time_t(value);
if (errno == ERANGE || sec < 0) {
slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c
index 3b4e672..922616f 100644
--- a/ldap/servers/slapd/log.c
+++ b/ldap/servers/slapd/log.c
@@ -2265,7 +2265,7 @@ vslapd_log_emergency_error(LOGFD fp, const char *msg, int locked)
} else {
#endif
time_t tnl;
- tnl = current_time();
+ tnl = slapi_current_utc_time();
if (format_localTime_log(tnl, sizeof(tbuf), tbuf, &size) != 0) {
syslog(LOG_EMERG, "vslapd_log_emergency_error, Unable to format system
time for message :: %s", msg);
return;
@@ -2353,7 +2353,7 @@ vslapd_log_error(
} else {
#endif
time_t tnl;
- tnl = current_time();
+ tnl = slapi_current_utc_time();
if (format_localTime_log(tnl, sizeof(buffer), buffer, &blen) != 0) {
PR_snprintf(buffer, sizeof(buffer), "vslapd_log_error, Unable to format
system time for message :: %s", vbuf);
log__error_emergency(buffer, 1 ,locked);
@@ -2543,7 +2543,7 @@ static int vslapd_log_access(char *fmt, va_list ap)
}
} else {
#endif
- tnl = current_time();
+ tnl = slapi_current_utc_time();
if (format_localTime_log(tnl, sizeof(buffer), buffer, &blen) != 0) {
/* MSG may be truncated */
PR_snprintf(buffer, sizeof(buffer), "vslapd_log_access, Unable to format
system time for message :: %s", vbuf);
@@ -2760,7 +2760,7 @@ log__open_accesslogfile(int logfile_state, int locked)
/* write the header in the log */
- now = current_time();
+ now = slapi_current_utc_time();
log_convert_time (now, tbuf, 2 /* long */);
PR_snprintf (buffer,sizeof(buffer),"LOGINFO:Log file created at: %s (%lu)\n",
tbuf, now);
LOG_WRITE(fpinfo, buffer, strlen(buffer), 0);
@@ -4627,7 +4627,7 @@ log__open_errorlogfile(int logfile_state, int locked)
}
/* write the header in the log */
- now = current_time();
+ now = slapi_current_utc_time();
log_convert_time (now, tbuf, 2 /*long */);
PR_snprintf(buffer, sizeof(buffer),"LOGINFO:Log file created at: %s (%lu)\n",
tbuf, now);
LOG_WRITE(fpinfo, buffer, strlen(buffer), 0);
@@ -4754,7 +4754,7 @@ log__open_auditlogfile(int logfile_state, int locked)
}
/* write the header in the log */
- now = current_time();
+ now = slapi_current_utc_time();
log_convert_time (now, tbuf, 2 /*long */);
PR_snprintf(buffer, sizeof(buffer), "LOGINFO:Log file created at: %s (%lu)\n",
tbuf, now);
LOG_WRITE(fpinfo, buffer, strlen(buffer), 0);
@@ -4880,7 +4880,7 @@ log__open_auditfaillogfile(int logfile_state, int locked)
}
/* write the header in the log */
- now = current_time();
+ now = slapi_current_utc_time();
log_convert_time (now, tbuf, 2 /*long */);
PR_snprintf(buffer, sizeof(buffer), "LOGINFO:Log file created at: %s
(%lu)\n", tbuf, now);
LOG_WRITE(fpinfo, buffer, strlen(buffer), 0);
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
index 252144f..be09217 100644
--- a/ldap/servers/slapd/main.c
+++ b/ldap/servers/slapd/main.c
@@ -1177,7 +1177,7 @@ main( int argc, char **argv)
}
{
- time( &starttime );
+ starttime = slapi_current_utc_time();
slapd_daemon(&ports_info, tp);
}
slapi_log_err(SLAPI_LOG_INFO, "main", "slapd stopped.\n");
diff --git a/ldap/servers/slapd/monitor.c b/ldap/servers/slapd/monitor.c
index 2271bfa..11d5138 100644
--- a/ldap/servers/slapd/monitor.c
+++ b/ldap/servers/slapd/monitor.c
@@ -45,7 +45,7 @@ monitor_info(Slapi_PBlock *pb __attribute__((unused)),
char buf[BUFSIZ];
struct berval val;
struct berval *vals[2];
- time_t curtime = current_time();
+ time_t curtime = slapi_current_utc_time();
struct tm utm;
Slapi_Backend *be;
char *cookie;
diff --git a/ldap/servers/slapd/operation.c b/ldap/servers/slapd/operation.c
index 3725b9f..0eb4c48 100644
--- a/ldap/servers/slapd/operation.c
+++ b/ldap/servers/slapd/operation.c
@@ -160,17 +160,13 @@ operation_init(Slapi_Operation *o, int flags)
slapi_sdn_init(&(o->o_sdn));
o->o_authtype = NULL;
o->o_isroot = 0;
- o->o_time = current_time();
+ clock_gettime(CLOCK_MONOTONIC, &(o->o_hr_time_rel));
+ clock_gettime(CLOCK_REALTIME, &(o->o_hr_time_utc));
o->o_opid = 0;
o->o_connid = 0;
o->o_next = NULL;
o->o_flags= flags;
o->o_reverse_search_state = 0;
- if ( config_get_accesslog_level() & LDAP_DEBUG_TIMING ) {
- o->o_interval = PR_IntervalNow();
- } else {
- o->o_interval = (PRIntervalTime)0;
- }
o->o_pagedresults_sizelimit = -1;
}
@@ -634,3 +630,23 @@ slapi_connection_remove_operation( Slapi_PBlock *pb
__attribute__((unused)), Sla
PR_ExitMonitor(conn->c_mutex);
return (rc);
}
+
+void
+slapi_operation_time_elapsed(Slapi_Operation *o, struct timespec *elapsed) {
+ struct timespec o_hr_time_now;
+ clock_gettime(CLOCK_MONOTONIC, &o_hr_time_now);
+
+ slapi_timespec_diff(&o_hr_time_now, &(o->o_hr_time_rel), elapsed);
+}
+
+void
+slapi_operation_time_initiated(Slapi_Operation *o, struct timespec *initiated) {
+ initiated->tv_sec = o->o_hr_time_utc.tv_sec;
+ initiated->tv_nsec = o->o_hr_time_utc.tv_nsec;
+}
+
+void
+slapi_operation_time_expiry(Slapi_Operation *o, time_t timeout, struct timespec *expiry)
{
+ slapi_timespec_expire_rel(timeout, &(o->o_hr_time_rel), expiry);
+}
+
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
index 133597f..6e1cca4 100644
--- a/ldap/servers/slapd/opshared.c
+++ b/ldap/servers/slapd/opshared.c
@@ -101,13 +101,11 @@ do_ps_service(Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chgtype,
ber_int_t c
void
modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
{
- char buf[20];
+ char buf[SLAPI_TIMESTAMP_BUFSIZE];
char *plugin_dn = NULL;
char *binddn = NULL;
struct berval bv;
struct berval *bvals[2];
- time_t curtime;
- struct tm utm;
Operation *op;
struct slapdplugin *plugin = NULL;
struct slapi_componentid *cid = NULL;
@@ -171,9 +169,8 @@ modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
"modifiersname", bvals);
/* fill in modifytimestamp */
- curtime = current_time();
- gmtime_r(&curtime, &utm);
- strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &utm);
+ slapi_timestamp_utc_hr(buf, SLAPI_TIMESTAMP_BUFSIZE);
+
bv.bv_val = buf;
bv.bv_len = strlen(bv.bv_val);
slapi_mods_add_modbvps(smods, LDAP_MOD_REPLACE | LDAP_MOD_BVALUES,
@@ -548,12 +545,9 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
/* set the timelimit to clean up the too-long-lived-paged results requests */
if (op_is_pagedresults(operation)) {
- time_t optime, time_up;
- int tlimit;
+ int32_t tlimit;
slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &tlimit );
- slapi_pblock_get( pb, SLAPI_OPINITIATED_TIME, &optime );
- time_up = (tlimit==-1 ? -1 : optime + tlimit); /* -1: no time limit */
- pagedresults_set_timelimit(pb_conn, operation, time_up, pr_idx);
+ pagedresults_set_timelimit(pb_conn, operation, (time_t)tlimit, pr_idx);
}
/*
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
index 673019a..7ae1b85 100644
--- a/ldap/servers/slapd/pagedresults.c
+++ b/ldap/servers/slapd/pagedresults.c
@@ -58,7 +58,6 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
Operation *op = NULL;
BerElement *ber = NULL;
PagedResults *prp = NULL;
- time_t ctime = current_time();
int i;
int maxreqs = config_get_maxsimplepaged_per_conn();
@@ -131,7 +130,7 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
prp->pr_current_be = be;
*index = i;
break;
- } else if (((prp->pr_timelimit > 0) && (ctime >
prp->pr_timelimit)) || /* timelimit exceeded */
+ } else if ( slapi_timespec_expire_check(&(prp->pr_timelimit_hr))
== TIMER_EXPIRED || /* timelimit exceeded */
(prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED) /*
abandoned */) {
_pr_cleanup_one_slot(prp);
conn->c_pagedresults.prl_count--;
@@ -198,7 +197,7 @@ bail:
prp = conn->c_pagedresults.prl_list;
for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++, prp++) {
if (prp->pr_current_be &&
- (((prp->pr_timelimit > 0) && (ctime > prp->pr_timelimit))
|| /* timelimit exceeded */
+ (slapi_timespec_expire_check(&(prp->pr_timelimit_hr)) == TIMER_EXPIRED
|| /* timelimit exceeded */
(prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED)) /* abandoned */)
{
_pr_cleanup_one_slot(prp);
conn->c_pagedresults.prl_count--;
@@ -698,7 +697,7 @@ pagedresults_set_timelimit(Connection *conn, Operation *op,
if (conn && (index > -1)) {
PR_EnterMonitor(conn->c_mutex);
if (index < conn->c_pagedresults.prl_maxlen) {
- conn->c_pagedresults.prl_list[index].pr_timelimit = timelimit;
+ slapi_timespec_expire_at(timelimit,
&(conn->c_pagedresults.prl_list[index].pr_timelimit_hr));
}
PR_ExitMonitor(conn->c_mutex);
rc = 0;
@@ -899,7 +898,6 @@ int
pagedresults_is_timedout_nolock(Connection *conn)
{
PagedResults *prp = NULL;
- time_t ctime;
slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_is_timedout",
"=>\n");
@@ -908,14 +906,11 @@ pagedresults_is_timedout_nolock(Connection *conn)
return 0;
}
- ctime = current_time();
prp = conn->c_pagedresults.prl_list;
if (prp && (1 == conn->c_pagedresults.prl_maxlen)) {
- if (prp->pr_current_be && (prp->pr_timelimit > 0)) {
- if (ctime > prp->pr_timelimit) {
- slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_is_timedout",
"<= true\n");
- return 1;
- }
+ if (slapi_timespec_expire_check(&(prp->pr_timelimit_hr)) == TIMER_EXPIRED)
{
+ slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_is_timedout",
"<= true\n");
+ return 1;
}
}
slapi_log_err(SLAPI_LOG_TRACE, "<-- pagedresults_is_timedout",
"<= false 2\n");
@@ -939,7 +934,8 @@ pagedresults_reset_timedout_nolock(Connection *conn)
for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) {
prp = conn->c_pagedresults.prl_list + i;
- prp->pr_timelimit = 0;
+ prp->pr_timelimit_hr.tv_sec = 0;
+ prp->pr_timelimit_hr.tv_nsec = 0;
}
slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_reset_timedout",
"<=\n");
return 0;
diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c
index 69fdd70..429329a 100644
--- a/ldap/servers/slapd/pblock.c
+++ b/ldap/servers/slapd/pblock.c
@@ -581,7 +581,7 @@ int slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) {
"slapi_pblock_get", "Operation is NULL and hence
cannot access SLAPI_OPINITIATED_TIME \n");
return (-1);
}
- (*(time_t *)value) = pblock->pb_op->o_time;
+ (*(time_t *)value) = pblock->pb_op->o_hr_time_utc.tv_sec;
break;
case SLAPI_REQUESTOR_ISROOT:
if (pblock->pb_intop != NULL) {
@@ -2321,9 +2321,6 @@ int slapi_pblock_set(Slapi_PBlock *pblock, int arg, void *value) {
pblock->pb_op = (Operation *)value;
break;
case SLAPI_OPINITIATED_TIME:
- if (pblock->pb_op != NULL) {
- pblock->pb_op->o_time = *((time_t *)value);
- }
break;
case SLAPI_REQUESTOR_ISROOT:
_pblock_assert_pb_intop(pblock);
diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
index 0ebc448..e75e447 100644
--- a/ldap/servers/slapd/pw.c
+++ b/ldap/servers/slapd/pw.c
@@ -618,7 +618,7 @@ update_pw_info ( Slapi_PBlock *pb , char *old_pw)
internal_op = slapi_operation_is_flag_set(operation, SLAPI_OP_FLAG_INTERNAL);
target_dn = slapi_sdn_get_ndn(sdn);
pwpolicy = new_passwdPolicy(pb, target_dn);
- cur_time = current_time();
+ cur_time = slapi_current_utc_time();
slapi_mods_init(&smods, 0);
if (slapi_entry_attr_hasvalue(e, SLAPI_ATTR_OBJECTCLASS, "shadowAccount")) {
@@ -762,7 +762,7 @@ check_pw_minage ( Slapi_PBlock *pb, const Slapi_DN *sdn, struct berval
**vals __
slapi_ch_free((void **) &passwordAllowChangeTime );
/* check if allow to change the password */
- cur_time_str = format_genTime ( current_time() );
+ cur_time_str = format_genTime ( slapi_current_utc_time() );
if ( difftime ( pw_allowchange_date,
parse_genTime ( cur_time_str )) > 0 )
{
@@ -1205,7 +1205,7 @@ update_pw_history( Slapi_PBlock *pb, const Slapi_DN *sdn, char
*old_pw )
vacnt_todelete = vacnt - pwpolicy->pw_inhistory;
}
- cur_time = current_time();
+ cur_time = slapi_current_utc_time();
str = format_genTime(cur_time);
/* values_replace is sorted. */
if (old_pw) {
@@ -1406,7 +1406,7 @@ add_password_attrs( Slapi_PBlock *pb, Operation *op
__attribute__((unused)), Sla
/* must change password when first time logon */
bv.bv_val = format_genTime ( NO_TIME );
} else if ( pwpolicy->pw_exp ) {
- exptime = time_plus_sec(current_time(), pwpolicy->pw_maxage);
+ exptime = time_plus_sec(slapi_current_utc_time(), pwpolicy->pw_maxage);
bv.bv_val = format_genTime(exptime);
}
bv.bv_len = strlen( bv.bv_val );
@@ -1418,7 +1418,7 @@ add_password_attrs( Slapi_PBlock *pb, Operation *op
__attribute__((unused)), Sla
/* must change password when first time logon */
bv.bv_val = slapi_ch_smprintf("0");
} else {
- exptime = current_time() / _SEC_PER_DAY;
+ exptime = slapi_current_utc_time() / _SEC_PER_DAY;
bv.bv_val = slapi_ch_smprintf("%ld", exptime);
}
bv.bv_len = strlen(bv.bv_val);
@@ -1435,8 +1435,8 @@ add_password_attrs( Slapi_PBlock *pb, Operation *op
__attribute__((unused)), Sla
* the password if we set a passwordallowchangetime in the future.
*/
if ( !has_allowchangetime && pwpolicy->pw_minage != 0 &&
- (has_expirationtime && existing_exptime > current_time()) ) {
- bv.bv_val = format_genTime ( time_plus_sec ( current_time (), pwpolicy->pw_minage )
);
+ (has_expirationtime && existing_exptime > slapi_current_utc_time()) ) {
+ bv.bv_val = format_genTime ( time_plus_sec ( slapi_current_utc_time(),
pwpolicy->pw_minage ) );
bv.bv_len = strlen( bv.bv_val );
slapi_entry_attr_merge( e, "passwordallowchangetime", bvals );
@@ -1792,7 +1792,7 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn)
slapi_attr_get_type(attr, &attr_name);
if (!strcasecmp(attr_name, "passwordminage")) {
if ((sval = attr_get_present_values(attr))) {
- pwdpolicy->pw_minage = slapi_value_get_timelonglong(*sval);
+ pwdpolicy->pw_minage = slapi_value_get_time_time_t(*sval);
if (-1 == pwdpolicy->pw_minage) {
slapi_log_err(SLAPI_LOG_ERR,
"new_passwdPolicy", "%s - Invalid passwordMinAge: %s\n",
@@ -1804,7 +1804,7 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn)
else
if (!strcasecmp(attr_name, "passwordmaxage")) {
if ((sval = attr_get_present_values(attr))) {
- pwdpolicy->pw_maxage = slapi_value_get_timelonglong(*sval);
+ pwdpolicy->pw_maxage = slapi_value_get_time_time_t(*sval);
if (-1 == pwdpolicy->pw_maxage) {
slapi_log_err(SLAPI_LOG_ERR,
"new_passwdPolicy", "%s - Invalid passwordMaxAge: %s\n",
@@ -1816,7 +1816,7 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn)
else
if (!strcasecmp(attr_name, "passwordwarning")) {
if ((sval = attr_get_present_values(attr))) {
- pwdpolicy->pw_warning = slapi_value_get_timelonglong(*sval);
+ pwdpolicy->pw_warning = slapi_value_get_time_time_t(*sval);
if (-1 == pwdpolicy->pw_warning) {
slapi_log_err(SLAPI_LOG_ERR,
"new_passwdPolicy", "%s - Invalid passwordWarning: %s\n",
@@ -1861,7 +1861,7 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn)
else
if (!strcasecmp(attr_name, "passwordlockoutduration")) {
if ((sval = attr_get_present_values(attr))) {
- pwdpolicy->pw_lockduration = slapi_value_get_timelong(*sval);
+ pwdpolicy->pw_lockduration = slapi_value_get_time_time_t(*sval);
}
}
else
@@ -2172,19 +2172,15 @@ check_pw_duration_value(const char *attr_name, char *value,
long minval, long maxval, char *errorbuf, size_t ebuflen)
{
int retVal = LDAP_SUCCESS;
- long long age;
+ time_t age;
- age = slapi_parse_duration_longlong(value);
+ age = slapi_parse_duration(value);
if (-1 == age) {
slapi_create_errormsg(errorbuf, ebuflen, "password minimum age \"%s\" is
invalid. ", value);
retVal = LDAP_CONSTRAINT_VIOLATION;
} else if (0 == strcasecmp(CONFIG_PW_LOCKDURATION_ATTRIBUTE, attr_name)) {
if ( (age <= 0) ||
-#if defined(CPU_x86_64)
- (age > (MAX_ALLOWED_TIME_IN_SECS_64 - current_time())) ||
-#else
- (age > (MAX_ALLOWED_TIME_IN_SECS - current_time())) ||
-#endif
+ (age > (MAX_ALLOWED_TIME_IN_SECS_64 - slapi_current_utc_time())) ||
((-1 != minval) && (age < minval)) ||
((-1 != maxval) && (age > maxval))) {
slapi_create_errormsg(errorbuf, ebuflen, "%s: \"%s\" seconds is
invalid. ", attr_name, value);
@@ -2192,11 +2188,7 @@ check_pw_duration_value(const char *attr_name, char *value,
}
} else {
if ( (age < 0) ||
-#if defined(CPU_x86_64)
- (age > (MAX_ALLOWED_TIME_IN_SECS_64 - current_time())) ||
-#else
- (age > (MAX_ALLOWED_TIME_IN_SECS - current_time())) ||
-#endif
+ (age > (MAX_ALLOWED_TIME_IN_SECS_64 - slapi_current_utc_time())) ||
((-1 != minval) && (age < minval)) ||
((-1 != maxval) && (age > maxval))) {
slapi_create_errormsg(errorbuf, ebuflen, "%s: \"%s\" seconds is
invalid. ", attr_name, value);
@@ -2212,11 +2204,11 @@ check_pw_resetfailurecount_value(const char *attr_name
__attribute__((unused)),
long minval __attribute__((unused)), long maxval
__attribute__((unused)), char *errorbuf, size_t ebuflen)
{
int retVal = LDAP_SUCCESS;
- long duration = 0; /* in minutes */
+ time_t duration = 0; /* in seconds */
/* in seconds */
- duration = strtol (value, NULL, 0);
- if ( duration < 0 || duration > (MAX_ALLOWED_TIME_IN_SECS - current_time()) ) {
+ duration = parse_duration_time_t(value);
+ if ( duration < 0 || duration > (MAX_ALLOWED_TIME_IN_SECS_64 -
slapi_current_utc_time()) ) {
slapi_create_errormsg(errorbuf, ebuflen, "password reset count duration
\"%s\" seconds is invalid.", value);
retVal = LDAP_CONSTRAINT_VIOLATION;
}
@@ -2375,7 +2367,7 @@ slapi_check_account_lock ( Slapi_PBlock *pb, Slapi_Entry *
bind_target_entry, in
0, NULL );
goto locked;
}
- cur_time = current_time();
+ cur_time = slapi_current_utc_time();
cur_time_str = format_genTime( cur_time);
if ( difftime ( parse_genTime( cur_time_str ), unlock_time ) < 0 ) {
@@ -2437,7 +2429,7 @@ slapi_pwpolicy_is_expired(Slapi_PWPolicy *pwpolicy, Slapi_Entry *e,
time_t *expi
if (expiration_val) {
_expire_time = parse_genTime(expiration_val);
- cur_time = current_time();
+ cur_time = slapi_current_utc_time();
cur_time_str = format_genTime(cur_time);
if ((_expire_time != NO_TIME) && (_expire_time != NOT_FIRST_TIME)
&&
@@ -2509,7 +2501,7 @@ slapi_pwpolicy_is_locked(Slapi_PWPolicy *pwpolicy, Slapi_Entry *e,
time_t *unloc
*unlock_time = (time_t)0;
}
} else {
- cur_time = current_time();
+ cur_time = slapi_current_utc_time();
cur_time_str = format_genTime(cur_time);
if (difftime(parse_genTime(cur_time_str), _unlock_time) < 0) {
diff --git a/ldap/servers/slapd/pw_mgmt.c b/ldap/servers/slapd/pw_mgmt.c
index a01afc5..677f11f 100644
--- a/ldap/servers/slapd/pw_mgmt.c
+++ b/ldap/servers/slapd/pw_mgmt.c
@@ -56,7 +56,7 @@ need_new_pw( Slapi_PBlock *pb, long *t, Slapi_Entry *e, int
pwresponse_req )
}
}
- cur_time = current_time();
+ cur_time = slapi_current_utc_time();
/* get passwordExpirationTime attribute */
passwordExpirationTime= slapi_entry_attr_get_charptr(e,
"passwordExpirationTime");
diff --git a/ldap/servers/slapd/pw_retry.c b/ldap/servers/slapd/pw_retry.c
index cb283ba..80b8944 100644
--- a/ldap/servers/slapd/pw_retry.c
+++ b/ldap/servers/slapd/pw_retry.c
@@ -51,7 +51,7 @@ int update_pw_retry ( Slapi_PBlock *pb )
return ( 1 );
}
- cur_time = current_time();
+ cur_time = slapi_current_utc_time();
/* check if the retry count can be reset. */
retryCountResetTime= slapi_entry_attr_get_charptr(e, "retryCountResetTime");
@@ -150,8 +150,7 @@ int set_retry_cnt_mods(Slapi_PBlock *pb, Slapi_Mods *smods, int
count)
/* lock until admin reset password */
unlock_time = NO_TIME;
} else {
- unlock_time = time_plus_sec ( current_time(),
- pwpolicy->pw_lockduration );
+ unlock_time = time_plus_sec ( slapi_current_utc_time(),
pwpolicy->pw_lockduration);
}
timestr= format_genTime ( unlock_time );
slapi_mods_add_string(smods, LDAP_MOD_REPLACE, "accountUnlockTime",
timestr);
diff --git a/ldap/servers/slapd/regex.c b/ldap/servers/slapd/regex.c
index 19a9b1d..a19ef2c 100644
--- a/ldap/servers/slapd/regex.c
+++ b/ldap/servers/slapd/regex.c
@@ -71,7 +71,7 @@ int
slapi_re_exec( Slapi_Regex *re_handle, const char *subject, time_t time_up )
{
int rc;
- time_t curtime = current_time();
+ time_t curtime = slapi_current_utc_time();
if (NULL == re_handle || NULL == re_handle->re_pcre || NULL == subject) {
return LDAP_PARAM_ERROR;
@@ -105,6 +105,52 @@ slapi_re_exec( Slapi_Regex *re_handle, const char *subject, time_t
time_up )
}
/**
+ * Matches a compiled regular expression pattern against a given string.
+ * A thin wrapper of pcre_exec.
+ *
+ * unlike slapi_re_exec, this has no timeout. The timeout was only checked
+ * at the start of the function, not during or after, so was essentially
+ * meaningless.
+ *
+ * \param re_handle The regex handler returned from slapi_re_comp.
+ * \param subject A string to be checked against the compiled pattern.
+ * \return This function returns 0 if the string did not match.
+ * \return This function returns 1 if the string matched.
+ * \return This function returns other values if any error occurred.
+ * \warning The regex handler should be released by slapi_re_free().
+ */
+int32_t
+slapi_re_exec_nt( Slapi_Regex *re_handle, const char *subject) {
+ int32_t rc;
+
+ if (NULL == re_handle || NULL == re_handle->re_pcre || NULL == subject) {
+ return LDAP_PARAM_ERROR;
+ }
+
+ if (NULL == re_handle->re_ovector) {
+ re_handle->re_oveccount = OVECCOUNT;
+ re_handle->re_ovector = (int *)slapi_ch_malloc(sizeof(int) * OVECCOUNT);
+ }
+
+ rc = pcre_exec( re_handle->re_pcre, /* the compiled pattern */
+ NULL, /* no extra data */
+ subject, /* the subject string */
+ strlen(subject), /* the length of the subject */
+ 0, /* start at offset 0 in the subject */
+ 0, /* default options */
+ re_handle->re_ovector, /* output vector for substring info */
+ re_handle->re_oveccount ); /* number of elems in the ovector */
+
+ if (rc >= 0) {
+ return 1; /* matched */
+ } else {
+ return 0; /* did not match */
+ }
+
+ return rc;
+}
+
+/**
* Substitutes '&' or '\#' in the param src with the matched string.
*
* \param re_handle The regex handler returned from slapi_re_comp.
diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
index a16c8e1..cf39902 100644
--- a/ldap/servers/slapd/result.c
+++ b/ldap/servers/slapd/result.c
@@ -1944,8 +1944,6 @@ notes2str( unsigned int notes, char *buf, size_t buflen )
}
-#define ETIME_BUFSIZ 16 /* room for 99999999.999999 */
-
static void
log_result( Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentries )
{
@@ -1963,13 +1961,10 @@ log_result( Slapi_PBlock *pb, Operation *op, int err, ber_tag_t
tag, int nentrie
internal_op = operation_is_flag_set( op, OP_FLAG_INTERNAL );
- if ( (config_get_accesslog_level() & LDAP_DEBUG_TIMING) &&
- (op->o_interval != (PRIntervalTime) 0) ) {
- PRIntervalTime delta = PR_IntervalNow() - op->o_interval;
- PR_snprintf(etime, ETIME_BUFSIZ, "%f",
(PRFloat64)delta/PR_TicksPerSecond());
- } else {
- PR_snprintf(etime, ETIME_BUFSIZ, "%ld", current_time() - op->o_time);
- }
+ struct timespec o_hr_time_end;
+ slapi_operation_time_elapsed(op, &o_hr_time_end);
+
+ snprintf(etime, ETIME_BUFSIZ, "%" PRId64 ".%010" PRId64
"", o_hr_time_end.tv_sec, o_hr_time_end.tv_nsec);
slapi_pblock_get(pb, SLAPI_OPERATION_NOTES, &operation_notes);
diff --git a/ldap/servers/slapd/sasl_map.c b/ldap/servers/slapd/sasl_map.c
index bc4381e..a7ba1de 100644
--- a/ldap/servers/slapd/sasl_map.c
+++ b/ldap/servers/slapd/sasl_map.c
@@ -585,7 +585,7 @@ sasl_map_check(sasl_map_data *dp, char *sasl_user_and_realm, char
**ldap_search_
dp->regular_expression, recomp_result?recomp_result:"unknown");
} else {
/* Matches the compiled regex against sasl_user_and_realm */
- matched = slapi_re_exec(re, sasl_user_and_realm, -1 /* no timelimit */);
+ matched = slapi_re_exec_nt(re, sasl_user_and_realm);
slapi_log_err(SLAPI_LOG_TRACE, "sasl_map_check", "regex: %s, id: %s,
%s\n",
dp->regular_expression, sasl_user_and_realm,
matched ? "matched" : "didn't match" );
@@ -643,7 +643,7 @@ sasl_map_check(sasl_map_data *dp, char *sasl_user_and_realm, char
**ldap_search_
}
} else {
slapi_log_err(SLAPI_LOG_ERR,
- "sasl_map_check", "slapi_re_exec failed: "
+ "sasl_map_check", "slapi_re_exec_nt failed: "
"regex: %s, subject: %s (%d)\n",
dp->regular_expression, sasl_user_and_realm, matched);
}
diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c
index 6f14893..db59fbd 100644
--- a/ldap/servers/slapd/schema.c
+++ b/ldap/servers/slapd/schema.c
@@ -2378,7 +2378,7 @@ modify_schema_dse (Slapi_PBlock *pb, Slapi_Entry *entryBefore,
Slapi_Entry *entr
if (NULL != new_schema_csn) {
char csn_str[CSN_STRSIZE + 1];
csn_set_replicaid(new_schema_csn, 0);
- csn_set_time(new_schema_csn, current_time());
+ csn_set_time(new_schema_csn, slapi_current_utc_time());
g_set_global_schema_csn(new_schema_csn);
slapi_entry_attr_delete(entryBefore, "nsschemacsn");
csn_as_string(new_schema_csn, PR_FALSE, csn_str);
@@ -7431,7 +7431,7 @@ modify_schema_internal_mod(Slapi_DN *sdn, Slapi_Mods *smods)
schema_csn = csn_new();
if (NULL != schema_csn) {
csn_set_replicaid(schema_csn, 0);
- csn_set_time(schema_csn, current_time());
+ csn_set_time(schema_csn, slapi_current_utc_time());
g_set_global_schema_csn(schema_csn);
}
} else {
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index d26a792..fdbd5d7 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -72,6 +72,8 @@ static char ptokPBE[34] = "Internal (Software) Token
";
#include <sys/socket.h>
#include <netinet/in.h>
+#include <time.h> /* For timespec definitions */
+
/* Provides our int types and platform specific requirements. */
#include <slapi_pal.h>
@@ -221,6 +223,8 @@ typedef void (*VFPV)(); /* takes undefined arguments */
#define SLAPD_INVALID_SOCKET_INDEX (-1)
+#define ETIME_BUFSIZ 42 /* room for struct timespec */
+
/* ============================================================================
* CONFIGURATION DEFAULTS
*
@@ -1475,8 +1479,8 @@ typedef struct op {
BerElement *o_ber; /* ber of the request */
ber_int_t o_msgid; /* msgid of the request */
ber_tag_t o_tag; /* tag of the request */
- time_t o_time; /* time op was initiated */
- PRIntervalTime o_interval; /* precise time op was initiated */
+ struct timespec o_hr_time_rel; /* internal system time op initiated */
+ struct timespec o_hr_time_utc; /* utc system time op initiated */
int o_isroot; /* requestor is manager */
Slapi_DN o_sdn; /* dn bound when op was initiated */
char *o_authtype; /* auth method used to bind dn */
@@ -1525,7 +1529,7 @@ typedef struct _paged_results {
int pr_search_result_count; /* search result count */
int pr_search_result_set_size_estimate; /* estimated search result set size
*/
int pr_sort_result_code; /* sort result put in response */
- time_t pr_timelimit; /* time limit for this request */
+ struct timespec pr_timelimit_hr; /* expiry time of this request rel to clock
monotonic */
int pr_flags;
ber_int_t pr_msgid; /* msgid of the request; to abandon */
PRLock *pr_mutex; /* protect each conn structure */
@@ -1711,15 +1715,15 @@ typedef struct passwordpolicyarray {
int pw_mintokenlength;
slapi_onoff_t pw_exp;
slapi_onoff_t pw_send_expiring;
- long long pw_maxage;
- long long pw_minage;
- long long pw_warning;
+ time_t pw_maxage;
+ time_t pw_minage;
+ time_t pw_warning;
slapi_onoff_t pw_history;
int pw_inhistory;
slapi_onoff_t pw_lockout;
int pw_maxfailure;
slapi_onoff_t pw_unlock;
- long pw_lockduration;
+ time_t pw_lockduration;
long pw_resetfailurecount;
int pw_gracelimit;
slapi_onoff_t pw_is_legacy;
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 2fc6d68..09fef07 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -4826,7 +4826,7 @@ long long slapi_value_get_longlong(const Slapi_Value *value);
unsigned long long slapi_value_get_ulonglong(const Slapi_Value *value);
/**
- * Retrieves the value of a \c Slapi_Value structure as a long integer.
+ * DEPRECATED: Retrieves the value of a \c Slapi_Value structure as a long integer.
*
* \param value Pointer to the value you wish to get as a long integer.
* The value could end with D or d for days, H or h for hours,
@@ -4835,16 +4835,12 @@ unsigned long long slapi_value_get_ulonglong(const Slapi_Value
*value);
* \c Slapi_Value structure.
* \return \c 0 if there is no value.
* \return \c -1 if the given value is invalid.
- * \see slapi_value_get_int()
- * \see slapi_value_get_uint()
- * \see slapi_value_get_ulong()
- * \see slapi_value_get_longlong()
- * \see slapi_value_get_ulonglong()
+ * \see slapi_value_get_time_time_t()
*/
-long slapi_value_get_timelong(const Slapi_Value *value);
+long slapi_value_get_timelong(const Slapi_Value *value) __attribute__((deprecated));
/**
- * Retrieves the value of a \c Slapi_Value structure as a long long integer.
+ * DEPRECATED: Retrieves the value of a \c Slapi_Value structure as a long long integer.
*
* \param value Pointer to the value you wish to get as a long long integer.
* The value could end with D or d for days, H or h for hours,
@@ -4853,13 +4849,29 @@ long slapi_value_get_timelong(const Slapi_Value *value);
* \c Slapi_Value structure.
* \return \c 0 if there is no value.
* \return \c -1 if the given value is invalid.
+ * \see slapi_value_get_time_time_t()
+ */
+long long slapi_value_get_timelonglong(const Slapi_Value *value)
__attribute__((deprecated));
+
+/**
+ * Retrieves the value of a \c Slapi_Value structure as a time_t.
+ *
+ * \param value Pointer to the value you wish to get as a time_t.
+ * The value could end with D or d for days, H or h for hours,
+ * M or m for minutes, S or s for seconds, or no extension.
+ * \return A long long integer that corresponds to the value stored in the
+ * \c Slapi_Value structure.
+ * \return \c 0 if there is no value.
+ * \return \c -1 if the given value is invalid.
* \see slapi_value_get_int()
* \see slapi_value_get_uint()
* \see slapi_value_get_ulong()
* \see slapi_value_get_longlong()
* \see slapi_value_get_ulonglong()
+ * \see slapi_value_get_time_time_t()
*/
-long long slapi_value_get_timelonglong(const Slapi_Value *value);
+time_t slapi_value_get_time_time_t(const Slapi_Value *value);
+
/**
* Gets the length of a value contained in a \c Slapi_Value structure.
@@ -6775,9 +6787,109 @@ int slapi_reslimit_get_integer_limit( Slapi_Connection *conn, int
handle,
/**
* Returns the current time
*
+ * CRITICAL: This funciton is NOT THREAD SAFE. DO NOT USE IT.
+ * You MUST use slapi_current_time_hr instead.
+ *
* \return The current time
*/
-time_t slapi_current_time( void );
+time_t slapi_current_time( void ) __attribute__((deprecated));
+
+/**
+ * Returns the current system time as a hr clock relative to uptime
+ * This means the clock is not affected by timezones
+ * which can normally cause issues with timers. Additionally, this
+ * is a thread safe clock.
+ *
+ * \return timespec of the current relative system time.
+ */
+struct timespec slapi_current_time_hr(void);
+/**
+ * Returns the current system time as a hr clock in UTC timezone.
+ * This clock adjusts with ntp steps, and should NOT be
+ * used for timer information.
+ *
+ * \return timespec of the current UTC time.
+ */
+struct timespec slapi_current_utc_time_hr(void);
+/**
+ * Returns the current system time as a clock in UTC timezone.
+ * This clock adjusts with ntp steps, and should NOT be
+ * used for timer information.
+ *
+ * \return time_t of the current UTC time.
+ */
+time_t slapi_current_utc_time(void);
+
+#define SLAPI_TIMESTAMP_BUFSIZE 32
+/**
+ * Populates a buffer with a timestamp formatted correctly for
+ * directory servers usage. This generally means UTC from localsystem
+ * time and in the format %Y%m%d%H%M%SZ.
+ *
+ * \param char *buf the buffer to populate.
+ * \param size_t bufsize Size of the buffer to populate. Must be at least
+ * SLAPI_TIMESTAMP_BUFSIZE
+ */
+void slapi_timestamp_utc_hr(char *buf, size_t bufsize);
+
+typedef enum {
+ TIMER_CONTINUE,
+ TIMER_EXPIRED
+} slapi_timer_result;
+
+/**
+ * populate a timespec with a time relative to now, that defines
+ * an expiry. IE, current time + timeout. This wraps the internal
+ * clock function to allow us to change clock operations without
+ * changing large parts of the codebase.
+ *
+ * if a negative timeout is provided, we set expire to 0.
+ *
+ * \param timeout the number of seconds relative to now when
+ * the timeout should occur.
+ * \param struct timespec the struct to populate with the relative
+ * time of when we should expire.
+ */
+void slapi_timespec_expire_at(time_t timeout, struct timespec *expire);
+
+/**
+ * populate a timespec with a time relative to start, that defines
+ * an expiry. IE, start time + timeout.
+ *
+ * if a negative timeout is provided, we set expire to 0.
+ *
+ * \param timeout the number of seconds relative to now when
+ * the timeout should occur.
+ * \param struct timespec start the struct containing the start
+ * time we are creating a relative expiry to.
+ * \param struct timespec the struct to populate with the relative
+ * time of when we should expire.
+ */
+void slapi_timespec_expire_rel(time_t timeout, struct timespec *start, struct timespec
*expire);
+
+/**
+ * Given a slapi_operation, and a timeout, calculate the expiry
+ * relative to the operations start time. This is used to determine
+ * time outs from op start time + timeout. To check the timeout
+ * you should call slapi_timespec_expire_check.
+ *
+ * \param Slapi_Operation o the operation to use.
+ * \param time_t timeout the timeout in seconds.
+ * \param struct timespec expiry the timespec that will be populated with
+ * the system relative expiry time.
+ */
+void slapi_operation_time_expiry(Slapi_Operation *o, time_t timeout, struct timespec
*expiry);
+
+/**
+ * check if a timespec has expired it's lifetime relative to now.
+ * if the timespec is 0, we do not cause a timeout.
+ *
+ * \param timespec to check for validity.
+ * \return slapi_time_result an enum of CONTINUE which means no
+ * expiry has occured, or EXPIRED, to defined tht the time is
+ * up. If timespec is 0, CONTINUE is always returned.
+ */
+slapi_timer_result slapi_timespec_expire_check(struct timespec *expire);
/*
@@ -7428,10 +7540,25 @@ Slapi_Regex *slapi_re_comp( const char *pat, const char **error
);
* \return This function returns other values if any error occurred.
* \warning The regex handler should be released by slapi_re_free().
*/
-int slapi_re_exec( Slapi_Regex *re_handle, const char *subject, time_t time_up );
+int slapi_re_exec( Slapi_Regex *re_handle, const char *subject, time_t time_up )
__attribute__((deprecated));
+/**
+ * Matches a compiled regular expression pattern against a given string.
+ * A thin wrapper of pcre_exec.
+ *
+ * \param re_handle The regex handler returned from slapi_re_comp.
+ * \param subject A string to be checked against the compiled pattern.
+ * returns immediately. (-1) means no time limit.
+ * \return This function returns 0 if the string did not match.
+ * \return This function returns 1 if the string matched.
+ * \return This function returns other values if any error occurred.
+ * \warning The regex handler should be released by slapi_re_free().
+ */
+int32_t slapi_re_exec_nt( Slapi_Regex *re_handle, const char *subject);
/**
* Substitutes '&' or '\#' in the param src with the matched string.
*
+ * This is identical to slapi_re_exec, except with no timeout.
+ *
* \param re_handle The regex handler returned from slapi_re_comp.
* \param subject A string checked against the compiled pattern.
* \param src A given string which could contain the substitution symbols.
@@ -8066,6 +8193,44 @@ int slapi_is_special_rdn(const char *rdn, int flag);
*/
void DS_Sleep(PRIntervalTime ticks);
+
+#ifdef HAVE_CLOCK_GETTIME
+/**
+ * Diffs two timespects a - b into *diff. This is useful with
+ * clock_monotonic to find time taken to perform operations.
+ *
+ * \param struct timespec a the "end" time.
+ * \param struct timespec b the "start" time.
+ * \param struct timespec c the difference.
+ */
+void slapi_timespec_diff(struct timespec *a, struct timespec *b, struct timespec *diff);
+/**
+ * Given an operation, determine the time elapsed since the op
+ * began.
+ *
+ * \param Slapi_Operation o - the operation which is inprogress
+ * \param struct timespec *elapsed - location where the time difference will be
+ * placed.
+ */
+void slapi_operation_time_elapsed(Slapi_Operation *o, struct timespec *elapsed);
+/**
+ * Given an operation, see it's initiated time based on clock_monotonic
+ * this is useful for timeout parameters and checks.
+ *
+ * \param Slapi_Operation o - the operation that is in progress
+ * \param struct timespec *initiated - location where we will populate the init time.
+ */
+void slapi_operation_time_initiated(Slapi_Operation *o, struct timespec *initiated);
+/**
+ * Given an operation and a timeout, return a populate struct with the expiry
+ * time of the operation suitable for checking with slapi_timespec_expire_check
+ *
+ * \param Slapi_Operation o - the operation that is in progress
+ * \param time_t timeout the seconds relative to operation initiation to expiry at.
+ * \param struct timespec *expiry the timespec to popluate with the relative expiry.
+ */
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 5703375..97cd964 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -265,10 +265,6 @@ void* csngen_register_callbacks(CSNGen *gen, GenCSNFn genFn, void
*genArg,
/* unregisters callbacks registered via call to csngenRegisterCallbacks */
void csngen_unregister_callbacks(CSNGen *gen, void *cookie);
-/* this functions is periodically called from daemon.c to
- update time used by all generators */
-void csngen_update_time(void);
-
/* debugging function */
void csngen_dump_state (const CSNGen *gen);
@@ -1164,12 +1160,14 @@ char* format_localTime(time_t from);
time_t read_localTime(struct berval* from);
time_t parse_localTime(char* from);
void write_localTime(time_t from, struct berval* into);
-time_t current_time( void );
+time_t current_time( void ) __attribute__((deprecated));
char* format_genTime(time_t from);
void write_genTime(time_t from, struct berval* into);
time_t read_genTime(struct berval* from);
time_t parse_genTime(char* from);
-long parse_duration(char *value);
+long parse_duration(char *value) __attribute__((deprecated));
+long parse_duration_32bit(char *value);
+time_t parse_duration_time_t(char *value);
char *gen_duration(long duration);
/* Client SSL code */
@@ -1365,7 +1363,7 @@ char *slapi_getSSLVersion_str(PRUint16 vnum, char *buf, size_t
bufsize);
* Failure: -1
*/
time_t slapi_parse_duration(const char *value);
-long long slapi_parse_duration_longlong(const char *value);
+long long slapi_parse_duration_longlong(const char *value) __attribute__((deprecated));
int slapi_is_duration_valid(const char *value);
/**
diff --git a/ldap/servers/slapd/time.c b/ldap/servers/slapd/time.c
index 16467af..2dc5522 100644
--- a/ldap/servers/slapd/time.c
+++ b/ldap/servers/slapd/time.c
@@ -23,71 +23,6 @@
unsigned long strntoul( char *from, size_t len, int base );
#define mktime_r(from) mktime (from) /* possible bug: is this thread-safe? */
-static time_t currenttime;
-static int currenttime_set = 0;
-/* XXX currenttime and currenttime_set are used by multiple threads,
- * concurrently (one thread sets them, many threads read them),
- * WITHOUT SYNCHRONIZATION. If assignment to currenttime especially
- * is not atomic, current_time() will return bogus values, and
- * bogus behavior may ensue. We think this isn't a problem, because
- * currenttime is a static variable, and defined first in this module;
- * consequently it's aligned, and doesn't cross cache lines or
- * otherwise run afoul of multiprocessor weirdness that might make
- * assignment to it non-atomic.
- */
-
-#ifndef HAVE_TIME_R
-PRLock *time_func_mutex;
-
-int gmtime_r(
- const time_t *timer,
- struct tm *result
-)
-{
- if ( result == NULL ) {
- return -1;
- }
- PR_Lock( time_func_mutex );
- memcpy( (void *) result, (const void *) gmtime( timer ),
- sizeof( struct tm ));
- PR_Unlock( time_func_mutex );
- return 0;
-}
-
-int localtime_r(
- const time_t *timer,
- struct tm *result
-)
-{
- if ( result == NULL ) {
- return -1;
- }
- PR_Lock( time_func_mutex );
- memcpy( (void *) result, (const void *) localtime( timer ),
- sizeof( struct tm ));
- PR_Unlock( time_func_mutex );
- return 0;
-}
-
-
-int ctime_r(
- const time_t *timer,
- char *buffer,
- int buflen
-)
-{
- if (( buffer == NULL ) || ( buflen < 26)) {
- return -1;
- }
- PR_Lock( time_func_mutex );
- memset( buffer, 0, buflen );
- memcpy( buffer, ctime( timer ), 26 );
- PR_Unlock( time_func_mutex );
- return 0;
-}
-#endif /* HAVE_TIME_R */
-
-
char *
get_timestring(time_t *t)
{
@@ -103,8 +38,9 @@ get_timestring(time_t *t)
void
free_timestring(char *timestr)
{
- if ( timestr != NULL )
+ if ( timestr != NULL ) {
slapi_ch_free((void**)×tr);
+ }
}
/*
@@ -116,54 +52,71 @@ free_timestring(char *timestr)
* Note: during server startup, poll_current_time() is not called at all so
* current_time() just calls through to time() until poll_current_time() starts
* to be called.
+ *
+ * WARNING: THIS IS NOT THREADSAFE.
*/
time_t
poll_current_time()
{
- if ( !currenttime_set ) {
- currenttime_set = 1;
- }
-
- time( ¤ttime );
- return( currenttime );
+ return 0;
}
time_t
current_time( void )
{
- if ( currenttime_set ) {
- return( currenttime );
- } else {
- return( time( (time_t *)0 ));
- }
+ /*
+ * For now wrap UTC time, but this interface
+ * but this should be removed in favour of the
+ * more accurately named slapi_current_utc_time
+ */
+ struct timespec now;
+ clock_gettime(CLOCK_REALTIME, &now);
+ return now.tv_sec;
}
time_t
slapi_current_time( void )
{
- return current_time();
+ return slapi_current_utc_time();
+}
+
+struct timespec
+slapi_current_rel_time_hr( void ) {
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ return now;
+}
+
+struct timespec
+slapi_current_utc_time_hr(void) {
+ struct timespec ltnow;
+ clock_gettime(CLOCK_REALTIME, <now);
+ return ltnow;
+}
+
+time_t
+slapi_current_utc_time(void) {
+ struct timespec ltnow;
+ clock_gettime(CLOCK_REALTIME, <now);
+ return ltnow.tv_sec;
+}
+
+void
+slapi_timestamp_utc_hr(char *buf, size_t bufsize) {
+ PR_ASSERT(bufsize >= SLAPI_TIMESTAMP_BUFSIZE);
+ struct timespec ltnow;
+ struct tm utctm;
+ clock_gettime(CLOCK_REALTIME, <now);
+ gmtime_r(&(ltnow.tv_sec), &utctm);
+ strftime(buf, bufsize, "%Y%m%d%H%M%SZ", &utctm);
}
time_t
time_plus_sec (time_t l, long r)
/* return the point in time 'r' seconds after 'l'. */
{
- /* On many (but not all) platforms this is simply l + r;
- perhaps it would be better to implement it that way. */
- struct tm t;
- if (r == 0) return l; /* performance optimization */
- localtime_r (&l, &t);
- /* Conceptually, we want to do: t.tm_sec += r;
- but to avoid overflowing fields: */
- r += t.tm_sec; t.tm_sec = r % 60; r /= 60;
- r += t.tm_min; t.tm_min = r % 60; r /= 60;
- r += t.tm_hour; t.tm_hour = r % 24; r /= 24;
- t.tm_mday += r; /* may be > 31; mktime_r() must handle this */
-
- /* These constants are chosen to work when the maximum
- field values are 127 (the worst case) or more.
- Perhaps this is excessively conservative. */
- return mktime_r (&t);
+ PR_ASSERT(r >= 0);
+ return l + (time_t)r;
}
@@ -217,7 +170,6 @@ format_localTime_log(time_t t, int initsize __attribute__((unused)),
char *buf,
return 0;
}
-#ifdef HAVE_CLOCK_GETTIME
/*
* format_localTime_hr_log will take a time value, and prepare it for
* log printing.
@@ -268,7 +220,62 @@ format_localTime_hr_log(time_t t, long nsec, int initsize
__attribute__((unused)
*bufsize = strlen(buf);
return 0;
}
-#endif /* HAVE_CLOCK_GETTIME */
+
+void
+slapi_timespec_diff(struct timespec *a, struct timespec *b, struct timespec *diff) {
+ /* Now diff the two */
+ time_t sec = a->tv_sec - b->tv_sec;
+ int32_t nsec = a->tv_nsec - b->tv_nsec;
+
+ if (nsec < 0) {
+ /* It's negative so take one second */
+ sec -= 1;
+ /* And set nsec to to a whole value */
+ nsec = 1000000000 - nsec;
+ }
+
+ diff->tv_sec = sec;
+ diff->tv_nsec = nsec;
+}
+
+void
+slapi_timespec_expire_at(time_t timeout, struct timespec *expire) {
+ if (timeout <= 0) {
+ expire->tv_sec = 0;
+ expire->tv_nsec = 0;
+ } else {
+ clock_gettime(CLOCK_MONOTONIC, expire);
+ expire->tv_sec += timeout;
+ }
+}
+
+void
+slapi_timespec_expire_rel(time_t timeout, struct timespec *start, struct timespec
*expire) {
+ if (timeout <= 0) {
+ expire->tv_sec = 0;
+ expire->tv_nsec = 0;
+ } else {
+ expire->tv_sec = start->tv_sec + timeout;
+ expire->tv_nsec = start->tv_nsec;
+ }
+}
+
+slapi_timer_result
+slapi_timespec_expire_check(struct timespec *expire) {
+ /*
+ * Check this first, as it makes no timeout virutally free.
+ */
+ if (expire->tv_sec == 0 && expire->tv_nsec == 0) {
+ return TIMER_CONTINUE;
+ }
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ if (now.tv_sec > expire->tv_sec ||
+ (expire->tv_sec == now.tv_sec && now.tv_sec > expire->tv_nsec))
{
+ return TIMER_EXPIRED;
+ }
+ return TIMER_CONTINUE;
+}
char*
format_localTime (time_t from)
@@ -348,7 +355,7 @@ format_genTime (time_t from)
struct tm t;
gmtime_r (&from, &t);
- into = slapi_ch_malloc (20);
+ into = slapi_ch_malloc (SLAPI_TIMESTAMP_BUFSIZE);
strftime(into, 20, "%Y%m%d%H%M%SZ", &t);
return into;
}
@@ -456,7 +463,7 @@ parse_genTime (char* from)
* Failure: -1
*/
long
-parse_duration(char *value)
+parse_duration_32bit(char *value)
{
char *input = NULL;
char *endp;
@@ -523,8 +530,8 @@ bail:
return duration;
}
-long long
-parse_duration_longlong(char *value)
+time_t
+parse_duration_time_t(char *value)
{
char *input = NULL;
char *endp;
@@ -584,7 +591,7 @@ parse_duration_longlong(char *value)
duration *= times;
bail:
if (duration == -1) {
- slapi_log_err(SLAPI_LOG_ERR, "parse_duration_longlong",
+ slapi_log_err(SLAPI_LOG_ERR, "parse_duration_time_t",
"Invalid duration (%s)\n", value?value:"null");
}
slapi_ch_free_string(&input);
@@ -594,13 +601,13 @@ bail:
time_t
slapi_parse_duration(const char *value)
{
- return (time_t)parse_duration((char *)value);
+ return parse_duration_time_t((char *)value);
}
long long
slapi_parse_duration_longlong(const char *value)
{
- return parse_duration_longlong((char *)value);
+ return parse_duration_time_t((char *)value);
}
static int
diff --git a/ldap/servers/slapd/uuid.c b/ldap/servers/slapd/uuid.c
index 333321c..14e75dc 100644
--- a/ldap/servers/slapd/uuid.c
+++ b/ldap/servers/slapd/uuid.c
@@ -883,7 +883,7 @@ static void get_system_time(uuid_time_t *uuid_time)
{
time_t cur_time;
- cur_time = current_time ();
+ cur_time = slapi_current_utc_time();
/* Offset between UUID formatted times and time() formatted times.
UUID UTC base time is October 15, 1582. time() base time is January 1, 1970.*/
diff --git a/ldap/servers/slapd/value.c b/ldap/servers/slapd/value.c
index 63a1ca9..879651b 100644
--- a/ldap/servers/slapd/value.c
+++ b/ldap/servers/slapd/value.c
@@ -503,7 +503,7 @@ slapi_value_get_timelong(const Slapi_Value *value)
p = slapi_ch_malloc(value->bv.bv_len + 1);
memcpy (p, value->bv.bv_val, value->bv.bv_len);
p [value->bv.bv_len] = '\0';
- r = parse_duration(p);
+ r = parse_duration_32bit(p);
slapi_ch_free((void **)&p);
}
return r;
@@ -519,12 +519,29 @@ slapi_value_get_timelonglong(const Slapi_Value *value)
p = slapi_ch_malloc(value->bv.bv_len + 1);
memcpy(p, value->bv.bv_val, value->bv.bv_len);
p[value->bv.bv_len] = '\0';
- r = slapi_parse_duration_longlong(p);
+ r = parse_duration_time_t(p);
slapi_ch_free_string(&p);
}
return r;
}
+time_t
+slapi_value_get_time_time_t(const Slapi_Value *value)
+{
+ long long r = 0;
+ if(value)
+ {
+ char *p;
+ p = slapi_ch_malloc(value->bv.bv_len + 1);
+ memcpy(p, value->bv.bv_val, value->bv.bv_len);
+ p[value->bv.bv_len] = '\0';
+ r = parse_duration_time_t(p);
+ slapi_ch_free_string(&p);
+ }
+ return r;
+}
+
+
int
slapi_value_compare(const Slapi_Attr *a,const Slapi_Value *v1,const Slapi_Value *v2)
{
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.