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>
2928f805ceSDag-Erling Smørgrav #include <sys/stat.h>
3028f805ceSDag-Erling Smørgrav #include <sys/time.h>
3128f805ceSDag-Erling Smørgrav
3206a99fe3SHajimu UMEMOTO #include <assert.h>
3306a99fe3SHajimu UMEMOTO #include <math.h>
3428f805ceSDag-Erling Smørgrav #include <nsswitch.h>
3528f805ceSDag-Erling Smørgrav #include <pthread.h>
3606a99fe3SHajimu UMEMOTO #include <stdio.h>
3706a99fe3SHajimu UMEMOTO #include <stdlib.h>
3806a99fe3SHajimu UMEMOTO #include <string.h>
3928f805ceSDag-Erling Smørgrav
4006a99fe3SHajimu UMEMOTO #include "config.h"
4106a99fe3SHajimu UMEMOTO #include "debug.h"
4206a99fe3SHajimu UMEMOTO #include "log.h"
4306a99fe3SHajimu UMEMOTO
4406a99fe3SHajimu UMEMOTO /*
4506a99fe3SHajimu UMEMOTO * Default entries, which always exist in the configuration
4606a99fe3SHajimu UMEMOTO */
4706a99fe3SHajimu UMEMOTO const char *c_default_entries[6] = {
4806a99fe3SHajimu UMEMOTO NSDB_PASSWD,
4906a99fe3SHajimu UMEMOTO NSDB_GROUP,
5006a99fe3SHajimu UMEMOTO NSDB_HOSTS,
5106a99fe3SHajimu UMEMOTO NSDB_SERVICES,
5206a99fe3SHajimu UMEMOTO NSDB_PROTOCOLS,
5306a99fe3SHajimu UMEMOTO NSDB_RPC
5406a99fe3SHajimu UMEMOTO };
5506a99fe3SHajimu UMEMOTO
5606a99fe3SHajimu UMEMOTO static int configuration_entry_cmp(const void *, const void *);
5706a99fe3SHajimu UMEMOTO static int configuration_entry_sort_cmp(const void *, const void *);
5806a99fe3SHajimu UMEMOTO static int configuration_entry_cache_mp_sort_cmp(const void *, const void *);
5906a99fe3SHajimu UMEMOTO static int configuration_entry_cache_mp_cmp(const void *, const void *);
6006a99fe3SHajimu UMEMOTO static int configuration_entry_cache_mp_part_cmp(const void *, const void *);
6106a99fe3SHajimu UMEMOTO static struct configuration_entry *create_configuration_entry(const char *,
6206a99fe3SHajimu UMEMOTO struct timeval const *, struct timeval const *,
6306a99fe3SHajimu UMEMOTO struct common_cache_entry_params const *,
6406a99fe3SHajimu UMEMOTO struct common_cache_entry_params const *,
6506a99fe3SHajimu UMEMOTO struct mp_cache_entry_params const *);
6606a99fe3SHajimu UMEMOTO
6706a99fe3SHajimu UMEMOTO static int
configuration_entry_sort_cmp(const void * e1,const void * e2)6806a99fe3SHajimu UMEMOTO configuration_entry_sort_cmp(const void *e1, const void *e2)
6906a99fe3SHajimu UMEMOTO {
7006a99fe3SHajimu UMEMOTO return (strcmp((*((struct configuration_entry **)e1))->name,
7106a99fe3SHajimu UMEMOTO (*((struct configuration_entry **)e2))->name
7206a99fe3SHajimu UMEMOTO ));
7306a99fe3SHajimu UMEMOTO }
7406a99fe3SHajimu UMEMOTO
7506a99fe3SHajimu UMEMOTO static int
configuration_entry_cmp(const void * e1,const void * e2)7606a99fe3SHajimu UMEMOTO configuration_entry_cmp(const void *e1, const void *e2)
7706a99fe3SHajimu UMEMOTO {
7806a99fe3SHajimu UMEMOTO return (strcmp((const char *)e1,
7906a99fe3SHajimu UMEMOTO (*((struct configuration_entry **)e2))->name
8006a99fe3SHajimu UMEMOTO ));
8106a99fe3SHajimu UMEMOTO }
8206a99fe3SHajimu UMEMOTO
8306a99fe3SHajimu UMEMOTO static int
configuration_entry_cache_mp_sort_cmp(const void * e1,const void * e2)8406a99fe3SHajimu UMEMOTO configuration_entry_cache_mp_sort_cmp(const void *e1, const void *e2)
8506a99fe3SHajimu UMEMOTO {
8606a99fe3SHajimu UMEMOTO return (strcmp((*((cache_entry *)e1))->params->entry_name,
8706a99fe3SHajimu UMEMOTO (*((cache_entry *)e2))->params->entry_name
8806a99fe3SHajimu UMEMOTO ));
8906a99fe3SHajimu UMEMOTO }
9006a99fe3SHajimu UMEMOTO
9106a99fe3SHajimu UMEMOTO static int
configuration_entry_cache_mp_cmp(const void * e1,const void * e2)9206a99fe3SHajimu UMEMOTO configuration_entry_cache_mp_cmp(const void *e1, const void *e2)
9306a99fe3SHajimu UMEMOTO {
9406a99fe3SHajimu UMEMOTO return (strcmp((const char *)e1,
9506a99fe3SHajimu UMEMOTO (*((cache_entry *)e2))->params->entry_name
9606a99fe3SHajimu UMEMOTO ));
9706a99fe3SHajimu UMEMOTO }
9806a99fe3SHajimu UMEMOTO
9906a99fe3SHajimu UMEMOTO static int
configuration_entry_cache_mp_part_cmp(const void * e1,const void * e2)10006a99fe3SHajimu UMEMOTO configuration_entry_cache_mp_part_cmp(const void *e1, const void *e2)
10106a99fe3SHajimu UMEMOTO {
10206a99fe3SHajimu UMEMOTO return (strncmp((const char *)e1,
10306a99fe3SHajimu UMEMOTO (*((cache_entry *)e2))->params->entry_name,
10406a99fe3SHajimu UMEMOTO strlen((const char *)e1)
10506a99fe3SHajimu UMEMOTO ));
10606a99fe3SHajimu UMEMOTO }
10706a99fe3SHajimu UMEMOTO
10806a99fe3SHajimu UMEMOTO static struct configuration_entry *
create_configuration_entry(const char * name,struct timeval const * common_timeout,struct timeval const * mp_timeout,struct common_cache_entry_params const * positive_params,struct common_cache_entry_params const * negative_params,struct mp_cache_entry_params const * mp_params)10906a99fe3SHajimu UMEMOTO create_configuration_entry(const char *name,
11006a99fe3SHajimu UMEMOTO struct timeval const *common_timeout,
11106a99fe3SHajimu UMEMOTO struct timeval const *mp_timeout,
11206a99fe3SHajimu UMEMOTO struct common_cache_entry_params const *positive_params,
11306a99fe3SHajimu UMEMOTO struct common_cache_entry_params const *negative_params,
11406a99fe3SHajimu UMEMOTO struct mp_cache_entry_params const *mp_params)
11506a99fe3SHajimu UMEMOTO {
11606a99fe3SHajimu UMEMOTO struct configuration_entry *retval;
11706a99fe3SHajimu UMEMOTO size_t size;
11806a99fe3SHajimu UMEMOTO int res;
11906a99fe3SHajimu UMEMOTO
12006a99fe3SHajimu UMEMOTO TRACE_IN(create_configuration_entry);
12106a99fe3SHajimu UMEMOTO assert(name != NULL);
12206a99fe3SHajimu UMEMOTO assert(positive_params != NULL);
12306a99fe3SHajimu UMEMOTO assert(negative_params != NULL);
12406a99fe3SHajimu UMEMOTO assert(mp_params != NULL);
12506a99fe3SHajimu UMEMOTO
1268eeaaffaSDag-Erling Smørgrav retval = calloc(1,
1278eeaaffaSDag-Erling Smørgrav sizeof(*retval));
12806a99fe3SHajimu UMEMOTO assert(retval != NULL);
12906a99fe3SHajimu UMEMOTO
13006a99fe3SHajimu UMEMOTO res = pthread_mutex_init(&retval->positive_cache_lock, NULL);
13106a99fe3SHajimu UMEMOTO if (res != 0) {
13206a99fe3SHajimu UMEMOTO free(retval);
13306a99fe3SHajimu UMEMOTO LOG_ERR_2("create_configuration_entry",
13406a99fe3SHajimu UMEMOTO "can't create positive cache lock");
13506a99fe3SHajimu UMEMOTO TRACE_OUT(create_configuration_entry);
13606a99fe3SHajimu UMEMOTO return (NULL);
13706a99fe3SHajimu UMEMOTO }
13806a99fe3SHajimu UMEMOTO
13906a99fe3SHajimu UMEMOTO res = pthread_mutex_init(&retval->negative_cache_lock, NULL);
14006a99fe3SHajimu UMEMOTO if (res != 0) {
14106a99fe3SHajimu UMEMOTO pthread_mutex_destroy(&retval->positive_cache_lock);
14206a99fe3SHajimu UMEMOTO free(retval);
14306a99fe3SHajimu UMEMOTO LOG_ERR_2("create_configuration_entry",
14406a99fe3SHajimu UMEMOTO "can't create negative cache lock");
14506a99fe3SHajimu UMEMOTO TRACE_OUT(create_configuration_entry);
14606a99fe3SHajimu UMEMOTO return (NULL);
14706a99fe3SHajimu UMEMOTO }
14806a99fe3SHajimu UMEMOTO
14906a99fe3SHajimu UMEMOTO res = pthread_mutex_init(&retval->mp_cache_lock, NULL);
15006a99fe3SHajimu UMEMOTO if (res != 0) {
15106a99fe3SHajimu UMEMOTO pthread_mutex_destroy(&retval->positive_cache_lock);
15206a99fe3SHajimu UMEMOTO pthread_mutex_destroy(&retval->negative_cache_lock);
15306a99fe3SHajimu UMEMOTO free(retval);
15406a99fe3SHajimu UMEMOTO LOG_ERR_2("create_configuration_entry",
15506a99fe3SHajimu UMEMOTO "can't create negative cache lock");
15606a99fe3SHajimu UMEMOTO TRACE_OUT(create_configuration_entry);
15706a99fe3SHajimu UMEMOTO return (NULL);
15806a99fe3SHajimu UMEMOTO }
15906a99fe3SHajimu UMEMOTO
16006a99fe3SHajimu UMEMOTO memcpy(&retval->positive_cache_params, positive_params,
16106a99fe3SHajimu UMEMOTO sizeof(struct common_cache_entry_params));
16206a99fe3SHajimu UMEMOTO memcpy(&retval->negative_cache_params, negative_params,
16306a99fe3SHajimu UMEMOTO sizeof(struct common_cache_entry_params));
16406a99fe3SHajimu UMEMOTO memcpy(&retval->mp_cache_params, mp_params,
16506a99fe3SHajimu UMEMOTO sizeof(struct mp_cache_entry_params));
16606a99fe3SHajimu UMEMOTO
16706a99fe3SHajimu UMEMOTO size = strlen(name);
1688eeaaffaSDag-Erling Smørgrav retval->name = calloc(1, size + 1);
16906a99fe3SHajimu UMEMOTO assert(retval->name != NULL);
17006a99fe3SHajimu UMEMOTO memcpy(retval->name, name, size);
17106a99fe3SHajimu UMEMOTO
17206a99fe3SHajimu UMEMOTO memcpy(&retval->common_query_timeout, common_timeout,
17306a99fe3SHajimu UMEMOTO sizeof(struct timeval));
17406a99fe3SHajimu UMEMOTO memcpy(&retval->mp_query_timeout, mp_timeout,
17506a99fe3SHajimu UMEMOTO sizeof(struct timeval));
17606a99fe3SHajimu UMEMOTO
17727f2bc9eSDag-Erling Smørgrav asprintf(&retval->positive_cache_params.cep.entry_name, "%s+", name);
17827f2bc9eSDag-Erling Smørgrav assert(retval->positive_cache_params.cep.entry_name != NULL);
17906a99fe3SHajimu UMEMOTO
18027f2bc9eSDag-Erling Smørgrav asprintf(&retval->negative_cache_params.cep.entry_name, "%s-", name);
18127f2bc9eSDag-Erling Smørgrav assert(retval->negative_cache_params.cep.entry_name != NULL);
18206a99fe3SHajimu UMEMOTO
18327f2bc9eSDag-Erling Smørgrav asprintf(&retval->mp_cache_params.cep.entry_name, "%s*", name);
18427f2bc9eSDag-Erling Smørgrav assert(retval->mp_cache_params.cep.entry_name != NULL);
18506a99fe3SHajimu UMEMOTO
18606a99fe3SHajimu UMEMOTO TRACE_OUT(create_configuration_entry);
18706a99fe3SHajimu UMEMOTO return (retval);
18806a99fe3SHajimu UMEMOTO }
18906a99fe3SHajimu UMEMOTO
19006a99fe3SHajimu UMEMOTO /*
19106a99fe3SHajimu UMEMOTO * Creates configuration entry and fills it with default values
19206a99fe3SHajimu UMEMOTO */
19306a99fe3SHajimu UMEMOTO struct configuration_entry *
create_def_configuration_entry(const char * name)19406a99fe3SHajimu UMEMOTO create_def_configuration_entry(const char *name)
19506a99fe3SHajimu UMEMOTO {
19606a99fe3SHajimu UMEMOTO struct common_cache_entry_params positive_params, negative_params;
19706a99fe3SHajimu UMEMOTO struct mp_cache_entry_params mp_params;
19806a99fe3SHajimu UMEMOTO struct timeval default_common_timeout, default_mp_timeout;
19906a99fe3SHajimu UMEMOTO
20006a99fe3SHajimu UMEMOTO struct configuration_entry *res = NULL;
20106a99fe3SHajimu UMEMOTO
20206a99fe3SHajimu UMEMOTO TRACE_IN(create_def_configuration_entry);
20306a99fe3SHajimu UMEMOTO memset(&positive_params, 0,
20406a99fe3SHajimu UMEMOTO sizeof(struct common_cache_entry_params));
20527f2bc9eSDag-Erling Smørgrav positive_params.cep.entry_type = CET_COMMON;
20606a99fe3SHajimu UMEMOTO positive_params.cache_entries_size = DEFAULT_CACHE_HT_SIZE;
20706a99fe3SHajimu UMEMOTO positive_params.max_elemsize = DEFAULT_POSITIVE_ELEMENTS_SIZE;
20806a99fe3SHajimu UMEMOTO positive_params.satisf_elemsize = DEFAULT_POSITIVE_ELEMENTS_SIZE / 2;
20906a99fe3SHajimu UMEMOTO positive_params.max_lifetime.tv_sec = DEFAULT_POSITIVE_LIFETIME;
210a397989dSStefan Eßer positive_params.confidence_threshold = DEFAULT_POSITIVE_CONF_THRESH;
21106a99fe3SHajimu UMEMOTO positive_params.policy = CPT_LRU;
21206a99fe3SHajimu UMEMOTO
21306a99fe3SHajimu UMEMOTO memcpy(&negative_params, &positive_params,
21406a99fe3SHajimu UMEMOTO sizeof(struct common_cache_entry_params));
21506a99fe3SHajimu UMEMOTO negative_params.max_elemsize = DEFAULT_NEGATIVE_ELEMENTS_SIZE;
21606a99fe3SHajimu UMEMOTO negative_params.satisf_elemsize = DEFAULT_NEGATIVE_ELEMENTS_SIZE / 2;
21706a99fe3SHajimu UMEMOTO negative_params.max_lifetime.tv_sec = DEFAULT_NEGATIVE_LIFETIME;
218a397989dSStefan Eßer negative_params.confidence_threshold = DEFAULT_NEGATIVE_CONF_THRESH;
21906a99fe3SHajimu UMEMOTO negative_params.policy = CPT_FIFO;
22006a99fe3SHajimu UMEMOTO
22106a99fe3SHajimu UMEMOTO memset(&default_common_timeout, 0, sizeof(struct timeval));
22206a99fe3SHajimu UMEMOTO default_common_timeout.tv_sec = DEFAULT_COMMON_ENTRY_TIMEOUT;
22306a99fe3SHajimu UMEMOTO
22406a99fe3SHajimu UMEMOTO memset(&default_mp_timeout, 0, sizeof(struct timeval));
22506a99fe3SHajimu UMEMOTO default_mp_timeout.tv_sec = DEFAULT_MP_ENTRY_TIMEOUT;
22606a99fe3SHajimu UMEMOTO
22706a99fe3SHajimu UMEMOTO memset(&mp_params, 0,
22806a99fe3SHajimu UMEMOTO sizeof(struct mp_cache_entry_params));
22927f2bc9eSDag-Erling Smørgrav mp_params.cep.entry_type = CET_MULTIPART;
23006a99fe3SHajimu UMEMOTO mp_params.max_elemsize = DEFAULT_MULTIPART_ELEMENTS_SIZE;
23106a99fe3SHajimu UMEMOTO mp_params.max_sessions = DEFAULT_MULITPART_SESSIONS_SIZE;
23206a99fe3SHajimu UMEMOTO mp_params.max_lifetime.tv_sec = DEFAULT_MULITPART_LIFETIME;
23306a99fe3SHajimu UMEMOTO
23406a99fe3SHajimu UMEMOTO res = create_configuration_entry(name, &default_common_timeout,
23506a99fe3SHajimu UMEMOTO &default_mp_timeout, &positive_params, &negative_params,
23606a99fe3SHajimu UMEMOTO &mp_params);
23706a99fe3SHajimu UMEMOTO
23806a99fe3SHajimu UMEMOTO TRACE_OUT(create_def_configuration_entry);
23906a99fe3SHajimu UMEMOTO return (res);
24006a99fe3SHajimu UMEMOTO }
24106a99fe3SHajimu UMEMOTO
24206a99fe3SHajimu UMEMOTO void
destroy_configuration_entry(struct configuration_entry * entry)24306a99fe3SHajimu UMEMOTO destroy_configuration_entry(struct configuration_entry *entry)
24406a99fe3SHajimu UMEMOTO {
24506a99fe3SHajimu UMEMOTO TRACE_IN(destroy_configuration_entry);
24606a99fe3SHajimu UMEMOTO assert(entry != NULL);
24706a99fe3SHajimu UMEMOTO pthread_mutex_destroy(&entry->positive_cache_lock);
24806a99fe3SHajimu UMEMOTO pthread_mutex_destroy(&entry->negative_cache_lock);
24906a99fe3SHajimu UMEMOTO pthread_mutex_destroy(&entry->mp_cache_lock);
25006a99fe3SHajimu UMEMOTO free(entry->name);
25127f2bc9eSDag-Erling Smørgrav free(entry->positive_cache_params.cep.entry_name);
25227f2bc9eSDag-Erling Smørgrav free(entry->negative_cache_params.cep.entry_name);
25327f2bc9eSDag-Erling Smørgrav free(entry->mp_cache_params.cep.entry_name);
25406a99fe3SHajimu UMEMOTO free(entry->mp_cache_entries);
25506a99fe3SHajimu UMEMOTO free(entry);
25606a99fe3SHajimu UMEMOTO TRACE_OUT(destroy_configuration_entry);
25706a99fe3SHajimu UMEMOTO }
25806a99fe3SHajimu UMEMOTO
25906a99fe3SHajimu UMEMOTO int
add_configuration_entry(struct configuration * config,struct configuration_entry * entry)26006a99fe3SHajimu UMEMOTO add_configuration_entry(struct configuration *config,
26106a99fe3SHajimu UMEMOTO struct configuration_entry *entry)
26206a99fe3SHajimu UMEMOTO {
26306a99fe3SHajimu UMEMOTO TRACE_IN(add_configuration_entry);
26406a99fe3SHajimu UMEMOTO assert(entry != NULL);
26506a99fe3SHajimu UMEMOTO assert(entry->name != NULL);
26606a99fe3SHajimu UMEMOTO if (configuration_find_entry(config, entry->name) != NULL) {
26706a99fe3SHajimu UMEMOTO TRACE_OUT(add_configuration_entry);
26806a99fe3SHajimu UMEMOTO return (-1);
26906a99fe3SHajimu UMEMOTO }
27006a99fe3SHajimu UMEMOTO
27106a99fe3SHajimu UMEMOTO if (config->entries_size == config->entries_capacity) {
27206a99fe3SHajimu UMEMOTO struct configuration_entry **new_entries;
27306a99fe3SHajimu UMEMOTO
27406a99fe3SHajimu UMEMOTO config->entries_capacity *= 2;
275*87959e27SPedro F. Giffuni new_entries = calloc(config->entries_capacity,
276*87959e27SPedro F. Giffuni sizeof(*new_entries));
27706a99fe3SHajimu UMEMOTO assert(new_entries != NULL);
27806a99fe3SHajimu UMEMOTO memcpy(new_entries, config->entries,
27906a99fe3SHajimu UMEMOTO sizeof(struct configuration_entry *) *
28006a99fe3SHajimu UMEMOTO config->entries_size);
28106a99fe3SHajimu UMEMOTO
28206a99fe3SHajimu UMEMOTO free(config->entries);
28306a99fe3SHajimu UMEMOTO config->entries = new_entries;
28406a99fe3SHajimu UMEMOTO }
28506a99fe3SHajimu UMEMOTO
28606a99fe3SHajimu UMEMOTO config->entries[config->entries_size++] = entry;
28706a99fe3SHajimu UMEMOTO qsort(config->entries, config->entries_size,
28806a99fe3SHajimu UMEMOTO sizeof(struct configuration_entry *),
28906a99fe3SHajimu UMEMOTO configuration_entry_sort_cmp);
29006a99fe3SHajimu UMEMOTO
29106a99fe3SHajimu UMEMOTO TRACE_OUT(add_configuration_entry);
29206a99fe3SHajimu UMEMOTO return (0);
29306a99fe3SHajimu UMEMOTO }
29406a99fe3SHajimu UMEMOTO
29506a99fe3SHajimu UMEMOTO size_t
configuration_get_entries_size(struct configuration * config)29606a99fe3SHajimu UMEMOTO configuration_get_entries_size(struct configuration *config)
29706a99fe3SHajimu UMEMOTO {
29806a99fe3SHajimu UMEMOTO TRACE_IN(configuration_get_entries_size);
29906a99fe3SHajimu UMEMOTO assert(config != NULL);
30006a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_get_entries_size);
30106a99fe3SHajimu UMEMOTO return (config->entries_size);
30206a99fe3SHajimu UMEMOTO }
30306a99fe3SHajimu UMEMOTO
30406a99fe3SHajimu UMEMOTO struct configuration_entry *
configuration_get_entry(struct configuration * config,size_t index)30506a99fe3SHajimu UMEMOTO configuration_get_entry(struct configuration *config, size_t index)
30606a99fe3SHajimu UMEMOTO {
30706a99fe3SHajimu UMEMOTO TRACE_IN(configuration_get_entry);
30806a99fe3SHajimu UMEMOTO assert(config != NULL);
30906a99fe3SHajimu UMEMOTO assert(index < config->entries_size);
31006a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_get_entry);
31106a99fe3SHajimu UMEMOTO return (config->entries[index]);
31206a99fe3SHajimu UMEMOTO }
31306a99fe3SHajimu UMEMOTO
31406a99fe3SHajimu UMEMOTO struct configuration_entry *
configuration_find_entry(struct configuration * config,const char * name)31506a99fe3SHajimu UMEMOTO configuration_find_entry(struct configuration *config,
31606a99fe3SHajimu UMEMOTO const char *name)
31706a99fe3SHajimu UMEMOTO {
31806a99fe3SHajimu UMEMOTO struct configuration_entry **retval;
31906a99fe3SHajimu UMEMOTO
32006a99fe3SHajimu UMEMOTO TRACE_IN(configuration_find_entry);
32106a99fe3SHajimu UMEMOTO
32206a99fe3SHajimu UMEMOTO retval = bsearch(name, config->entries, config->entries_size,
32306a99fe3SHajimu UMEMOTO sizeof(struct configuration_entry *), configuration_entry_cmp);
32406a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_find_entry);
32506a99fe3SHajimu UMEMOTO
32606a99fe3SHajimu UMEMOTO return ((retval != NULL) ? *retval : NULL);
32706a99fe3SHajimu UMEMOTO }
32806a99fe3SHajimu UMEMOTO
32906a99fe3SHajimu UMEMOTO /*
33006a99fe3SHajimu UMEMOTO * All multipart cache entries are stored in the configuration_entry in the
33106a99fe3SHajimu UMEMOTO * sorted array (sorted by names). The 3 functions below manage this array.
33206a99fe3SHajimu UMEMOTO */
33306a99fe3SHajimu UMEMOTO
33406a99fe3SHajimu UMEMOTO int
configuration_entry_add_mp_cache_entry(struct configuration_entry * config_entry,cache_entry c_entry)33506a99fe3SHajimu UMEMOTO configuration_entry_add_mp_cache_entry(struct configuration_entry *config_entry,
33606a99fe3SHajimu UMEMOTO cache_entry c_entry)
33706a99fe3SHajimu UMEMOTO {
33806a99fe3SHajimu UMEMOTO cache_entry *new_mp_entries, *old_mp_entries;
33906a99fe3SHajimu UMEMOTO
34006a99fe3SHajimu UMEMOTO TRACE_IN(configuration_entry_add_mp_cache_entry);
34106a99fe3SHajimu UMEMOTO ++config_entry->mp_cache_entries_size;
3428eeaaffaSDag-Erling Smørgrav new_mp_entries = malloc(sizeof(*new_mp_entries) *
34306a99fe3SHajimu UMEMOTO config_entry->mp_cache_entries_size);
34406a99fe3SHajimu UMEMOTO assert(new_mp_entries != NULL);
34506a99fe3SHajimu UMEMOTO new_mp_entries[0] = c_entry;
34606a99fe3SHajimu UMEMOTO
34706a99fe3SHajimu UMEMOTO if (config_entry->mp_cache_entries_size - 1 > 0) {
34806a99fe3SHajimu UMEMOTO memcpy(new_mp_entries + 1,
34906a99fe3SHajimu UMEMOTO config_entry->mp_cache_entries,
35006a99fe3SHajimu UMEMOTO (config_entry->mp_cache_entries_size - 1) *
35106a99fe3SHajimu UMEMOTO sizeof(cache_entry));
35206a99fe3SHajimu UMEMOTO }
35306a99fe3SHajimu UMEMOTO
35406a99fe3SHajimu UMEMOTO old_mp_entries = config_entry->mp_cache_entries;
35506a99fe3SHajimu UMEMOTO config_entry->mp_cache_entries = new_mp_entries;
35606a99fe3SHajimu UMEMOTO free(old_mp_entries);
35706a99fe3SHajimu UMEMOTO
35806a99fe3SHajimu UMEMOTO qsort(config_entry->mp_cache_entries,
35906a99fe3SHajimu UMEMOTO config_entry->mp_cache_entries_size,
36006a99fe3SHajimu UMEMOTO sizeof(cache_entry),
36106a99fe3SHajimu UMEMOTO configuration_entry_cache_mp_sort_cmp);
36206a99fe3SHajimu UMEMOTO
36306a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_entry_add_mp_cache_entry);
36406a99fe3SHajimu UMEMOTO return (0);
36506a99fe3SHajimu UMEMOTO }
36606a99fe3SHajimu UMEMOTO
36706a99fe3SHajimu UMEMOTO cache_entry
configuration_entry_find_mp_cache_entry(struct configuration_entry * config_entry,const char * mp_name)36806a99fe3SHajimu UMEMOTO configuration_entry_find_mp_cache_entry(
36906a99fe3SHajimu UMEMOTO struct configuration_entry *config_entry, const char *mp_name)
37006a99fe3SHajimu UMEMOTO {
37106a99fe3SHajimu UMEMOTO cache_entry *result;
37206a99fe3SHajimu UMEMOTO
37306a99fe3SHajimu UMEMOTO TRACE_IN(configuration_entry_find_mp_cache_entry);
37406a99fe3SHajimu UMEMOTO result = bsearch(mp_name, config_entry->mp_cache_entries,
37506a99fe3SHajimu UMEMOTO config_entry->mp_cache_entries_size,
37606a99fe3SHajimu UMEMOTO sizeof(cache_entry), configuration_entry_cache_mp_cmp);
37706a99fe3SHajimu UMEMOTO
37806a99fe3SHajimu UMEMOTO if (result == NULL) {
37906a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_entry_find_mp_cache_entry);
38006a99fe3SHajimu UMEMOTO return (NULL);
38106a99fe3SHajimu UMEMOTO } else {
38206a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_entry_find_mp_cache_entry);
38306a99fe3SHajimu UMEMOTO return (*result);
38406a99fe3SHajimu UMEMOTO }
38506a99fe3SHajimu UMEMOTO }
38606a99fe3SHajimu UMEMOTO
38706a99fe3SHajimu UMEMOTO /*
38806a99fe3SHajimu UMEMOTO * Searches for all multipart entries with names starting with mp_name.
38906a99fe3SHajimu UMEMOTO * Needed for cache flushing.
39006a99fe3SHajimu UMEMOTO */
39106a99fe3SHajimu UMEMOTO int
configuration_entry_find_mp_cache_entries(struct configuration_entry * config_entry,const char * mp_name,cache_entry ** start,cache_entry ** finish)39206a99fe3SHajimu UMEMOTO configuration_entry_find_mp_cache_entries(
39306a99fe3SHajimu UMEMOTO struct configuration_entry *config_entry, const char *mp_name,
39406a99fe3SHajimu UMEMOTO cache_entry **start, cache_entry **finish)
39506a99fe3SHajimu UMEMOTO {
39606a99fe3SHajimu UMEMOTO cache_entry *result;
39706a99fe3SHajimu UMEMOTO
39806a99fe3SHajimu UMEMOTO TRACE_IN(configuration_entry_find_mp_cache_entries);
39906a99fe3SHajimu UMEMOTO result = bsearch(mp_name, config_entry->mp_cache_entries,
40006a99fe3SHajimu UMEMOTO config_entry->mp_cache_entries_size,
40106a99fe3SHajimu UMEMOTO sizeof(cache_entry), configuration_entry_cache_mp_part_cmp);
40206a99fe3SHajimu UMEMOTO
40306a99fe3SHajimu UMEMOTO if (result == NULL) {
40406a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_entry_find_mp_cache_entries);
40506a99fe3SHajimu UMEMOTO return (-1);
40606a99fe3SHajimu UMEMOTO }
40706a99fe3SHajimu UMEMOTO
40806a99fe3SHajimu UMEMOTO *start = result;
40906a99fe3SHajimu UMEMOTO *finish = result + 1;
41006a99fe3SHajimu UMEMOTO
41106a99fe3SHajimu UMEMOTO while (*start != config_entry->mp_cache_entries) {
41206a99fe3SHajimu UMEMOTO if (configuration_entry_cache_mp_part_cmp(mp_name, *start - 1) == 0)
41306a99fe3SHajimu UMEMOTO *start = *start - 1;
41406a99fe3SHajimu UMEMOTO else
41506a99fe3SHajimu UMEMOTO break;
41606a99fe3SHajimu UMEMOTO }
41706a99fe3SHajimu UMEMOTO
41806a99fe3SHajimu UMEMOTO while (*finish != config_entry->mp_cache_entries +
41906a99fe3SHajimu UMEMOTO config_entry->mp_cache_entries_size) {
42006a99fe3SHajimu UMEMOTO
42106a99fe3SHajimu UMEMOTO if (configuration_entry_cache_mp_part_cmp(
42206a99fe3SHajimu UMEMOTO mp_name, *finish) == 0)
42306a99fe3SHajimu UMEMOTO *finish = *finish + 1;
42406a99fe3SHajimu UMEMOTO else
42506a99fe3SHajimu UMEMOTO break;
42606a99fe3SHajimu UMEMOTO }
42706a99fe3SHajimu UMEMOTO
42806a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_entry_find_mp_cache_entries);
42906a99fe3SHajimu UMEMOTO return (0);
43006a99fe3SHajimu UMEMOTO }
43106a99fe3SHajimu UMEMOTO
43206a99fe3SHajimu UMEMOTO /*
43306a99fe3SHajimu UMEMOTO * Configuration entry uses rwlock to handle access to its fields.
43406a99fe3SHajimu UMEMOTO */
43506a99fe3SHajimu UMEMOTO void
configuration_lock_rdlock(struct configuration * config)43606a99fe3SHajimu UMEMOTO configuration_lock_rdlock(struct configuration *config)
43706a99fe3SHajimu UMEMOTO {
43806a99fe3SHajimu UMEMOTO TRACE_IN(configuration_lock_rdlock);
43906a99fe3SHajimu UMEMOTO pthread_rwlock_rdlock(&config->rwlock);
44006a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_lock_rdlock);
44106a99fe3SHajimu UMEMOTO }
44206a99fe3SHajimu UMEMOTO
44306a99fe3SHajimu UMEMOTO void
configuration_lock_wrlock(struct configuration * config)44406a99fe3SHajimu UMEMOTO configuration_lock_wrlock(struct configuration *config)
44506a99fe3SHajimu UMEMOTO {
44606a99fe3SHajimu UMEMOTO TRACE_IN(configuration_lock_wrlock);
44706a99fe3SHajimu UMEMOTO pthread_rwlock_wrlock(&config->rwlock);
44806a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_lock_wrlock);
44906a99fe3SHajimu UMEMOTO }
45006a99fe3SHajimu UMEMOTO
45106a99fe3SHajimu UMEMOTO void
configuration_unlock(struct configuration * config)45206a99fe3SHajimu UMEMOTO configuration_unlock(struct configuration *config)
45306a99fe3SHajimu UMEMOTO {
45406a99fe3SHajimu UMEMOTO TRACE_IN(configuration_unlock);
45506a99fe3SHajimu UMEMOTO pthread_rwlock_unlock(&config->rwlock);
45606a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_unlock);
45706a99fe3SHajimu UMEMOTO }
45806a99fe3SHajimu UMEMOTO
45906a99fe3SHajimu UMEMOTO /*
46006a99fe3SHajimu UMEMOTO * Configuration entry uses 3 mutexes to handle cache operations. They are
46106a99fe3SHajimu UMEMOTO * acquired by configuration_lock_entry and configuration_unlock_entry
46206a99fe3SHajimu UMEMOTO * functions.
46306a99fe3SHajimu UMEMOTO */
46406a99fe3SHajimu UMEMOTO void
configuration_lock_entry(struct configuration_entry * entry,enum config_entry_lock_type lock_type)46506a99fe3SHajimu UMEMOTO configuration_lock_entry(struct configuration_entry *entry,
46606a99fe3SHajimu UMEMOTO enum config_entry_lock_type lock_type)
46706a99fe3SHajimu UMEMOTO {
46806a99fe3SHajimu UMEMOTO TRACE_IN(configuration_lock_entry);
46906a99fe3SHajimu UMEMOTO assert(entry != NULL);
47006a99fe3SHajimu UMEMOTO
47106a99fe3SHajimu UMEMOTO switch (lock_type) {
47206a99fe3SHajimu UMEMOTO case CELT_POSITIVE:
47306a99fe3SHajimu UMEMOTO pthread_mutex_lock(&entry->positive_cache_lock);
47406a99fe3SHajimu UMEMOTO break;
47506a99fe3SHajimu UMEMOTO case CELT_NEGATIVE:
47606a99fe3SHajimu UMEMOTO pthread_mutex_lock(&entry->negative_cache_lock);
47706a99fe3SHajimu UMEMOTO break;
47806a99fe3SHajimu UMEMOTO case CELT_MULTIPART:
47906a99fe3SHajimu UMEMOTO pthread_mutex_lock(&entry->mp_cache_lock);
48006a99fe3SHajimu UMEMOTO break;
48106a99fe3SHajimu UMEMOTO default:
48206a99fe3SHajimu UMEMOTO /* should be unreachable */
48306a99fe3SHajimu UMEMOTO break;
48406a99fe3SHajimu UMEMOTO }
48506a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_lock_entry);
48606a99fe3SHajimu UMEMOTO }
48706a99fe3SHajimu UMEMOTO
48806a99fe3SHajimu UMEMOTO void
configuration_unlock_entry(struct configuration_entry * entry,enum config_entry_lock_type lock_type)48906a99fe3SHajimu UMEMOTO configuration_unlock_entry(struct configuration_entry *entry,
49006a99fe3SHajimu UMEMOTO enum config_entry_lock_type lock_type)
49106a99fe3SHajimu UMEMOTO {
49206a99fe3SHajimu UMEMOTO TRACE_IN(configuration_unlock_entry);
49306a99fe3SHajimu UMEMOTO assert(entry != NULL);
49406a99fe3SHajimu UMEMOTO
49506a99fe3SHajimu UMEMOTO switch (lock_type) {
49606a99fe3SHajimu UMEMOTO case CELT_POSITIVE:
49706a99fe3SHajimu UMEMOTO pthread_mutex_unlock(&entry->positive_cache_lock);
49806a99fe3SHajimu UMEMOTO break;
49906a99fe3SHajimu UMEMOTO case CELT_NEGATIVE:
50006a99fe3SHajimu UMEMOTO pthread_mutex_unlock(&entry->negative_cache_lock);
50106a99fe3SHajimu UMEMOTO break;
50206a99fe3SHajimu UMEMOTO case CELT_MULTIPART:
50306a99fe3SHajimu UMEMOTO pthread_mutex_unlock(&entry->mp_cache_lock);
50406a99fe3SHajimu UMEMOTO break;
50506a99fe3SHajimu UMEMOTO default:
50606a99fe3SHajimu UMEMOTO /* should be unreachable */
50706a99fe3SHajimu UMEMOTO break;
50806a99fe3SHajimu UMEMOTO }
50906a99fe3SHajimu UMEMOTO TRACE_OUT(configuration_unlock_entry);
51006a99fe3SHajimu UMEMOTO }
51106a99fe3SHajimu UMEMOTO
51206a99fe3SHajimu UMEMOTO struct configuration *
init_configuration(void)51306a99fe3SHajimu UMEMOTO init_configuration(void)
51406a99fe3SHajimu UMEMOTO {
51506a99fe3SHajimu UMEMOTO struct configuration *retval;
51606a99fe3SHajimu UMEMOTO
51706a99fe3SHajimu UMEMOTO TRACE_IN(init_configuration);
5188eeaaffaSDag-Erling Smørgrav retval = calloc(1, sizeof(*retval));
51906a99fe3SHajimu UMEMOTO assert(retval != NULL);
52006a99fe3SHajimu UMEMOTO
52106a99fe3SHajimu UMEMOTO retval->entries_capacity = INITIAL_ENTRIES_CAPACITY;
522*87959e27SPedro F. Giffuni retval->entries = calloc(retval->entries_capacity,
523*87959e27SPedro F. Giffuni sizeof(*retval->entries));
52406a99fe3SHajimu UMEMOTO assert(retval->entries != NULL);
52506a99fe3SHajimu UMEMOTO
52606a99fe3SHajimu UMEMOTO pthread_rwlock_init(&retval->rwlock, NULL);
52706a99fe3SHajimu UMEMOTO
52806a99fe3SHajimu UMEMOTO TRACE_OUT(init_configuration);
52906a99fe3SHajimu UMEMOTO return (retval);
53006a99fe3SHajimu UMEMOTO }
53106a99fe3SHajimu UMEMOTO
53206a99fe3SHajimu UMEMOTO void
fill_configuration_defaults(struct configuration * config)53306a99fe3SHajimu UMEMOTO fill_configuration_defaults(struct configuration *config)
53406a99fe3SHajimu UMEMOTO {
53506a99fe3SHajimu UMEMOTO size_t len, i;
53606a99fe3SHajimu UMEMOTO
53706a99fe3SHajimu UMEMOTO TRACE_IN(fill_configuration_defaults);
53806a99fe3SHajimu UMEMOTO assert(config != NULL);
53906a99fe3SHajimu UMEMOTO
54006a99fe3SHajimu UMEMOTO if (config->socket_path != NULL)
54106a99fe3SHajimu UMEMOTO free(config->socket_path);
54206a99fe3SHajimu UMEMOTO
54306a99fe3SHajimu UMEMOTO len = strlen(DEFAULT_SOCKET_PATH);
5448eeaaffaSDag-Erling Smørgrav config->socket_path = calloc(1, len + 1);
54506a99fe3SHajimu UMEMOTO assert(config->socket_path != NULL);
54606a99fe3SHajimu UMEMOTO memcpy(config->socket_path, DEFAULT_SOCKET_PATH, len);
54706a99fe3SHajimu UMEMOTO
54806a99fe3SHajimu UMEMOTO len = strlen(DEFAULT_PIDFILE_PATH);
5498eeaaffaSDag-Erling Smørgrav config->pidfile_path = calloc(1, len + 1);
55006a99fe3SHajimu UMEMOTO assert(config->pidfile_path != NULL);
55106a99fe3SHajimu UMEMOTO memcpy(config->pidfile_path, DEFAULT_PIDFILE_PATH, len);
55206a99fe3SHajimu UMEMOTO
55306a99fe3SHajimu UMEMOTO config->socket_mode = S_IFSOCK | S_IRUSR | S_IWUSR |
55406a99fe3SHajimu UMEMOTO S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
55506a99fe3SHajimu UMEMOTO config->force_unlink = 1;
55606a99fe3SHajimu UMEMOTO
55706a99fe3SHajimu UMEMOTO config->query_timeout = DEFAULT_QUERY_TIMEOUT;
55806a99fe3SHajimu UMEMOTO config->threads_num = DEFAULT_THREADS_NUM;
55906a99fe3SHajimu UMEMOTO
56006a99fe3SHajimu UMEMOTO for (i = 0; i < config->entries_size; ++i)
56106a99fe3SHajimu UMEMOTO destroy_configuration_entry(config->entries[i]);
56206a99fe3SHajimu UMEMOTO config->entries_size = 0;
56306a99fe3SHajimu UMEMOTO
56406a99fe3SHajimu UMEMOTO TRACE_OUT(fill_configuration_defaults);
56506a99fe3SHajimu UMEMOTO }
56606a99fe3SHajimu UMEMOTO
56706a99fe3SHajimu UMEMOTO void
destroy_configuration(struct configuration * config)56806a99fe3SHajimu UMEMOTO destroy_configuration(struct configuration *config)
56906a99fe3SHajimu UMEMOTO {
57051d6ddb5SDag-Erling Smørgrav unsigned int i;
57151d6ddb5SDag-Erling Smørgrav
57206a99fe3SHajimu UMEMOTO TRACE_IN(destroy_configuration);
57306a99fe3SHajimu UMEMOTO assert(config != NULL);
57406a99fe3SHajimu UMEMOTO free(config->pidfile_path);
57506a99fe3SHajimu UMEMOTO free(config->socket_path);
57606a99fe3SHajimu UMEMOTO
57706a99fe3SHajimu UMEMOTO for (i = 0; i < config->entries_size; ++i)
57806a99fe3SHajimu UMEMOTO destroy_configuration_entry(config->entries[i]);
57906a99fe3SHajimu UMEMOTO free(config->entries);
58006a99fe3SHajimu UMEMOTO
58106a99fe3SHajimu UMEMOTO pthread_rwlock_destroy(&config->rwlock);
58206a99fe3SHajimu UMEMOTO free(config);
58306a99fe3SHajimu UMEMOTO TRACE_OUT(destroy_configuration);
58406a99fe3SHajimu UMEMOTO }
585