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