1/* time.c - deal with time subsystem */ 2/* $OpenLDAP$ */ 3/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 4 * 5 * Copyright 2001-2011 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 34static int 35monitor_subsys_time_update( 36 Operation *op, 37 SlapReply *rs, 38 Entry *e ); 39 40int 41monitor_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 181static int 182monitor_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 char tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; 200 Attribute *a; 201 ber_len_t len; 202 time_t currtime; 203 204 currtime = slap_get_time(); 205 206 ldap_pvt_gmtime( &currtime, &tm ); 207 lutil_gentime( tmbuf, sizeof( tmbuf ), &tm ); 208 209 len = strlen( tmbuf ); 210 211 a = attr_find( e->e_attrs, mi->mi_ad_monitorTimestamp ); 212 if ( a == NULL ) { 213 return rs->sr_err = LDAP_OTHER; 214 } 215 216 assert( len == a->a_vals[ 0 ].bv_len ); 217 AC_MEMCPY( a->a_vals[ 0 ].bv_val, tmbuf, len ); 218 219 /* FIXME: touch modifyTimestamp? */ 220 221 } else if ( dn_match( &rdn, &bv_uptime ) ) { 222 Attribute *a; 223 double diff; 224 char buf[ BACKMONITOR_BUFSIZE ]; 225 struct berval bv; 226 227 a = attr_find( e->e_attrs, mi->mi_ad_monitoredInfo ); 228 if ( a == NULL ) { 229 return rs->sr_err = LDAP_OTHER; 230 } 231 232 diff = difftime( slap_get_time(), starttime ); 233 bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", 234 (unsigned long) diff ); 235 bv.bv_val = buf; 236 237 ber_bvreplace( &a->a_vals[ 0 ], &bv ); 238 if ( a->a_nvals != a->a_vals ) { 239 ber_bvreplace( &a->a_nvals[ 0 ], &bv ); 240 } 241 242 /* FIXME: touch modifyTimestamp? */ 243 } 244 245 return SLAP_CB_CONTINUE; 246} 247 248