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