config.c revision 194097
1158115Sume/*-
2158115Sume * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru>
3158115Sume * All rights reserved.
4158115Sume *
5158115Sume * Redistribution and use in source and binary forms, with or without
6158115Sume * modification, are permitted provided that the following conditions
7158115Sume * are met:
8158115Sume * 1. Redistributions of source code must retain the above copyright
9158115Sume *    notice, this list of conditions and the following disclaimer.
10158115Sume * 2. Redistributions in binary form must reproduce the above copyright
11158115Sume *    notice, this list of conditions and the following disclaimer in the
12158115Sume *    documentation and/or other materials provided with the distribution.
13158115Sume *
14158115Sume * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15158115Sume * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16158115Sume * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17158115Sume * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18158115Sume * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19158115Sume * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20158115Sume * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21158115Sume * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22158115Sume * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23158115Sume * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24158115Sume * SUCH DAMAGE.
25158115Sume *
26158115Sume */
27158115Sume
28158115Sume#include <sys/cdefs.h>
29158115Sume__FBSDID("$FreeBSD: head/usr.sbin/nscd/config.c 194097 2009-06-13 01:22:56Z des $");
30158115Sume
31194089Sdes#include <sys/stat.h>
32194089Sdes#include <sys/time.h>
33194089Sdes
34158115Sume#include <assert.h>
35158115Sume#include <math.h>
36194089Sdes#include <nsswitch.h>
37194089Sdes#include <pthread.h>
38158115Sume#include <stdio.h>
39158115Sume#include <stdlib.h>
40158115Sume#include <string.h>
41194089Sdes
42158115Sume#include "config.h"
43158115Sume#include "debug.h"
44158115Sume#include "log.h"
45158115Sume
46158115Sume/*
47158115Sume * Default entries, which always exist in the configuration
48158115Sume */
49158115Sumeconst char *c_default_entries[6] = {
50158115Sume	NSDB_PASSWD,
51158115Sume	NSDB_GROUP,
52158115Sume	NSDB_HOSTS,
53158115Sume	NSDB_SERVICES,
54158115Sume	NSDB_PROTOCOLS,
55158115Sume	NSDB_RPC
56158115Sume	};
57158115Sume
58158115Sumestatic int configuration_entry_cmp(const void *, const void *);
59158115Sumestatic int configuration_entry_sort_cmp(const void *, const void *);
60158115Sumestatic int configuration_entry_cache_mp_sort_cmp(const void *, const void *);
61158115Sumestatic int configuration_entry_cache_mp_cmp(const void *, const void *);
62158115Sumestatic int configuration_entry_cache_mp_part_cmp(const void *, const void *);
63158115Sumestatic struct configuration_entry *create_configuration_entry(const char *,
64158115Sume	struct timeval const *, struct timeval const *,
65158115Sume	struct common_cache_entry_params const *,
66158115Sume	struct common_cache_entry_params const *,
67158115Sume	struct mp_cache_entry_params const *);
68158115Sume
69158115Sumestatic int
70158115Sumeconfiguration_entry_sort_cmp(const void *e1, const void *e2)
71158115Sume{
72158115Sume	return (strcmp((*((struct configuration_entry **)e1))->name,
73158115Sume		(*((struct configuration_entry **)e2))->name
74158115Sume		));
75158115Sume}
76158115Sume
77158115Sumestatic int
78158115Sumeconfiguration_entry_cmp(const void *e1, const void *e2)
79158115Sume{
80158115Sume	return (strcmp((const char *)e1,
81158115Sume		(*((struct configuration_entry **)e2))->name
82158115Sume		));
83158115Sume}
84158115Sume
85158115Sumestatic int
86158115Sumeconfiguration_entry_cache_mp_sort_cmp(const void *e1, const void *e2)
87158115Sume{
88158115Sume	return (strcmp((*((cache_entry *)e1))->params->entry_name,
89158115Sume		(*((cache_entry *)e2))->params->entry_name
90158115Sume		));
91158115Sume}
92158115Sume
93158115Sumestatic int
94158115Sumeconfiguration_entry_cache_mp_cmp(const void *e1, const void *e2)
95158115Sume{
96158115Sume	return (strcmp((const char *)e1,
97158115Sume		(*((cache_entry *)e2))->params->entry_name
98158115Sume		));
99158115Sume}
100158115Sume
101158115Sumestatic int
102158115Sumeconfiguration_entry_cache_mp_part_cmp(const void *e1, const void *e2)
103158115Sume{
104158115Sume	return (strncmp((const char *)e1,
105158115Sume		(*((cache_entry *)e2))->params->entry_name,
106158115Sume		strlen((const char *)e1)
107158115Sume		));
108158115Sume}
109158115Sume
110158115Sumestatic struct configuration_entry *
111158115Sumecreate_configuration_entry(const char *name,
112158115Sume	struct timeval const *common_timeout,
113158115Sume	struct timeval const *mp_timeout,
114158115Sume	struct common_cache_entry_params const *positive_params,
115158115Sume	struct common_cache_entry_params const *negative_params,
116158115Sume	struct mp_cache_entry_params const *mp_params)
117158115Sume{
118158115Sume	struct configuration_entry *retval;
119158115Sume	size_t	size;
120158115Sume	int res;
121158115Sume
122158115Sume	TRACE_IN(create_configuration_entry);
123158115Sume	assert(name != NULL);
124158115Sume	assert(positive_params != NULL);
125158115Sume	assert(negative_params != NULL);
126158115Sume	assert(mp_params != NULL);
127158115Sume
128183770Sdelphij	retval = (struct configuration_entry *)calloc(1,
129158115Sume		sizeof(struct configuration_entry));
130158115Sume	assert(retval != NULL);
131158115Sume
132158115Sume	res = pthread_mutex_init(&retval->positive_cache_lock, NULL);
133158115Sume	if (res != 0) {
134158115Sume		free(retval);
135158115Sume		LOG_ERR_2("create_configuration_entry",
136158115Sume			"can't create positive cache lock");
137158115Sume		TRACE_OUT(create_configuration_entry);
138158115Sume		return (NULL);
139158115Sume	}
140158115Sume
141158115Sume	res = pthread_mutex_init(&retval->negative_cache_lock, NULL);
142158115Sume	if (res != 0) {
143158115Sume		pthread_mutex_destroy(&retval->positive_cache_lock);
144158115Sume		free(retval);
145158115Sume		LOG_ERR_2("create_configuration_entry",
146158115Sume			"can't create negative cache lock");
147158115Sume		TRACE_OUT(create_configuration_entry);
148158115Sume		return (NULL);
149158115Sume	}
150158115Sume
151158115Sume	res = pthread_mutex_init(&retval->mp_cache_lock, NULL);
152158115Sume	if (res != 0) {
153158115Sume		pthread_mutex_destroy(&retval->positive_cache_lock);
154158115Sume		pthread_mutex_destroy(&retval->negative_cache_lock);
155158115Sume		free(retval);
156158115Sume		LOG_ERR_2("create_configuration_entry",
157158115Sume			"can't create negative cache lock");
158158115Sume		TRACE_OUT(create_configuration_entry);
159158115Sume		return (NULL);
160158115Sume	}
161158115Sume
162158115Sume	memcpy(&retval->positive_cache_params, positive_params,
163158115Sume		sizeof(struct common_cache_entry_params));
164158115Sume	memcpy(&retval->negative_cache_params, negative_params,
165158115Sume		sizeof(struct common_cache_entry_params));
166158115Sume	memcpy(&retval->mp_cache_params, mp_params,
167158115Sume		sizeof(struct mp_cache_entry_params));
168158115Sume
169158115Sume	size = strlen(name);
170183770Sdelphij	retval->name = (char *)calloc(1, size + 1);
171158115Sume	assert(retval->name != NULL);
172158115Sume	memcpy(retval->name, name, size);
173158115Sume
174158115Sume	memcpy(&retval->common_query_timeout, common_timeout,
175158115Sume		sizeof(struct timeval));
176158115Sume	memcpy(&retval->mp_query_timeout, mp_timeout,
177158115Sume		sizeof(struct timeval));
178158115Sume
179194097Sdes	asprintf(&retval->positive_cache_params.cep.entry_name, "%s+", name);
180194097Sdes	assert(retval->positive_cache_params.cep.entry_name != NULL);
181158115Sume
182194097Sdes	asprintf(&retval->negative_cache_params.cep.entry_name, "%s-", name);
183194097Sdes	assert(retval->negative_cache_params.cep.entry_name != NULL);
184158115Sume
185194097Sdes	asprintf(&retval->mp_cache_params.cep.entry_name, "%s*", name);
186194097Sdes	assert(retval->mp_cache_params.cep.entry_name != NULL);
187158115Sume
188158115Sume	TRACE_OUT(create_configuration_entry);
189158115Sume	return (retval);
190158115Sume}
191158115Sume
192158115Sume/*
193158115Sume * Creates configuration entry and fills it with default values
194158115Sume */
195158115Sumestruct configuration_entry *
196158115Sumecreate_def_configuration_entry(const char *name)
197158115Sume{
198158115Sume	struct common_cache_entry_params positive_params, negative_params;
199158115Sume	struct mp_cache_entry_params mp_params;
200158115Sume	struct timeval default_common_timeout, default_mp_timeout;
201158115Sume
202158115Sume	struct configuration_entry *res = NULL;
203158115Sume
204158115Sume	TRACE_IN(create_def_configuration_entry);
205158115Sume	memset(&positive_params, 0,
206158115Sume		sizeof(struct common_cache_entry_params));
207194097Sdes	positive_params.cep.entry_type = CET_COMMON;
208158115Sume	positive_params.cache_entries_size = DEFAULT_CACHE_HT_SIZE;
209158115Sume	positive_params.max_elemsize = DEFAULT_POSITIVE_ELEMENTS_SIZE;
210158115Sume	positive_params.satisf_elemsize = DEFAULT_POSITIVE_ELEMENTS_SIZE / 2;
211158115Sume	positive_params.max_lifetime.tv_sec = DEFAULT_POSITIVE_LIFETIME;
212158115Sume	positive_params.policy = CPT_LRU;
213158115Sume
214158115Sume	memcpy(&negative_params, &positive_params,
215158115Sume		sizeof(struct common_cache_entry_params));
216158115Sume	negative_params.max_elemsize = DEFAULT_NEGATIVE_ELEMENTS_SIZE;
217158115Sume	negative_params.satisf_elemsize = DEFAULT_NEGATIVE_ELEMENTS_SIZE / 2;
218158115Sume	negative_params.max_lifetime.tv_sec = DEFAULT_NEGATIVE_LIFETIME;
219158115Sume	negative_params.policy = CPT_FIFO;
220158115Sume
221158115Sume	memset(&default_common_timeout, 0, sizeof(struct timeval));
222158115Sume	default_common_timeout.tv_sec = DEFAULT_COMMON_ENTRY_TIMEOUT;
223158115Sume
224158115Sume	memset(&default_mp_timeout, 0, sizeof(struct timeval));
225158115Sume	default_mp_timeout.tv_sec = DEFAULT_MP_ENTRY_TIMEOUT;
226158115Sume
227158115Sume	memset(&mp_params, 0,
228158115Sume		sizeof(struct mp_cache_entry_params));
229194097Sdes	mp_params.cep.entry_type = CET_MULTIPART;
230158115Sume	mp_params.max_elemsize = DEFAULT_MULTIPART_ELEMENTS_SIZE;
231158115Sume	mp_params.max_sessions = DEFAULT_MULITPART_SESSIONS_SIZE;
232158115Sume	mp_params.max_lifetime.tv_sec = DEFAULT_MULITPART_LIFETIME;
233158115Sume
234158115Sume	res = create_configuration_entry(name, &default_common_timeout,
235158115Sume		&default_mp_timeout, &positive_params, &negative_params,
236158115Sume		&mp_params);
237158115Sume
238158115Sume	TRACE_OUT(create_def_configuration_entry);
239158115Sume	return (res);
240158115Sume}
241158115Sume
242158115Sumevoid
243158115Sumedestroy_configuration_entry(struct configuration_entry *entry)
244158115Sume{
245158115Sume	TRACE_IN(destroy_configuration_entry);
246158115Sume	assert(entry != NULL);
247158115Sume	pthread_mutex_destroy(&entry->positive_cache_lock);
248158115Sume	pthread_mutex_destroy(&entry->negative_cache_lock);
249158115Sume	pthread_mutex_destroy(&entry->mp_cache_lock);
250158115Sume	free(entry->name);
251194097Sdes	free(entry->positive_cache_params.cep.entry_name);
252194097Sdes	free(entry->negative_cache_params.cep.entry_name);
253194097Sdes	free(entry->mp_cache_params.cep.entry_name);
254158115Sume	free(entry->mp_cache_entries);
255158115Sume	free(entry);
256158115Sume	TRACE_OUT(destroy_configuration_entry);
257158115Sume}
258158115Sume
259158115Sumeint
260158115Sumeadd_configuration_entry(struct configuration *config,
261158115Sume	struct configuration_entry *entry)
262158115Sume{
263158115Sume	TRACE_IN(add_configuration_entry);
264158115Sume	assert(entry != NULL);
265158115Sume	assert(entry->name != NULL);
266158115Sume	if (configuration_find_entry(config, entry->name) != NULL) {
267158115Sume		TRACE_OUT(add_configuration_entry);
268158115Sume		return (-1);
269158115Sume	}
270158115Sume
271158115Sume	if (config->entries_size == config->entries_capacity) {
272158115Sume		struct configuration_entry **new_entries;
273158115Sume
274158115Sume		config->entries_capacity *= 2;
275183770Sdelphij		new_entries = (struct configuration_entry **)calloc(1,
276158115Sume			sizeof(struct configuration_entry *) *
277158115Sume			config->entries_capacity);
278158115Sume		assert(new_entries != NULL);
279158115Sume		memcpy(new_entries, config->entries,
280158115Sume			sizeof(struct configuration_entry *) *
281158115Sume		        config->entries_size);
282158115Sume
283158115Sume		free(config->entries);
284158115Sume		config->entries = new_entries;
285158115Sume	}
286158115Sume
287158115Sume	config->entries[config->entries_size++] = entry;
288158115Sume	qsort(config->entries, config->entries_size,
289158115Sume		sizeof(struct configuration_entry *),
290158115Sume		configuration_entry_sort_cmp);
291158115Sume
292158115Sume	TRACE_OUT(add_configuration_entry);
293158115Sume	return (0);
294158115Sume}
295158115Sume
296158115Sumesize_t
297158115Sumeconfiguration_get_entries_size(struct configuration *config)
298158115Sume{
299158115Sume	TRACE_IN(configuration_get_entries_size);
300158115Sume	assert(config != NULL);
301158115Sume	TRACE_OUT(configuration_get_entries_size);
302158115Sume	return (config->entries_size);
303158115Sume}
304158115Sume
305158115Sumestruct configuration_entry *
306158115Sumeconfiguration_get_entry(struct configuration *config, size_t index)
307158115Sume{
308158115Sume	TRACE_IN(configuration_get_entry);
309158115Sume	assert(config != NULL);
310158115Sume	assert(index < config->entries_size);
311158115Sume	TRACE_OUT(configuration_get_entry);
312158115Sume	return (config->entries[index]);
313158115Sume}
314158115Sume
315158115Sumestruct configuration_entry *
316158115Sumeconfiguration_find_entry(struct configuration *config,
317158115Sume	const char *name)
318158115Sume{
319158115Sume	struct configuration_entry	**retval;
320158115Sume
321158115Sume	TRACE_IN(configuration_find_entry);
322158115Sume
323158115Sume	retval = bsearch(name, config->entries, config->entries_size,
324158115Sume		sizeof(struct configuration_entry *), configuration_entry_cmp);
325158115Sume	TRACE_OUT(configuration_find_entry);
326158115Sume
327158115Sume	return ((retval != NULL) ? *retval : NULL);
328158115Sume}
329158115Sume
330158115Sume/*
331158115Sume * All multipart cache entries are stored in the configuration_entry in the
332158115Sume * sorted array (sorted by names). The 3 functions below manage this array.
333158115Sume */
334158115Sume
335158115Sumeint
336158115Sumeconfiguration_entry_add_mp_cache_entry(struct configuration_entry *config_entry,
337158115Sume	cache_entry c_entry)
338158115Sume{
339158115Sume	cache_entry *new_mp_entries, *old_mp_entries;
340158115Sume
341158115Sume	TRACE_IN(configuration_entry_add_mp_cache_entry);
342158115Sume	++config_entry->mp_cache_entries_size;
343158115Sume	new_mp_entries = (cache_entry *)malloc(sizeof(cache_entry) *
344158115Sume		config_entry->mp_cache_entries_size);
345158115Sume	assert(new_mp_entries != NULL);
346158115Sume	new_mp_entries[0] = c_entry;
347158115Sume
348158115Sume	if (config_entry->mp_cache_entries_size - 1 > 0) {
349158115Sume		memcpy(new_mp_entries + 1,
350158115Sume		    config_entry->mp_cache_entries,
351158115Sume		    (config_entry->mp_cache_entries_size - 1) *
352158115Sume		    sizeof(cache_entry));
353158115Sume	}
354158115Sume
355158115Sume	old_mp_entries = config_entry->mp_cache_entries;
356158115Sume	config_entry->mp_cache_entries = new_mp_entries;
357158115Sume	free(old_mp_entries);
358158115Sume
359158115Sume	qsort(config_entry->mp_cache_entries,
360158115Sume		config_entry->mp_cache_entries_size,
361158115Sume		sizeof(cache_entry),
362158115Sume		configuration_entry_cache_mp_sort_cmp);
363158115Sume
364158115Sume	TRACE_OUT(configuration_entry_add_mp_cache_entry);
365158115Sume	return (0);
366158115Sume}
367158115Sume
368158115Sumecache_entry
369158115Sumeconfiguration_entry_find_mp_cache_entry(
370158115Sume	struct configuration_entry *config_entry, const char *mp_name)
371158115Sume{
372158115Sume	cache_entry *result;
373158115Sume
374158115Sume	TRACE_IN(configuration_entry_find_mp_cache_entry);
375158115Sume	result = bsearch(mp_name, config_entry->mp_cache_entries,
376158115Sume		config_entry->mp_cache_entries_size,
377158115Sume		sizeof(cache_entry), configuration_entry_cache_mp_cmp);
378158115Sume
379158115Sume	if (result == NULL) {
380158115Sume		TRACE_OUT(configuration_entry_find_mp_cache_entry);
381158115Sume		return (NULL);
382158115Sume	} else {
383158115Sume		TRACE_OUT(configuration_entry_find_mp_cache_entry);
384158115Sume		return (*result);
385158115Sume	}
386158115Sume}
387158115Sume
388158115Sume/*
389158115Sume * Searches for all multipart entries with names starting with mp_name.
390158115Sume * Needed for cache flushing.
391158115Sume */
392158115Sumeint
393158115Sumeconfiguration_entry_find_mp_cache_entries(
394158115Sume	struct configuration_entry *config_entry, const char *mp_name,
395158115Sume	cache_entry **start, cache_entry **finish)
396158115Sume{
397158115Sume	cache_entry *result;
398158115Sume
399158115Sume	TRACE_IN(configuration_entry_find_mp_cache_entries);
400158115Sume	result = bsearch(mp_name, config_entry->mp_cache_entries,
401158115Sume		config_entry->mp_cache_entries_size,
402158115Sume		sizeof(cache_entry), configuration_entry_cache_mp_part_cmp);
403158115Sume
404158115Sume	if (result == NULL) {
405158115Sume		TRACE_OUT(configuration_entry_find_mp_cache_entries);
406158115Sume		return (-1);
407158115Sume	}
408158115Sume
409158115Sume	*start = result;
410158115Sume	*finish = result + 1;
411158115Sume
412158115Sume	while (*start != config_entry->mp_cache_entries) {
413158115Sume	    if (configuration_entry_cache_mp_part_cmp(mp_name, *start - 1) == 0)
414158115Sume		*start = *start - 1;
415158115Sume	    else
416158115Sume		break;
417158115Sume	}
418158115Sume
419158115Sume	while (*finish != config_entry->mp_cache_entries +
420158115Sume		config_entry->mp_cache_entries_size) {
421158115Sume
422158115Sume	    if (configuration_entry_cache_mp_part_cmp(
423158115Sume		mp_name, *finish) == 0)
424158115Sume	    	*finish = *finish + 1;
425158115Sume	    else
426158115Sume		break;
427158115Sume	}
428158115Sume
429158115Sume	TRACE_OUT(configuration_entry_find_mp_cache_entries);
430158115Sume	return (0);
431158115Sume}
432158115Sume
433158115Sume/*
434158115Sume * Configuration entry uses rwlock to handle access to its fields.
435158115Sume */
436158115Sumevoid
437158115Sumeconfiguration_lock_rdlock(struct configuration *config)
438158115Sume{
439158115Sume    TRACE_IN(configuration_lock_rdlock);
440158115Sume    pthread_rwlock_rdlock(&config->rwlock);
441158115Sume    TRACE_OUT(configuration_lock_rdlock);
442158115Sume}
443158115Sume
444158115Sumevoid
445158115Sumeconfiguration_lock_wrlock(struct configuration *config)
446158115Sume{
447158115Sume    TRACE_IN(configuration_lock_wrlock);
448158115Sume    pthread_rwlock_wrlock(&config->rwlock);
449158115Sume    TRACE_OUT(configuration_lock_wrlock);
450158115Sume}
451158115Sume
452158115Sumevoid
453158115Sumeconfiguration_unlock(struct configuration *config)
454158115Sume{
455158115Sume    TRACE_IN(configuration_unlock);
456158115Sume    pthread_rwlock_unlock(&config->rwlock);
457158115Sume    TRACE_OUT(configuration_unlock);
458158115Sume}
459158115Sume
460158115Sume/*
461158115Sume * Configuration entry uses 3 mutexes to handle cache operations. They are
462158115Sume * acquired by configuration_lock_entry and configuration_unlock_entry
463158115Sume * functions.
464158115Sume */
465158115Sumevoid
466158115Sumeconfiguration_lock_entry(struct configuration_entry *entry,
467158115Sume	enum config_entry_lock_type lock_type)
468158115Sume{
469158115Sume	TRACE_IN(configuration_lock_entry);
470158115Sume	assert(entry != NULL);
471158115Sume
472158115Sume	switch (lock_type) {
473158115Sume	case CELT_POSITIVE:
474158115Sume		pthread_mutex_lock(&entry->positive_cache_lock);
475158115Sume		break;
476158115Sume	case CELT_NEGATIVE:
477158115Sume		pthread_mutex_lock(&entry->negative_cache_lock);
478158115Sume		break;
479158115Sume	case CELT_MULTIPART:
480158115Sume		pthread_mutex_lock(&entry->mp_cache_lock);
481158115Sume		break;
482158115Sume	default:
483158115Sume		/* should be unreachable */
484158115Sume		break;
485158115Sume	}
486158115Sume	TRACE_OUT(configuration_lock_entry);
487158115Sume}
488158115Sume
489158115Sumevoid
490158115Sumeconfiguration_unlock_entry(struct configuration_entry *entry,
491158115Sume	enum config_entry_lock_type lock_type)
492158115Sume{
493158115Sume	TRACE_IN(configuration_unlock_entry);
494158115Sume	assert(entry != NULL);
495158115Sume
496158115Sume	switch (lock_type) {
497158115Sume	case CELT_POSITIVE:
498158115Sume		pthread_mutex_unlock(&entry->positive_cache_lock);
499158115Sume		break;
500158115Sume	case CELT_NEGATIVE:
501158115Sume		pthread_mutex_unlock(&entry->negative_cache_lock);
502158115Sume		break;
503158115Sume	case CELT_MULTIPART:
504158115Sume		pthread_mutex_unlock(&entry->mp_cache_lock);
505158115Sume		break;
506158115Sume	default:
507158115Sume		/* should be unreachable */
508158115Sume		break;
509158115Sume	}
510158115Sume	TRACE_OUT(configuration_unlock_entry);
511158115Sume}
512158115Sume
513158115Sumestruct configuration *
514158115Sumeinit_configuration(void)
515158115Sume{
516158115Sume	struct configuration	*retval;
517158115Sume
518158115Sume	TRACE_IN(init_configuration);
519183770Sdelphij	retval = (struct configuration *)calloc(1, sizeof(struct configuration));
520158115Sume	assert(retval != NULL);
521158115Sume
522158115Sume	retval->entries_capacity = INITIAL_ENTRIES_CAPACITY;
523183770Sdelphij	retval->entries = (struct configuration_entry **)calloc(1,
524158115Sume		sizeof(struct configuration_entry *) *
525158115Sume		retval->entries_capacity);
526158115Sume	assert(retval->entries != NULL);
527158115Sume
528158115Sume	pthread_rwlock_init(&retval->rwlock, NULL);
529158115Sume
530158115Sume	TRACE_OUT(init_configuration);
531158115Sume	return (retval);
532158115Sume}
533158115Sume
534158115Sumevoid
535158115Sumefill_configuration_defaults(struct configuration *config)
536158115Sume{
537158115Sume	size_t	len, i;
538158115Sume
539158115Sume	TRACE_IN(fill_configuration_defaults);
540158115Sume	assert(config != NULL);
541158115Sume
542158115Sume	if (config->socket_path != NULL)
543158115Sume		free(config->socket_path);
544158115Sume
545158115Sume	len = strlen(DEFAULT_SOCKET_PATH);
546183770Sdelphij	config->socket_path = (char *)calloc(1, len + 1);
547158115Sume	assert(config->socket_path != NULL);
548158115Sume	memcpy(config->socket_path, DEFAULT_SOCKET_PATH, len);
549158115Sume
550158115Sume	len = strlen(DEFAULT_PIDFILE_PATH);
551183770Sdelphij	config->pidfile_path = (char *)calloc(1, len + 1);
552158115Sume	assert(config->pidfile_path != NULL);
553158115Sume	memcpy(config->pidfile_path, DEFAULT_PIDFILE_PATH, len);
554158115Sume
555158115Sume	config->socket_mode =  S_IFSOCK | S_IRUSR | S_IWUSR |
556158115Sume		S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
557158115Sume	config->force_unlink = 1;
558158115Sume
559158115Sume	config->query_timeout = DEFAULT_QUERY_TIMEOUT;
560158115Sume	config->threads_num = DEFAULT_THREADS_NUM;
561158115Sume
562158115Sume	for (i = 0; i < config->entries_size; ++i)
563158115Sume		destroy_configuration_entry(config->entries[i]);
564158115Sume	config->entries_size = 0;
565158115Sume
566158115Sume	TRACE_OUT(fill_configuration_defaults);
567158115Sume}
568158115Sume
569158115Sumevoid
570158115Sumedestroy_configuration(struct configuration *config)
571158115Sume{
572194096Sdes	unsigned int i;
573194096Sdes
574158115Sume	TRACE_IN(destroy_configuration);
575158115Sume	assert(config != NULL);
576158115Sume	free(config->pidfile_path);
577158115Sume	free(config->socket_path);
578158115Sume
579158115Sume	for (i = 0; i < config->entries_size; ++i)
580158115Sume		destroy_configuration_entry(config->entries[i]);
581158115Sume	free(config->entries);
582158115Sume
583158115Sume	pthread_rwlock_destroy(&config->rwlock);
584158115Sume	free(config);
585158115Sume	TRACE_OUT(destroy_configuration);
586158115Sume}
587