aboutsummaryrefslogtreecommitdiff
path: root/nscd/nscd_stat.c
diff options
context:
space:
mode:
Diffstat (limited to 'nscd/nscd_stat.c')
-rw-r--r--nscd/nscd_stat.c181
1 files changed, 135 insertions, 46 deletions
diff --git a/nscd/nscd_stat.c b/nscd/nscd_stat.c
index d8182885ac..f9d21aeb01 100644
--- a/nscd/nscd_stat.c
+++ b/nscd/nscd_stat.c
@@ -17,71 +17,160 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#include <errno.h>
+#include <error.h>
+#include <langinfo.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
-#include <sys/types.h>
+
#include "nscd.h"
+#include "dbg_log.h"
+
+/* We use this to make sure the receiver is the same. */
+static const char compilation[21] = __DATE__ " " __TIME__;
+
+/* Statistic data for one database. */
+struct dbstat
+{
+ int enabled;
+ int check_file;
+ size_t module;
+
+ unsigned long int postimeout;
+ unsigned long int negtimeout;
+
+ unsigned long int poshit;
+ unsigned long int neghit;
+ unsigned long int posmiss;
+ unsigned long int negmiss;
+};
+
+/* Record for transmitting statistics. */
+struct statdata
+{
+ char version[sizeof (compilation)];
+ int debug_level;
+ int ndbs;
+ struct dbstat dbs[lastdb];
+};
+
void
-print_stat (void)
+send_stats (int fd, struct database dbs[lastdb])
{
- int sock = __nscd_open_socket ();
- request_header req;
- stat_response_header resp;
- ssize_t nbytes;
+ struct statdata data;
+ int cnt;
+
+ memcpy (data.version, compilation, sizeof (compilation));
+ data.debug_level = debug_level;
+ data.ndbs = lastdb;
+
+ for (cnt = 0; cnt < lastdb; ++cnt)
+ {
+ data.dbs[cnt].enabled = dbs[cnt].enabled;
+ data.dbs[cnt].check_file = dbs[cnt].check_file;
+ data.dbs[cnt].module = dbs[cnt].module;
+ data.dbs[cnt].postimeout = dbs[cnt].postimeout;
+ data.dbs[cnt].negtimeout = dbs[cnt].negtimeout;
+ data.dbs[cnt].poshit = dbs[cnt].poshit;
+ data.dbs[cnt].neghit = dbs[cnt].neghit;
+ data.dbs[cnt].posmiss = dbs[cnt].posmiss;
+ data.dbs[cnt].negmiss = dbs[cnt].negmiss;
+ }
- if (sock == -1)
+ if (TEMP_FAILURE_RETRY (write (fd, &data, sizeof (data))) != sizeof (data))
{
- fputs (_("nscd not running!\n"), stdout);
- exit (EXIT_FAILURE);
+ char buf[256];
+ dbg_log (_("cannot write statistics: %s"),
+ strerror_r (errno, buf, sizeof (buf)));
}
+}
+
+
+int
+receive_print_stats (void)
+{
+ struct statdata data;
+ request_header req;
+ ssize_t nbytes;
+ int fd;
+ int i;
+ /* Open a socket to the running nscd. */
+ fd = nscd_open_socket ();
+ if (fd == -1)
+ error (EXIT_FAILURE, 0, _("nscd not running!\n"));
+
+ /* Send the request. */
req.version = NSCD_VERSION;
req.type = GETSTAT;
req.key_len = 0;
- nbytes = write (sock, &req, sizeof (request_header));
+ nbytes = TEMP_FAILURE_RETRY (write (fd, &req, sizeof (request_header)));
if (nbytes != sizeof (request_header))
{
- perror (_("write incomplete"));
- close (sock);
- exit (EXIT_FAILURE);
+ int err = errno;
+ close (fd);
+ error (EXIT_FAILURE, err, _("write incomplete"));
}
- nbytes = read (sock, &resp, sizeof (stat_response_header));
- if (nbytes != sizeof (stat_response_header))
+ /* Read as much data as we expect. */
+ if (TEMP_FAILURE_RETRY (read (fd, &data, sizeof (data))) != sizeof (data)
+ || (memcmp (data.version, compilation, sizeof (compilation)) != 0
+ /* Yes, this is an assignment! */
+ && errno == EINVAL))
{
- perror (_("read incomplete"));
- close (sock);
- exit (EXIT_FAILURE);
+ /* Not the right version. */
+ int err = errno;
+ close (fd);
+ error (EXIT_FAILURE, err, _("cannot read statistics data"));
}
- close (sock);
-
- printf (_("nscd configuration:\n\n"));
- printf (_("%12d server debug level\n\n"), resp.debug_level);
-
- printf (_("passwd cache:\n\n"));
- printf (_("%12s cache is enabled\n"), resp.pw_enabled ? _("Yes") : _("No"));
- printf (_("%12ld cache hits on positive entries\n"), resp.pw_poshit);
- printf (_("%12ld cache hits on negative entries\n"), resp.pw_neghit);
- printf (_("%12ld cache misses on positive entries\n"), resp.pw_posmiss);
- printf (_("%12ld cache misses on negative entries\n"), resp.pw_negmiss);
- printf (_("%12ld suggested size\n"), resp.pw_size);
- printf (_("%12ld seconds time to live for positive entries\n"),
- resp.pw_posttl);
- printf (_("%12ld seconds time to live for negative entries\n\n"),
- resp.pw_negttl);
-
- printf (_("group cache:\n\n"));
- printf (_("%12s cache is enabled\n"), resp.gr_enabled ? _("Yes") : _("No"));
- printf (_("%12ld cache hits on positive entries\n"), resp.gr_poshit);
- printf (_("%12ld cache hits on negative entries\n"), resp.gr_neghit);
- printf (_("%12ld cache misses on positive entries\n"), resp.gr_posmiss);
- printf (_("%12ld cache misses on negative entries\n"), resp.gr_negmiss);
- printf (_("%12ld suggested size\n"), resp.gr_size);
- printf (_("%12ld seconds time to live for positive entries\n"),
- resp.gr_posttl);
- printf (_("%12ld seconds time to live for negative entries\n"),
- resp.gr_negttl);
+ printf (_("nscd configuration:\n\n%15d server debug level\n"),
+ data.debug_level);
+
+ for (i = 0; i < lastdb; ++i)
+ {
+ unsigned long int hit = data.dbs[i].poshit + data.dbs[i].neghit;
+ unsigned long int all = hit + data.dbs[i].posmiss + data.dbs[i].negmiss;
+ const char *enabled = nl_langinfo (data.dbs[i].enabled ? YESSTR : NOSTR);
+ const char *check_file = nl_langinfo (data.dbs[i].check_file
+ ? YESSTR : NOSTR);
+
+ if (enabled[0] == '\0')
+ /* The locale does not provide this information so we have to
+ translate it ourself. Since we should avoid short translation
+ terms we artifically increase the length. */
+ enabled = data.dbs[i].enabled ? _(" yes") : _(" no");
+ if (check_file[0] == '\0')
+ check_file = data.dbs[i].check_file ? _(" yes") : _(" no");
+
+ if (all == 0)
+ /* If nothing happened so far report a 0% hit rate. */
+ all = 1;
+
+ printf (_("\n%s cache:\n\n"
+ "%15s cache is enabled\n"
+ "%15Zd suggested size\n"
+ "%15ld seconds time to live for positive entries\n"
+ "%15ld seconds time to live for negative entries\n"
+ "%15ld cache hits on positive entries\n"
+ "%15ld cache hits on negative entries\n"
+ "%15ld cache misses on positive entries\n"
+ "%15ld cache misses on negative entries\n"
+ "%15ld%% cache hit rate\n"
+ "%15s check /etc/%s for changes\n"),
+ dbnames[i], enabled,
+ data.dbs[i].module,
+ data.dbs[i].postimeout, data.dbs[i].negtimeout,
+ data.dbs[i].poshit, data.dbs[i].neghit,
+ data.dbs[i].posmiss, data.dbs[i].negmiss,
+ (100 * hit) / all,
+ check_file, dbnames[i]);
+ }
+
+ close (fd);
+
+ exit (0);
}