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/time.h> 3028f805ceSDag-Erling Smørgrav 3106a99fe3SHajimu UMEMOTO #include <assert.h> 3206a99fe3SHajimu UMEMOTO #include <stdio.h> 3328f805ceSDag-Erling Smørgrav #include <stdlib.h> 3406a99fe3SHajimu UMEMOTO #include <string.h> 3528f805ceSDag-Erling Smørgrav 3606a99fe3SHajimu UMEMOTO #include "config.h" 3706a99fe3SHajimu UMEMOTO #include "debug.h" 3806a99fe3SHajimu UMEMOTO #include "log.h" 3906a99fe3SHajimu UMEMOTO #include "parser.h" 4006a99fe3SHajimu UMEMOTO 4106a99fe3SHajimu UMEMOTO static void enable_cache(struct configuration *,const char *, int); 4206a99fe3SHajimu UMEMOTO static struct configuration_entry *find_create_entry(struct configuration *, 4306a99fe3SHajimu UMEMOTO const char *); 4406a99fe3SHajimu UMEMOTO static int get_number(const char *, int, int); 4506a99fe3SHajimu UMEMOTO static enum cache_policy_t get_policy(const char *); 4606a99fe3SHajimu UMEMOTO static int get_yesno(const char *); 4706a99fe3SHajimu UMEMOTO static int check_cachename(const char *); 4806a99fe3SHajimu UMEMOTO static void check_files(struct configuration *, const char *, int); 4906a99fe3SHajimu UMEMOTO static void set_keep_hot_count(struct configuration *, const char *, int); 5006a99fe3SHajimu UMEMOTO static void set_negative_policy(struct configuration *, const char *, 5106a99fe3SHajimu UMEMOTO enum cache_policy_t); 5206a99fe3SHajimu UMEMOTO static void set_negative_time_to_live(struct configuration *, 5306a99fe3SHajimu UMEMOTO const char *, int); 5406a99fe3SHajimu UMEMOTO static void set_positive_policy(struct configuration *, const char *, 5506a99fe3SHajimu UMEMOTO enum cache_policy_t); 5606a99fe3SHajimu UMEMOTO static void set_perform_actual_lookups(struct configuration *, const char *, 5706a99fe3SHajimu UMEMOTO int); 5806a99fe3SHajimu UMEMOTO static void set_positive_time_to_live(struct configuration *, 5906a99fe3SHajimu UMEMOTO const char *, int); 6006a99fe3SHajimu UMEMOTO static void set_suggested_size(struct configuration *, const char *, 6106a99fe3SHajimu UMEMOTO int size); 6206a99fe3SHajimu UMEMOTO static void set_threads_num(struct configuration *, int); 6306a99fe3SHajimu UMEMOTO static int strbreak(char *, char **, int); 6406a99fe3SHajimu UMEMOTO 6506a99fe3SHajimu UMEMOTO static int 6606a99fe3SHajimu UMEMOTO strbreak(char *str, char **fields, int fields_size) 6706a99fe3SHajimu UMEMOTO { 6806a99fe3SHajimu UMEMOTO char *c = str; 6906a99fe3SHajimu UMEMOTO int i, num; 7006a99fe3SHajimu UMEMOTO 7106a99fe3SHajimu UMEMOTO TRACE_IN(strbreak); 7206a99fe3SHajimu UMEMOTO num = 0; 7306a99fe3SHajimu UMEMOTO for (i = 0; 7406a99fe3SHajimu UMEMOTO ((*fields = 7506a99fe3SHajimu UMEMOTO strsep(i < fields_size ? &c : NULL, "\n\t ")) != NULL); 7606a99fe3SHajimu UMEMOTO ++i) 7706a99fe3SHajimu UMEMOTO if ((*(*fields)) != '\0') { 7806a99fe3SHajimu UMEMOTO ++fields; 7906a99fe3SHajimu UMEMOTO ++num; 8006a99fe3SHajimu UMEMOTO } 8106a99fe3SHajimu UMEMOTO 8206a99fe3SHajimu UMEMOTO TRACE_OUT(strbreak); 8306a99fe3SHajimu UMEMOTO return (num); 8406a99fe3SHajimu UMEMOTO } 8506a99fe3SHajimu UMEMOTO 8606a99fe3SHajimu UMEMOTO /* 8706a99fe3SHajimu UMEMOTO * Tries to find the configuration entry with the specified name. If search 8806a99fe3SHajimu UMEMOTO * fails, the new entry with the default parameters will be created. 8906a99fe3SHajimu UMEMOTO */ 9006a99fe3SHajimu UMEMOTO static struct configuration_entry * 9106a99fe3SHajimu UMEMOTO find_create_entry(struct configuration *config, 9206a99fe3SHajimu UMEMOTO const char *entry_name) 9306a99fe3SHajimu UMEMOTO { 9406a99fe3SHajimu UMEMOTO struct configuration_entry *entry = NULL; 9506a99fe3SHajimu UMEMOTO int res; 9606a99fe3SHajimu UMEMOTO 9706a99fe3SHajimu UMEMOTO TRACE_IN(find_create_entry); 9806a99fe3SHajimu UMEMOTO entry = configuration_find_entry(config, entry_name); 9906a99fe3SHajimu UMEMOTO if (entry == NULL) { 10006a99fe3SHajimu UMEMOTO entry = create_def_configuration_entry(entry_name); 10106a99fe3SHajimu UMEMOTO assert( entry != NULL); 10206a99fe3SHajimu UMEMOTO res = add_configuration_entry(config, entry); 10306a99fe3SHajimu UMEMOTO assert(res == 0); 10406a99fe3SHajimu UMEMOTO } 10506a99fe3SHajimu UMEMOTO 10606a99fe3SHajimu UMEMOTO TRACE_OUT(find_create_entry); 10706a99fe3SHajimu UMEMOTO return (entry); 10806a99fe3SHajimu UMEMOTO } 10906a99fe3SHajimu UMEMOTO 11006a99fe3SHajimu UMEMOTO /* 11106a99fe3SHajimu UMEMOTO * The vast majority of the functions below corresponds to the particular 11206a99fe3SHajimu UMEMOTO * keywords in the configuration file. 11306a99fe3SHajimu UMEMOTO */ 11406a99fe3SHajimu UMEMOTO static void 11506a99fe3SHajimu UMEMOTO enable_cache(struct configuration *config, const char *entry_name, int flag) 11606a99fe3SHajimu UMEMOTO { 11706a99fe3SHajimu UMEMOTO struct configuration_entry *entry; 11806a99fe3SHajimu UMEMOTO 11906a99fe3SHajimu UMEMOTO TRACE_IN(enable_cache); 12006a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name); 12106a99fe3SHajimu UMEMOTO entry->enabled = flag; 12206a99fe3SHajimu UMEMOTO TRACE_OUT(enable_cache); 12306a99fe3SHajimu UMEMOTO } 12406a99fe3SHajimu UMEMOTO 12506a99fe3SHajimu UMEMOTO static void 12606a99fe3SHajimu UMEMOTO set_positive_time_to_live(struct configuration *config, 12706a99fe3SHajimu UMEMOTO const char *entry_name, int ttl) 12806a99fe3SHajimu UMEMOTO { 12906a99fe3SHajimu UMEMOTO struct configuration_entry *entry; 13006a99fe3SHajimu UMEMOTO struct timeval lifetime; 13106a99fe3SHajimu UMEMOTO 13206a99fe3SHajimu UMEMOTO TRACE_IN(set_positive_time_to_live); 13306a99fe3SHajimu UMEMOTO assert(ttl >= 0); 13406a99fe3SHajimu UMEMOTO assert(entry_name != NULL); 13506a99fe3SHajimu UMEMOTO memset(&lifetime, 0, sizeof(struct timeval)); 13606a99fe3SHajimu UMEMOTO lifetime.tv_sec = ttl; 13706a99fe3SHajimu UMEMOTO 13806a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name); 13906a99fe3SHajimu UMEMOTO memcpy(&entry->positive_cache_params.max_lifetime, 14006a99fe3SHajimu UMEMOTO &lifetime, sizeof(struct timeval)); 14106a99fe3SHajimu UMEMOTO memcpy(&entry->mp_cache_params.max_lifetime, 14206a99fe3SHajimu UMEMOTO &lifetime, sizeof(struct timeval)); 14306a99fe3SHajimu UMEMOTO 14406a99fe3SHajimu UMEMOTO TRACE_OUT(set_positive_time_to_live); 14506a99fe3SHajimu UMEMOTO } 14606a99fe3SHajimu UMEMOTO 14706a99fe3SHajimu UMEMOTO static void 14806a99fe3SHajimu UMEMOTO set_negative_time_to_live(struct configuration *config, 14906a99fe3SHajimu UMEMOTO const char *entry_name, int nttl) 15006a99fe3SHajimu UMEMOTO { 15106a99fe3SHajimu UMEMOTO struct configuration_entry *entry; 15206a99fe3SHajimu UMEMOTO struct timeval lifetime; 15306a99fe3SHajimu UMEMOTO 15406a99fe3SHajimu UMEMOTO TRACE_IN(set_negative_time_to_live); 15506a99fe3SHajimu UMEMOTO assert(nttl > 0); 15606a99fe3SHajimu UMEMOTO assert(entry_name != NULL); 15706a99fe3SHajimu UMEMOTO memset(&lifetime, 0, sizeof(struct timeval)); 15806a99fe3SHajimu UMEMOTO lifetime.tv_sec = nttl; 15906a99fe3SHajimu UMEMOTO 16006a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name); 16106a99fe3SHajimu UMEMOTO assert(entry != NULL); 16206a99fe3SHajimu UMEMOTO memcpy(&entry->negative_cache_params.max_lifetime, 16306a99fe3SHajimu UMEMOTO &lifetime, sizeof(struct timeval)); 16406a99fe3SHajimu UMEMOTO 16506a99fe3SHajimu UMEMOTO TRACE_OUT(set_negative_time_to_live); 16606a99fe3SHajimu UMEMOTO } 16706a99fe3SHajimu UMEMOTO 168a397989dSStefan Eßer static void 169a397989dSStefan Eßer set_positive_confidence_threshold(struct configuration *config, 170a397989dSStefan Eßer const char *entry_name, int conf_thresh) 171a397989dSStefan Eßer { 172a397989dSStefan Eßer struct configuration_entry *entry; 173a397989dSStefan Eßer 174a397989dSStefan Eßer TRACE_IN(set_positive_conf_thresh); 175a397989dSStefan Eßer assert(conf_thresh > 0); 176a397989dSStefan Eßer assert(entry_name != NULL); 177a397989dSStefan Eßer 178a397989dSStefan Eßer entry = find_create_entry(config, entry_name); 179a397989dSStefan Eßer assert(entry != NULL); 180a397989dSStefan Eßer entry->positive_cache_params.confidence_threshold = conf_thresh; 181a397989dSStefan Eßer 182a397989dSStefan Eßer TRACE_OUT(set_positive_conf_thresh); 183a397989dSStefan Eßer } 184a397989dSStefan Eßer 185a397989dSStefan Eßer static void 186a397989dSStefan Eßer set_negative_confidence_threshold(struct configuration *config, 187a397989dSStefan Eßer const char *entry_name, int conf_thresh) 188a397989dSStefan Eßer { 189a397989dSStefan Eßer struct configuration_entry *entry; 190a397989dSStefan Eßer 191a397989dSStefan Eßer TRACE_IN(set_negative_conf_thresh); 192a397989dSStefan Eßer assert(conf_thresh > 0); 193a397989dSStefan Eßer assert(entry_name != NULL); 194a397989dSStefan Eßer entry = find_create_entry(config, entry_name); 195a397989dSStefan Eßer assert(entry != NULL); 196a397989dSStefan Eßer entry->negative_cache_params.confidence_threshold = conf_thresh; 197a397989dSStefan Eßer TRACE_OUT(set_negative_conf_thresh); 198a397989dSStefan Eßer } 199a397989dSStefan Eßer 20006a99fe3SHajimu UMEMOTO /* 20106a99fe3SHajimu UMEMOTO * Hot count is actually the elements size limit. 20206a99fe3SHajimu UMEMOTO */ 20306a99fe3SHajimu UMEMOTO static void 20406a99fe3SHajimu UMEMOTO set_keep_hot_count(struct configuration *config, 20506a99fe3SHajimu UMEMOTO const char *entry_name, int count) 20606a99fe3SHajimu UMEMOTO { 20706a99fe3SHajimu UMEMOTO struct configuration_entry *entry; 20806a99fe3SHajimu UMEMOTO 20906a99fe3SHajimu UMEMOTO TRACE_IN(set_keep_hot_count); 21006a99fe3SHajimu UMEMOTO assert(count >= 0); 21106a99fe3SHajimu UMEMOTO assert(entry_name != NULL); 21206a99fe3SHajimu UMEMOTO 21306a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name); 21406a99fe3SHajimu UMEMOTO assert(entry != NULL); 21506a99fe3SHajimu UMEMOTO entry->positive_cache_params.max_elemsize = count; 21606a99fe3SHajimu UMEMOTO 21706a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name); 21806a99fe3SHajimu UMEMOTO assert(entry != NULL); 21906a99fe3SHajimu UMEMOTO entry->negative_cache_params.max_elemsize = count; 22006a99fe3SHajimu UMEMOTO 22106a99fe3SHajimu UMEMOTO TRACE_OUT(set_keep_hot_count); 22206a99fe3SHajimu UMEMOTO } 22306a99fe3SHajimu UMEMOTO 22406a99fe3SHajimu UMEMOTO static void 22506a99fe3SHajimu UMEMOTO set_positive_policy(struct configuration *config, 22606a99fe3SHajimu UMEMOTO const char *entry_name, enum cache_policy_t policy) 22706a99fe3SHajimu UMEMOTO { 22806a99fe3SHajimu UMEMOTO struct configuration_entry *entry; 22906a99fe3SHajimu UMEMOTO 23006a99fe3SHajimu UMEMOTO TRACE_IN(set_positive_policy); 23106a99fe3SHajimu UMEMOTO assert(entry_name != NULL); 23206a99fe3SHajimu UMEMOTO 23306a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name); 23406a99fe3SHajimu UMEMOTO assert(entry != NULL); 23506a99fe3SHajimu UMEMOTO entry->positive_cache_params.policy = policy; 23606a99fe3SHajimu UMEMOTO 23706a99fe3SHajimu UMEMOTO TRACE_OUT(set_positive_policy); 23806a99fe3SHajimu UMEMOTO } 23906a99fe3SHajimu UMEMOTO 24006a99fe3SHajimu UMEMOTO static void 24106a99fe3SHajimu UMEMOTO set_negative_policy(struct configuration *config, 24206a99fe3SHajimu UMEMOTO const char *entry_name, enum cache_policy_t policy) 24306a99fe3SHajimu UMEMOTO { 24406a99fe3SHajimu UMEMOTO struct configuration_entry *entry; 24506a99fe3SHajimu UMEMOTO 24606a99fe3SHajimu UMEMOTO TRACE_IN(set_negative_policy); 24706a99fe3SHajimu UMEMOTO assert(entry_name != NULL); 24806a99fe3SHajimu UMEMOTO 24906a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name); 25006a99fe3SHajimu UMEMOTO assert(entry != NULL); 25106a99fe3SHajimu UMEMOTO entry->negative_cache_params.policy = policy; 25206a99fe3SHajimu UMEMOTO 25306a99fe3SHajimu UMEMOTO TRACE_OUT(set_negative_policy); 25406a99fe3SHajimu UMEMOTO } 25506a99fe3SHajimu UMEMOTO 25606a99fe3SHajimu UMEMOTO static void 25706a99fe3SHajimu UMEMOTO set_perform_actual_lookups(struct configuration *config, 25806a99fe3SHajimu UMEMOTO const char *entry_name, int flag) 25906a99fe3SHajimu UMEMOTO { 26006a99fe3SHajimu UMEMOTO struct configuration_entry *entry; 26106a99fe3SHajimu UMEMOTO 26206a99fe3SHajimu UMEMOTO TRACE_IN(set_perform_actual_lookups); 26306a99fe3SHajimu UMEMOTO assert(entry_name != NULL); 26406a99fe3SHajimu UMEMOTO 26506a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name); 26606a99fe3SHajimu UMEMOTO assert(entry != NULL); 26706a99fe3SHajimu UMEMOTO entry->perform_actual_lookups = flag; 26806a99fe3SHajimu UMEMOTO 26906a99fe3SHajimu UMEMOTO TRACE_OUT(set_perform_actual_lookups); 27006a99fe3SHajimu UMEMOTO } 27106a99fe3SHajimu UMEMOTO 27206a99fe3SHajimu UMEMOTO static void 27306a99fe3SHajimu UMEMOTO set_suggested_size(struct configuration *config, 27406a99fe3SHajimu UMEMOTO const char *entry_name, int size) 27506a99fe3SHajimu UMEMOTO { 27606a99fe3SHajimu UMEMOTO struct configuration_entry *entry; 27706a99fe3SHajimu UMEMOTO 27806a99fe3SHajimu UMEMOTO TRACE_IN(set_suggested_size); 27906a99fe3SHajimu UMEMOTO assert(config != NULL); 28006a99fe3SHajimu UMEMOTO assert(entry_name != NULL); 28106a99fe3SHajimu UMEMOTO assert(size > 0); 28206a99fe3SHajimu UMEMOTO 28306a99fe3SHajimu UMEMOTO entry = find_create_entry(config, entry_name); 28406a99fe3SHajimu UMEMOTO assert(entry != NULL); 28506a99fe3SHajimu UMEMOTO entry->positive_cache_params.cache_entries_size = size; 28606a99fe3SHajimu UMEMOTO entry->negative_cache_params.cache_entries_size = size; 28706a99fe3SHajimu UMEMOTO 28806a99fe3SHajimu UMEMOTO TRACE_OUT(set_suggested_size); 28906a99fe3SHajimu UMEMOTO } 29006a99fe3SHajimu UMEMOTO 29106a99fe3SHajimu UMEMOTO static void 29206a99fe3SHajimu UMEMOTO check_files(struct configuration *config, const char *entry_name, int flag) 29306a99fe3SHajimu UMEMOTO { 29406a99fe3SHajimu UMEMOTO 29506a99fe3SHajimu UMEMOTO TRACE_IN(check_files); 29606a99fe3SHajimu UMEMOTO assert(entry_name != NULL); 29706a99fe3SHajimu UMEMOTO TRACE_OUT(check_files); 29806a99fe3SHajimu UMEMOTO } 29906a99fe3SHajimu UMEMOTO 30006a99fe3SHajimu UMEMOTO static int 30106a99fe3SHajimu UMEMOTO get_yesno(const char *str) 30206a99fe3SHajimu UMEMOTO { 30306a99fe3SHajimu UMEMOTO 30406a99fe3SHajimu UMEMOTO if (strcmp(str, "yes") == 0) 30506a99fe3SHajimu UMEMOTO return (1); 30606a99fe3SHajimu UMEMOTO else if (strcmp(str, "no") == 0) 30706a99fe3SHajimu UMEMOTO return (0); 30806a99fe3SHajimu UMEMOTO else 30906a99fe3SHajimu UMEMOTO return (-1); 31006a99fe3SHajimu UMEMOTO } 31106a99fe3SHajimu UMEMOTO 31206a99fe3SHajimu UMEMOTO static int 31306a99fe3SHajimu UMEMOTO get_number(const char *str, int low, int max) 31406a99fe3SHajimu UMEMOTO { 31506a99fe3SHajimu UMEMOTO 31606a99fe3SHajimu UMEMOTO char *end = NULL; 31706a99fe3SHajimu UMEMOTO int res = 0; 31806a99fe3SHajimu UMEMOTO 31906a99fe3SHajimu UMEMOTO if (str[0] == '\0') 32006a99fe3SHajimu UMEMOTO return (-1); 32106a99fe3SHajimu UMEMOTO 32206a99fe3SHajimu UMEMOTO res = strtol(str, &end, 10); 32306a99fe3SHajimu UMEMOTO if (*end != '\0') 32406a99fe3SHajimu UMEMOTO return (-1); 32506a99fe3SHajimu UMEMOTO else 32606a99fe3SHajimu UMEMOTO if (((res >= low) || (low == -1)) && 32706a99fe3SHajimu UMEMOTO ((res <= max) || (max == -1))) 32806a99fe3SHajimu UMEMOTO return (res); 32906a99fe3SHajimu UMEMOTO else 33006a99fe3SHajimu UMEMOTO return (-2); 33106a99fe3SHajimu UMEMOTO } 33206a99fe3SHajimu UMEMOTO 33306a99fe3SHajimu UMEMOTO static enum cache_policy_t 33406a99fe3SHajimu UMEMOTO get_policy(const char *str) 33506a99fe3SHajimu UMEMOTO { 33606a99fe3SHajimu UMEMOTO 33706a99fe3SHajimu UMEMOTO if (strcmp(str, "fifo") == 0) 33806a99fe3SHajimu UMEMOTO return (CPT_FIFO); 33906a99fe3SHajimu UMEMOTO else if (strcmp(str, "lru") == 0) 34006a99fe3SHajimu UMEMOTO return (CPT_LRU); 34106a99fe3SHajimu UMEMOTO else if (strcmp(str, "lfu") == 0) 34206a99fe3SHajimu UMEMOTO return (CPT_LFU); 34306a99fe3SHajimu UMEMOTO 34406a99fe3SHajimu UMEMOTO return (-1); 34506a99fe3SHajimu UMEMOTO } 34606a99fe3SHajimu UMEMOTO 34706a99fe3SHajimu UMEMOTO static int 34806a99fe3SHajimu UMEMOTO check_cachename(const char *str) 34906a99fe3SHajimu UMEMOTO { 35006a99fe3SHajimu UMEMOTO 35106a99fe3SHajimu UMEMOTO assert(str != NULL); 35206a99fe3SHajimu UMEMOTO return ((strlen(str) > 0) ? 0 : -1); 35306a99fe3SHajimu UMEMOTO } 35406a99fe3SHajimu UMEMOTO 35506a99fe3SHajimu UMEMOTO static void 35606a99fe3SHajimu UMEMOTO set_threads_num(struct configuration *config, int value) 35706a99fe3SHajimu UMEMOTO { 35806a99fe3SHajimu UMEMOTO 35906a99fe3SHajimu UMEMOTO assert(config != NULL); 36006a99fe3SHajimu UMEMOTO config->threads_num = value; 36106a99fe3SHajimu UMEMOTO } 36206a99fe3SHajimu UMEMOTO 36306a99fe3SHajimu UMEMOTO /* 36406a99fe3SHajimu UMEMOTO * The main configuration routine. Its implementation is hugely inspired by the 365*ec8a394dSElyes Haouas * same routine implementation in Solaris NSCD. 36606a99fe3SHajimu UMEMOTO */ 36706a99fe3SHajimu UMEMOTO int 36806a99fe3SHajimu UMEMOTO parse_config_file(struct configuration *config, 36906a99fe3SHajimu UMEMOTO const char *fname, char const **error_str, int *error_line) 37006a99fe3SHajimu UMEMOTO { 37106a99fe3SHajimu UMEMOTO FILE *fin; 37206a99fe3SHajimu UMEMOTO char buffer[255]; 37306a99fe3SHajimu UMEMOTO char *fields[128]; 37406a99fe3SHajimu UMEMOTO int field_count, line_num, value; 37506a99fe3SHajimu UMEMOTO int res; 37686e88c4fSAllan Jude int invalid_value; 37706a99fe3SHajimu UMEMOTO 37806a99fe3SHajimu UMEMOTO TRACE_IN(parse_config_file); 37906a99fe3SHajimu UMEMOTO assert(config != NULL); 38006a99fe3SHajimu UMEMOTO assert(fname != NULL); 38106a99fe3SHajimu UMEMOTO 38206a99fe3SHajimu UMEMOTO fin = fopen(fname, "r"); 38306a99fe3SHajimu UMEMOTO if (fin == NULL) { 38406a99fe3SHajimu UMEMOTO TRACE_OUT(parse_config_file); 38506a99fe3SHajimu UMEMOTO return (-1); 38606a99fe3SHajimu UMEMOTO } 38706a99fe3SHajimu UMEMOTO 38806a99fe3SHajimu UMEMOTO res = 0; 38906a99fe3SHajimu UMEMOTO line_num = 0; 39086e88c4fSAllan Jude invalid_value = 0; 39106a99fe3SHajimu UMEMOTO memset(buffer, 0, sizeof(buffer)); 39206a99fe3SHajimu UMEMOTO while ((res == 0) && (fgets(buffer, sizeof(buffer) - 1, fin) != NULL)) { 39306a99fe3SHajimu UMEMOTO field_count = strbreak(buffer, fields, sizeof(fields)); 39406a99fe3SHajimu UMEMOTO ++line_num; 39506a99fe3SHajimu UMEMOTO 39606a99fe3SHajimu UMEMOTO if (field_count == 0) 39706a99fe3SHajimu UMEMOTO continue; 39806a99fe3SHajimu UMEMOTO 39906a99fe3SHajimu UMEMOTO switch (fields[0][0]) { 40006a99fe3SHajimu UMEMOTO case '#': 40106a99fe3SHajimu UMEMOTO case '\0': 40206a99fe3SHajimu UMEMOTO continue; 40306a99fe3SHajimu UMEMOTO case 'e': 40406a99fe3SHajimu UMEMOTO if ((field_count == 3) && 40506a99fe3SHajimu UMEMOTO (strcmp(fields[0], "enable-cache") == 0) && 40606a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) && 40706a99fe3SHajimu UMEMOTO ((value = get_yesno(fields[2])) != -1)) { 40806a99fe3SHajimu UMEMOTO enable_cache(config, fields[1], value); 40906a99fe3SHajimu UMEMOTO continue; 41006a99fe3SHajimu UMEMOTO } 41106a99fe3SHajimu UMEMOTO break; 41206a99fe3SHajimu UMEMOTO case 'd': 41306a99fe3SHajimu UMEMOTO if ((field_count == 2) && 41406a99fe3SHajimu UMEMOTO (strcmp(fields[0], "debug-level") == 0) && 41506a99fe3SHajimu UMEMOTO ((value = get_number(fields[1], 0, 10)) != -1)) { 41606a99fe3SHajimu UMEMOTO continue; 41706a99fe3SHajimu UMEMOTO } 41806a99fe3SHajimu UMEMOTO break; 41906a99fe3SHajimu UMEMOTO case 'p': 42006a99fe3SHajimu UMEMOTO if ((field_count == 3) && 42106a99fe3SHajimu UMEMOTO (strcmp(fields[0], "positive-time-to-live") == 0) && 42206a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) && 42306a99fe3SHajimu UMEMOTO ((value = get_number(fields[2], 0, -1)) != -1)) { 42486e88c4fSAllan Jude if (value <= 0) { 42586e88c4fSAllan Jude invalid_value = 1; 42686e88c4fSAllan Jude break; 42786e88c4fSAllan Jude } 42806a99fe3SHajimu UMEMOTO set_positive_time_to_live(config, 42906a99fe3SHajimu UMEMOTO fields[1], value); 43006a99fe3SHajimu UMEMOTO continue; 43106a99fe3SHajimu UMEMOTO } else if ((field_count == 3) && 432a397989dSStefan Eßer (strcmp(fields[0], "positive-confidence-threshold") == 0) && 433a397989dSStefan Eßer ((value = get_number(fields[2], 1, -1)) != -1)) { 43486e88c4fSAllan Jude if (value <= 0) { 43586e88c4fSAllan Jude invalid_value = 1; 43686e88c4fSAllan Jude break; 43786e88c4fSAllan Jude } 438a397989dSStefan Eßer set_positive_confidence_threshold(config, 439a397989dSStefan Eßer fields[1], value); 440a397989dSStefan Eßer continue; 441a397989dSStefan Eßer } else if ((field_count == 3) && 44206a99fe3SHajimu UMEMOTO (strcmp(fields[0], "positive-policy") == 0) && 44306a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) && 44406a99fe3SHajimu UMEMOTO ((value = get_policy(fields[2])) != -1)) { 44506a99fe3SHajimu UMEMOTO set_positive_policy(config, fields[1], value); 44606a99fe3SHajimu UMEMOTO continue; 44706a99fe3SHajimu UMEMOTO } else if ((field_count == 3) && 44806a99fe3SHajimu UMEMOTO (strcmp(fields[0], "perform-actual-lookups") == 0) && 44906a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) && 45006a99fe3SHajimu UMEMOTO ((value = get_yesno(fields[2])) != -1)) { 45106a99fe3SHajimu UMEMOTO set_perform_actual_lookups(config, fields[1], 45206a99fe3SHajimu UMEMOTO value); 45306a99fe3SHajimu UMEMOTO continue; 45406a99fe3SHajimu UMEMOTO } 45506a99fe3SHajimu UMEMOTO break; 45606a99fe3SHajimu UMEMOTO case 'n': 45706a99fe3SHajimu UMEMOTO if ((field_count == 3) && 45806a99fe3SHajimu UMEMOTO (strcmp(fields[0], "negative-time-to-live") == 0) && 45906a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) && 46006a99fe3SHajimu UMEMOTO ((value = get_number(fields[2], 0, -1)) != -1)) { 46186e88c4fSAllan Jude if (value <= 0) { 46286e88c4fSAllan Jude invalid_value = 1; 46386e88c4fSAllan Jude break; 46486e88c4fSAllan Jude } 46506a99fe3SHajimu UMEMOTO set_negative_time_to_live(config, 46606a99fe3SHajimu UMEMOTO fields[1], value); 46706a99fe3SHajimu UMEMOTO continue; 46806a99fe3SHajimu UMEMOTO } else if ((field_count == 3) && 469a397989dSStefan Eßer (strcmp(fields[0], "negative-confidence-threshold") == 0) && 470a397989dSStefan Eßer ((value = get_number(fields[2], 1, -1)) != -1)) { 47186e88c4fSAllan Jude if (value <= 0) { 47286e88c4fSAllan Jude invalid_value = 1; 47386e88c4fSAllan Jude break; 47486e88c4fSAllan Jude } 475a397989dSStefan Eßer set_negative_confidence_threshold(config, 476a397989dSStefan Eßer fields[1], value); 477a397989dSStefan Eßer continue; 478a397989dSStefan Eßer } else if ((field_count == 3) && 47906a99fe3SHajimu UMEMOTO (strcmp(fields[0], "negative-policy") == 0) && 48006a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) && 48106a99fe3SHajimu UMEMOTO ((value = get_policy(fields[2])) != -1)) { 48206a99fe3SHajimu UMEMOTO set_negative_policy(config, 48306a99fe3SHajimu UMEMOTO fields[1], value); 48406a99fe3SHajimu UMEMOTO continue; 48506a99fe3SHajimu UMEMOTO } 48606a99fe3SHajimu UMEMOTO break; 48706a99fe3SHajimu UMEMOTO case 's': 48806a99fe3SHajimu UMEMOTO if ((field_count == 3) && 48906a99fe3SHajimu UMEMOTO (strcmp(fields[0], "suggested-size") == 0) && 49006a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) && 49106a99fe3SHajimu UMEMOTO ((value = get_number(fields[2], 1, -1)) != -1)) { 49286e88c4fSAllan Jude if (value <= 0) { 49386e88c4fSAllan Jude invalid_value = 1; 49486e88c4fSAllan Jude break; 49586e88c4fSAllan Jude } 49606a99fe3SHajimu UMEMOTO set_suggested_size(config, fields[1], value); 49706a99fe3SHajimu UMEMOTO continue; 49806a99fe3SHajimu UMEMOTO } 49906a99fe3SHajimu UMEMOTO break; 50006a99fe3SHajimu UMEMOTO case 't': 50106a99fe3SHajimu UMEMOTO if ((field_count == 2) && 50206a99fe3SHajimu UMEMOTO (strcmp(fields[0], "threads") == 0) && 50306a99fe3SHajimu UMEMOTO ((value = get_number(fields[1], 1, -1)) != -1)) { 50406a99fe3SHajimu UMEMOTO set_threads_num(config, value); 50506a99fe3SHajimu UMEMOTO continue; 50606a99fe3SHajimu UMEMOTO } 50706a99fe3SHajimu UMEMOTO break; 50806a99fe3SHajimu UMEMOTO case 'k': 50906a99fe3SHajimu UMEMOTO if ((field_count == 3) && 51006a99fe3SHajimu UMEMOTO (strcmp(fields[0], "keep-hot-count") == 0) && 51106a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) && 51206a99fe3SHajimu UMEMOTO ((value = get_number(fields[2], 0, -1)) != -1)) { 51386e88c4fSAllan Jude if (value < 0) { 51486e88c4fSAllan Jude invalid_value = 1; 51586e88c4fSAllan Jude break; 51686e88c4fSAllan Jude } 51706a99fe3SHajimu UMEMOTO set_keep_hot_count(config, 51806a99fe3SHajimu UMEMOTO fields[1], value); 51906a99fe3SHajimu UMEMOTO continue; 52006a99fe3SHajimu UMEMOTO } 52106a99fe3SHajimu UMEMOTO break; 52206a99fe3SHajimu UMEMOTO case 'c': 52306a99fe3SHajimu UMEMOTO if ((field_count == 3) && 52406a99fe3SHajimu UMEMOTO (strcmp(fields[0], "check-files") == 0) && 52506a99fe3SHajimu UMEMOTO (check_cachename(fields[1]) == 0) && 52606a99fe3SHajimu UMEMOTO ((value = get_yesno(fields[2])) != -1)) { 52706a99fe3SHajimu UMEMOTO check_files(config, 52806a99fe3SHajimu UMEMOTO fields[1], value); 52906a99fe3SHajimu UMEMOTO continue; 53006a99fe3SHajimu UMEMOTO } 53106a99fe3SHajimu UMEMOTO break; 53206a99fe3SHajimu UMEMOTO default: 53306a99fe3SHajimu UMEMOTO break; 53406a99fe3SHajimu UMEMOTO } 53506a99fe3SHajimu UMEMOTO 53686e88c4fSAllan Jude if (invalid_value != 0) { 53786e88c4fSAllan Jude LOG_ERR_2("Invalid value for parameter", 53886e88c4fSAllan Jude "error in file %s on line %d", 53986e88c4fSAllan Jude fname, line_num); 54086e88c4fSAllan Jude *error_str = "invalid value"; 54186e88c4fSAllan Jude } else { 54206a99fe3SHajimu UMEMOTO LOG_ERR_2("config file parser", "error in file " 54306a99fe3SHajimu UMEMOTO "%s on line %d", fname, line_num); 54406a99fe3SHajimu UMEMOTO *error_str = "syntax error"; 54586e88c4fSAllan Jude } 54606a99fe3SHajimu UMEMOTO *error_line = line_num; 54706a99fe3SHajimu UMEMOTO res = -1; 54806a99fe3SHajimu UMEMOTO } 54906a99fe3SHajimu UMEMOTO fclose(fin); 55006a99fe3SHajimu UMEMOTO 55106a99fe3SHajimu UMEMOTO TRACE_OUT(parse_config_file); 55206a99fe3SHajimu UMEMOTO return (res); 55306a99fe3SHajimu UMEMOTO } 554