Home | History | Annotate | Line # | Download | only in back-monitor
time.c revision 1.1
      1 /* time.c - deal with time subsystem */
      2 /* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/time.c,v 1.37.2.3 2008/02/11 23:26:47 kurt Exp $ */
      3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      4  *
      5  * Copyright 2001-2008 The OpenLDAP Foundation.
      6  * Portions Copyright 2001-2003 Pierangelo Masarati.
      7  * All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted only as authorized by the OpenLDAP
     11  * Public License.
     12  *
     13  * A copy of this license is available in file LICENSE in the
     14  * top-level directory of the distribution or, alternatively, at
     15  * <http://www.OpenLDAP.org/license.html>.
     16  */
     17 /* ACKNOWLEDGEMENTS:
     18  * This work was initially developed by Pierangelo Masarati for inclusion
     19  * in OpenLDAP Software.
     20  */
     21 
     22 #include "portable.h"
     23 
     24 #include <stdio.h>
     25 #include <ac/string.h>
     26 #include <ac/time.h>
     27 
     28 
     29 #include "slap.h"
     30 #include <lutil.h>
     31 #include "proto-slap.h"
     32 #include "back-monitor.h"
     33 
     34 static int
     35 monitor_subsys_time_update(
     36 	Operation		*op,
     37 	SlapReply		*rs,
     38 	Entry                   *e );
     39 
     40 int
     41 monitor_subsys_time_init(
     42 	BackendDB		*be,
     43 	monitor_subsys_t	*ms )
     44 {
     45 	monitor_info_t	*mi;
     46 
     47 	Entry		*e, **ep, *e_time;
     48 	monitor_entry_t	*mp;
     49 	struct berval	bv, value;
     50 
     51 	assert( be != NULL );
     52 
     53 	ms->mss_update = monitor_subsys_time_update;
     54 
     55 	mi = ( monitor_info_t * )be->be_private;
     56 
     57 	if ( monitor_cache_get( mi,
     58 			&ms->mss_ndn, &e_time ) ) {
     59 		Debug( LDAP_DEBUG_ANY,
     60 			"monitor_subsys_time_init: "
     61 			"unable to get entry \"%s\"\n",
     62 			ms->mss_ndn.bv_val, 0, 0 );
     63 		return( -1 );
     64 	}
     65 
     66 	mp = ( monitor_entry_t * )e_time->e_private;
     67 	mp->mp_children = NULL;
     68 	ep = &mp->mp_children;
     69 
     70 	BER_BVSTR( &bv, "cn=Start" );
     71 	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
     72 		mi->mi_oc_monitoredObject, mi, NULL, NULL );
     73 	if ( e == NULL ) {
     74 		Debug( LDAP_DEBUG_ANY,
     75 			"monitor_subsys_time_init: "
     76 			"unable to create entry \"%s,%s\"\n",
     77 			bv.bv_val, ms->mss_ndn.bv_val, 0 );
     78 		return( -1 );
     79 	}
     80 	attr_merge_normalize_one( e, mi->mi_ad_monitorTimestamp,
     81 		&mi->mi_startTime, NULL );
     82 
     83 	mp = monitor_entrypriv_create();
     84 	if ( mp == NULL ) {
     85 		return -1;
     86 	}
     87 	e->e_private = ( void * )mp;
     88 	mp->mp_info = ms;
     89 	mp->mp_flags = ms->mss_flags \
     90 		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
     91 
     92 	if ( monitor_cache_add( mi, e ) ) {
     93 		Debug( LDAP_DEBUG_ANY,
     94 			"monitor_subsys_time_init: "
     95 			"unable to add entry \"%s,%s\"\n",
     96 			bv.bv_val, ms->mss_ndn.bv_val, 0 );
     97 		return( -1 );
     98 	}
     99 
    100 	*ep = e;
    101 	ep = &mp->mp_next;
    102 
    103 	/*
    104 	 * Current
    105 	 */
    106 	BER_BVSTR( &bv, "cn=Current" );
    107 	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
    108 		mi->mi_oc_monitoredObject, mi, NULL, NULL );
    109 	if ( e == NULL ) {
    110 		Debug( LDAP_DEBUG_ANY,
    111 			"monitor_subsys_time_init: "
    112 			"unable to create entry \"%s,%s\"\n",
    113 			bv.bv_val, ms->mss_ndn.bv_val, 0 );
    114 		return( -1 );
    115 	}
    116 	attr_merge_normalize_one( e, mi->mi_ad_monitorTimestamp,
    117 		&mi->mi_startTime, NULL );
    118 
    119 	mp = monitor_entrypriv_create();
    120 	if ( mp == NULL ) {
    121 		return -1;
    122 	}
    123 	e->e_private = ( void * )mp;
    124 	mp->mp_info = ms;
    125 	mp->mp_flags = ms->mss_flags \
    126 		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
    127 
    128 	if ( monitor_cache_add( mi, e ) ) {
    129 		Debug( LDAP_DEBUG_ANY,
    130 			"monitor_subsys_time_init: "
    131 			"unable to add entry \"%s,%s\"\n",
    132 			bv.bv_val, ms->mss_ndn.bv_val, 0 );
    133 		return( -1 );
    134 	}
    135 
    136 	*ep = e;
    137 	ep = &mp->mp_next;
    138 
    139 	/*
    140 	 * Uptime
    141 	 */
    142 	BER_BVSTR( &bv, "cn=Uptime" );
    143 	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
    144 		mi->mi_oc_monitoredObject, mi, NULL, NULL );
    145 	if ( e == NULL ) {
    146 		Debug( LDAP_DEBUG_ANY,
    147 			"monitor_subsys_time_init: "
    148 			"unable to create entry \"%s,%s\"\n",
    149 			bv.bv_val, ms->mss_ndn.bv_val, 0 );
    150 		return( -1 );
    151 	}
    152 	BER_BVSTR( &value, "0" );
    153 	attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo,
    154 		&value, NULL );
    155 
    156 	mp = monitor_entrypriv_create();
    157 	if ( mp == NULL ) {
    158 		return -1;
    159 	}
    160 	e->e_private = ( void * )mp;
    161 	mp->mp_info = ms;
    162 	mp->mp_flags = ms->mss_flags \
    163 		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
    164 
    165 	if ( monitor_cache_add( mi, e ) ) {
    166 		Debug( LDAP_DEBUG_ANY,
    167 			"monitor_subsys_time_init: "
    168 			"unable to add entry \"%s,%s\"\n",
    169 			bv.bv_val, ms->mss_ndn.bv_val, 0 );
    170 		return( -1 );
    171 	}
    172 
    173 	*ep = e;
    174 	ep = &mp->mp_next;
    175 
    176 	monitor_cache_release( mi, e_time );
    177 
    178 	return( 0 );
    179 }
    180 
    181 static int
    182 monitor_subsys_time_update(
    183 	Operation		*op,
    184 	SlapReply		*rs,
    185 	Entry                   *e )
    186 {
    187 	monitor_info_t		*mi = ( monitor_info_t * )op->o_bd->be_private;
    188 	static struct berval	bv_current = BER_BVC( "cn=current" ),
    189 				bv_uptime = BER_BVC( "cn=uptime" );
    190 	struct berval		rdn;
    191 
    192 	assert( mi != NULL );
    193 	assert( e != NULL );
    194 
    195 	dnRdn( &e->e_nname, &rdn );
    196 
    197 	if ( dn_match( &rdn, &bv_current ) ) {
    198 		struct tm	*tm;
    199 #ifdef HAVE_GMTIME_R
    200 		struct tm	tm_buf;
    201 #endif
    202 		char		tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
    203 		Attribute	*a;
    204 		ber_len_t	len;
    205 		time_t		currtime;
    206 
    207 		currtime = slap_get_time();
    208 
    209 #ifndef HAVE_GMTIME_R
    210 		ldap_pvt_thread_mutex_lock( &gmtime_mutex );
    211 #endif
    212 #ifdef HACK_LOCAL_TIME
    213 # ifdef HAVE_LOCALTIME_R
    214 		tm = localtime_r( &currtime, &tm_buf );
    215 # else
    216 		tm = localtime( &currtime );
    217 # endif /* HAVE_LOCALTIME_R */
    218 		lutil_localtime( tmbuf, sizeof( tmbuf ), tm, -timezone );
    219 #else /* !HACK_LOCAL_TIME */
    220 # ifdef HAVE_GMTIME_R
    221 		tm = gmtime_r( &currtime, &tm_buf );
    222 # else
    223 		tm = gmtime( &currtime );
    224 # endif /* HAVE_GMTIME_R */
    225 		lutil_gentime( tmbuf, sizeof( tmbuf ), tm );
    226 #endif /* !HACK_LOCAL_TIME */
    227 #ifndef HAVE_GMTIME_R
    228 		ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
    229 #endif
    230 
    231 		len = strlen( tmbuf );
    232 
    233 		a = attr_find( e->e_attrs, mi->mi_ad_monitorTimestamp );
    234 		if ( a == NULL ) {
    235 			return rs->sr_err = LDAP_OTHER;
    236 		}
    237 
    238 		assert( len == a->a_vals[ 0 ].bv_len );
    239 		AC_MEMCPY( a->a_vals[ 0 ].bv_val, tmbuf, len );
    240 
    241 		/* FIXME: touch modifyTimestamp? */
    242 
    243 	} else if ( dn_match( &rdn, &bv_uptime ) ) {
    244 		Attribute	*a;
    245 		double		diff;
    246 		char		buf[ BACKMONITOR_BUFSIZE ];
    247 		struct berval	bv;
    248 
    249 		a = attr_find( e->e_attrs, mi->mi_ad_monitoredInfo );
    250 		if ( a == NULL ) {
    251 			return rs->sr_err = LDAP_OTHER;
    252 		}
    253 
    254 		diff = difftime( slap_get_time(), starttime );
    255 		bv.bv_len = snprintf( buf, sizeof( buf ), "%lu",
    256 			(unsigned long) diff );
    257 		bv.bv_val = buf;
    258 
    259 		ber_bvreplace( &a->a_vals[ 0 ], &bv );
    260 		if ( a->a_nvals != a->a_vals ) {
    261 			ber_bvreplace( &a->a_nvals[ 0 ], &bv );
    262 		}
    263 
    264 		/* FIXME: touch modifyTimestamp? */
    265 	}
    266 
    267 	return SLAP_CB_CONTINUE;
    268 }
    269 
    270