mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-01 10:06:57 +03:00
Update.
* nscd/cache.c (cache_search): Keep track of how many chain links we searched and update table statistics. (cache_add): Keep track of how many values are in the table. (prune_cache): Likewise. Keep track of locking success. Print messages about removed entries in separate pass. * nscd/connections.c (handle_request): Don't print debug message here. The caller will do it. Keep track of locking success. (nscd_run): Print debug message. Also print PID of the client process. * nscd/nscd.c (start_time): New variable. (main): Remember start time. * nscd/nscd.h: Declare start_time. (struct database): Add more members for new statistics. * nscd/nscd_stat.c: Add support for sending, receiving, and printing of new statistics.
This commit is contained in:
15
ChangeLog
15
ChangeLog
@ -1,5 +1,20 @@
|
|||||||
2003-04-25 Ulrich Drepper <drepper@redhat.com>
|
2003-04-25 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* nscd/cache.c (cache_search): Keep track of how many chain links
|
||||||
|
we searched and update table statistics.
|
||||||
|
(cache_add): Keep track of how many values are in the table.
|
||||||
|
(prune_cache): Likewise. Keep track of locking success.
|
||||||
|
Print messages about removed entries in separate pass.
|
||||||
|
* nscd/connections.c (handle_request): Don't print debug message here.
|
||||||
|
The caller will do it. Keep track of locking success.
|
||||||
|
(nscd_run): Print debug message. Also print PID of the client process.
|
||||||
|
* nscd/nscd.c (start_time): New variable.
|
||||||
|
(main): Remember start time.
|
||||||
|
* nscd/nscd.h: Declare start_time.
|
||||||
|
(struct database): Add more members for new statistics.
|
||||||
|
* nscd/nscd_stat.c: Add support for sending, receiving, and printing
|
||||||
|
of new statistics.
|
||||||
|
|
||||||
* sysdeps/posix/getaddrinfo.c: Include <stdbool.h>.
|
* sysdeps/posix/getaddrinfo.c: Include <stdbool.h>.
|
||||||
|
|
||||||
2003-04-22 Jakub Jelinek <jakub@redhat.com>
|
2003-04-22 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
@ -120,14 +120,17 @@ struct _pthread_descr_struct
|
|||||||
union dtv *dtvp;
|
union dtv *dtvp;
|
||||||
pthread_descr self; /* Pointer to this structure */
|
pthread_descr self; /* Pointer to this structure */
|
||||||
int multiple_threads;
|
int multiple_threads;
|
||||||
# define p_multiple_threads(descr) (descr)->p_header.data.multiple_threads
|
|
||||||
# ifdef NEED_DL_SYSINFO
|
# ifdef NEED_DL_SYSINFO
|
||||||
uintptr_t sysinfo;
|
uintptr_t sysinfo;
|
||||||
# endif
|
# endif
|
||||||
} data;
|
} data;
|
||||||
void *__padding[16];
|
void *__padding[16];
|
||||||
} p_header;
|
} p_header;
|
||||||
|
# define p_multiple_threads p_header.data.multiple_threads
|
||||||
|
#elif TLS_MULTIPLE_THREADS_IN_TCB
|
||||||
|
int p_multiple_threads;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pthread_descr p_nextlive, p_prevlive;
|
pthread_descr p_nextlive, p_prevlive;
|
||||||
/* Double chaining of active threads */
|
/* Double chaining of active threads */
|
||||||
pthread_descr p_nextwaiting; /* Next element in the queue holding the thr */
|
pthread_descr p_nextwaiting; /* Next element in the queue holding the thr */
|
||||||
@ -186,22 +189,7 @@ struct _pthread_descr_struct
|
|||||||
#endif
|
#endif
|
||||||
size_t p_alloca_cutoff; /* Maximum size which should be allocated
|
size_t p_alloca_cutoff; /* Maximum size which should be allocated
|
||||||
using alloca() instead of malloc(). */
|
using alloca() instead of malloc(). */
|
||||||
/* New elements must be added at the end before __multiple_threads. */
|
/* New elements must be added at the end. */
|
||||||
#if TLS_MULTIPLE_THREADS_IN_TCB
|
|
||||||
/* This field here isn't necessarily multiple_threads, which is really
|
|
||||||
the last integer in struct _pthread_descr_struct. */
|
|
||||||
int __multiple_threads;
|
|
||||||
# define p_multiple_threads(descr) \
|
|
||||||
(((union \
|
|
||||||
{ \
|
|
||||||
struct _pthread_descr_struct s; \
|
|
||||||
struct \
|
|
||||||
{ \
|
|
||||||
char dummy[sizeof (struct _pthread_descr_struct) - sizeof (int)]; \
|
|
||||||
int multiple_threads; \
|
|
||||||
} m; \
|
|
||||||
} *)(descr))->m.multiple_threads)
|
|
||||||
#endif
|
|
||||||
} __attribute__ ((aligned(32))); /* We need to align the structure so that
|
} __attribute__ ((aligned(32))); /* We need to align the structure so that
|
||||||
doubles are aligned properly. This is 8
|
doubles are aligned properly. This is 8
|
||||||
bytes on MIPS and 16 bytes on MIPS64.
|
bytes on MIPS and 16 bytes on MIPS64.
|
||||||
|
@ -571,7 +571,7 @@ int __pthread_initialize_manager(void)
|
|||||||
|
|
||||||
__pthread_multiple_threads = 1;
|
__pthread_multiple_threads = 1;
|
||||||
#if TLS_MULTIPLE_THREADS_IN_TCB || !defined USE_TLS || !TLS_DTV_AT_TP
|
#if TLS_MULTIPLE_THREADS_IN_TCB || !defined USE_TLS || !TLS_DTV_AT_TP
|
||||||
p_multiple_threads (__pthread_main_thread) = 1;
|
__pthread_main_thread->p_multiple_threads = 1;
|
||||||
#endif
|
#endif
|
||||||
*__libc_multiple_threads_ptr = 1;
|
*__libc_multiple_threads_ptr = 1;
|
||||||
|
|
||||||
@ -620,7 +620,7 @@ int __pthread_initialize_manager(void)
|
|||||||
#if !defined USE_TLS || !TLS_DTV_AT_TP
|
#if !defined USE_TLS || !TLS_DTV_AT_TP
|
||||||
mgr->p_header.data.tcb = tcbp;
|
mgr->p_header.data.tcb = tcbp;
|
||||||
mgr->p_header.data.self = mgr;
|
mgr->p_header.data.self = mgr;
|
||||||
p_multiple_threads (mgr) = 1;
|
mgr->p_header.data.multiple_threads = 1;
|
||||||
#elif TLS_MULTIPLE_THREADS_IN_TCB
|
#elif TLS_MULTIPLE_THREADS_IN_TCB
|
||||||
p_multiple_threads (mgr) = 1;
|
p_multiple_threads (mgr) = 1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
--
|
--
|
||||||
#ifdef USE_TLS
|
#ifdef USE_TLS
|
||||||
MULTIPLE_THREADS_OFFSET -sizeof(int)
|
MULTIPLE_THREADS_OFFSET offsetof (struct _pthread_descr_struct, p_multiple_threads) - sizeof (struct _pthread_descr_struct)
|
||||||
#else
|
#else
|
||||||
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
|
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,6 +32,8 @@ typedef union dtv
|
|||||||
void *pointer;
|
void *pointer;
|
||||||
} dtv_t;
|
} dtv_t;
|
||||||
|
|
||||||
|
#else /* __ASSEMBLER__ */
|
||||||
|
# include <tcb-offsets.h>
|
||||||
#endif /* __ASSEMBLER__ */
|
#endif /* __ASSEMBLER__ */
|
||||||
|
|
||||||
#ifdef HAVE_TLS_SUPPORT
|
#ifdef HAVE_TLS_SUPPORT
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
--
|
--
|
||||||
#ifdef USE_TLS
|
#ifdef USE_TLS
|
||||||
MULTIPLE_THREADS_OFFSET ((char *) &p_multiple_threads ((struct _pthread_descr_struct *)0) - (char *) 0)
|
MULTIPLE_THREADS_OFFSET offsetof (struct _pthread_descr_struct, p_multiple_threads)
|
||||||
TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct)
|
TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct)
|
||||||
#else
|
#else
|
||||||
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
|
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
|
||||||
|
@ -21,8 +21,6 @@
|
|||||||
#include <tls.h>
|
#include <tls.h>
|
||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
# include <linuxthreads/internals.h>
|
# include <linuxthreads/internals.h>
|
||||||
#else
|
|
||||||
# include <tcb-offsets.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined NOT_IN_libc || defined IS_IN_libpthread
|
#if !defined NOT_IN_libc || defined IS_IN_libpthread
|
||||||
@ -87,7 +85,7 @@
|
|||||||
|
|
||||||
# ifndef __ASSEMBLER__
|
# ifndef __ASSEMBLER__
|
||||||
# define SINGLE_THREAD_P \
|
# define SINGLE_THREAD_P \
|
||||||
__builtin_expect (p_multiple_threads (THREAD_SELF) == 0, 1)
|
__builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1)
|
||||||
# else
|
# else
|
||||||
# define SINGLE_THREAD_P \
|
# define SINGLE_THREAD_P \
|
||||||
lwz 10,MULTIPLE_THREADS_OFFSET(2); \
|
lwz 10,MULTIPLE_THREADS_OFFSET(2); \
|
||||||
|
@ -121,7 +121,7 @@
|
|||||||
# ifndef __ASSEMBLER__
|
# ifndef __ASSEMBLER__
|
||||||
# if defined FLOATING_STACKS && USE___THREAD && defined PIC
|
# if defined FLOATING_STACKS && USE___THREAD && defined PIC
|
||||||
# define SINGLE_THREAD_P \
|
# define SINGLE_THREAD_P \
|
||||||
__builtin_expect (p_multiple_threads (THREAD_SELF) == 0, 1)
|
__builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1)
|
||||||
# else
|
# else
|
||||||
extern int __local_multiple_threads attribute_hidden;
|
extern int __local_multiple_threads attribute_hidden;
|
||||||
# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
|
# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
|
||||||
|
50
nscd/cache.c
50
nscd/cache.c
@ -44,11 +44,14 @@ cache_search (request_type type, void *key, size_t len, struct database *table,
|
|||||||
{
|
{
|
||||||
unsigned long int hash = __nis_hash (key, len) % table->module;
|
unsigned long int hash = __nis_hash (key, len) % table->module;
|
||||||
struct hashentry *work;
|
struct hashentry *work;
|
||||||
|
unsigned long int nsearched = 0;
|
||||||
|
|
||||||
work = table->array[hash];
|
work = table->array[hash];
|
||||||
|
|
||||||
while (work != NULL)
|
while (work != NULL)
|
||||||
{
|
{
|
||||||
|
++nsearched;
|
||||||
|
|
||||||
if (type == work->type && len == work->len
|
if (type == work->type && len == work->len
|
||||||
&& memcmp (key, work->key, len) == 0 && work->owner == owner)
|
&& memcmp (key, work->key, len) == 0 && work->owner == owner)
|
||||||
{
|
{
|
||||||
@ -58,13 +61,16 @@ cache_search (request_type type, void *key, size_t len, struct database *table,
|
|||||||
else
|
else
|
||||||
++table->poshit;
|
++table->poshit;
|
||||||
|
|
||||||
return work;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
work = work->next;
|
work = work->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
if (nsearched > table->maxnsearched)
|
||||||
|
table->maxnsearched = nsearched;
|
||||||
|
|
||||||
|
return work;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a new entry to the cache. The return value is zero if the function
|
/* Add a new entry to the cache. The return value is zero if the function
|
||||||
@ -109,6 +115,12 @@ cache_add (int type, void *key, size_t len, const void *packet, size_t total,
|
|||||||
++table->negmiss;
|
++table->negmiss;
|
||||||
else if (last)
|
else if (last)
|
||||||
++table->posmiss;
|
++table->posmiss;
|
||||||
|
|
||||||
|
/* Instead of slowing down the normal process for statistics
|
||||||
|
collection we accept living with some incorrect data. */
|
||||||
|
unsigned long int nentries = ++table->nentries;
|
||||||
|
if (nentries > table->maxnentries)
|
||||||
|
table->maxnentries = nentries;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Walk through the table and remove all entries which lifetime ended.
|
/* Walk through the table and remove all entries which lifetime ended.
|
||||||
@ -195,7 +207,11 @@ prune_cache (struct database *table, time_t now)
|
|||||||
|
|
||||||
/* Now we have to get the write lock since we are about to modify
|
/* Now we have to get the write lock since we are about to modify
|
||||||
the table. */
|
the table. */
|
||||||
|
if (__builtin_expect (pthread_rwlock_trywrlock (&table->lock) != 0, 0))
|
||||||
|
{
|
||||||
|
++table->wrlockdelayed;
|
||||||
pthread_rwlock_wrlock (&table->lock);
|
pthread_rwlock_wrlock (&table->lock);
|
||||||
|
}
|
||||||
|
|
||||||
while (first <= last)
|
while (first <= last)
|
||||||
{
|
{
|
||||||
@ -208,6 +224,7 @@ prune_cache (struct database *table, time_t now)
|
|||||||
table->array[first]->dellist = head;
|
table->array[first]->dellist = head;
|
||||||
head = table->array[first];
|
head = table->array[first];
|
||||||
table->array[first] = head->next;
|
table->array[first] = head->next;
|
||||||
|
--table->nentries;
|
||||||
if (--mark[first] == 0)
|
if (--mark[first] == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -221,6 +238,7 @@ prune_cache (struct database *table, time_t now)
|
|||||||
head = runp->next;
|
head = runp->next;
|
||||||
runp->next = head->next;
|
runp->next = head->next;
|
||||||
--mark[first];
|
--mark[first];
|
||||||
|
--table->nentries;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
runp = runp->next;
|
runp = runp->next;
|
||||||
@ -232,29 +250,35 @@ prune_cache (struct database *table, time_t now)
|
|||||||
/* It's all done. */
|
/* It's all done. */
|
||||||
pthread_rwlock_unlock (&table->lock);
|
pthread_rwlock_unlock (&table->lock);
|
||||||
|
|
||||||
/* And another run to free the data. */
|
/* One extra pass if we do debugging. */
|
||||||
do
|
if (__builtin_expect (debug_level > 0, 0))
|
||||||
{
|
{
|
||||||
struct hashentry *old = head;
|
struct hashentry *runp = head;
|
||||||
|
|
||||||
if (debug_level > 0)
|
while (runp != NULL)
|
||||||
{
|
{
|
||||||
char buf[INET6_ADDRSTRLEN];
|
char buf[INET6_ADDRSTRLEN];
|
||||||
const char *str;
|
const char *str;
|
||||||
|
|
||||||
if ((old->type == GETHOSTBYADDR || old->type == GETHOSTBYADDRv6)
|
if (runp->type == GETHOSTBYADDR || runp->type == GETHOSTBYADDRv6)
|
||||||
&& (old->last || old->data == (void *) -1))
|
|
||||||
{
|
{
|
||||||
inet_ntop (old->type == GETHOSTBYADDR ? AF_INET : AF_INET6,
|
inet_ntop (runp->type == GETHOSTBYADDR ? AF_INET : AF_INET6,
|
||||||
old->key, buf, sizeof (buf));
|
runp->key, buf, sizeof (buf));
|
||||||
str = buf;
|
str = buf;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
str = old->last ? old->key : (old->data == (void *) -1
|
str = runp->key;
|
||||||
? old->key : "???");
|
|
||||||
|
|
||||||
dbg_log ("remove %s entry \"%s\"", serv2str[old->type], str);
|
dbg_log ("remove %s entry \"%s\"", serv2str[runp->type], str);
|
||||||
|
|
||||||
|
runp = runp->next;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And another run to free the data. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
struct hashentry *old = head;
|
||||||
|
|
||||||
/* Free the data structures. */
|
/* Free the data structures. */
|
||||||
if (old->data == (void *) -1)
|
if (old->data == (void *) -1)
|
||||||
|
@ -256,10 +256,6 @@ invalidate_cache (char *key)
|
|||||||
static void
|
static void
|
||||||
handle_request (int fd, request_header *req, void *key, uid_t uid)
|
handle_request (int fd, request_header *req, void *key, uid_t uid)
|
||||||
{
|
{
|
||||||
if (__builtin_expect (debug_level, 0) > 0)
|
|
||||||
dbg_log (_("handle_request: request received (Version = %d)"),
|
|
||||||
req->version);
|
|
||||||
|
|
||||||
if (__builtin_expect (req->version, NSCD_VERSION) != NSCD_VERSION)
|
if (__builtin_expect (req->version, NSCD_VERSION) != NSCD_VERSION)
|
||||||
{
|
{
|
||||||
if (debug_level > 0)
|
if (debug_level > 0)
|
||||||
@ -309,7 +305,11 @@ cannot handle old request version %d; current version is %d"),
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Be sure we can read the data. */
|
/* Be sure we can read the data. */
|
||||||
|
if (__builtin_expect (pthread_rwlock_tryrdlock (&db->lock) != 0, 0))
|
||||||
|
{
|
||||||
|
++db->rdlockdelayed;
|
||||||
pthread_rwlock_rdlock (&db->lock);
|
pthread_rwlock_rdlock (&db->lock);
|
||||||
|
}
|
||||||
|
|
||||||
/* See whether we can handle it from the cache. */
|
/* See whether we can handle it from the cache. */
|
||||||
cached = (struct hashentry *) cache_search (req->type, key, req->key_len,
|
cached = (struct hashentry *) cache_search (req->type, key, req->key_len,
|
||||||
@ -465,6 +465,9 @@ nscd_run (void *p)
|
|||||||
request_header req;
|
request_header req;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
uid_t uid = 0;
|
uid_t uid = 0;
|
||||||
|
#ifdef SO_PEERCRED
|
||||||
|
pid_t pid = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (__builtin_expect (fd, 0) < 0)
|
if (__builtin_expect (fd, 0) < 0)
|
||||||
{
|
{
|
||||||
@ -505,6 +508,17 @@ nscd_run (void *p)
|
|||||||
if (req.type < GETPWBYNAME || req.type > LASTDBREQ
|
if (req.type < GETPWBYNAME || req.type > LASTDBREQ
|
||||||
|| secure[serv2db[req.type]])
|
|| secure[serv2db[req.type]])
|
||||||
uid = caller.uid;
|
uid = caller.uid;
|
||||||
|
|
||||||
|
pid = caller.pid;
|
||||||
|
}
|
||||||
|
else if (__builtin_expect (debug_level > 0, 0))
|
||||||
|
{
|
||||||
|
struct ucred caller;
|
||||||
|
socklen_t optlen = sizeof (caller);
|
||||||
|
|
||||||
|
if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED,
|
||||||
|
&caller, &optlen) == 0)
|
||||||
|
pid = caller.pid;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -535,6 +549,19 @@ nscd_run (void *p)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (__builtin_expect (debug_level, 0) > 0)
|
||||||
|
{
|
||||||
|
#ifdef SO_PEERCRED
|
||||||
|
if (pid != 0)
|
||||||
|
dbg_log (_("\
|
||||||
|
handle_request: request received (Version = %d) from PID %ld"),
|
||||||
|
req.version, (long int) pid);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
dbg_log (_("\
|
||||||
|
handle_request: request received (Version = %d)"), req.version);
|
||||||
|
}
|
||||||
|
|
||||||
/* Phew, we got all the data, now process it. */
|
/* Phew, we got all the data, now process it. */
|
||||||
handle_request (fd, &req, keybuf, uid);
|
handle_request (fd, &req, keybuf, uid);
|
||||||
|
|
||||||
|
@ -72,6 +72,8 @@ int secure[lastdb];
|
|||||||
int secure_in_use;
|
int secure_in_use;
|
||||||
static const char *conffile = _PATH_NSCDCONF;
|
static const char *conffile = _PATH_NSCDCONF;
|
||||||
|
|
||||||
|
time_t start_time;
|
||||||
|
|
||||||
static int check_pid (const char *file);
|
static int check_pid (const char *file);
|
||||||
static int write_pid (const char *file);
|
static int write_pid (const char *file);
|
||||||
|
|
||||||
@ -131,6 +133,9 @@ main (int argc, char **argv)
|
|||||||
if (check_pid (_PATH_NSCDPID))
|
if (check_pid (_PATH_NSCDPID))
|
||||||
error (EXIT_FAILURE, 0, _("already running"));
|
error (EXIT_FAILURE, 0, _("already running"));
|
||||||
|
|
||||||
|
/* Remember when we started. */
|
||||||
|
start_time = time (NULL);
|
||||||
|
|
||||||
/* Behave like a daemon. */
|
/* Behave like a daemon. */
|
||||||
if (go_background)
|
if (go_background)
|
||||||
{
|
{
|
||||||
|
10
nscd/nscd.h
10
nscd/nscd.h
@ -77,6 +77,13 @@ struct database
|
|||||||
unsigned long int posmiss;
|
unsigned long int posmiss;
|
||||||
unsigned long int negmiss;
|
unsigned long int negmiss;
|
||||||
|
|
||||||
|
unsigned long int nentries;
|
||||||
|
unsigned long int maxnentries;
|
||||||
|
unsigned long int maxnsearched;
|
||||||
|
|
||||||
|
unsigned long int rdlockdelayed;
|
||||||
|
unsigned long int wrlockdelayed;
|
||||||
|
|
||||||
struct hashentry **array;
|
struct hashentry **array;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -99,6 +106,9 @@ extern int secure_in_use; /* Is one of the above 1 ? */
|
|||||||
/* User name to run server processes as */
|
/* User name to run server processes as */
|
||||||
extern const char *server_user;
|
extern const char *server_user;
|
||||||
|
|
||||||
|
/* Time the server was started. */
|
||||||
|
extern time_t start_time;
|
||||||
|
|
||||||
/* Prototypes for global functions. */
|
/* Prototypes for global functions. */
|
||||||
|
|
||||||
/* nscd.c */
|
/* nscd.c */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 1998 Free Software Foundation, Inc.
|
/* Copyright (c) 1998, 2003 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
|
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
|
||||||
|
|
||||||
@ -46,6 +46,13 @@ struct dbstat
|
|||||||
unsigned long int neghit;
|
unsigned long int neghit;
|
||||||
unsigned long int posmiss;
|
unsigned long int posmiss;
|
||||||
unsigned long int negmiss;
|
unsigned long int negmiss;
|
||||||
|
|
||||||
|
unsigned long int nentries;
|
||||||
|
unsigned long int maxnentries;
|
||||||
|
unsigned long int maxnsearched;
|
||||||
|
|
||||||
|
unsigned long int rdlockdelayed;
|
||||||
|
unsigned long int wrlockdelayed;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Record for transmitting statistics. */
|
/* Record for transmitting statistics. */
|
||||||
@ -53,6 +60,7 @@ struct statdata
|
|||||||
{
|
{
|
||||||
char version[sizeof (compilation)];
|
char version[sizeof (compilation)];
|
||||||
int debug_level;
|
int debug_level;
|
||||||
|
time_t runtime;
|
||||||
int ndbs;
|
int ndbs;
|
||||||
struct dbstat dbs[lastdb];
|
struct dbstat dbs[lastdb];
|
||||||
};
|
};
|
||||||
@ -66,6 +74,7 @@ send_stats (int fd, struct database dbs[lastdb])
|
|||||||
|
|
||||||
memcpy (data.version, compilation, sizeof (compilation));
|
memcpy (data.version, compilation, sizeof (compilation));
|
||||||
data.debug_level = debug_level;
|
data.debug_level = debug_level;
|
||||||
|
data.runtime = time (NULL) - start_time;
|
||||||
data.ndbs = lastdb;
|
data.ndbs = lastdb;
|
||||||
|
|
||||||
for (cnt = 0; cnt < lastdb; ++cnt)
|
for (cnt = 0; cnt < lastdb; ++cnt)
|
||||||
@ -79,6 +88,11 @@ send_stats (int fd, struct database dbs[lastdb])
|
|||||||
data.dbs[cnt].neghit = dbs[cnt].neghit;
|
data.dbs[cnt].neghit = dbs[cnt].neghit;
|
||||||
data.dbs[cnt].posmiss = dbs[cnt].posmiss;
|
data.dbs[cnt].posmiss = dbs[cnt].posmiss;
|
||||||
data.dbs[cnt].negmiss = dbs[cnt].negmiss;
|
data.dbs[cnt].negmiss = dbs[cnt].negmiss;
|
||||||
|
data.dbs[cnt].nentries = dbs[cnt].nentries;
|
||||||
|
data.dbs[cnt].maxnentries = dbs[cnt].maxnentries;
|
||||||
|
data.dbs[cnt].maxnsearched = dbs[cnt].maxnsearched;
|
||||||
|
data.dbs[cnt].rdlockdelayed = dbs[cnt].rdlockdelayed;
|
||||||
|
data.dbs[cnt].wrlockdelayed = dbs[cnt].wrlockdelayed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TEMP_FAILURE_RETRY (write (fd, &data, sizeof (data))) != sizeof (data))
|
if (TEMP_FAILURE_RETRY (write (fd, &data, sizeof (data))) != sizeof (data))
|
||||||
@ -120,7 +134,7 @@ receive_print_stats (void)
|
|||||||
if (TEMP_FAILURE_RETRY (read (fd, &data, sizeof (data))) != sizeof (data)
|
if (TEMP_FAILURE_RETRY (read (fd, &data, sizeof (data))) != sizeof (data)
|
||||||
|| (memcmp (data.version, compilation, sizeof (compilation)) != 0
|
|| (memcmp (data.version, compilation, sizeof (compilation)) != 0
|
||||||
/* Yes, this is an assignment! */
|
/* Yes, this is an assignment! */
|
||||||
&& errno == EINVAL))
|
&& (errno = EINVAL)))
|
||||||
{
|
{
|
||||||
/* Not the right version. */
|
/* Not the right version. */
|
||||||
int err = errno;
|
int err = errno;
|
||||||
@ -131,6 +145,36 @@ receive_print_stats (void)
|
|||||||
printf (_("nscd configuration:\n\n%15d server debug level\n"),
|
printf (_("nscd configuration:\n\n%15d server debug level\n"),
|
||||||
data.debug_level);
|
data.debug_level);
|
||||||
|
|
||||||
|
/* We know that we can simply subtract time_t values. */
|
||||||
|
unsigned long int diff = data.runtime;
|
||||||
|
unsigned int ndays = 0;
|
||||||
|
unsigned int nhours = 0;
|
||||||
|
unsigned int nmins = 0;
|
||||||
|
if (diff > 24 * 60 * 60)
|
||||||
|
{
|
||||||
|
ndays = diff / (24 * 60 * 60);
|
||||||
|
diff %= 24 * 60 * 60;
|
||||||
|
}
|
||||||
|
if (diff > 60 * 60)
|
||||||
|
{
|
||||||
|
nhours = diff / (60 * 60);
|
||||||
|
diff %= 60 * 60;
|
||||||
|
}
|
||||||
|
if (diff > 60)
|
||||||
|
{
|
||||||
|
nmins = diff / 60;
|
||||||
|
diff %= 60;
|
||||||
|
}
|
||||||
|
if (ndays != 0)
|
||||||
|
printf (_("%3ud %2uh %2um %2lus server runtime\n"),
|
||||||
|
ndays, nhours, nmins, diff);
|
||||||
|
else if (nhours != 0)
|
||||||
|
printf (_(" %2uh %2um %2lus server runtime\n"), nhours, nmins, diff);
|
||||||
|
else if (nmins != 0)
|
||||||
|
printf (_(" %2um %2lus server runtime\n"), nmins, diff);
|
||||||
|
else
|
||||||
|
printf (_(" %2lus server runtime\n"), diff);
|
||||||
|
|
||||||
for (i = 0; i < lastdb; ++i)
|
for (i = 0; i < lastdb; ++i)
|
||||||
{
|
{
|
||||||
unsigned long int hit = data.dbs[i].poshit + data.dbs[i].neghit;
|
unsigned long int hit = data.dbs[i].poshit + data.dbs[i].neghit;
|
||||||
@ -153,14 +197,19 @@ receive_print_stats (void)
|
|||||||
|
|
||||||
printf (_("\n%s cache:\n\n"
|
printf (_("\n%s cache:\n\n"
|
||||||
"%15s cache is enabled\n"
|
"%15s cache is enabled\n"
|
||||||
"%15Zd suggested size\n"
|
"%15Zu suggested size\n"
|
||||||
"%15ld seconds time to live for positive entries\n"
|
"%15lu seconds time to live for positive entries\n"
|
||||||
"%15ld seconds time to live for negative entries\n"
|
"%15lu seconds time to live for negative entries\n"
|
||||||
"%15ld cache hits on positive entries\n"
|
"%15lu cache hits on positive entries\n"
|
||||||
"%15ld cache hits on negative entries\n"
|
"%15lu cache hits on negative entries\n"
|
||||||
"%15ld cache misses on positive entries\n"
|
"%15lu cache misses on positive entries\n"
|
||||||
"%15ld cache misses on negative entries\n"
|
"%15lu cache misses on negative entries\n"
|
||||||
"%15ld%% cache hit rate\n"
|
"%15lu%% cache hit rate\n"
|
||||||
|
"%15lu current number of cached values\n"
|
||||||
|
"%15lu maximum number of cached values\n"
|
||||||
|
"%15lu maximum chain length searched\n"
|
||||||
|
"%15lu number of delays on rdlock\n"
|
||||||
|
"%15lu number of delays on wrlock\n"
|
||||||
"%15s check /etc/%s for changes\n"),
|
"%15s check /etc/%s for changes\n"),
|
||||||
dbnames[i], enabled,
|
dbnames[i], enabled,
|
||||||
data.dbs[i].module,
|
data.dbs[i].module,
|
||||||
@ -168,7 +217,10 @@ receive_print_stats (void)
|
|||||||
data.dbs[i].poshit, data.dbs[i].neghit,
|
data.dbs[i].poshit, data.dbs[i].neghit,
|
||||||
data.dbs[i].posmiss, data.dbs[i].negmiss,
|
data.dbs[i].posmiss, data.dbs[i].negmiss,
|
||||||
(100 * hit) / all,
|
(100 * hit) / all,
|
||||||
check_file, dbnames[i]);
|
data.dbs[i].nentries, data.dbs[i].maxnentries,
|
||||||
|
data.dbs[i].maxnsearched,
|
||||||
|
data.dbs[i].rdlockdelayed,
|
||||||
|
data.dbs[i].wrlockdelayed, check_file, dbnames[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
close (fd);
|
close (fd);
|
||||||
|
Reference in New Issue
Block a user