106a99fe3SHajimu UMEMOTO /*- 206a99fe3SHajimu UMEMOTO * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru> 306a99fe3SHajimu UMEMOTO * All rights reserved. 406a99fe3SHajimu UMEMOTO * 506a99fe3SHajimu UMEMOTO * Redistribution and use in source and binary forms, with or without 606a99fe3SHajimu UMEMOTO * modification, are permitted provided that the following conditions 706a99fe3SHajimu UMEMOTO * are met: 806a99fe3SHajimu UMEMOTO * 1. Redistributions of source code must retain the above copyright 906a99fe3SHajimu UMEMOTO * notice, this list of conditions and the following disclaimer. 1006a99fe3SHajimu UMEMOTO * 2. Redistributions in binary form must reproduce the above copyright 1106a99fe3SHajimu UMEMOTO * notice, this list of conditions and the following disclaimer in the 1206a99fe3SHajimu UMEMOTO * documentation and/or other materials provided with the distribution. 1306a99fe3SHajimu UMEMOTO * 1406a99fe3SHajimu UMEMOTO * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1506a99fe3SHajimu UMEMOTO * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1606a99fe3SHajimu UMEMOTO * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1706a99fe3SHajimu UMEMOTO * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1806a99fe3SHajimu UMEMOTO * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1906a99fe3SHajimu UMEMOTO * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2006a99fe3SHajimu UMEMOTO * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2106a99fe3SHajimu UMEMOTO * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2206a99fe3SHajimu UMEMOTO * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2306a99fe3SHajimu UMEMOTO * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2406a99fe3SHajimu UMEMOTO * SUCH DAMAGE. 2506a99fe3SHajimu UMEMOTO * 2606a99fe3SHajimu UMEMOTO */ 2706a99fe3SHajimu UMEMOTO 2806a99fe3SHajimu UMEMOTO #include <sys/cdefs.h> 2906a99fe3SHajimu UMEMOTO __FBSDID("$FreeBSD$"); 3006a99fe3SHajimu UMEMOTO 3128f805ceSDag-Erling Smørgrav #include <sys/stat.h> 3228f805ceSDag-Erling Smørgrav #include <sys/time.h> 3328f805ceSDag-Erling Smørgrav 3406a99fe3SHajimu UMEMOTO #include <assert.h> 3506a99fe3SHajimu UMEMOTO #include <math.h> 3628f805ceSDag-Erling Smørgrav #include <nsswitch.h> 3728f805ceSDag-Erling Smørgrav #include <pthread.h> 3806a99fe3SHajimu UMEMOTO #include <stdio.h> 3906a99fe3SHajimu UMEMOTO #include <stdlib.h> 4006a99fe3SHajimu UMEMOTO #include <string.h> 4128f805ceSDag-Erling Smørgrav 4206a99fe3SHajimu UMEMOTO #include "config.h" 4306a99fe3SHajimu UMEMOTO #include "debug.h" 4406a99fe3SHajimu UMEMOTO #include "log.h" 4506a99fe3SHajimu UMEMOTO 4606a99fe3SHajimu UMEMOTO /* 4706a99fe3SHajimu UMEMOTO * Default entries, which always exist in the configuration 4806a99fe3SHajimu UMEMOTO */ 4906a99fe3SHajimu UMEMOTO const char *c_default_entries[6] = { 5006a99fe3SHajimu UMEMOTO NSDB_PASSWD, 5106a99fe3SHajimu UMEMOTO NSDB_GROUP, 5206a99fe3SHajimu UMEMOTO NSDB_HOSTS, 5306a99fe3SHajimu UMEMOTO NSDB_SERVICES, 5406a99fe3SHajimu UMEMOTO NSDB_PROTOCOLS, 5506a99fe3SHajimu UMEMOTO NSDB_RPC 5606a99fe3SHajimu UMEMOTO }; 5706a99fe3SHajimu UMEMOTO 5806a99fe3SHajimu UMEMOTO static int configuration_entry_cmp(const void *, const void *); 5906a99fe3SHajimu UMEMOTO static int configuration_entry_sort_cmp(const void *, const void *); 6006a99fe3SHajimu UMEMOTO static int configuration_entry_cache_mp_sort_cmp(const void *, const void *); 6106a99fe3SHajimu UMEMOTO static int configuration_entry_cache_mp_cmp(const void *, const void *); 6206a99fe3SHajimu UMEMOTO static int configuration_entry_cache_mp_part_cmp(const void *, const void *); 6306a99fe3SHajimu UMEMOTO static struct configuration_entry *create_configuration_entry(const char *, 6406a99fe3SHajimu UMEMOTO struct timeval const *, struct timeval const *, 6506a99fe3SHajimu UMEMOTO struct common_cache_entry_params const *, 6606a99fe3SHajimu UMEMOTO struct common_cache_entry_params const *, 6706a99fe3SHajimu UMEMOTO struct mp_cache_entry_params const *); 6806a99fe3SHajimu UMEMOTO 6906a99fe3SHajimu UMEMOTO static int 7006a99fe3SHajimu UMEMOTO configuration_entry_sort_cmp(const void *e1, const void *e2) 7106a99fe3SHajimu UMEMOTO { 7206a99fe3SHajimu UMEMOTO return (strcmp((*((struct configuration_entry **)e1))->name, 7306a99fe3SHajimu UMEMOTO (*((struct configuration_entry **)e2))->name 7406a99fe3SHajimu UMEMOTO )); 7506a99fe3SHajimu UMEMOTO } 7606a99fe3SHajimu UMEMOTO 7706a99fe3SHajimu UMEMOTO static int 7806a99fe3SHajimu UMEMOTO configuration_entry_cmp(const void *e1, const void *e2) 7906a99fe3SHajimu UMEMOTO { 8006a99fe3SHajimu UMEMOTO return (strcmp((const char *)e1, 8106a99fe3SHajimu UMEMOTO (*((struct configuration_entry **)e2))->name 8206a99fe3SHajimu UMEMOTO )); 8306a99fe3SHajimu UMEMOTO } 8406a99fe3SHajimu UMEMOTO 8506a99fe3SHajimu UMEMOTO static int 8606a99fe3SHajimu UMEMOTO configuration_entry_cache_mp_sort_cmp(const void *e1, const void *e2) 8706a99fe3SHajimu UMEMOTO { 8806a99fe3SHajimu UMEMOTO return (strcmp((*((cache_entry *)e1))->params->entry_name, 8906a99fe3SHajimu UMEMOTO (*((cache_entry *)e2))->params->entry_name 9006a99fe3SHajimu UMEMOTO )); 9106a99fe3SHajimu UMEMOTO } 9206a99fe3SHajimu UMEMOTO 9306a99fe3SHajimu UMEMOTO static int 9406a99fe3SHajimu UMEMOTO configuration_entry_cache_mp_cmp(const void *e1, const void *e2) 9506a99fe3SHajimu UMEMOTO { 9606a99fe3SHajimu UMEMOTO return (strcmp((const char *)e1, 9706a99fe3SHajimu UMEMOTO (*((cache_entry *)e2))->params->entry_name 9806a99fe3SHajimu UMEMOTO )); 9906a99fe3SHajimu UMEMOTO } 10006a99fe3SHajimu UMEMOTO 10106a99fe3SHajimu UMEMOTO static int 10206a99fe3SHajimu UMEMOTO configuration_entry_cache_mp_part_cmp(const void *e1, const void *e2) 10306a99fe3SHajimu UMEMOTO { 10406a99fe3SHajimu UMEMOTO return (strncmp((const char *)e1, 10506a99fe3SHajimu UMEMOTO (*((cache_entry *)e2))->params->entry_name, 10606a99fe3SHajimu UMEMOTO strlen((const char *)e1) 10706a99fe3SHajimu UMEMOTO )); 10806a99fe3SHajimu UMEMOTO } 10906a99fe3SHajimu UMEMOTO 11006a99fe3SHajimu UMEMOTO static struct configuration_entry * 11106a99fe3SHajimu UMEMOTO create_configuration_entry(const char *name, 11206a99fe3SHajimu UMEMOTO struct timeval const *common_timeout, 11306a99fe3SHajimu UMEMOTO struct timeval const *mp_timeout, 11406a99fe3SHajimu UMEMOTO struct common_cache_entry_params const *positive_params, 11506a99fe3SHajimu UMEMOTO struct common_cache_entry_params const *negative_params, 11606a99fe3SHajimu UMEMOTO struct mp_cache_entry_params const *mp_params) 11706a99fe3SHajimu UMEMOTO { 11806a99fe3SHajimu UMEMOTO struct configuration_entry *retval; 11906a99fe3SHajimu UMEMOTO size_t size; 12006a99fe3SHajimu UMEMOTO int res; 12106a99fe3SHajimu UMEMOTO 12206a99fe3SHajimu UMEMOTO TRACE_IN(create_configuration_entry); 12306a99fe3SHajimu UMEMOTO assert(name != NULL); 12406a99fe3SHajimu UMEMOTO assert(positive_params != NULL); 12506a99fe3SHajimu UMEMOTO assert(negative_params != NULL); 12606a99fe3SHajimu UMEMOTO assert(mp_params != NULL); 12706a99fe3SHajimu UMEMOTO 1288eeaaffaSDag-Erling Smørgrav retval = calloc(1, 1298eeaaffaSDag-Erling Smørgrav sizeof(*retval)); 13006a99fe3SHajimu UMEMOTO assert(retval != NULL); 13106a99fe3SHajimu UMEMOTO 13206a99fe3SHajimu UMEMOTO res = pthread_mutex_init(&retval->positive_cache_lock, NULL); 13306a99fe3SHajimu UMEMOTO if (res != 0) { 13406a99fe3SHajimu UMEMOTO free(retval); 13506a99fe3SHajimu UMEMOTO LOG_ERR_2("create_configuration_entry", 13606a99fe3SHajimu UMEMOTO "can't create positive cache lock"); 13706a99fe3SHajimu UMEMOTO TRACE_OUT(create_configuration_entry); 13806a99fe3SHajimu UMEMOTO return (NULL); 13906a99fe3SHajimu UMEMOTO } 14006a99fe3SHajimu UMEMOTO 14106a99fe3SHajimu UMEMOTO res = pthread_mutex_init(&retval->negative_cache_lock, NULL); 14206a99fe3SHajimu UMEMOTO if (res != 0) { 14306a99fe3SHajimu UMEMOTO pthread_mutex_destroy(&retval->positive_cache_lock); 14406a99fe3SHajimu UMEMOTO free(retval); 14506a99fe3SHajimu UMEMOTO LOG_ERR_2("create_configuration_entry", 14606a99fe3SHajimu UMEMOTO "can't create negative cache lock"); 14706a99fe3SHajimu UMEMOTO TRACE_OUT(create_configuration_entry); 14806a99fe3SHajimu UMEMOTO return (NULL); 14906a99fe3SHajimu UMEMOTO } 15006a99fe3SHajimu UMEMOTO 15106a99fe3SHajimu UMEMOTO res = pthread_mutex_init(&retval->mp_cache_lock, NULL); 15206a99fe3SHajimu UMEMOTO if (res != 0) { 15306a99fe3SHajimu UMEMOTO pthread_mutex_destroy(&retval->positive_cache_lock); 15406a99fe3SHajimu UMEMOTO pthread_mutex_destroy(&retval->negative_cache_lock); 15506a99fe3SHajimu UMEMOTO free(retval); 15606a99fe3SHajimu UMEMOTO LOG_ERR_2("create_configuration_entry", 15706a99fe3SHajimu UMEMOTO "can't create negative cache lock"); 15806a99fe3SHajimu UMEMOTO TRACE_OUT(create_configuration_entry); 15906a99fe3SHajimu UMEMOTO return (NULL); 16006a99fe3SHajimu UMEMOTO } 16106a99fe3SHajimu UMEMOTO 16206a99fe3SHajimu UMEMOTO memcpy(&retval->positive_cache_params, positive_params, 16306a99fe3SHajimu UMEMOTO sizeof(struct common_cache_entry_params)); 16406a99fe3SHajimu UMEMOTO memcpy(&retval->negative_cache_params, negative_params, 16506a99fe3SHajimu UMEMOTO sizeof(struct common_cache_entry_params)); 16606a99fe3SHajimu UMEMOTO memcpy(&retval->mp_cache_params, mp_params, 16706a99fe3SHajimu UMEMOTO sizeof(struct mp_cache_entry_params)); 16806a99fe3SHajimu UMEMOTO 16906a99fe3SHajimu UMEMOTO size = strlen(name); 1708eeaaffaSDag-Erling Smørgrav retval->name = calloc(1, size + 1); 17106a99fe3SHajimu UMEMOTO assert(retval->name != NULL); 17206a99fe3SHajimu UMEMOTO memcpy(retval->name, name, size); 17306a99fe3SHajimu UMEMOTO 17406a99fe3SHajimu UMEMOTO memcpy(&retval->common_query_timeout, common_timeout, 17506a99fe3SHajimu UMEMOTO sizeof(struct timeval)); 17606a99fe3SHajimu UMEMOTO memcpy(&retval->mp_query_timeout, mp_timeout, 17706a99fe3SHajimu UMEMOTO sizeof(struct timeval)); 17806a99fe3SHajimu UMEMOTO 17927f2bc9eSDag-Erling Smørgrav asprintf(&retval->positive_cache_params.cep.entry_name, "%s+", name); 18027f2bc9eSDag-Erling Smørgrav assert(retval->positive_cache_params.cep.entry_name != NULL); 18106a99fe3SHajimu UMEMOTO 18227f2bc9eSDag-Erling Smørgrav asprintf(&retval->negative_cache_params.cep.entry_name, "%s-", name); 18327f2bc9eSDag-Erling Smørgrav assert(retval->negative_cache_params.cep.entry_name != NULL); 18406a99fe3SHajimu UMEMOTO 18527f2bc9eSDag-Erling Smørgrav asprintf(&retval->mp_cache_params.cep.entry_name, "%s*", name); 18627f2bc9eSDag-Erling Smørgrav assert(retval->mp_cache_params.cep.entry_name != NULL); 18706a99fe3SHajimu UMEMOTO 18806a99fe3SHajimu UMEMOTO TRACE_OUT(create_configuration_entry); 18906a99fe3SHajimu UMEMOTO return (retval); 19006a99fe3SHajimu UMEMOTO } 19106a99fe3SHajimu UMEMOTO 19206a99fe3SHajimu UMEMOTO /* 19306a99fe3SHajimu UMEMOTO * Creates configuration entry and fills it with default values 19406a99fe3SHajimu UMEMOTO */ 19506a99fe3SHajimu UMEMOTO struct configuration_entry * 19606a99fe3SHajimu UMEMOTO create_def_configuration_entry(const char *name) 19706a99fe3SHajimu UMEMOTO { 19806a99fe3SHajimu UMEMOTO struct common_cache_entry_params positive_params, negative_params; 19906a99fe3SHajimu UMEMOTO struct mp_cache_entry_params mp_params; 20006a99fe3SHajimu UMEMOTO struct timeval default_common_timeout, default_mp_timeout; 20106a99fe3SHajimu UMEMOTO 20206a99fe3SHajimu UMEMOTO struct configuration_entry *res = NULL; 20306a99fe3SHajimu UMEMOTO 20406a99fe3SHajimu UMEMOTO TRACE_IN(create_def_configuration_entry); 20506a99fe3SHajimu UMEMOTO memset(&positive_params, 0, 20606a99fe3SHajimu UMEMOTO sizeof(struct common_cache_entry_params)); 20727f2bc9eSDag-Erling Smørgrav positive_params.cep.entry_type = CET_COMMON; 20806a99fe3SHajimu UMEMOTO positive_params.cache_entries_size = DEFAULT_CACHE_HT_SIZE; 20906a99fe3SHajimu UMEMOTO positive_params.max_elemsize = DEFAULT_POSITIVE_ELEMENTS_SIZE; 21006a99fe3SHajimu UMEMOTO positive_params.satisf_elemsize = DEFAULT_POSITIVE_ELEMENTS_SIZE / 2; 21106a99fe3SHajimu UMEMOTO positive_params.max_lifetime.tv_sec = DEFAULT_POSITIVE_LIFETIME; 212a397989dSStefan Eßer positive_params.confidence_threshold = DEFAULT_POSITIVE_CONF_THRESH; 21306a99fe3SHajimu UMEMOTO positive_params.policy = CPT_LRU; 21406a99fe3SHajimu UMEMOTO 21506a99fe3SHajimu UMEMOTO memcpy(&negative_params, &positive_params, 21606a99fe3SHajimu UMEMOTO sizeof(struct common_cache_entry_params)); 21706a99fe3SHajimu UMEMOTO negative_params.max_elemsize = DEFAULT_NEGATIVE_ELEMENTS_SIZE; 21806a99fe3SHajimu UMEMOTO negative_params.satisf_elemsize = DEFAULT_NEGATIVE_ELEMENTS_SIZE / 2; 21906a99fe3SHajimu UMEMOTO negative_params.max_lifetime.tv_sec = DEFAULT_NEGATIVE_LIFETIME; 220a397989dSStefan Eßer negative_params.confidence_threshold = DEFAULT_NEGATIVE_CONF_THRESH; 22106a99fe3SHajimu UMEMOTO negative_params.policy = CPT_FIFO; 22206a99fe3SHajimu UMEMOTO 22306a99fe3SHajimu UMEMOTO memset(&default_common_timeout, 0, sizeof(struct timeval)); 22406a99fe3SHajimu UMEMOTO default_common_timeout.tv_sec = DEFAULT_COMMON_ENTRY_TIMEOUT; 22506a99fe3SHajimu UMEMOTO 22606a99fe3SHajimu UMEMOTO memset(&default_mp_timeout, 0, sizeof(struct timeval)); 22706a99fe3SHajimu UMEMOTO default_mp_timeout.tv_sec = DEFAULT_MP_ENTRY_TIMEOUT; 22806a99fe3SHajimu UMEMOTO 22906a99fe3SHajimu UMEMOTO memset(&mp_params, 0, 23006a99fe3SHajimu UMEMOTO sizeof(struct mp_cache_entry_params)); 23127f2bc9eSDag-Erling Smørgrav mp_params.cep.entry_type = CET_MULTIPART; 23206a99fe3SHajimu UMEMOTO mp_params.max_elemsize = DEFAULT_MULTIPART_ELEMENTS_SIZE; 23306a99fe3SHajimu UMEMOTO mp_params.max_sessions = DEFAULT_MULITPART_SESSIONS_SIZE; 23406a99fe3SHajimu UMEMOTO mp_params.max_lifetime.tv_sec = DEFAULT_MULITPART_LIFETIME; 23506a99fe3SHajimu UMEMOTO 23606a99fe3SHajimu UMEMOTO res = create_configuration_entry(name, &default_common_timeout, 23706a99fe3SHajimu UMEMOTO &default_mp_timeout, &positive_params, &negative_params, 23806a99fe3SHajimu UMEMOTO &mp_params); 23906a99fe3SHajimu UMEMOTO 24006a99fe3SHajimu UMEMOTO TRACE_OUT(create_def_configuration_entry); 24106a99fe3SHajimu UMEMOTO return (res); 24206a99fe3SHajimu UMEMOTO } 24306a99fe3SHajimu UMEMOTO 24406a99fe3SHajimu UMEMOTO void 24506a99fe3SHajimu UMEMOTO destroy_configuration_entry(struct configuration_entry *entry) 24606a99fe3SHajimu UMEMOTO { 24706a99fe3SHajimu UMEMOTO TRACE_IN(destroy_configuration_entry); 24806a99fe3SHajimu UMEMOTO assert(entry != NULL); 24906a99fe3SHajimu UMEMOTO pthread_mutex_destroy(&entry->positive_cache_lock); 25006a99fe3SHajimu UMEMOTO pthread_mutex_destroy(&entry->negative_cache_lock); 25106a99fe3SHajimu UMEMOTO pthread_mutex_destroy(&entry->mp_cache_lock); 25206a99fe3SHajimu UMEMOTO free(entry->name); 25327f2bc9eSDag-Erling Smørgrav free(entry->positive_cache_params.cep.entry_name); 25427f2bc9eSDag-Erling Smørgrav free(entry->negative_cache_params.cep.entry_name); 25527f2bc9eSDag-Erling Smørgrav free(entry->mp_cache_params.cep.entry_name); 25606a99fe3SHajimu UMEMOTO free(entry->mp_cache_entries); 25706a99fe3SHajimu UMEMOTO free(entry); 25806a99fe3SHajimu UMEMOTO TRACE_OUT(destroy_configuration_entry); 25906a99fe3SHajimu UMEMOTO } 26006a99fe3SHajimu UMEMOTO 26106a99fe3SHajimu UMEMOTO int 26206a99fe3SHajimu UMEMOTO add_configuration_entry(struct configuration *config, 26306a99fe3SHajimu UMEMOTO struct configuration_entry *entry) 26406a99fe3SHajimu UMEMOTO { 26506a99fe3SHajimu UMEMOTO TRACE_IN(add_configuration_entry); 26606a99fe3SHajimu UMEMOTO assert(entry != NULL); 26706a99fe3SHajimu UMEMOTO assert(entry->name != NULL); 26806a99fe3SHajimu UMEMOTO if (configuration_find_entry(config, entry->name) != NULL) { 26906a99fe3SHajimu UMEMOTO TRACE_OUT(add_configuration_entry); 27006a99fe3SHajimu UMEMOTO return (-1); 27106a99fe3SHajimu UMEMOTO } 27206a99fe3SHajimu UMEMOTO 27306a99fe3SHajimu UMEMOTO if (config->entries_size == config->entries_capacity) { 27406a99fe3SHajimu UMEMOTO struct configuration_entry **new_entries; 27506a99fe3SHajimu UMEMOTO 27606a99fe3SHajimu UMEMOTO config->entries_capacity *= 2; 277*87959e27SPedro F. Giffuni new_entries = calloc(config->entries_capacity, 278*87959e27SPedro F. Giffuni sizeof(*new_entries)); 27906a99fe3SHajimu UMEMOTO assert(new_entries != NULL); 28006a99fe3SHajimu UMEMOTO memcpy(new_entries, config->entries, 28106a99fe3SHajimu UMEMOTO sizeof(struct configuration_entry *) * 28206a99fe3SHajimu UMEMOTO config->entries_size); 28306a99fe3SHajimu UMEMOTO 28406a99fe3SHajimu UMEMOTO free(config->entries); 28506a99fe3SHajimu UMEMOTO config->entries = new_entries; 28606a99fe3SHajimu UMEMOTO } 28706a99fe3SHajimu UMEMOTO 28806a99fe3SHajimu UMEMOTO config->entries[config->entries_size++] = entry; 28906a99fe3SHajimu UMEMOTO qsort(config->entries, config->entries_size, 29006a99fe3SHajimu UMEMOTO sizeof(struct configuration_entry *), 29106a99fe3SHajimu UMEMOTO configuration_entry_sort_cmp); 29206a99fe3SHajimu UMEMOTO 29306a99fe3SHajimu UMEMOTO TRACE_OUT(add_configuration_entry); 29406a99fe3SHajimu UMEMOTO return (0); 29506a99fe3SHajimu UMEMOTO } 29606a99fe3SHajimu UMEMOTO 29706a99fe3SHajimu UMEMOTO size_t 29806a99fe3SHajimu UMEMOTO configuration_get_entries_size(struct configuration *config) 29906a99fe3SHajimu UMEMOTO { 30006a99fe3SHajimu UMEMOTO TRACE_IN(configuration_get_entries_size); 30106a99fe3SHajimu UMEMOTO assert(config != NULL); 30206a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_get_entries_size); 30306a99fe3SHajimu UMEMOTO return (config->entries_size); 30406a99fe3SHajimu UMEMOTO } 30506a99fe3SHajimu UMEMOTO 30606a99fe3SHajimu UMEMOTO struct configuration_entry * 30706a99fe3SHajimu UMEMOTO configuration_get_entry(struct configuration *config, size_t index) 30806a99fe3SHajimu UMEMOTO { 30906a99fe3SHajimu UMEMOTO TRACE_IN(configuration_get_entry); 31006a99fe3SHajimu UMEMOTO assert(config != NULL); 31106a99fe3SHajimu UMEMOTO assert(index < config->entries_size); 31206a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_get_entry); 31306a99fe3SHajimu UMEMOTO return (config->entries[index]); 31406a99fe3SHajimu UMEMOTO } 31506a99fe3SHajimu UMEMOTO 31606a99fe3SHajimu UMEMOTO struct configuration_entry * 31706a99fe3SHajimu UMEMOTO configuration_find_entry(struct configuration *config, 31806a99fe3SHajimu UMEMOTO const char *name) 31906a99fe3SHajimu UMEMOTO { 32006a99fe3SHajimu UMEMOTO struct configuration_entry **retval; 32106a99fe3SHajimu UMEMOTO 32206a99fe3SHajimu UMEMOTO TRACE_IN(configuration_find_entry); 32306a99fe3SHajimu UMEMOTO 32406a99fe3SHajimu UMEMOTO retval = bsearch(name, config->entries, config->entries_size, 32506a99fe3SHajimu UMEMOTO sizeof(struct configuration_entry *), configuration_entry_cmp); 32606a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_find_entry); 32706a99fe3SHajimu UMEMOTO 32806a99fe3SHajimu UMEMOTO return ((retval != NULL) ? *retval : NULL); 32906a99fe3SHajimu UMEMOTO } 33006a99fe3SHajimu UMEMOTO 33106a99fe3SHajimu UMEMOTO /* 33206a99fe3SHajimu UMEMOTO * All multipart cache entries are stored in the configuration_entry in the 33306a99fe3SHajimu UMEMOTO * sorted array (sorted by names). The 3 functions below manage this array. 33406a99fe3SHajimu UMEMOTO */ 33506a99fe3SHajimu UMEMOTO 33606a99fe3SHajimu UMEMOTO int 33706a99fe3SHajimu UMEMOTO configuration_entry_add_mp_cache_entry(struct configuration_entry *config_entry, 33806a99fe3SHajimu UMEMOTO cache_entry c_entry) 33906a99fe3SHajimu UMEMOTO { 34006a99fe3SHajimu UMEMOTO cache_entry *new_mp_entries, *old_mp_entries; 34106a99fe3SHajimu UMEMOTO 34206a99fe3SHajimu UMEMOTO TRACE_IN(configuration_entry_add_mp_cache_entry); 34306a99fe3SHajimu UMEMOTO ++config_entry->mp_cache_entries_size; 3448eeaaffaSDag-Erling Smørgrav new_mp_entries = malloc(sizeof(*new_mp_entries) * 34506a99fe3SHajimu UMEMOTO config_entry->mp_cache_entries_size); 34606a99fe3SHajimu UMEMOTO assert(new_mp_entries != NULL); 34706a99fe3SHajimu UMEMOTO new_mp_entries[0] = c_entry; 34806a99fe3SHajimu UMEMOTO 34906a99fe3SHajimu UMEMOTO if (config_entry->mp_cache_entries_size - 1 > 0) { 35006a99fe3SHajimu UMEMOTO memcpy(new_mp_entries + 1, 35106a99fe3SHajimu UMEMOTO config_entry->mp_cache_entries, 35206a99fe3SHajimu UMEMOTO (config_entry->mp_cache_entries_size - 1) * 35306a99fe3SHajimu UMEMOTO sizeof(cache_entry)); 35406a99fe3SHajimu UMEMOTO } 35506a99fe3SHajimu UMEMOTO 35606a99fe3SHajimu UMEMOTO old_mp_entries = config_entry->mp_cache_entries; 35706a99fe3SHajimu UMEMOTO config_entry->mp_cache_entries = new_mp_entries; 35806a99fe3SHajimu UMEMOTO free(old_mp_entries); 35906a99fe3SHajimu UMEMOTO 36006a99fe3SHajimu UMEMOTO qsort(config_entry->mp_cache_entries, 36106a99fe3SHajimu UMEMOTO config_entry->mp_cache_entries_size, 36206a99fe3SHajimu UMEMOTO sizeof(cache_entry), 36306a99fe3SHajimu UMEMOTO configuration_entry_cache_mp_sort_cmp); 36406a99fe3SHajimu UMEMOTO 36506a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_entry_add_mp_cache_entry); 36606a99fe3SHajimu UMEMOTO return (0); 36706a99fe3SHajimu UMEMOTO } 36806a99fe3SHajimu UMEMOTO 36906a99fe3SHajimu UMEMOTO cache_entry 37006a99fe3SHajimu UMEMOTO configuration_entry_find_mp_cache_entry( 37106a99fe3SHajimu UMEMOTO struct configuration_entry *config_entry, const char *mp_name) 37206a99fe3SHajimu UMEMOTO { 37306a99fe3SHajimu UMEMOTO cache_entry *result; 37406a99fe3SHajimu UMEMOTO 37506a99fe3SHajimu UMEMOTO TRACE_IN(configuration_entry_find_mp_cache_entry); 37606a99fe3SHajimu UMEMOTO result = bsearch(mp_name, config_entry->mp_cache_entries, 37706a99fe3SHajimu UMEMOTO config_entry->mp_cache_entries_size, 37806a99fe3SHajimu UMEMOTO sizeof(cache_entry), configuration_entry_cache_mp_cmp); 37906a99fe3SHajimu UMEMOTO 38006a99fe3SHajimu UMEMOTO if (result == NULL) { 38106a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_entry_find_mp_cache_entry); 38206a99fe3SHajimu UMEMOTO return (NULL); 38306a99fe3SHajimu UMEMOTO } else { 38406a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_entry_find_mp_cache_entry); 38506a99fe3SHajimu UMEMOTO return (*result); 38606a99fe3SHajimu UMEMOTO } 38706a99fe3SHajimu UMEMOTO } 38806a99fe3SHajimu UMEMOTO 38906a99fe3SHajimu UMEMOTO /* 39006a99fe3SHajimu UMEMOTO * Searches for all multipart entries with names starting with mp_name. 39106a99fe3SHajimu UMEMOTO * Needed for cache flushing. 39206a99fe3SHajimu UMEMOTO */ 39306a99fe3SHajimu UMEMOTO int 39406a99fe3SHajimu UMEMOTO configuration_entry_find_mp_cache_entries( 39506a99fe3SHajimu UMEMOTO struct configuration_entry *config_entry, const char *mp_name, 39606a99fe3SHajimu UMEMOTO cache_entry **start, cache_entry **finish) 39706a99fe3SHajimu UMEMOTO { 39806a99fe3SHajimu UMEMOTO cache_entry *result; 39906a99fe3SHajimu UMEMOTO 40006a99fe3SHajimu UMEMOTO TRACE_IN(configuration_entry_find_mp_cache_entries); 40106a99fe3SHajimu UMEMOTO result = bsearch(mp_name, config_entry->mp_cache_entries, 40206a99fe3SHajimu UMEMOTO config_entry->mp_cache_entries_size, 40306a99fe3SHajimu UMEMOTO sizeof(cache_entry), configuration_entry_cache_mp_part_cmp); 40406a99fe3SHajimu UMEMOTO 40506a99fe3SHajimu UMEMOTO if (result == NULL) { 40606a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_entry_find_mp_cache_entries); 40706a99fe3SHajimu UMEMOTO return (-1); 40806a99fe3SHajimu UMEMOTO } 40906a99fe3SHajimu UMEMOTO 41006a99fe3SHajimu UMEMOTO *start = result; 41106a99fe3SHajimu UMEMOTO *finish = result + 1; 41206a99fe3SHajimu UMEMOTO 41306a99fe3SHajimu UMEMOTO while (*start != config_entry->mp_cache_entries) { 41406a99fe3SHajimu UMEMOTO if (configuration_entry_cache_mp_part_cmp(mp_name, *start - 1) == 0) 41506a99fe3SHajimu UMEMOTO *start = *start - 1; 41606a99fe3SHajimu UMEMOTO else 41706a99fe3SHajimu UMEMOTO break; 41806a99fe3SHajimu UMEMOTO } 41906a99fe3SHajimu UMEMOTO 42006a99fe3SHajimu UMEMOTO while (*finish != config_entry->mp_cache_entries + 42106a99fe3SHajimu UMEMOTO config_entry->mp_cache_entries_size) { 42206a99fe3SHajimu UMEMOTO 42306a99fe3SHajimu UMEMOTO if (configuration_entry_cache_mp_part_cmp( 42406a99fe3SHajimu UMEMOTO mp_name, *finish) == 0) 42506a99fe3SHajimu UMEMOTO *finish = *finish + 1; 42606a99fe3SHajimu UMEMOTO else 42706a99fe3SHajimu UMEMOTO break; 42806a99fe3SHajimu UMEMOTO } 42906a99fe3SHajimu UMEMOTO 43006a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_entry_find_mp_cache_entries); 43106a99fe3SHajimu UMEMOTO return (0); 43206a99fe3SHajimu UMEMOTO } 43306a99fe3SHajimu UMEMOTO 43406a99fe3SHajimu UMEMOTO /* 43506a99fe3SHajimu UMEMOTO * Configuration entry uses rwlock to handle access to its fields. 43606a99fe3SHajimu UMEMOTO */ 43706a99fe3SHajimu UMEMOTO void 43806a99fe3SHajimu UMEMOTO configuration_lock_rdlock(struct configuration *config) 43906a99fe3SHajimu UMEMOTO { 44006a99fe3SHajimu UMEMOTO TRACE_IN(configuration_lock_rdlock); 44106a99fe3SHajimu UMEMOTO pthread_rwlock_rdlock(&config->rwlock); 44206a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_lock_rdlock); 44306a99fe3SHajimu UMEMOTO } 44406a99fe3SHajimu UMEMOTO 44506a99fe3SHajimu UMEMOTO void 44606a99fe3SHajimu UMEMOTO configuration_lock_wrlock(struct configuration *config) 44706a99fe3SHajimu UMEMOTO { 44806a99fe3SHajimu UMEMOTO TRACE_IN(configuration_lock_wrlock); 44906a99fe3SHajimu UMEMOTO pthread_rwlock_wrlock(&config->rwlock); 45006a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_lock_wrlock); 45106a99fe3SHajimu UMEMOTO } 45206a99fe3SHajimu UMEMOTO 45306a99fe3SHajimu UMEMOTO void 45406a99fe3SHajimu UMEMOTO configuration_unlock(struct configuration *config) 45506a99fe3SHajimu UMEMOTO { 45606a99fe3SHajimu UMEMOTO TRACE_IN(configuration_unlock); 45706a99fe3SHajimu UMEMOTO pthread_rwlock_unlock(&config->rwlock); 45806a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_unlock); 45906a99fe3SHajimu UMEMOTO } 46006a99fe3SHajimu UMEMOTO 46106a99fe3SHajimu UMEMOTO /* 46206a99fe3SHajimu UMEMOTO * Configuration entry uses 3 mutexes to handle cache operations. They are 46306a99fe3SHajimu UMEMOTO * acquired by configuration_lock_entry and configuration_unlock_entry 46406a99fe3SHajimu UMEMOTO * functions. 46506a99fe3SHajimu UMEMOTO */ 46606a99fe3SHajimu UMEMOTO void 46706a99fe3SHajimu UMEMOTO configuration_lock_entry(struct configuration_entry *entry, 46806a99fe3SHajimu UMEMOTO enum config_entry_lock_type lock_type) 46906a99fe3SHajimu UMEMOTO { 47006a99fe3SHajimu UMEMOTO TRACE_IN(configuration_lock_entry); 47106a99fe3SHajimu UMEMOTO assert(entry != NULL); 47206a99fe3SHajimu UMEMOTO 47306a99fe3SHajimu UMEMOTO switch (lock_type) { 47406a99fe3SHajimu UMEMOTO case CELT_POSITIVE: 47506a99fe3SHajimu UMEMOTO pthread_mutex_lock(&entry->positive_cache_lock); 47606a99fe3SHajimu UMEMOTO break; 47706a99fe3SHajimu UMEMOTO case CELT_NEGATIVE: 47806a99fe3SHajimu UMEMOTO pthread_mutex_lock(&entry->negative_cache_lock); 47906a99fe3SHajimu UMEMOTO break; 48006a99fe3SHajimu UMEMOTO case CELT_MULTIPART: 48106a99fe3SHajimu UMEMOTO pthread_mutex_lock(&entry->mp_cache_lock); 48206a99fe3SHajimu UMEMOTO break; 48306a99fe3SHajimu UMEMOTO default: 48406a99fe3SHajimu UMEMOTO /* should be unreachable */ 48506a99fe3SHajimu UMEMOTO break; 48606a99fe3SHajimu UMEMOTO } 48706a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_lock_entry); 48806a99fe3SHajimu UMEMOTO } 48906a99fe3SHajimu UMEMOTO 49006a99fe3SHajimu UMEMOTO void 49106a99fe3SHajimu UMEMOTO configuration_unlock_entry(struct configuration_entry *entry, 49206a99fe3SHajimu UMEMOTO enum config_entry_lock_type lock_type) 49306a99fe3SHajimu UMEMOTO { 49406a99fe3SHajimu UMEMOTO TRACE_IN(configuration_unlock_entry); 49506a99fe3SHajimu UMEMOTO assert(entry != NULL); 49606a99fe3SHajimu UMEMOTO 49706a99fe3SHajimu UMEMOTO switch (lock_type) { 49806a99fe3SHajimu UMEMOTO case CELT_POSITIVE: 49906a99fe3SHajimu UMEMOTO pthread_mutex_unlock(&entry->positive_cache_lock); 50006a99fe3SHajimu UMEMOTO break; 50106a99fe3SHajimu UMEMOTO case CELT_NEGATIVE: 50206a99fe3SHajimu UMEMOTO pthread_mutex_unlock(&entry->negative_cache_lock); 50306a99fe3SHajimu UMEMOTO break; 50406a99fe3SHajimu UMEMOTO case CELT_MULTIPART: 50506a99fe3SHajimu UMEMOTO pthread_mutex_unlock(&entry->mp_cache_lock); 50606a99fe3SHajimu UMEMOTO break; 50706a99fe3SHajimu UMEMOTO default: 50806a99fe3SHajimu UMEMOTO /* should be unreachable */ 50906a99fe3SHajimu UMEMOTO break; 51006a99fe3SHajimu UMEMOTO } 51106a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_unlock_entry); 51206a99fe3SHajimu UMEMOTO } 51306a99fe3SHajimu UMEMOTO 51406a99fe3SHajimu UMEMOTO struct configuration * 51506a99fe3SHajimu UMEMOTO init_configuration(void) 51606a99fe3SHajimu UMEMOTO { 51706a99fe3SHajimu UMEMOTO struct configuration *retval; 51806a99fe3SHajimu UMEMOTO 51906a99fe3SHajimu UMEMOTO TRACE_IN(init_configuration); 5208eeaaffaSDag-Erling Smørgrav retval = calloc(1, sizeof(*retval)); 52106a99fe3SHajimu UMEMOTO assert(retval != NULL); 52206a99fe3SHajimu UMEMOTO 52306a99fe3SHajimu UMEMOTO retval->entries_capacity = INITIAL_ENTRIES_CAPACITY; 524*87959e27SPedro F. Giffuni retval->entries = calloc(retval->entries_capacity, 525*87959e27SPedro F. Giffuni sizeof(*retval->entries)); 52606a99fe3SHajimu UMEMOTO assert(retval->entries != NULL); 52706a99fe3SHajimu UMEMOTO 52806a99fe3SHajimu UMEMOTO pthread_rwlock_init(&retval->rwlock, NULL); 52906a99fe3SHajimu UMEMOTO 53006a99fe3SHajimu UMEMOTO TRACE_OUT(init_configuration); 53106a99fe3SHajimu UMEMOTO return (retval); 53206a99fe3SHajimu UMEMOTO } 53306a99fe3SHajimu UMEMOTO 53406a99fe3SHajimu UMEMOTO void 53506a99fe3SHajimu UMEMOTO fill_configuration_defaults(struct configuration *config) 53606a99fe3SHajimu UMEMOTO { 53706a99fe3SHajimu UMEMOTO size_t len, i; 53806a99fe3SHajimu UMEMOTO 53906a99fe3SHajimu UMEMOTO TRACE_IN(fill_configuration_defaults); 54006a99fe3SHajimu UMEMOTO assert(config != NULL); 54106a99fe3SHajimu UMEMOTO 54206a99fe3SHajimu UMEMOTO if (config->socket_path != NULL) 54306a99fe3SHajimu UMEMOTO free(config->socket_path); 54406a99fe3SHajimu UMEMOTO 54506a99fe3SHajimu UMEMOTO len = strlen(DEFAULT_SOCKET_PATH); 5468eeaaffaSDag-Erling Smørgrav config->socket_path = calloc(1, len + 1); 54706a99fe3SHajimu UMEMOTO assert(config->socket_path != NULL); 54806a99fe3SHajimu UMEMOTO memcpy(config->socket_path, DEFAULT_SOCKET_PATH, len); 54906a99fe3SHajimu UMEMOTO 55006a99fe3SHajimu UMEMOTO len = strlen(DEFAULT_PIDFILE_PATH); 5518eeaaffaSDag-Erling Smørgrav config->pidfile_path = calloc(1, len + 1); 55206a99fe3SHajimu UMEMOTO assert(config->pidfile_path != NULL); 55306a99fe3SHajimu UMEMOTO memcpy(config->pidfile_path, DEFAULT_PIDFILE_PATH, len); 55406a99fe3SHajimu UMEMOTO 55506a99fe3SHajimu UMEMOTO config->socket_mode = S_IFSOCK | S_IRUSR | S_IWUSR | 55606a99fe3SHajimu UMEMOTO S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; 55706a99fe3SHajimu UMEMOTO config->force_unlink = 1; 55806a99fe3SHajimu UMEMOTO 55906a99fe3SHajimu UMEMOTO config->query_timeout = DEFAULT_QUERY_TIMEOUT; 56006a99fe3SHajimu UMEMOTO config->threads_num = DEFAULT_THREADS_NUM; 56106a99fe3SHajimu UMEMOTO 56206a99fe3SHajimu UMEMOTO for (i = 0; i < config->entries_size; ++i) 56306a99fe3SHajimu UMEMOTO destroy_configuration_entry(config->entries[i]); 56406a99fe3SHajimu UMEMOTO config->entries_size = 0; 56506a99fe3SHajimu UMEMOTO 56606a99fe3SHajimu UMEMOTO TRACE_OUT(fill_configuration_defaults); 56706a99fe3SHajimu UMEMOTO } 56806a99fe3SHajimu UMEMOTO 56906a99fe3SHajimu UMEMOTO void 57006a99fe3SHajimu UMEMOTO destroy_configuration(struct configuration *config) 57106a99fe3SHajimu UMEMOTO { 57251d6ddb5SDag-Erling Smørgrav unsigned int i; 57351d6ddb5SDag-Erling Smørgrav 57406a99fe3SHajimu UMEMOTO TRACE_IN(destroy_configuration); 57506a99fe3SHajimu UMEMOTO assert(config != NULL); 57606a99fe3SHajimu UMEMOTO free(config->pidfile_path); 57706a99fe3SHajimu UMEMOTO free(config->socket_path); 57806a99fe3SHajimu UMEMOTO 57906a99fe3SHajimu UMEMOTO for (i = 0; i < config->entries_size; ++i) 58006a99fe3SHajimu UMEMOTO destroy_configuration_entry(config->entries[i]); 58106a99fe3SHajimu UMEMOTO free(config->entries); 58206a99fe3SHajimu UMEMOTO 58306a99fe3SHajimu UMEMOTO pthread_rwlock_destroy(&config->rwlock); 58406a99fe3SHajimu UMEMOTO free(config); 58506a99fe3SHajimu UMEMOTO TRACE_OUT(destroy_configuration); 58606a99fe3SHajimu UMEMOTO } 587