cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * CDDL HEADER START
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * The contents of this file are subject to the terms of the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Common Development and Distribution License (the "License").
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * You may not use this file except in compliance with the License.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * or http://www.opensolaris.org/os/licensing.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * See the License for the specific language governing permissions
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * and limitations under the License.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * When distributing Covered Code, include this CDDL HEADER in each
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * If applicable, add the following below this CDDL HEADER, with the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * fields enclosed by brackets "[]" replaced with your own identifying
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * information: Portions Copyright [yyyy] [name of copyright owner]
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * CDDL HEADER END
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
07925104db56e5c3eacc4865b918bd16af5cec59gww * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik * Copyright 2012 Milan Jurik. All rights reserved.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Cache routines for nscd
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <assert.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <errno.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <memory.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <signal.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <stdlib.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <stddef.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <stdio.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <string.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <sys/stat.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <sys/time.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <sys/types.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <sys/wait.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <unistd.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <ucred.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <nss_common.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <locale.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <ctype.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <strings.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <string.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <umem.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <fcntl.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "cache.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_door.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_log.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_config.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_frontend.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_switch.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#define SUCCESS 0
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#define NOTFOUND -1
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#define SERVERERROR -2
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#define NOSERVER -3
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#define CONTINUE -4
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic nsc_db_t *nsc_get_db(nsc_ctx_t *, int);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic nscd_rc_t lookup_cache(nsc_lookup_args_t *, nscd_cfg_cache_t *,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_XbyY_args_t *, char *, nsc_entry_t **);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic uint_t reap_cache(nsc_ctx_t *, uint_t, uint_t);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void delete_entry(nsc_db_t *, nsc_ctx_t *, nsc_entry_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void print_stats(nscd_cfg_stat_cache_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void print_cfg(nscd_cfg_cache_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int lookup_int(nsc_lookup_args_t *, int);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#ifdef NSCD_DEBUG
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void print_entry(nsc_db_t *, time_t, nsc_entry_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void avl_dump(nsc_db_t *, time_t);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void hash_dump(nsc_db_t *, time_t);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#endif /* NSCD_DEBUG */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic nsc_entry_t *hash_find(nsc_db_t *, nsc_entry_t *, uint_t *, nscd_bool_t);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void queue_adjust(nsc_db_t *, nsc_entry_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void queue_remove(nsc_db_t *, nsc_entry_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#ifdef NSCD_DEBUG
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void queue_dump(nsc_db_t *, time_t);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#endif /* NSCD_DEBUG */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int launch_update(nsc_lookup_args_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void do_update(nsc_lookup_args_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void getxy_keepalive(nsc_ctx_t *, nsc_db_t *, int, int);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void ctx_info(nsc_ctx_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void ctx_info_nolock(nsc_ctx_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void ctx_invalidate(nsc_ctx_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void nsc_db_str_key_getlogstr(char *, char *, size_t, nss_XbyY_args_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void nsc_db_int_key_getlogstr(char *, char *, size_t, nss_XbyY_args_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void nsc_db_any_key_getlogstr(char *, char *, size_t, nss_XbyY_args_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int nsc_db_cis_key_compar(const void *, const void *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int nsc_db_ces_key_compar(const void *, const void *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int nsc_db_int_key_compar(const void *, const void *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic uint_t nsc_db_cis_key_gethash(nss_XbyY_key_t *, int);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic uint_t nsc_db_ces_key_gethash(nss_XbyY_key_t *, int);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic uint_t nsc_db_int_key_gethash(nss_XbyY_key_t *, int);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic umem_cache_t *nsc_entry_cache;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic nsc_ctx_t *init_cache_ctx(int);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void reaper(nsc_ctx_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void revalidate(nsc_ctx_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic nss_status_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjldup_packed_buffer(void *src, void *dst) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_lookup_args_t *s = (nsc_lookup_args_t *)src;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_entry_t *d = (nsc_entry_t *)dst;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *sphdr = (nss_pheader_t *)s->buffer;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *dphdr = (nss_pheader_t *)d->buffer;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int slen, new_pbufsiz = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (NSCD_GET_STATUS(sphdr) != NSS_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* no result, copy header only (status, errno, etc) */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl slen = sphdr->data_off;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * lookup result returned, data to copy is the packed
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * header plus result (add 1 for the terminating NULL
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * just in case)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl slen = sphdr->data_off + sphdr->data_len + 1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* allocate cache packed buffer */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (dphdr != NULL && d->bufsize <= slen && d->bufsize != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* old buffer too small, free it */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(dphdr);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl d->buffer = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl d->bufsize = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dphdr = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (dphdr == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* get new buffer */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dphdr = calloc(1, slen + 1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (dphdr == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSS_ERROR);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl d->buffer = dphdr;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl d->bufsize = slen + 1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl new_pbufsiz = slen + 1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) memcpy(dphdr, sphdr, slen);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (new_pbufsiz != 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dphdr->pbufsiz = new_pbufsiz;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSS_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlchar *cache_name[CACHE_CTX_COUNT] = {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_PASSWD,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_GROUP,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_HOSTS,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_IPNODES,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_EXECATTR,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_PROFATTR,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_USERATTR,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_ETHERS,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_RPC,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_PROTOCOLS,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_NETWORKS,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_BOOTPARAMS,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_AUTHATTR,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_SERVICES,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_NETMASKS,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_PRINTERS,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_PROJECT,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_TSOL_TP,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSS_DBNAM_TSOL_RH
cb5caa98562cf06753163f558cbcfe30b8f4673adjl};
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjltypedef void (*cache_init_ctx_t)(nsc_ctx_t *);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic cache_init_ctx_t cache_init_ctx[CACHE_CTX_COUNT] = {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl passwd_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl group_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl host_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ipnode_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl exec_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl prof_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl user_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ether_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl rpc_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl proto_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl net_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl bootp_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl auth_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl serv_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl netmask_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl printer_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl project_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl tnrhtp_init_ctx,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl tnrhdb_init_ctx
cb5caa98562cf06753163f558cbcfe30b8f4673adjl};
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnsc_ctx_t *cache_ctx_p[CACHE_CTX_COUNT] = { 0 };
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic nscd_cfg_stat_cache_t null_stats = { 0 };
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic nscd_cfg_global_cache_t global_cfg;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Given database name 'dbname' find cache index
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlint
cb5caa98562cf06753163f558cbcfe30b8f4673adjlget_cache_idx(char *dbname) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *nsc_name;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i < CACHE_CTX_COUNT; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_name = cache_name[i];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (strcmp(nsc_name, dbname) == 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (i);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Given database name 'dbname' retrieve cache context,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * if not created yet, allocate and initialize it.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic nscd_rc_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjlget_cache_ctx(char *dbname, nsc_ctx_t **ctx) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *ctx = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl i = get_cache_idx(dbname);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (i == -1)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_INVALID_ARGUMENT);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((*ctx = cache_ctx_p[i]) == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *ctx = init_cache_ctx(i);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (*ctx == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_NO_MEMORY);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Generate a log string to identify backend operation in debug logs
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnsc_db_str_key_getlogstr(char *name, char *whoami, size_t len,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_XbyY_args_t *argp) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) snprintf(whoami, len, "%s [key=%s]", name, argp->key.name);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnsc_db_int_key_getlogstr(char *name, char *whoami, size_t len,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_XbyY_args_t *argp) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) snprintf(whoami, len, "%s [key=%d]", name, argp->key.number);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*ARGSUSED*/
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnsc_db_any_key_getlogstr(char *name, char *whoami, size_t len,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_XbyY_args_t *argp) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) snprintf(whoami, len, "%s", name);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Returns cache based on dbop
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic nsc_db_t *
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnsc_get_db(nsc_ctx_t *ctx, int dbop) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i < ctx->db_count; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ctx->nsc_db[i] && dbop == ctx->nsc_db[i]->dbop)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (ctx->nsc_db[i]);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * integer compare routine for _NSC_DB_INT_KEY
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnsc_db_int_key_compar(const void *n1, const void *n2) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_entry_t *e1, *e2;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl e1 = (nsc_entry_t *)n1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl e2 = (nsc_entry_t *)n2;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (_NSC_INT_KEY_CMP(e1->key.number, e2->key.number));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * case sensitive name compare routine for _NSC_DB_CES_KEY
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnsc_db_ces_key_compar(const void *n1, const void *n2) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_entry_t *e1, *e2;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int res, l1, l2;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl e1 = (nsc_entry_t *)n1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl e2 = (nsc_entry_t *)n2;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl l1 = strlen(e1->key.name);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl l2 = strlen(e2->key.name);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl res = strncmp(e1->key.name, e2->key.name, (l1 > l2)?l1:l2);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (_NSC_INT_KEY_CMP(res, 0));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * case insensitive name compare routine _NSC_DB_CIS_KEY
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnsc_db_cis_key_compar(const void *n1, const void *n2) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_entry_t *e1, *e2;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int res, l1, l2;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl e1 = (nsc_entry_t *)n1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl e2 = (nsc_entry_t *)n2;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl l1 = strlen(e1->key.name);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl l2 = strlen(e2->key.name);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl res = strncasecmp(e1->key.name, e2->key.name, (l1 > l2)?l1:l2);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (_NSC_INT_KEY_CMP(res, 0));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * macro used to generate elf hashes for strings
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#define _NSC_ELF_STR_GETHASH(func, str, htsize, hval) \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hval = 0; \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl while (*str) { \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl uint_t g; \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hval = (hval << 4) + func(*str++); \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((g = (hval & 0xf0000000)) != 0) \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hval ^= g >> 24; \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hval &= ~g; \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hval %= htsize;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * cis hash function
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjluint_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjlcis_gethash(const char *key, int htsize) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl uint_t hval;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (key == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSC_ELF_STR_GETHASH(tolower, key, htsize, hval);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (hval);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * ces hash function
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjluint_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjlces_gethash(const char *key, int htsize) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl uint_t hval;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (key == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSC_ELF_STR_GETHASH(, key, htsize, hval);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (hval);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * one-at-a-time hash function
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjluint_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjldb_gethash(const void *key, int len, int htsize) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl uint_t hval, i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl const char *str = key;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (str == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (hval = 0, i = 0; i < len; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hval += str[i];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hval += (hval << 10);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hval ^= (hval >> 6);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hval += (hval << 3);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hval ^= (hval >> 11);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hval += (hval << 15);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (hval % htsize);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * case insensitive name gethash routine _NSC_DB_CIS_KEY
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic uint_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnsc_db_cis_key_gethash(nss_XbyY_key_t *key, int htsize) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (cis_gethash(key->name, htsize));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * case sensitive name gethash routine _NSC_DB_CES_KEY
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic uint_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnsc_db_ces_key_gethash(nss_XbyY_key_t *key, int htsize) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (ces_gethash(key->name, htsize));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * integer gethash routine _NSC_DB_INT_KEY
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic uint_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnsc_db_int_key_gethash(nss_XbyY_key_t *key, int htsize) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (db_gethash(&key->number, sizeof (key->number), htsize));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Find entry in the hash table
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * if cmp == nscd_true)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * return entry only if the keys match
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * return entry in the hash location without checking the keys
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic nsc_entry_t *
cb5caa98562cf06753163f558cbcfe30b8f4673adjlhash_find(nsc_db_t *nscdb, nsc_entry_t *entry, uint_t *hash,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_bool_t cmp) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_entry_t *hashentry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->gethash)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *hash = nscdb->gethash(&entry->key, nscdb->htsize);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl hashentry = nscdb->htable[*hash];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cmp == nscd_false || hashentry == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (hashentry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->compar) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->compar(entry, hashentry) == 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (hashentry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#define HASH_REMOVE(nscdb, entry, hash, cmp) \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->htable) { \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (entry == hash_find(nscdb, entry, &hash, cmp)) \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->htable[hash] = NULL; \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#define HASH_INSERT(nscdb, entry, hash, cmp) \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->htable) { \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) hash_find(nscdb, entry, &hash, cmp); \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->htable[hash] = entry; \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#ifdef NSCD_DEBUG
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlprint_entry(nsc_db_t *nscdb, time_t now, nsc_entry_t *entry) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_XbyY_args_t args;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char whoami[512];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl switch (entry->stats.status) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case ST_NEW_ENTRY:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t status: new entry\n"));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case ST_UPDATE_PENDING:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t status: update pending\n"));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case ST_LOOKUP_PENDING:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t status: lookup pending\n"));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case ST_DISCARD:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t status: discarded entry\n"));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl default:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (entry->stats.timestamp < now)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl gettext("\t status: expired (%d seconds ago)\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl now - entry->stats.timestamp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl gettext("\t status: valid (expiry in %d seconds)\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry->stats.timestamp - now);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t hits: %u\n"), entry->stats.hits);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl args.key = entry->key;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) nscdb->getlogstr(nscdb->name, whoami, sizeof (whoami), &args);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, "\t %s\n", whoami);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#endif /* NSCD_DEBUG */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlprint_stats(nscd_cfg_stat_cache_t *statsp) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\n\t STATISTICS:\n"));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t positive hits: %lu\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->pos_hits);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t negative hits: %lu\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->neg_hits);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t positive misses: %lu\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->pos_misses);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t negative misses: %lu\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->neg_misses);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t total entries: %lu\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->entries);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t queries queued: %lu\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->wait_count);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t queries dropped: %lu\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->drop_count);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t cache invalidations: %lu\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->invalidate_count);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSC_GET_HITRATE(statsp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t cache hit rate: %10.1f\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->hitrate);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlprint_cfg(nscd_cfg_cache_t *cfgp) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\n\t CONFIG:\n"));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t enabled: %s\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl yes_no(cfgp->enable));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t per user cache: %s\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl yes_no(cfgp->per_user));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t avoid name service: %s\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl yes_no(cfgp->avoid_ns));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t check file: %s\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl yes_no(cfgp->check_files));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t check file interval: %d\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cfgp->check_interval);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t positive ttl: %d\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cfgp->pos_ttl);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t negative ttl: %d\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cfgp->neg_ttl);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t keep hot count: %d\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cfgp->keephot);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t hint size: %d\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cfgp->hint_size);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\t max entries: %lu%s"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cfgp->maxentries,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cfgp->maxentries?"\n":" (unlimited)\n");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#ifdef NSCD_DEBUG
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlhash_dump(nsc_db_t *nscdb, time_t now) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_entry_t *entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\n\nHASH TABLE:\n"));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i < nscdb->htsize; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((entry = nscdb->htable[i]) != NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, "hash[%d]:\n", i);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl print_entry(nscdb, now, entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#endif /* NSCD_DEBUG */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#ifdef NSCD_DEBUG
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlavl_dump(nsc_db_t *nscdb, time_t now) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_entry_t *entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\n\nAVL TREE:\n"));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (entry = avl_first(&nscdb->tree), i = 0; entry != NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry = avl_walk(&nscdb->tree, entry, AVL_AFTER)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, "avl node[%d]:\n", i++);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl print_entry(nscdb, now, entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#endif /* NSCD_DEBUG */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#ifdef NSCD_DEBUG
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlqueue_dump(nsc_db_t *nscdb, time_t now) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_entry_t *entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl gettext("\n\nCACHE [name=%s, nodes=%lu]:\n"),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->name, avl_numnodes(&nscdb->tree));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl gettext("Starting with the most recently accessed:\n"));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (entry = nscdb->qtail, i = 0; entry; entry = entry->qnext) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, "entry[%d]:\n", i++);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl print_entry(nscdb, now, entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#endif /* NSCD_DEBUG */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlqueue_remove(nsc_db_t *nscdb, nsc_entry_t *entry) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->qtail == entry)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->qtail = entry->qnext;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry->qprev->qnext = entry->qnext;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->qhead == entry)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->qhead = entry->qprev;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry->qnext->qprev = entry->qprev;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->reap_node == entry)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->reap_node = entry->qnext;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry->qnext = entry->qprev = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlqueue_adjust(nsc_db_t *nscdb, nsc_entry_t *entry) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#ifdef NSCD_DEBUG
cb5caa98562cf06753163f558cbcfe30b8f4673adjl assert(nscdb->qtail || entry->qnext == NULL &&
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry->qprev == NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl assert(nscdb->qtail && nscdb->qhead ||
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->qtail == NULL && nscdb->qhead == NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl assert(entry->qprev || entry->qnext == NULL ||
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->qtail == entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#endif /* NSCD_DEBUG */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* already in the desired position */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->qtail == entry)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* new queue */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->qtail == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->qhead = nscdb->qtail = entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* new entry (prev == NULL AND tail != entry) */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (entry->qprev == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->qtail->qprev = entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry->qnext = nscdb->qtail;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->qtail = entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* existing entry */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->reap_node == entry)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->reap_node = entry->qnext;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->qhead == entry)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->qhead = entry->qprev;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry->qnext->qprev = entry->qprev;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry->qprev->qnext = entry->qnext;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry->qprev = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry->qnext = nscdb->qtail;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->qtail->qprev = entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->qtail = entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Init cache
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_rc_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjlinit_cache(int debug_level) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int cflags;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cflags = (debug_level > 0)?0:UMC_NODEBUG;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_entry_cache = umem_cache_create("nsc_entry_cache",
cb5caa98562cf06753163f558cbcfe30b8f4673adjl sizeof (nsc_entry_t), 0, NULL, NULL, NULL,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NULL, NULL, cflags);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nsc_entry_cache == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_NO_MEMORY);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Create cache
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnsc_db_t *
cb5caa98562cf06753163f558cbcfe30b8f4673adjlmake_cache(enum db_type dbtype, int dbop, char *name,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik int (*compar) (const void *, const void *),
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik void (*getlogstr)(char *, char *, size_t, nss_XbyY_args_t *),
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik uint_t (*gethash)(nss_XbyY_key_t *, int),
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik enum hash_type httype, int htsize)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_db_t *nscdb;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "make_cache";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb = (nsc_db_t *)malloc(sizeof (*nscdb));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: memory allocation failure\n", name);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl goto out;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) memset(nscdb, 0, sizeof (*nscdb));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->dbop = dbop;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->name = name;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->db_type = dbtype;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* Assign compare routine */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (compar == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_NSC_DB_CES_KEY(nscdb))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->compar = nsc_db_ces_key_compar;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else if (_NSC_DB_CIS_KEY(nscdb))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->compar = nsc_db_cis_key_compar;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else if (_NSC_DB_INT_KEY(nscdb))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->compar = nsc_db_int_key_compar;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl assert(0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->compar = compar;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* The cache is an AVL tree */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl avl_create(&nscdb->tree, nscdb->compar, sizeof (nsc_entry_t),
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik offsetof(nsc_entry_t, avl_link));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* Assign log routine */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (getlogstr == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_NSC_DB_STR_KEY(nscdb))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->getlogstr = nsc_db_str_key_getlogstr;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else if (_NSC_DB_INT_KEY(nscdb))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->getlogstr = nsc_db_int_key_getlogstr;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->getlogstr = nsc_db_any_key_getlogstr;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->getlogstr = getlogstr;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* The AVL tree based cache uses a hash table for quick access */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (htsize != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* Determine hash table size based on type */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->hash_type = httype;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (htsize < 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl switch (httype) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case nsc_ht_power2:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl htsize = _NSC_INIT_HTSIZE_POWER2;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case nsc_ht_prime:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case nsc_ht_default:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl default:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl htsize = _NSC_INIT_HTSIZE_PRIME;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->htsize = htsize;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* Create the hash table */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->htable = calloc(htsize, sizeof (*(nscdb->htable)));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->htable == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: memory allocation failure\n", name);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl goto out;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* Assign gethash routine */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (gethash == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_NSC_DB_CES_KEY(nscdb))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->gethash = nsc_db_ces_key_gethash;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else if (_NSC_DB_CIS_KEY(nscdb))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->gethash = nsc_db_cis_key_gethash;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else if (_NSC_DB_INT_KEY(nscdb))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->gethash = nsc_db_int_key_gethash;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl assert(0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->gethash = gethash;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_init(&nscdb->db_mutex, USYNC_THREAD, NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (nscdb);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlout:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->htable)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(nscdb->htable);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(nscdb);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * verify
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/* ARGSUSED */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_rc_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_cfg_cache_verify(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void *data,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct nscd_cfg_param_desc *pdesc,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_id_t *nswdb,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_flag_t dflag,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_error_t **errorp,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void **cookie)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * notify
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/* ARGSUSED */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_rc_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_cfg_cache_notify(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void *data,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct nscd_cfg_param_desc *pdesc,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_id_t *nswdb,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_flag_t dflag,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_error_t **errorp,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void **cookie)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_ctx_t *ctx;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void *dp;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* group data */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_GROUP)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_nscd_cfg_flag_is_set(pdesc->pflag,
18bdb8a7484e018149ac9a2766c97bdea9752c87michen NSCD_CFG_PFLAG_GLOBAL)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* global config */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl global_cfg = *(nscd_cfg_global_cache_t *)data;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else if (_nscd_cfg_flag_is_set(dflag,
18bdb8a7484e018149ac9a2766c97bdea9752c87michen NSCD_CFG_DFLAG_SET_ALL_DB)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* non-global config for all dbs */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i < CACHE_CTX_COUNT; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx = cache_ctx_p[i];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ctx == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_CTX_NOT_FOUND);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_wrlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->cfg = *(nscd_cfg_cache_t *)data;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->cfg_mtime = time(NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_unlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* non-global config for a specific db */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* ignore non-caching databases */
18bdb8a7484e018149ac9a2766c97bdea9752c87michen if (get_cache_ctx(nswdb->name, &ctx) != NSCD_SUCCESS)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_wrlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->cfg = *(nscd_cfg_cache_t *)data;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->cfg_mtime = time(NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_unlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* individual data */
18bdb8a7484e018149ac9a2766c97bdea9752c87michen if (_nscd_cfg_flag_is_set(pdesc->pflag, NSCD_CFG_PFLAG_GLOBAL)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* global config */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dp = (char *)&global_cfg + pdesc->p_offset;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) memcpy(dp, data, pdesc->p_size);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else if (_nscd_cfg_flag_is_set(dflag,
18bdb8a7484e018149ac9a2766c97bdea9752c87michen NSCD_CFG_DFLAG_SET_ALL_DB)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* non-global config for all dbs */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i < CACHE_CTX_COUNT; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx = cache_ctx_p[i];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ctx == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_CTX_NOT_FOUND);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dp = (char *)&ctx->cfg + pdesc->p_offset;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_wrlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) memcpy(dp, data, pdesc->p_size);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->cfg_mtime = time(NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_unlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* non-global config for a specific db */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* ignore non-caching databases */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (get_cache_ctx(nswdb->name, &ctx) != NSCD_SUCCESS)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dp = (char *)&ctx->cfg + pdesc->p_offset;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_wrlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) memcpy(dp, data, pdesc->p_size);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->cfg_mtime = time(NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_unlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * get stat
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/* ARGSUSED */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_rc_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_cfg_cache_get_stat(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void **stat,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct nscd_cfg_stat_desc *sdesc,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_id_t *nswdb,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_flag_t *dflag,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void (**free_stat)(void *stat),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_error_t **errorp)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_stat_cache_t *statsp, stats;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_ctx_t *ctx;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_rc_t rc;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp = calloc(1, sizeof (*statsp));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (statsp == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_NO_MEMORY);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_nscd_cfg_flag_is_set(sdesc->sflag, NSCD_CFG_SFLAG_GLOBAL)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i < CACHE_CTX_COUNT; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cache_ctx_p[i] == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl stats = null_stats;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&cache_ctx_p[i]->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl stats = cache_ctx_p[i]->stats;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(
18bdb8a7484e018149ac9a2766c97bdea9752c87michen &cache_ctx_p[i]->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->pos_hits += stats.pos_hits;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->neg_hits += stats.neg_hits;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->pos_misses += stats.pos_misses;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->neg_misses += stats.neg_misses;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->entries += stats.entries;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->drop_count += stats.drop_count;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->wait_count += stats.wait_count;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl statsp->invalidate_count +=
18bdb8a7484e018149ac9a2766c97bdea9752c87michen stats.invalidate_count;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((rc = get_cache_ctx(nswdb->name, &ctx)) != NSCD_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(statsp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (rc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *statsp = ctx->stats;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSC_GET_HITRATE(statsp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *stat = statsp;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * This function should only be called when nscd is
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * not a daemon.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlvoid
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnsc_info(nsc_ctx_t *ctx, char *dbname, nscd_cfg_cache_t cfg[],
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik nscd_cfg_stat_cache_t stats[])
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "nsc_info";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_ctx_t *ctx1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_ctx_t ctx2;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_rc_t rc;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ctx) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx_info(ctx);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (dbname) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl rc = get_cache_ctx(dbname, &ctx1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (rc == NSCD_INVALID_ARGUMENT) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_WARNING)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: no cache context found\n", dbname);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else if (rc == NSCD_NO_MEMORY) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_WARNING)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: unable to create cache context - no memory\n",
18bdb8a7484e018149ac9a2766c97bdea9752c87michen dbname);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx_info(ctx1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cfg == NULL || stats == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i < CACHE_CTX_COUNT; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx2.dbname = cache_name[i];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx2.cfg = cfg[i];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx2.stats = stats[i];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx_info_nolock(&ctx2);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlctx_info_nolock(nsc_ctx_t *ctx) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_cache_t cfg;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_stat_cache_t stats;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cfg = ctx->cfg;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\n\nCACHE: %s\n"), ctx->dbname);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) print_cfg(&cfg);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cfg.enable == nscd_false)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl stats = ctx->stats;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) print_stats(&stats);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlctx_info(nsc_ctx_t *ctx) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_cache_t cfg;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_stat_cache_t stats;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_rdlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cfg = ctx->cfg;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_unlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("\n\nCACHE: %s\n"), ctx->dbname);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) print_cfg(&cfg);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cfg.enable == nscd_false)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl stats = ctx->stats;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) print_stats(&stats);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#ifdef NSCD_DEBUG
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * This function should only be called when nscd is
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * not a daemon.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlint
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Juriknsc_dump(char *dbname, int dbop)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_ctx_t *ctx;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_db_t *nscdb;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_bool_t enabled;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl time_t now;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "nsc_dump";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((i = get_cache_idx(dbname)) == -1) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("invalid cache name\n"));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_WARNING)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: invalid cache name\n", dbname);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_CACHE_INVALID_CACHE_NAME);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((ctx = cache_ctx_p[i]) == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) fprintf(stdout, gettext("no cache context\n"));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_WARNING)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: no cache context\n", dbname);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_CACHE_NO_CACHE_CTX);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl now = time(NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_rdlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl enabled = ctx->cfg.enable;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_unlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (enabled == nscd_false)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_CACHE_DISABLED);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb = nsc_get_db(ctx, dbop);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_WARNING)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s:%d: no cache found\n", dbname, dbop);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_CACHE_NO_CACHE_FOUND);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) queue_dump(nscdb, now);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) hash_dump(nscdb, now);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) avl_dump(nscdb, now);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#endif /* NSCD_DEBUG */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * These macros are for exclusive use of nsc_lookup
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik#define NSC_LOOKUP_LOG(loglevel, fmt) \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_##loglevel) \
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (me, fmt, whoami);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurikstatic int
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Juriknsc_lookup_no_cache(nsc_lookup_args_t *largs, const char *str)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik{
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik char *me = "nsc_lookup_no_cache";
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik nss_status_t status;
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (me, "%s: name service lookup (bypassing cache)\n", str);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik nss_psearch(largs->buffer, largs->bufsize);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik status = NSCD_GET_STATUS(largs->buffer);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (me, "%s: name service lookup status = %d\n", str, status);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik if (status == NSS_SUCCESS) {
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (SUCCESS);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik } else if (status == NSS_NOTFOUND) {
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (NOTFOUND);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (SERVERERROR);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik }
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * This function starts the revalidation and reaper threads
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * for a cache
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurikstart_threads(nsc_ctx_t *ctx)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int errnum;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "start_threads";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * kick off the revalidate thread (if necessary)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ctx->revalidate_on != nscd_true) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (thr_create(NULL, NULL, (void *(*)(void *))revalidate,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik ctx, 0, NULL) != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = errno;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_ERROR)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (me, "thr_create (revalidate thread for %s): %s\n",
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik ctx->dbname, strerror(errnum));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl exit(1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->revalidate_on = nscd_true;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * kick off the reaper thread (if necessary)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ctx->reaper_on != nscd_true) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (thr_create(NULL, NULL, (void *(*)(void *))reaper,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik ctx, 0, NULL) != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = errno;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_ERROR)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (me, "thr_create (reaper thread for %s): %s\n",
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik ctx->dbname, strerror(errnum));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl exit(1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->reaper_on = nscd_true;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Examine the packed buffer, see if the front-end parameters
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * indicate that the caller specified nsswitch config should be
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * used for the lookup. Return 1 if yes, otherwise 0.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnsw_config_in_phdr(void *buf)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *pbuf = (nss_pheader_t *)buf;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nssuint_t off;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_dbd_t *pdbd;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "nsw_config_in_phdr";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl off = pbuf->dbd_off;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (off == 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl pdbd = (nss_dbd_t *)((void *)((char *)pbuf + off));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (pdbd->o_default_config == 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((enum nss_dbp_flags)pdbd->flags & NSS_USE_DEFAULT_CONFIG) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "use caller specified nsswitch config\n");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic nss_status_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjlcopy_result(void *rbuf, void *cbuf)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *rphdr = (nss_pheader_t *)rbuf;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *cphdr = (nss_pheader_t *)cbuf;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "copy_result";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* return NSS_ERROR if not enough room to copy result */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cphdr->data_len + 1 > rphdr->data_len) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSCD_SET_STATUS(rphdr, NSS_ERROR, ERANGE);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSS_ERROR);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *dst;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cphdr->data_len == 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSS_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dst = (char *)rphdr + rphdr->data_off;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) memcpy(dst, (char *)cphdr + cphdr->data_off,
18bdb8a7484e018149ac9a2766c97bdea9752c87michen cphdr->data_len);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl rphdr->data_len = cphdr->data_len;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* some frontend code expects a terminating NULL char */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *(dst + rphdr->data_len) = '\0';
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
e37190e5b4531a897e4191a30b8f41678b582e25michen (me, "cache data (len = %lld): >>%s<<\n",
18bdb8a7484e018149ac9a2766c97bdea9752c87michen cphdr->data_len, (char *)cphdr + cphdr->data_off);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSS_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int
cb5caa98562cf06753163f558cbcfe30b8f4673adjlget_dns_ttl(void *pbuf, char *dbname)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *phdr = (nss_pheader_t *)pbuf;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int ttl;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "get_dns_ttl";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* if returned, dns ttl is stored in the extended data area */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (phdr->ext_off == 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (strcmp(dbname, NSS_DBNAM_HOSTS) != 0 &&
18bdb8a7484e018149ac9a2766c97bdea9752c87michen strcmp(dbname, NSS_DBNAM_IPNODES) != 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ttl = *(nssuint_t *)((void *)((char *)pbuf + phdr->ext_off));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "dns ttl is %d seconds\n", ttl);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (ttl);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int
cb5caa98562cf06753163f558cbcfe30b8f4673adjlcheck_config(nsc_lookup_args_t *largs, nscd_cfg_cache_t *cfgp,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik char *whoami, int flag)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_db_t *nscdb;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_ctx_t *ctx;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "check_config";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx = largs->ctx;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb = largs->nscdb;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* see if the cached config needs update */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->cfg_mtime != ctx->cfg_mtime) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_rdlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->cfg = ctx->cfg;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->cfg_mtime = ctx->cfg_mtime;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_unlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "config for context %s, database %s updated\n",
18bdb8a7484e018149ac9a2766c97bdea9752c87michen ctx->dbname, nscdb->name);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *cfgp = nscdb->cfg;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cfgp->enable == nscd_false) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: cache disabled\n", ctx->dbname);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (UPDATEBIT & flag)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NOTFOUND);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik else
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (nsc_lookup_no_cache(largs, whoami));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * if caller requests lookup using his
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * own nsswitch config, bypass cache
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik if (nsw_config_in_phdr(largs->buffer))
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (nsc_lookup_no_cache(largs, whoami));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* no need of cache if we are dealing with 0 ttls */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cfgp->pos_ttl <= 0 && cfgp->neg_ttl <= 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (flag & UPDATEBIT)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NOTFOUND);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else if (cfgp->avoid_ns == nscd_true)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (SERVERERROR);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (nsc_lookup_no_cache(largs, whoami));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (CONTINUE);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Invalidate cache if database file has been modified.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * See check_files config param for details.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlcheck_db_file(nsc_ctx_t *ctx, nscd_cfg_cache_t cfg,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik char *whoami, time_t now)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl struct stat buf;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_bool_t file_modified = nscd_false;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "check_db_file";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cfg.check_interval != 0 &&
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (now - ctx->file_chktime) < cfg.check_interval)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->file_chktime = now;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (stat(ctx->file_name, &buf) == 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ctx->file_mtime == 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&ctx->file_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ctx->file_mtime == 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->file_mtime = buf.st_mtime;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->file_size = buf.st_size;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->file_ino = buf.st_ino;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&ctx->file_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else if (ctx->file_mtime < buf.st_mtime ||
18bdb8a7484e018149ac9a2766c97bdea9752c87michen ctx->file_size != buf.st_size ||
18bdb8a7484e018149ac9a2766c97bdea9752c87michen ctx->file_ino != buf.st_ino) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&ctx->file_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ctx->file_mtime < buf.st_mtime ||
18bdb8a7484e018149ac9a2766c97bdea9752c87michen ctx->file_size != buf.st_size ||
18bdb8a7484e018149ac9a2766c97bdea9752c87michen ctx->file_ino != buf.st_ino) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl file_modified = nscd_true;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->file_mtime = buf.st_mtime;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->file_size = buf.st_size;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->file_ino = buf.st_ino;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&ctx->file_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (file_modified == nscd_true) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
18bdb8a7484e018149ac9a2766c97bdea9752c87michen (me, "%s: file %s has been modified - invalidating cache\n",
18bdb8a7484e018149ac9a2766c97bdea9752c87michen whoami, ctx->file_name);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx_invalidate(ctx);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Juriklookup_int(nsc_lookup_args_t *largs, int flag)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_ctx_t *ctx;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_db_t *nscdb;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_cache_t cfg;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_entry_t *this_entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_entry_stat_t *this_stats;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_action_t next_action;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_status_t status;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_bool_t delete;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_rc_t rc;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *dbname;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int dbop, errnum;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int cfg_rc;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_XbyY_args_t args;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char whoami[128];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl time_t now = time(NULL); /* current time */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "lookup_int";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* extract dbop, dbname, key and cred */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl status = nss_packed_getkey(largs->buffer, largs->bufsize, &dbname,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik &dbop, &args);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (status != NSS_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "nss_packed_getkey failure (%d)\n", status);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (SERVERERROR);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* get the cache context */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (largs->ctx == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (get_cache_ctx(dbname, &largs->ctx) != NSCD_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_WARNING)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: no cache context found\n", dbname);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (UPDATEBIT & flag)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NOTFOUND);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik else
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (nsc_lookup_no_cache(largs, dbname));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx = largs->ctx;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (largs->nscdb == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((largs->nscdb = nsc_get_db(ctx, dbop)) == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_WARNING)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s:%d: no cache found\n",
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik dbname, dbop);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (UPDATEBIT & flag)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NOTFOUND);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik else
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (nsc_lookup_no_cache(largs, dbname));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb = largs->nscdb;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG_IF(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_ALL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) nscdb->getlogstr(nscdb->name, whoami,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik sizeof (whoami), &args);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (UPDATEBIT & flag) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: refresh start\n", whoami);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: lookup start\n", whoami);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cfg_rc = check_config(largs, &cfg, whoami, flag);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cfg_rc != CONTINUE)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (cfg_rc);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Invalidate cache if file has been modified.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cfg.check_files == nscd_true)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl check_db_file(ctx, cfg, whoami, now);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* Lookup the cache table */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (;;) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl delete = nscd_false;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl rc = lookup_cache(largs, &cfg, &args, whoami, &this_entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (rc != NSCD_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* Either no entry and avoid name service */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (rc == NSCD_DB_ENTRY_NOT_FOUND ||
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik rc == NSCD_INVALID_ARGUMENT)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NOTFOUND);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* OR memory error */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (SERVERERROR);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* get the stats from the entry */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl this_stats = &this_entry->stats;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * What should we do next ?
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl switch (this_stats->status) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case ST_NEW_ENTRY:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl delete = nscd_true;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_action = _NSC_NSLOOKUP;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case ST_UPDATE_PENDING:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (flag & UPDATEBIT) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NOTFOUND);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else if (this_stats->timestamp < now)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_action = _NSC_WAIT;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_action = _NSC_USECACHED;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case ST_LOOKUP_PENDING:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (flag & UPDATEBIT) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NOTFOUND);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_action = _NSC_WAIT;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case ST_DISCARD:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cfg.avoid_ns == nscd_true) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NOTFOUND);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* otherwise reuse the entry */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) memset(this_stats, 0, sizeof (*this_stats));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_action = _NSC_NSLOOKUP;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl default:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cfg.avoid_ns == nscd_true)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_action = _NSC_USECACHED;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else if ((flag & UPDATEBIT) ||
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (this_stats->timestamp < now)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: cached entry needs to be updated\n",
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik whoami);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_action = _NSC_NSLOOKUP;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_action = _NSC_USECACHED;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (next_action == _NSC_WAIT) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: need to wait\n", whoami);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* do we have clearance ? */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_nscd_get_clearance(&ctx->throttle_sema) != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* nope. quit */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->stats.drop_count++;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&ctx->stats_mutex);
18bdb8a7484e018149ac9a2766c97bdea9752c87michen _NSCD_LOG(NSCD_LOG_CACHE,
18bdb8a7484e018149ac9a2766c97bdea9752c87michen NSCD_LOG_LEVEL_DEBUG_6)
18bdb8a7484e018149ac9a2766c97bdea9752c87michen (me, "%s: throttling load\n", whoami);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (void) mutex_unlock(&nscdb->db_mutex);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSC_LOOKUP_LOG(WARNING,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "%s: no clearance to wait\n");
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (NOSERVER);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* yes can wait */
3ea037cc19cdc1fa08072c41271d316bfbf9c54amichen (void) nscd_wait(ctx, nscdb, this_entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) _nscd_release_clearance(&ctx->throttle_sema);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl continue;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (!(UPDATEBIT & flag))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl this_stats->hits++; /* update hit count */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (next_action == _NSC_NSLOOKUP) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: name service lookup required\n", whoami);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_nscd_get_clearance(&ctx->throttle_sema) != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (delete == nscd_true)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl delete_entry(nscdb, ctx, this_entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl this_stats->status = ST_DISCARD;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->stats.drop_count++;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&ctx->stats_mutex);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (void) mutex_unlock(&nscdb->db_mutex);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSC_LOOKUP_LOG(WARNING,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "%s: no clearance for lookup\n");
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (NOSERVER);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* block any threads accessing this entry */
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik this_stats->status = (flag & UPDATEBIT) ?
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik ST_UPDATE_PENDING : ST_LOOKUP_PENDING;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* release lock and do name service lookup */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_psearch(largs->buffer, largs->bufsize);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl status = NSCD_GET_STATUS(largs->buffer);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl this_stats->status = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) _nscd_release_clearance(&ctx->throttle_sema);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* signal waiting threads */
3ea037cc19cdc1fa08072c41271d316bfbf9c54amichen (void) nscd_signal(ctx, nscdb, this_entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: name service lookup status = %d\n",
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik whoami, status);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (status == NSS_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int ttl;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * data found in name service
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * update cache
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl status = dup_packed_buffer(largs, this_entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (status != NSS_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl delete_entry(nscdb, ctx, this_entry);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (void) mutex_unlock(&nscdb->db_mutex);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSC_LOOKUP_LOG(ERROR,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "%s: failed to update cache\n");
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (SERVERERROR);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * store unpacked key in cache
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl status = nss_packed_getkey(this_entry->buffer,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik this_entry->bufsize,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik &dbname, &dbop, &args);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (status != NSS_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl delete_entry(nscdb, ctx, this_entry);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (void) mutex_unlock(&nscdb->db_mutex);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSC_LOOKUP_LOG(ERROR,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "%s: failed to extract key\n");
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (SERVERERROR);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl this_entry->key = args.key; /* struct copy */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* update +ve miss count */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (!(UPDATEBIT & flag)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->stats.pos_misses++;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* update +ve ttl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ttl = get_dns_ttl(largs->buffer, dbname);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* honor the dns ttl less than postive ttl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ttl < 0 || ttl > cfg.pos_ttl)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ttl = cfg.pos_ttl;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl this_stats->timestamp = time(NULL) + ttl;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * start the revalidation and reaper threads
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * if not already started
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl start_threads(ctx);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (void) mutex_unlock(&nscdb->db_mutex);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSC_LOOKUP_LOG(DEBUG,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "%s: cache updated with positive entry\n");
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else if (status == NSS_NOTFOUND) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * data not found in name service
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * update cache
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
18bdb8a7484e018149ac9a2766c97bdea9752c87michen _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG_6)
18bdb8a7484e018149ac9a2766c97bdea9752c87michen (me, "%s: name service lookup failed\n", whoami);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (NSCD_GET_ERRNO(largs->buffer) == ERANGE) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl delete_entry(nscdb, ctx, this_entry);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (void) mutex_unlock(&nscdb->db_mutex);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSC_LOOKUP_LOG(DEBUG,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "%s: ERANGE, cache not updated "
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "with negative entry\n");
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (NOTFOUND);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl status = dup_packed_buffer(largs, this_entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (status != NSS_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl delete_entry(nscdb, ctx, this_entry);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (void) mutex_unlock(&nscdb->db_mutex);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSC_LOOKUP_LOG(ERROR,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "%s: failed to update cache\n");
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (SERVERERROR);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* store unpacked key in cache */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl status = nss_packed_getkey(this_entry->buffer,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik this_entry->bufsize,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik &dbname, &dbop, &args);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (status != NSS_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl delete_entry(nscdb, ctx, this_entry);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (void) mutex_unlock(&nscdb->db_mutex);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSC_LOOKUP_LOG(ERROR,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "%s: failed to extract key\n");
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (SERVERERROR);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl this_entry->key = args.key; /* struct copy */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* update -ve ttl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl this_stats->timestamp = time(NULL) + cfg.neg_ttl;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* update -ve miss count */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (!(UPDATEBIT & flag)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->stats.neg_misses++;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * start the revalidation and reaper threads
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * if not already started
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl start_threads(ctx);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (void) mutex_unlock(&nscdb->db_mutex);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSC_LOOKUP_LOG(DEBUG,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "%s: cache updated with negative entry\n");
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (NOTFOUND);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * name service lookup failed
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
18bdb8a7484e018149ac9a2766c97bdea9752c87michen _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG_6)
18bdb8a7484e018149ac9a2766c97bdea9752c87michen (me, "%s: name service lookup failed\n", whoami);
18bdb8a7484e018149ac9a2766c97bdea9752c87michen
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = NSCD_GET_ERRNO(largs->buffer);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (delete == nscd_true)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl delete_entry(nscdb, ctx, this_entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl this_stats->status = ST_DISCARD;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_WARNING)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (me, "%s: name service lookup failed "
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "(status=%d, errno=%d)\n",
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik whoami, status, errnum);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (SERVERERROR);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else if (next_action == _NSC_USECACHED) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * found entry in cache
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (UPDATEBIT & flag) {
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (void) mutex_unlock(&nscdb->db_mutex);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSC_LOOKUP_LOG(DEBUG, "%s: no need to update\n");
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (NSCD_GET_STATUS((nss_pheader_t *)this_entry->buffer) ==
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSS_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* positive hit */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->stats.pos_hits++;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* update response buffer */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (copy_result(largs->buffer,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik this_entry->buffer) != NSS_SUCCESS) {
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (void) mutex_unlock(&nscdb->db_mutex);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSC_LOOKUP_LOG(ERROR,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "%s: response buffer insufficient\n");
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (SERVERERROR);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (void) mutex_unlock(&nscdb->db_mutex);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSC_LOOKUP_LOG(DEBUG,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "%s: positive entry in cache\n");
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* negative hit */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->stats.neg_hits++;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSCD_SET_STATUS((nss_pheader_t *)largs->buffer,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSCD_GET_STATUS(this_entry->buffer),
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSCD_GET_ERRNO(this_entry->buffer));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NSCD_SET_HERRNO((nss_pheader_t *)largs->buffer,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSCD_GET_HERRNO(this_entry->buffer));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (void) mutex_unlock(&nscdb->db_mutex);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSC_LOOKUP_LOG(DEBUG,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "%s: negative entry in cache\n");
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (NOTFOUND);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (void) mutex_unlock(&nscdb->db_mutex);
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSC_LOOKUP_LOG(ERROR, "%s: cache backend failure\n");
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik return (SERVERERROR);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * NSCD cache backend lookup function
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*ARGSUSED*/
cb5caa98562cf06753163f558cbcfe30b8f4673adjlvoid
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnsc_lookup(nsc_lookup_args_t *largs, int flag) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *phdr = (nss_pheader_t *)largs->buffer;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int rc;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl rc = lookup_int(largs, 0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (NSCD_GET_STATUS(phdr) == NSS_TRYLOCAL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl switch (rc) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case SUCCESS:
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSCD_SET_STATUS(phdr, NSS_SUCCESS, 0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NOTFOUND:
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSCD_SET_STATUS(phdr, NSS_NOTFOUND, -1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case SERVERERROR:
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen /*
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * status and errno should have been set in the phdr,
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen * if not, set status to NSS_ERROR
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen */
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen if (NSCD_STATUS_IS_OK(phdr)) {
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen NSCD_SET_STATUS(phdr, NSS_ERROR, 0);
606f6aa3d37f0f8e8282e483c1400bae5275aeebmichen }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl case NOSERVER:
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik NSCD_SET_STATUS(phdr, NSS_TRYLOCAL, -1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic nsc_ctx_t *
cb5caa98562cf06753163f558cbcfe30b8f4673adjlinit_cache_ctx(int i) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_ctx_t *ctx;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx = calloc(1, sizeof (nsc_ctx_t));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ctx == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* init locks and semaphores */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_init(&ctx->file_mutex, USYNC_THREAD, NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rwlock_init(&ctx->cfg_rwlp, USYNC_THREAD, NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_init(&ctx->stats_mutex, USYNC_THREAD, NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) _nscd_init_cache_sema(&ctx->throttle_sema, cache_name[i]);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cache_init_ctx[i](ctx);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cache_ctx_p[i] = ctx;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (ctx);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlrevalidate(nsc_ctx_t *ctx)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (;;) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i, slp, interval, count;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_rdlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl slp = ctx->cfg.pos_ttl;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl count = ctx->cfg.keephot;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_unlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (slp < 60)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl slp = 60;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (count != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl interval = (slp/2)/count;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (interval == 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl interval = 1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) sleep(slp*2/3);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i < ctx->db_count; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl getxy_keepalive(ctx, ctx->nsc_db[i],
18bdb8a7484e018149ac9a2766c97bdea9752c87michen count, interval);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) sleep(slp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjlgetxy_keepalive(nsc_ctx_t *ctx, nsc_db_t *nscdb, int keep, int interval)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_keephot_t *table;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_entry_t *entry, *ptr;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_lookup_args_t *largs;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *phdr;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int bufsiz;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "getxy_keepalive";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* we won't be here if keep == 0 so need to check that */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: keep alive\n", nscdb->name);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((table = maken(keep)) == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "memory allocation failure\n");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl exit(1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry = nscdb->qtail;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl while (entry != NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* leave pending calls alone */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (!(entry->stats.status & ST_PENDING)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* do_revalidate */
18bdb8a7484e018149ac9a2766c97bdea9752c87michen (void) insertn(table, entry->stats.hits, entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry = entry->qnext;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 1; i <= keep; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (table[i].ptr == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl continue;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ptr = (nsc_entry_t *)table[i].ptr;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl phdr = (nss_pheader_t *)ptr->buffer;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (NSCD_GET_STATUS(phdr) == NSS_SUCCESS)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * for positive cache, in addition to the packed
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * header size, allocate twice the size of the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * existing result (in case the result grows
ad0e80f7538b612141768bfda60009eb76550ee7michen * larger) plus 2K (for the file/compat backend to
ad0e80f7538b612141768bfda60009eb76550ee7michen * process a possible large entry in the /etc files)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
ad0e80f7538b612141768bfda60009eb76550ee7michen bufsiz = phdr->data_off + 2 * phdr->data_len + 2048;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * for negative cache, allocate 8K buffer to
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * hold result in case the next lookup may
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * return something (in addition to the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * packed header size)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl bufsiz = phdr->data_off + 8096;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl table[i].ptr = malloc(bufsiz);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (table[i].ptr == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "memory allocation failure\n");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl exit(1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) memcpy(table[i].ptr, ptr->buffer, ptr->bufsize);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ((nss_pheader_t *)table[i].ptr)->pbufsiz = bufsiz;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl table[i].num = bufsiz;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* launch update thread for each keep hot entry */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = keep; i > 0; i--) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (table[i].ptr == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl continue; /* unused slot in table */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: launching update\n", nscdb->name);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl largs = (nsc_lookup_args_t *)malloc(sizeof (*largs));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (largs == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "memory allocation failure\n");
cb5caa98562cf06753163f558cbcfe30b8f4673adjl exit(1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl largs->buffer = table[i].ptr;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl largs->bufsize = table[i].num;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl largs->ctx = ctx;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl largs->nscdb = nscdb;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (launch_update(largs) < 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl exit(1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) sleep(interval);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * The update thread will handle freeing of buffer and largs.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Free the table here.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(table);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int
cb5caa98562cf06753163f558cbcfe30b8f4673adjllaunch_update(nsc_lookup_args_t *in)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "launch_update";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int errnum;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl errnum = thr_create(NULL, NULL, (void *(*)(void*))do_update,
18bdb8a7484e018149ac9a2766c97bdea9752c87michen in, 0|THR_DETACHED, NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (errnum != 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_ERROR)
18bdb8a7484e018149ac9a2766c97bdea9752c87michen (me, "%s: thread creation failure (%d)\n",
18bdb8a7484e018149ac9a2766c97bdea9752c87michen in->nscdb->name, errnum);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjldo_update(nsc_lookup_args_t *in) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nss_pheader_t *phdr = (nss_pheader_t *)in->buffer;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* update the length of the data buffer */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl phdr->data_len = phdr->pbufsiz - phdr->data_off;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) lookup_int(in, UPDATEBIT);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (in->buffer)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(in->buffer);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(in);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Invalidate cache
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlvoid
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Juriknsc_invalidate(nsc_ctx_t *ctx, char *dbname, nsc_ctx_t **ctxs)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "nsc_invalidate";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ctx) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx_invalidate(ctx);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (dbname) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((i = get_cache_idx(dbname)) == -1) {
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_WARNING)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: invalid cache name\n", dbname);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((ctx = cache_ctx_p[i]) == NULL) {
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_WARNING)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: no cache context found\n",
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik dbname);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx_invalidate(ctx);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ctxs == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctxs = cache_ctx_p;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i < CACHE_CTX_COUNT; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ctxs[i] != NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx_invalidate(ctxs[i]);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Invalidate cache by context
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurikctx_invalidate(nsc_ctx_t *ctx)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_entry_t *entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "ctx_invalidate";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: invalidate cache\n", ctx->dbname);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i < ctx->db_count; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ctx->nsc_db[i] == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl continue;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&ctx->nsc_db[i]->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry = ctx->nsc_db[i]->qtail;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl while (entry != NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* leave pending calls alone */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (!(entry->stats.status & ST_PENDING))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry->stats.status = ST_DISCARD;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry = entry->qnext;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&ctx->nsc_db[i]->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->stats.invalidate_count++;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Free nsc_entry_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Pre-reqs:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * nscdb->db_mutex lock must be held before calling this function
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjldelete_entry(nsc_db_t *nscdb, nsc_ctx_t *ctx, nsc_entry_t *entry) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl uint_t hash;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl avl_remove(&nscdb->tree, entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl HASH_REMOVE(nscdb, entry, hash, nscd_false);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl queue_remove(nscdb, entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (entry->buffer != NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(entry->buffer);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl entry->buffer = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl umem_cache_free(nsc_entry_cache, entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx->stats.entries--;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic nscd_rc_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjllookup_cache(nsc_lookup_args_t *largs, nscd_cfg_cache_t *cfgp,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik nss_XbyY_args_t *argp, char *whoami, nsc_entry_t **entry)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_db_t *nscdb;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_ctx_t *ctx;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl uint_t hash;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl avl_index_t pos;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ulong_t nentries;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_entry_t find_entry, *node;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "lookup_cache";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ctx = largs->ctx;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb = largs->nscdb;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* set the search key */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl find_entry.key = argp->key; /* struct copy (not deep) */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* lookup the hash table ==> O(1) */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->htable) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *entry = hash_find(nscdb, &find_entry, &hash, nscd_true);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (*entry != NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) queue_adjust(nscdb, *entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* if not found, lookup the AVL tree ==> O(log n) */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *entry = (nsc_entry_t *)avl_find(&nscdb->tree, &find_entry, &pos);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (*entry != NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) queue_adjust(nscdb, *entry);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* move it to the hash table */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->htable) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->htable[hash] == NULL ||
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (*entry)->stats.hits >=
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik nscdb->htable[hash]->stats.hits) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->htable[hash] = *entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* entry not found in the cache */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: cache miss\n", whoami);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cfgp->avoid_ns == nscd_true) {
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: avoid name service\n", whoami);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_DB_ENTRY_NOT_FOUND);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* allocate memory for new entry (stub) */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *entry = (nsc_entry_t *)umem_cache_alloc(nsc_entry_cache,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik UMEM_DEFAULT);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (*entry == NULL) {
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_ERROR)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: memory allocation failure\n", whoami);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_NO_MEMORY);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) memset(*entry, 0, sizeof (**entry));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Note that the actual data for the key is stored within
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * the largs->buffer (input buffer to nsc_lookup).
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * find_entry.key only contains pointers to this data.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * If largs->buffer will be re-allocated by nss_psearch
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * then (*entry)->key will have dangling pointers.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * In such case, the following assignment needs to be
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * replaced by code that duplicates the key.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (*entry)->key = find_entry.key;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Add the entry to the cache.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl avl_insert(&nscdb->tree, *entry, pos); /* O(log n) */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) queue_adjust(nscdb, *entry); /* constant */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->htable) /* constant */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->htable[hash] = *entry;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (*entry)->stats.status = ST_NEW_ENTRY;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nentries = ++(ctx->stats.entries);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* Have we exceeded max entries ? */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cfgp->maxentries > 0 && nentries > cfgp->maxentries) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: maximum entries exceeded -- "
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "deleting least recently used entry\n",
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik whoami);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl node = nscdb->qhead;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl while (node != NULL && node != *entry) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (node->stats.status == ST_DISCARD ||
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik !(node->stats.status & ST_PENDING)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl delete_entry(nscdb, ctx, node);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl node = node->qprev;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * It's okay if we were not able to find one to delete.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * The reaper (when invoked) will return the cache to a
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * safe level.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NSCD_SUCCESS);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurikreaper(nsc_ctx_t *ctx)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl uint_t ttl, extra_sleep, total_sleep, intervals;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl uint_t nodes_per_interval, seconds_per_interval;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ulong_t nsc_entries;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "reaper";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (;;) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_entries = ctx->stats.entries;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_rdlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ttl = ctx->cfg.pos_ttl;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_unlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nsc_entries == 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: nothing to reap\n", ctx->dbname);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* sleep for atleast 60 seconds */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ttl < 60)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ttl = 60;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: sleep %d\n", ctx->dbname, ttl);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) sleep(ttl);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl continue;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ttl < 32) ttl = 32;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ttl > (1<<28)) ttl = 1<<28;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * minimum nodes_per_interval = 256 or 1<<8
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * maximum nodes_per_interval = nsc_entries
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * minimum seconds_per_interval = 32 or 1<<5
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * maximum_seconds_per_interval = ttl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nsc_entries <= ttl) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl intervals = (nsc_entries >> 8) + 1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl seconds_per_interval = ttl / intervals;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nodes_per_interval = 256;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl intervals = (ttl >> 5) + 1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl seconds_per_interval = 32;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nodes_per_interval = nsc_entries / intervals;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nodes_per_interval < 256)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nodes_per_interval = 256;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: total entries = %d, "
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "seconds per interval = %d, "
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik "nodes per interval = %d\n",
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik ctx->dbname, nsc_entries, seconds_per_interval,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik nodes_per_interval);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl total_sleep = reap_cache(ctx, nodes_per_interval,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik seconds_per_interval);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl extra_sleep = 1 + ttl - total_sleep;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (extra_sleep > 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) sleep(extra_sleep);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic uint_t
cb5caa98562cf06753163f558cbcfe30b8f4673adjlreap_cache(nsc_ctx_t *ctx, uint_t nodes_per_interval,
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik uint_t seconds_per_interval)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl uint_t nodes_togo, total_sleep;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl time_t now;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_entry_t *node, *next_node;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nsc_db_t *nscdb;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl uint_t primes[] = {_NSC_HTSIZE_PRIMES};
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ulong_t count, nentries, maxentries;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i, slot, value, newhtsize;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "reap_cache";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl count = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl total_sleep = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nodes_togo = nodes_per_interval;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl now = time(NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i < ctx->db_count; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb = ctx->nsc_db[i];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->reap_node = nscdb->qtail;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl while (nscdb->reap_node != NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nodes_togo == 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) sleep(seconds_per_interval);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl total_sleep += seconds_per_interval;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nodes_togo = nodes_per_interval;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl now = time(NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* delete ST_DISCARD and expired nodes */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((node = nscdb->reap_node) == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl break;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (node->stats.status == ST_DISCARD ||
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (!(node->stats.status & ST_PENDING) &&
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik node->stats.timestamp < now)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Delete entry if its discard flag is
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * set OR if it has expired. Entries
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * with pending updates are not
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * deleted.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * nscdb->reap_node will be adjusted
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * by delete_entry()
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl delete_entry(nscdb, ctx, node);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl count++;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->reap_node = node->qnext;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nodes_togo--;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->htsize == 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl continue;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Dynamic adjustment of hash table size.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Hash table size is roughly 1/8th of the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * total entries. However the size is changed
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * only when the number of entries double or
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * reduced by half
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nentries = avl_numnodes(&nscdb->tree);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (slot = 0, value = _NSC_INIT_HTSIZE_SLOT_VALUE;
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik slot < _NSC_HTSIZE_NUM_SLOTS && nentries > value;
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik value = (value << 1) + 1, slot++)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik ;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->hash_type == nsc_ht_power2)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl newhtsize = _NSC_INIT_HTSIZE_POWER2 << slot;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl newhtsize = primes[slot];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* Recommended size is same as the current size. Done */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->htsize == newhtsize) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl continue;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: resizing hash table from %d to %d\n",
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik nscdb->name, nscdb->htsize, newhtsize);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Dump old hashes because it would be time
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * consuming to rehash them.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) free(nscdb->htable);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->htable = calloc(newhtsize, sizeof (*(nscdb->htable)));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (nscdb->htable == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_ERROR)
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik (me, "%s: memory allocation failure\n",
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik nscdb->name);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* -1 to try later */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->htsize = -1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb->htsize = newhtsize;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: reaped %lu entries\n", ctx->dbname, count);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * if cache is almost full then reduce it to a safe level by
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * evicting LRU entries
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_rdlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl maxentries = ctx->cfg.maxentries;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_unlock(&ctx->cfg_rwlp);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* No limit on number of entries. Done */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (maxentries == 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl goto out;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nentries = ctx->stats.entries;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&ctx->stats_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* what is the percentage of cache used ? */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl value = (nentries * 100) / maxentries;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (value < _NSC_EVICTION_START_LEVEL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl goto out;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * cache needs to be reduced to a safe level
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl value -= _NSC_EVICTION_SAFE_LEVEL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0, count = 0; i < ctx->db_count; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Reduce each subcache by 'value' percent
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscdb = ctx->nsc_db[i];
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nodes_togo = (value * avl_numnodes(&nscdb->tree)) / 100;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* Start from LRU entry i.e queue head */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_node = nscdb->qhead;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl while (nodes_togo > 0 && next_node != NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl node = next_node;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl next_node = next_node->qprev;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (node->stats.status == ST_DISCARD ||
7d7551bcfe5ded1738ddbe3268520996a32023b4Milan Jurik !(node->stats.status & ST_PENDING)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* Leave nodes with pending updates alone */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl delete_entry(nscdb, ctx, node);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl count++;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nodes_togo--;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&nscdb->db_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%s: evicted %lu LRU entries\n", ctx->dbname, count);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlout:
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (total_sleep);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}