Commit 761f2879 authored by Pierangelo Masarati's avatar Pierangelo Masarati
Browse files

multiple precision with BIGNUM/gmp/ulong

parent 2e9d6474
......@@ -171,6 +171,10 @@ OL_ARG_WITH(tls,[ --with-tls with TLS/SSL support],
auto, [auto ssleay openssl yes no] )
OL_ARG_WITH(yielding_select,[ --with-yielding-select with implicitly yielding select],
auto, [auto yes no manual] )
OL_ARG_WITH(multiple_precision,[ --with-multiple-precision
multiple precision support for statistics
auto|bignum|gmp],
auto, [auto bignum gmp yes no] )
dnl ----------------------------------------------------------------
dnl Server options
......@@ -1207,10 +1211,11 @@ fi
dnl ----------------------------------------------------------------
dnl TLS/SSL
ol_link_tls=no
if test $ol_with_tls != no ; then
AC_CHECK_HEADERS(openssl/ssl.h ssl.h)
if test $ac_cv_header_openssl_ssl_h = yes \
-o $ac_cv_header_ssl_h = yes ; then
AC_CHECK_LIB(ssl, SSLeay_add_ssl_algorithms,
......@@ -2230,15 +2235,96 @@ if test $ol_enable_slp != no ; then
fi
dnl ----------------------------------------------------------------
dnl Check for GMP API Library
AC_CHECK_HEADERS( gmp.h )
dnl Check for multiple precision support
if test "$ol_with_multiple_precision" != "no" ; then
ol_have_bignum=no
ol_have_gmp=no
AC_CHECK_HEADERS(openssl/bn.h bn.h)
AC_CHECK_HEADERS(openssl/crypto.h crypto.h)
AC_CHECK_HEADERS( gmp.h )
if test "$ol_with_tls" = "found" ; then
ol_have_bn_h=no
ol_have_crypto_h=no
if test "$ac_cv_header_openssl_bn_h" = "yes" \
-o "$ac_cv_header_bn_h" = "yes" ; then
ol_have_bn_h=yes
fi
if test "$ac_cv_header_openssl_crypto_h" = "yes" \
-o "$ac_cv_header_crypto_h" = "yes" ; then
ol_have_crypto_h=yes
fi
if test "$ol_have_bn_h" = "yes" \
-a "$ol_have_crypto_h" = "yes" ; then
ol_have_bignum=yes
fi
fi
if test $ac_cv_header_gmp_h = yes ; then
AC_CHECK_LIB(gmp, __gmpz_add_ui, [have_gmp=yes], [have_gmp=no])
if test $have_gmp = yes ; then
ol_have_gmp=yes
fi
fi
if test $ac_cv_header_gmp_h = yes ; then
AC_CHECK_LIB(gmp, __gmpz_add_ui, [have_gmp=yes], [have_gmp=no])
if test $have_gmp = yes ; then
AC_MSG_CHECKING([for multiple precision support])
ol_mp_support="none"
case "$ol_with_multiple_precision" in
auto)
dnl preferred sequence:
dnl - OpenSSL's BIGNUM (if libssl is already linked)
dnl - GNU's MP
dnl - unsigned long
if test "$ol_have_bignum" = "yes" ; then
ol_mp_support="bignum"
else
if test "$ol_have_gmp" = "yes" ; then
ol_mp_support="gmp"
fi
fi
;;
bignum)
if test "$ol_have_bignum" != "yes" ; then
AC_MSG_ERROR([OpenSSL's BIGNUM not available])
fi
ol_mp_support="bignum"
;;
gmp)
if test "$ol_have_gmp" != "yes" ; then
AC_MSG_ERROR([GMP not available])
fi
ol_mp_support="gmp"
;;
yes)
if test "$ol_have_bignum" = "yes" ; then
ol_mp_support="bignum"
elif test "$ol_have_gmp" = "yes" ; then
ol_mp_support="gmp"
else
AC_MSG_ERROR([not available])
fi
;;
esac
case "$ol_mp_support" in
bignum)
AC_DEFINE(HAVE_BIGNUM, 1,
[define if you have SSLeay or OpenSSL's BIGNUM])
;;
gmp)
AC_DEFINE(HAVE_GMP, 1, [define if you have -lgmp])
SLAPD_GMP_LIBS=-lgmp
fi
;;
none)
;;
esac
AC_MSG_RESULT($ol_mp_support)
fi
dnl ----------------------------------------------------------------
......
......@@ -249,7 +249,95 @@ LDAP_F (int) ldap_pvt_tls_get_strength LDAP_P(( void *ctx ));
LDAP_END_DECL
#include "ldap_pvt_uc.h"
/*
* Multiple precision stuff
*
* May use OpenSSL's BIGNUM if built with TLS,
* or GNU's multiple precision library.
*
* If none is available, unsigned long data is used.
*/
#ifdef HAVE_BIGNUM
/*
* Use OpenSSL's BIGNUM
*/
#if defined(HAVE_OPENSSL_CRYPTO_H)
#include <openssl/crypto.h>
#elif HAVE_CRYPTO_H
#include <crypto.h>
#endif /* HAVE_OPENSSL_CRYPTO_H || HAVE_CRYPTO_H */
#ifdef HAVE_OPENSSL_BN_H
#include <openssl/bn.h>
#elif HAVE_BN_H
#include <bn.h>
#endif /* HAVE_OPENSSL_BN_H || HAVE_BN_H */
typedef BIGNUM* ldap_pvt_mp_t;
#define ldap_pvt_mp_init(mp) \
do { (mp) = BN_new(); BN_init((mp)); } while (0)
/* FIXME: we rely on mpr being initialized */
#define ldap_pvt_mp_init_set(mpr,mpv) \
do { ldap_pvt_mp_init((mpr)); BN_add((mpr), (mpr), (mpv)); } while (0)
#define ldap_pvt_mp_add(mpr,mpv) \
BN_add((mpr), (mpr), (mpv))
#define ldap_pvt_mp_add_ulong(mp,v) \
BN_add_word((mp), (v))
#define ldap_pvt_mp_clear(mp) \
do { BN_free((mp)); (mp) = 0; } while (0)
#elif defined(HAVE_GMP)
/*
* Use GNU's multiple precision library
*/
#ifdef HAVE_GMP_H
#include <gmp.h>
#endif
typedef mpz_t ldap_pvt_mp_t;
#define ldap_pvt_mp_init(mp) \
mpz_init((mp))
#define ldap_pvt_mp_init_set(mpr,mpv) \
mpz_init_set((mpr), (mpv))
#define ldap_pvt_mp_add(mpr,mpv) \
mpz_add((mpr), (mpr), (mpv))
#define ldap_pvt_mp_add_ulong(mp,v) \
mpz_add_ui((mp), (mp), (v))
#define ldap_pvt_mp_clear(mp) \
mpz_clear((mp))
#else /* ! HAVE_BIGNUM && ! HAVE_GMP */
/*
* Use unsigned long
*/
typedef unsigned long ldap_pvt_mp_t;
#define ldap_pvt_mp_init(mp) \
(mp) = 0
#define ldap_pvt_mp_init_set(mpr,mpv) \
(mpr) = (mpv)
#define ldap_pvt_mp_add(mpr,mpv) \
(mpr) += (mpv)
#define ldap_pvt_mp_add_ulong(mp,v) \
(mp) += (v)
#define ldap_pvt_mp_clear(mp) \
(mp) = 0
#endif /* ! HAVE_BIGNUM && ! HAVE_GMP */
#include "ldap_pvt_uc.h"
#endif
......@@ -24,7 +24,6 @@
#include <ac/string.h>
#include <ac/time.h>
#include "ldap_pvt.h"
#include "slap.h"
#include "lutil.h"
......@@ -793,6 +792,7 @@ str2anlist( AttributeName *an, char *in, const char *brkstr )
}
an = ch_realloc( an, ( i + j + 1 ) * sizeof( AttributeName ) );
BER_BVZERO( &an[i + j].an_name );
anew = an + i;
for ( s = ldap_pvt_strtok( str, brkstr, &lasts );
s != NULL;
......
......@@ -30,7 +30,6 @@
#include <ac/time.h>
#include <ac/socket.h>
#include "ldap_pvt.h"
#include "slap.h"
#ifdef LDAP_SLAPI
......
......@@ -24,7 +24,6 @@
#include <ac/string.h>
#include <ac/time.h>
#include "ldap_pvt.h"
#include "slap.h"
......
......@@ -38,7 +38,6 @@
#include <ac/string.h>
#include <ac/time.h>
#include "ldap_pvt.h"
#include "slap.h"
void
......
......@@ -31,7 +31,6 @@
#include "slap.h"
#include "../back-ldap/back-ldap.h"
#include "back-meta.h"
#include "ldap_pvt.h"
#undef ldap_debug /* silence a warning in ldap-int.h */
#include "ldap_log.h"
#include "../../../libraries/libldap/ldap-int.h"
......
......@@ -159,13 +159,8 @@ monitor_subsys_ops_update(
struct monitorinfo *mi =
(struct monitorinfo *)op->o_bd->be_private;
#ifdef HAVE_GMP
mpz_t nInitiated,
ldap_pvt_mp_t nInitiated,
nCompleted;
#else /* ! HAVE_GMP */
unsigned long nInitiated = 0,
nCompleted = 0;
#endif /* ! HAVE_GMP */
struct berval rdn;
int i;
Attribute *a;
......@@ -177,20 +172,13 @@ monitor_subsys_ops_update(
dnRdn( &e->e_nname, &rdn );
if ( dn_match( &rdn, &bv_ops ) ) {
#ifdef HAVE_GMP
mpz_init( nInitiated );
mpz_init( nCompleted );
#endif /* HAVE_GMP */
ldap_pvt_mp_init( nInitiated );
ldap_pvt_mp_init( nCompleted );
ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex );
for ( i = 0; i < SLAP_OP_LAST; i++ ) {
#ifdef HAVE_GMP
mpz_add( nInitiated, nInitiated, slap_counters.sc_ops_initiated_[ i ] );
mpz_add( nCompleted, nCompleted, slap_counters.sc_ops_completed_[ i ] );
#else /* ! HAVE_GMP */
nInitiated += slap_counters.sc_ops_initiated_[ i ];
nCompleted += slap_counters.sc_ops_completed_[ i ];
#endif /* ! HAVE_GMP */
ldap_pvt_mp_add( nInitiated, slap_counters.sc_ops_initiated_[ i ] );
ldap_pvt_mp_add( nCompleted, slap_counters.sc_ops_completed_[ i ] );
}
ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex );
......@@ -199,13 +187,8 @@ monitor_subsys_ops_update(
if ( dn_match( &rdn, &monitor_op[ i ].nrdn ) )
{
ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex );
#ifdef HAVE_GMP
mpz_init_set( nInitiated, slap_counters.sc_ops_initiated_[ i ] );
mpz_init_set( nCompleted, slap_counters.sc_ops_completed_[ i ] );
#else /* ! HAVE_GMP */
nInitiated = slap_counters.sc_ops_initiated_[ i ];
nCompleted = slap_counters.sc_ops_completed_[ i ];
#endif /* ! HAVE_GMP */
ldap_pvt_mp_init_set( nInitiated, slap_counters.sc_ops_initiated_[ i ] );
ldap_pvt_mp_init_set( nCompleted, slap_counters.sc_ops_completed_[ i ] );
ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex );
break;
}
......@@ -222,18 +205,14 @@ monitor_subsys_ops_update(
/* NOTE: no minus sign is allowed in the counters... */
UI2BV( &a->a_vals[ 0 ], nInitiated );
#ifdef HAVE_GMP
mpz_clear( nInitiated );
#endif /* HAVE_GMP */
ldap_pvt_mp_clear( nInitiated );
a = attr_find( e->e_attrs, mi->mi_ad_monitorOpCompleted );
assert ( a != NULL );
/* NOTE: no minus sign is allowed in the counters... */
UI2BV( &a->a_vals[ 0 ], nCompleted );
#ifdef HAVE_GMP
mpz_clear( nCompleted );
#endif /* HAVE_GMP */
ldap_pvt_mp_clear( nCompleted );
return( 0 );
}
......
......@@ -99,7 +99,26 @@ int monitor_subsys_time_update LDAP_P(( Operation *op, Entry *e ));
/* NOTE: this macro assumes that bv has been allocated
* by ber_* malloc functions or is { 0L, NULL } */
#ifdef HAVE_GMP
#if defined(HAVE_BIGNUM)
#define UI2BV(bv,ui) \
do { \
char *val; \
ber_len_t len; \
val = BN_bn2dec(ui); \
if (val) { \
len = strlen(val); \
if ( len > (bv)->bv_len ) { \
(bv)->bv_val = ber_memrealloc( (bv)->bv_val, len + 1 ); \
} \
AC_MEMCPY((bv)->bv_val, val, len + 1); \
(bv)->bv_len = len; \
OPENSSL_free(val); \
} else { \
ber_memfree( (bv)->bv_val ); \
BER_BVZERO( (bv) ); \
} \
} while ( 0 )
#elif defined(HAVE_GMP)
/* NOTE: according to the documentation, the result
* of mpz_sizeinbase() can exceed the length of the
* string representation of the number by 1
......@@ -116,7 +135,7 @@ int monitor_subsys_time_update LDAP_P(( Operation *op, Entry *e ));
} \
(bv)->bv_len = len; \
} while ( 0 )
#else /* ! HAVE_GMP */
#else /* ! HAVE_BIGNUM && ! HAVE_GMP */
#define UI2BV(bv,ui) \
do { \
char buf[] = "+9223372036854775807L"; \
......
......@@ -28,6 +28,22 @@
#include "lutil.h"
#include "back-monitor.h"
enum {
MONITOR_RWW_READ = 0,
MONITOR_RWW_WRITE,
MONITOR_RWW_LAST
};
struct monitor_rww_t {
struct berval rdn;
struct berval nrdn;
} monitor_rww[] = {
{ BER_BVC("cn=Read"), BER_BVNULL },
{ BER_BVC("cn=Write"), BER_BVNULL },
{ BER_BVNULL, BER_BVNULL }
};
int
monitor_subsys_rww_init(
BackendDB *be
......@@ -35,10 +51,9 @@ monitor_subsys_rww_init(
{
struct monitorinfo *mi;
Entry *e, **ep, *e_conn;
Entry **ep, *e_conn;
struct monitorentrypriv *mp;
char buf[ BACKMONITOR_BUFSIZE ];
struct berval bv;
int i;
assert( be != NULL );
......@@ -57,109 +72,66 @@ monitor_subsys_rww_init(
mp->mp_children = NULL;
ep = &mp->mp_children;
/*
* Total conns
*/
snprintf( buf, sizeof( buf ),
"dn: cn=Read,%s\n"
"objectClass: %s\n"
"structuralObjectClass: %s\n"
"cn: Read\n"
"creatorsName: %s\n"
"modifiersName: %s\n"
"createTimestamp: %s\n"
"modifyTimestamp: %s\n",
monitor_subsys[SLAPD_MONITOR_RWW].mss_dn.bv_val,
mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
mi->mi_creatorsName.bv_val,
mi->mi_creatorsName.bv_val,
mi->mi_startTime.bv_val,
mi->mi_startTime.bv_val );
e = str2entry( buf );
if ( e == NULL ) {
Debug( LDAP_DEBUG_ANY,
"monitor_subsys_rww_init: "
"unable to create entry \"cn=Read,%s\"\n",
monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn.bv_val, 0, 0 );
return( -1 );
}
bv.bv_val = "0";
bv.bv_len = 1;
attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
e->e_private = ( void * )mp;
mp->mp_next = NULL;
mp->mp_children = NULL;
mp->mp_info = &monitor_subsys[SLAPD_MONITOR_RWW];
mp->mp_flags = monitor_subsys[SLAPD_MONITOR_RWW].mss_flags \
| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
if ( monitor_cache_add( mi, e ) ) {
Debug( LDAP_DEBUG_ANY,
"monitor_subsys_rww_init: "
"unable to add entry \"cn=Read,%s\"\n",
monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn.bv_val, 0, 0 );
return( -1 );
}
*ep = e;
ep = &mp->mp_next;
/*
* Current conns
*/
snprintf( buf, sizeof( buf ),
"dn: cn=Write,%s\n"
for ( i = 0; i < MONITOR_RWW_LAST; i++ ) {
char buf[ BACKMONITOR_BUFSIZE ];
struct berval nrdn, bv;
Entry *e;
snprintf( buf, sizeof( buf ),
"dn: %s,%s\n"
"objectClass: %s\n"
"structuralObjectClass: %s\n"
"cn: Write\n"
"cn: %s\n"
"creatorsName: %s\n"
"modifiersName: %s\n"
"createTimestamp: %s\n"
"modifyTimestamp: %s\n",
monitor_rww[i].rdn.bv_val,
monitor_subsys[SLAPD_MONITOR_RWW].mss_dn.bv_val,
mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
&monitor_rww[i].rdn.bv_val[STRLENOF("cn")],
mi->mi_creatorsName.bv_val,
mi->mi_creatorsName.bv_val,
mi->mi_startTime.bv_val,
mi->mi_startTime.bv_val );
e = str2entry( buf );
if ( e == NULL ) {
Debug( LDAP_DEBUG_ANY,
"monitor_subsys_rww_init: "
"unable to create entry \"cn=Write,%s\"\n",
monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn.bv_val, 0, 0 );
return( -1 );
}
e = str2entry( buf );
if ( e == NULL ) {
Debug( LDAP_DEBUG_ANY,
"monitor_subsys_rww_init: "
"unable to create entry \"cn=Read,%s\"\n",
monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn.bv_val, 0, 0 );
return( -1 );
}
/* steal normalized RDN */
dnRdn( &e->e_nname, &nrdn );
ber_dupbv( &monitor_rww[i].nrdn, &nrdn );
bv.bv_val = "0";
bv.bv_len = 1;
attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
BER_BVSTR( &bv, "0" );
attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
e->e_private = ( void * )mp;
mp->mp_next = NULL;
mp->mp_children = NULL;
mp->mp_info = &monitor_subsys[SLAPD_MONITOR_RWW];
mp->mp_flags = monitor_subsys[SLAPD_MONITOR_RWW].mss_flags \
| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
if ( monitor_cache_add( mi, e ) ) {
Debug( LDAP_DEBUG_ANY,
"monitor_subsys_rww_init: "
"unable to add entry \"cn=Write,%s\"\n",
monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn.bv_val, 0, 0 );
return( -1 );
}
mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
e->e_private = ( void * )mp;
mp->mp_next = NULL;
mp->mp_children = NULL;
mp->mp_info = &monitor_subsys[SLAPD_MONITOR_RWW];
mp->mp_flags = monitor_subsys[SLAPD_MONITOR_RWW].mss_flags \
| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
if ( monitor_cache_add( mi, e ) ) {
Debug( LDAP_DEBUG_ANY,
"monitor_subsys_rww_init: "
"unable to add entry \"%s,%s\"\n",
monitor_rww[i].rdn.bv_val,
monitor_subsys[SLAPD_MONITOR_RWW].mss_ndn.bv_val, 0 );
return( -1 );
}
*ep = e;
ep = &mp->mp_next;
*ep = e;
ep = &mp->mp_next;
}
monitor_cache_release( mi, e_conn );
......@@ -177,49 +149,51 @@ monitor_subsys_rww_update(
int connindex;
long nconns, nwritewaiters, nreadwaiters;
#define RWW_NONE 0
#define RWW_READ 1
#define RWW_WRITE 2
int type = RWW_NONE;
int i;
struct berval nrdn;
Attribute *a;
char buf[] = "+9223372036854775807L";
long num = 0;
ber_len_t len;
assert( mi != NULL );
assert( e != NULL );
if ( strncasecmp( e->e_ndn, "cn=read",
sizeof("cn=read")-1 ) == 0 ) {
type = RWW_READ;
} else if ( strncasecmp( e->e_ndn, "cn=write",
sizeof("cn=write")-1 ) == 0 ) {
type = RWW_WRITE;
dnRdn( &e->e_nname, &nrdn );
for ( i = 0; !BER_BVISNULL( &monitor_rww[i].nrdn ); i++ ) {
if ( dn_match( &nrdn, &monitor_rww[i].nrdn ) ) {
break;
}
}
} else {
return( 0 );
if ( i == MONITOR_RWW_LAST ) {
return 0;
}
nconns = nwritewaiters = nreadwaiters = 0;
for ( c = connection_first( &connindex );
c != NULL;
c = connection_next( c, &connindex ), nconns++ ) {
c = connection_next( c, &connindex ), nconns++ )
{
if ( c->c_writewaiter ) {
nwritewaiters++;
}