diff --git a/servers/slapd/back-monitor/back-monitor.h b/servers/slapd/back-monitor/back-monitor.h index e6441f27db..0bf28cbecb 100644 --- a/servers/slapd/back-monitor/back-monitor.h +++ b/servers/slapd/back-monitor/back-monitor.h @@ -141,6 +141,12 @@ typedef struct monitor_info_t { AttributeDescription *mi_ad_monitorLogLevel; AttributeDescription *mi_ad_monitorDebugLevel; AttributeDescription *mi_ad_monitorTotalListenerConnections; + AttributeDescription *mi_ad_monitorConnectionOpsDeferTotal; + AttributeDescription *mi_ad_monitorConnectionOpsDeferBinding; + AttributeDescription *mi_ad_monitorConnectionOpsDeferClosing; + AttributeDescription *mi_ad_monitorConnectionOpsDeferExecuting; + AttributeDescription *mi_ad_monitorConnectionOpsDeferPending; + AttributeDescription *mi_ad_monitorConnectionOpsDeferWritewait; /* * Generic description attribute diff --git a/servers/slapd/back-monitor/conn.c b/servers/slapd/back-monitor/conn.c index 2c24708d72..f075a6cdfa 100644 --- a/servers/slapd/back-monitor/conn.c +++ b/servers/slapd/back-monitor/conn.c @@ -370,6 +370,24 @@ conn_create( bv.bv_len = snprintf( buf, sizeof( buf ), "%ld", c->c_n_write ); attr_merge_one( e, mi->mi_ad_monitorConnectionWrite, &bv, NULL ); + bv.bv_len = snprintf( buf, sizeof( buf ), "%ld", c->c_n_ops_defer_total ); + attr_merge_one( e, mi->mi_ad_monitorConnectionOpsDeferTotal, &bv, NULL ); + + bv.bv_len = snprintf( buf, sizeof( buf ), "%ld", c->c_n_ops_defer_binding ); + attr_merge_one( e, mi->mi_ad_monitorConnectionOpsDeferBinding, &bv, NULL ); + + bv.bv_len = snprintf( buf, sizeof( buf ), "%ld", c->c_n_ops_defer_closing ); + attr_merge_one( e, mi->mi_ad_monitorConnectionOpsDeferClosing, &bv, NULL ); + + bv.bv_len = snprintf( buf, sizeof( buf ), "%ld", c->c_n_ops_defer_executing ); + attr_merge_one( e, mi->mi_ad_monitorConnectionOpsDeferExecuting, &bv, NULL ); + + bv.bv_len = snprintf( buf, sizeof( buf ), "%ld", c->c_n_ops_defer_pending ); + attr_merge_one( e, mi->mi_ad_monitorConnectionOpsDeferPending, &bv, NULL ); + + bv.bv_len = snprintf( buf, sizeof( buf ), "%ld", c->c_n_ops_defer_writewait ); + attr_merge_one( e, mi->mi_ad_monitorConnectionOpsDeferWritewait, &bv, NULL ); + bv.bv_len = snprintf( buf, sizeof( buf ), "%s%s%s%s%s%s", c->c_currentber ? "r" : "", c->c_writewaiter ? "w" : "", diff --git a/servers/slapd/back-monitor/init.c b/servers/slapd/back-monitor/init.c index 48e3e630d9..cdf7360737 100644 --- a/servers/slapd/back-monitor/init.c +++ b/servers/slapd/back-monitor/init.c @@ -1961,6 +1961,48 @@ monitor_back_initialize( "NO-USER-MODIFICATION " "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, offsetof(monitor_info_t, mi_ad_monitorTotalListenerConnections) }, + { "( 1.3.6.1.4.1.4203.666.1.55.35 " + "NAME 'monitorConnectionOpsDeferTotal' " + "DESC 'monitor total number of deferred operations within the connection' " + "SUP monitorCounter " + "NO-USER-MODIFICATION " + "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, + offsetof(monitor_info_t, mi_ad_monitorConnectionOpsDeferTotal) }, + { "( 1.3.6.1.4.1.4203.666.1.55.36 " + "NAME 'monitorConnectionOpsDeferBinding' " + "DESC 'monitor number of operations deferred because the connection is binding' " + "SUP monitorCounter " + "NO-USER-MODIFICATION " + "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, + offsetof(monitor_info_t, mi_ad_monitorConnectionOpsDeferBinding) }, + { "( 1.3.6.1.4.1.4203.666.1.55.37 " + "NAME 'monitorConnectionOpsDeferClosing' " + "DESC 'monitor number of operations deferred because the connection is closing' " + "SUP monitorCounter " + "NO-USER-MODIFICATION " + "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, + offsetof(monitor_info_t, mi_ad_monitorConnectionOpsDeferClosing) }, + { "( 1.3.6.1.4.1.4203.666.1.55.38 " + "NAME 'monitorConnectionOpsDeferExecuting' " + "DESC 'monitor number of operations deferred because there are too many executing operations within the connection' " + "SUP monitorCounter " + "NO-USER-MODIFICATION " + "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, + offsetof(monitor_info_t, mi_ad_monitorConnectionOpsDeferExecuting) }, + { "( 1.3.6.1.4.1.4203.666.1.55.39 " + "NAME 'monitorConnectionOpsDeferPending' " + "DESC 'monitor number of operations deferred because there are too many pending operations within the connection' " + "SUP monitorCounter " + "NO-USER-MODIFICATION " + "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, + offsetof(monitor_info_t, mi_ad_monitorConnectionOpsDeferPending) }, + { "( 1.3.6.1.4.1.4203.666.1.55.40 " + "NAME 'monitorConnectionOpsDeferWritewait' " + "DESC 'monitor number of operations deferred because the server is waiting to write on the connection' " + "SUP monitorCounter " + "NO-USER-MODIFICATION " + "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, + offsetof(monitor_info_t, mi_ad_monitorConnectionOpsDeferWritewait) }, { NULL, 0, -1 } }; diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index 2766b94193..073e7a33c2 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -430,6 +430,13 @@ Connection * connection_init( c->c_n_ops_completed = 0; c->c_n_ops_async = 0; + c->c_n_ops_defer_total = 0; + c->c_n_ops_defer_binding = 0; + c->c_n_ops_defer_closing = 0; + c->c_n_ops_defer_executing = 0; + c->c_n_ops_defer_pending = 0; + c->c_n_ops_defer_writewait = 0; + c->c_n_get = 0; c->c_n_read = 0; c->c_n_write = 0; @@ -1661,11 +1668,14 @@ connection_input( Connection *conn , conn_readinfo *cri ) /* Abandon and Unbind are exempt from these checks */ if (conn->c_conn_state == SLAP_C_CLOSING) { defer = "closing"; + conn->c_n_ops_defer_closing++; break; } else if (conn->c_writewaiter) { defer = "awaiting write"; + conn->c_n_ops_defer_writewait++; break; } else if (conn->c_n_ops_pending) { + conn->c_n_ops_defer_pending++; defer = "pending operations"; break; } @@ -1673,9 +1683,11 @@ connection_input( Connection *conn , conn_readinfo *cri ) case LDAP_REQ_ABANDON: /* Unbind is exempt from these checks */ if (conn->c_n_ops_executing >= connection_pool_max/2) { + conn->c_n_ops_defer_executing++; defer = "too many executing"; break; } else if (conn->c_conn_state == SLAP_C_BINDING) { + conn->c_n_ops_defer_binding++; defer = "binding"; break; } @@ -1692,6 +1704,7 @@ connection_input( Connection *conn , conn_readinfo *cri ) Debug( LDAP_DEBUG_ANY, "connection_input: conn=%lu deferring operation: %s\n", conn->c_connid, defer ); + conn->c_n_ops_defer_total++; conn->c_n_ops_pending++; LDAP_STAILQ_INSERT_TAIL( &conn->c_pending_ops, op, o_next ); rc = ( conn->c_n_ops_pending > max ) ? -1 : 0; diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index d0d6d69395..cf071b813f 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -2990,6 +2990,13 @@ struct Connection { long c_n_ops_completed; /* num of ops completed */ long c_n_ops_async; /* mum of ops currently executing asynchronously */ + long c_n_ops_defer_total; /* num of total deferred ops */ + long c_n_ops_defer_binding; /* num of ops deferred because the connection is binding */ + long c_n_ops_defer_closing; /* num of ops deferred because the connection is closing */ + long c_n_ops_defer_executing; /* num of ops deferred because of too many executing ops */ + long c_n_ops_defer_pending; /* num of ops deferred because of too many pending ops */ + long c_n_ops_defer_writewait; /* num of ops deferred because the connection is waiting to write */ + long c_n_get; /* num of get calls */ long c_n_read; /* num of read calls */ long c_n_write; /* num of write calls */