X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fpazpar2_config.c;h=ec87cafff457601301c9936e3df2a03ba6b1294d;hb=03e77a36926d8db74ac218397ddce9ccf181a4d9;hp=818eff4c176ea9b93f58278aeb611d0f8ae9c1a1;hpb=77c88af0dbe56288a1673315822c37bad9579cde;p=pazpar2-moved-to-github.git diff --git a/src/pazpar2_config.c b/src/pazpar2_config.c index 818eff4..ec87caf 100644 --- a/src/pazpar2_config.c +++ b/src/pazpar2_config.c @@ -1,5 +1,5 @@ /* This file is part of Pazpar2. - Copyright (C) 2006-2009 Index Data + Copyright (C) 2006-2010 Index Data Pazpar2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -26,30 +26,20 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include -#include -#include -#include #include #include #include #include +#include -#if HAVE_GLOB_H -#define USE_POSIX_GLOB 1 -#else -#define USE_POSIX_GLOB 0 -#endif - - -#if USE_POSIX_GLOB -#include -#endif #include #include #if HAVE_UNISTD_H #include #endif +#include "ppmutex.h" +#include "incref.h" #include "pazpar2_config.h" #include "settings.h" #include "eventl.h" @@ -59,7 +49,11 @@ struct conf_config { NMEM nmem; /* for conf_config and servers memory */ struct conf_server *servers; + + int no_threads; WRBUF confdir; + iochan_man_t iochan_man; + database_hosts_t database_hosts; }; @@ -122,6 +116,8 @@ static struct conf_service *service_init(struct conf_server *server, NMEM nmem = nmem_create(); service = nmem_malloc(nmem, sizeof(struct conf_service)); + service->mutex = 0; + service->ref_count = 1; service->nmem = nmem; service->next = 0; service->settings = 0; @@ -130,7 +126,7 @@ static struct conf_service *service_init(struct conf_server *server, service->server = server; service->session_timeout = 60; /* default session timeout */ service->z3950_session_timeout = 180; - service->z3950_connect_timeout = 15; + service->z3950_operation_timeout = 30; service->relevance_pct = 0; service->sort_pct = 0; @@ -244,17 +240,28 @@ static void conf_dir_path(struct conf_config *config, WRBUF w, const char *src) wrbuf_puts(w, src); } -static void service_destroy(struct conf_service *service) +void service_destroy(struct conf_service *service) { if (service) { - pp2_charset_destroy(service->relevance_pct); - pp2_charset_destroy(service->sort_pct); - pp2_charset_destroy(service->mergekey_pct); - nmem_destroy(service->nmem); + if (!pazpar2_decref(&service->ref_count, service->mutex)) + { + pp2_charset_destroy(service->relevance_pct); + pp2_charset_destroy(service->sort_pct); + pp2_charset_destroy(service->mergekey_pct); + yaz_mutex_destroy(&service->mutex); + nmem_destroy(service->nmem); + } } } +void service_incref(struct conf_service *service) +{ + yaz_log(YLOG_LOG, "service_incref. p=%p cnt=%d", service, + service->ref_count); + pazpar2_incref(&service->ref_count, service->mutex); +} + static int parse_metadata(struct conf_service *service, xmlNode *n, int *md_node, int *sk_node) { @@ -401,9 +408,19 @@ static int parse_metadata(struct conf_service *service, xmlNode *n, else sortkey_offset = -1; - if (xml_mergekey && strcmp((const char *) xml_mergekey, "no")) + if (xml_mergekey) { - mergekey_type = Metadata_mergekey_yes; + if (!strcmp((const char *) xml_mergekey, "required")) + mergekey_type = Metadata_mergekey_required; + else if (!strcmp((const char *) xml_mergekey, "optional")) + mergekey_type = Metadata_mergekey_optional; + else if (!strcmp((const char *) xml_mergekey, "no")) + mergekey_type = Metadata_mergekey_no; + else + { + yaz_log(YLOG_FATAL, "Unknown value for mergekey: %s", xml_mergekey); + return -1; + } } @@ -422,13 +439,14 @@ static int parse_metadata(struct conf_service *service, xmlNode *n, xmlFree(xml_termlist); xmlFree(xml_rank); xmlFree(xml_setting); + xmlFree(xml_mergekey); (*md_node)++; return 0; } -static struct conf_service *service_create(struct conf_server *server, - xmlNode *node, - const char *service_id) +static struct conf_service *service_create_static(struct conf_server *server, + xmlNode *node, + const char *service_id) { xmlNode *n; int md_node = 0; @@ -470,14 +488,14 @@ static struct conf_service *service_create(struct conf_server *server, return 0; } } - src = xmlGetProp(n, (xmlChar *) "z3950_connect"); + src = xmlGetProp(n, (xmlChar *) "z3950_operation"); if (src) { - service->z3950_connect_timeout = atoi((const char *) src); + service->z3950_operation_timeout = atoi((const char *) src); xmlFree(src); if (service->z3950_session_timeout < 9) { - yaz_log(YLOG_FATAL, "Z39.50 connect timeout out of range"); + yaz_log(YLOG_FATAL, "Z39.50 operation timeout out of range"); return 0; } } @@ -614,77 +632,89 @@ static char *parse_settings(struct conf_config *config, return r; } -static void inherit_server_settings(struct conf_server *server) +static void inherit_server_settings(struct conf_service *s) { - struct conf_service *s; - for (s = server->service; s; s = s->next) + struct conf_server *server = s->server; + if (!s->dictionary) /* service has no config settings ? */ { - if (!s->dictionary) /* service has no config settings ? */ + if (server->server_settings) { - if (server->server_settings) - { - /* inherit settings from server */ - init_settings(s); - settings_read_file(s, server->server_settings, 1); - settings_read_file(s, server->server_settings, 2); - } - else - { - yaz_log(YLOG_WARN, "service '%s' has no settings", - s->id ? s->id : "unnamed"); - init_settings(s); - } + /* inherit settings from server */ + init_settings(s); + settings_read_file(s, server->server_settings, 1); + settings_read_file(s, server->server_settings, 2); } - - /* use relevance/sort/mergekey from server if not defined - for this service.. */ - if (!s->relevance_pct) + else { - if (server->relevance_pct) - { - s->relevance_pct = server->relevance_pct; - pp2_charset_incref(s->relevance_pct); - } - else - s->relevance_pct = pp2_charset_create(0); + yaz_log(YLOG_WARN, "service '%s' has no settings", + s->id ? s->id : "unnamed"); + init_settings(s); } - - if (!s->sort_pct) + } + + /* use relevance/sort/mergekey from server if not defined + for this service.. */ + if (!s->relevance_pct) + { + if (server->relevance_pct) { - if (server->sort_pct) - { - s->sort_pct = server->sort_pct; - pp2_charset_incref(s->sort_pct); - } - else - s->sort_pct = pp2_charset_create(0); + s->relevance_pct = server->relevance_pct; + pp2_charset_incref(s->relevance_pct); } - - if (!s->mergekey_pct) + else + s->relevance_pct = pp2_charset_create(0); + } + + if (!s->sort_pct) + { + if (server->sort_pct) { - if (server->mergekey_pct) - { - s->mergekey_pct = server->mergekey_pct; - pp2_charset_incref(s->mergekey_pct); - } - else - s->mergekey_pct = pp2_charset_create(0); + s->sort_pct = server->sort_pct; + pp2_charset_incref(s->sort_pct); + } + else + s->sort_pct = pp2_charset_create(0); + } + + if (!s->mergekey_pct) + { + if (server->mergekey_pct) + { + s->mergekey_pct = server->mergekey_pct; + pp2_charset_incref(s->mergekey_pct); } + else + s->mergekey_pct = pp2_charset_create(0); } } +struct conf_service *service_create(struct conf_server *server, + xmlNode *node) +{ + struct conf_service *service = service_create_static(server, + node, 0); + if (service) + { + inherit_server_settings(service); + resolve_databases(service); + assert(service->mutex == 0); + pazpar2_mutex_create(&service->mutex, "conf"); + } + return service; +} + static struct conf_server *server_create(struct conf_config *config, NMEM nmem, xmlNode *node) { xmlNode *n; struct conf_server *server = nmem_malloc(nmem, sizeof(struct conf_server)); + xmlChar *server_id = xmlGetProp(node, (xmlChar *) "id"); server->host = 0; server->port = 0; server->proxy_host = 0; server->proxy_port = 0; server->myurl = 0; - server->proxy_addr = 0; server->service = 0; server->config = config; server->next = 0; @@ -692,7 +722,17 @@ static struct conf_server *server_create(struct conf_config *config, server->sort_pct = 0; server->mergekey_pct = 0; server->server_settings = 0; + server->http_server = 0; + server->iochan_man = 0; + server->database_hosts = 0; + if (server_id) + { + server->server_id = nmem_strdup(nmem, (const char *)server_id); + xmlFree(server_id); + } + else + server->server_id = 0; for (n = node->children; n; n = n->next) { if (n->type != XML_ELEMENT_NODE) @@ -766,8 +806,7 @@ static struct conf_server *server_create(struct conf_config *config, } else if (!(*sp)->id && !service_id) { - yaz_log(YLOG_FATAL, "Duplicate unnamed service '%s'", - service_id); + yaz_log(YLOG_FATAL, "Duplicate unnamed service"); break; } @@ -778,8 +817,8 @@ static struct conf_server *server_create(struct conf_config *config, } else { - struct conf_service *s = service_create(server, n, - service_id); + struct conf_service *s = service_create_static(server, n, + service_id); xmlFree(service_id); if (!s) return 0; @@ -792,21 +831,21 @@ static struct conf_server *server_create(struct conf_config *config, return 0; } } - inherit_server_settings(server); + if (server->service) + { + struct conf_service *s; + for (s = server->service; s; s = s->next) + inherit_server_settings(s); + } return server; } -xsltStylesheet *conf_load_stylesheet(struct conf_service *service, - const char *fname) +WRBUF conf_get_fname(struct conf_config *config, const char *fname) { - struct conf_config *config = service->server->config; WRBUF w = wrbuf_alloc(); - xsltStylesheet *s; conf_dir_path(config, w, fname); - s = xsltParseStylesheetFile((xmlChar *) wrbuf_cstr(w)); - wrbuf_destroy(w); - return s; + return w; } static struct conf_targetprofiles *parse_targetprofiles(NMEM nmem, @@ -852,10 +891,12 @@ struct conf_service *locate_service(struct conf_server *server, struct conf_service *s = server->service; for (; s; s = s->next) if (s->id && service_id && 0 == strcmp(s->id, service_id)) - return s; + break; else if (!s->id && !service_id) - return s; - return 0; + break; + if (s) + service_incref(s); + return s; } @@ -875,6 +916,15 @@ static int parse_config(struct conf_config *config, xmlNode *root) tmp->next = config->servers; config->servers = tmp; } + else if (!strcmp((const char *) n->name, "threads")) + { + xmlChar *number = xmlGetProp(n, (xmlChar *) "number"); + if (number) + { + config->no_threads = atoi((const char *) number); + xmlFree(number); + } + } else if (!strcmp((const char *) n->name, "targetprofiles")) { yaz_log(YLOG_FATAL, "targetprofiles unsupported here. Must be part of service"); @@ -890,114 +940,6 @@ static int parse_config(struct conf_config *config, xmlNode *root) return 0; } -static int process_config_includes(struct conf_config *config, xmlNode *n); - -static int config_include_one(struct conf_config *config, xmlNode **sib, - const char *path) -{ - struct stat st; - if (stat(path, &st) < 0) - { - yaz_log(YLOG_FATAL|YLOG_ERRNO, "stat %s", path); - return -1; - } - else - { - if ((st.st_mode & S_IFMT) == S_IFREG) - { - xmlDoc *doc = xmlParseFile(path); - if (doc) - { - xmlNodePtr t = xmlDocGetRootElement(doc); - int ret = process_config_includes(config, t); - *sib = xmlAddNextSibling(*sib, xmlCopyNode(t, 1)); - xmlFreeDoc(doc); - if (ret) - return -1; - } - else - { - yaz_log(YLOG_FATAL, "Could not parse %s", path); - return -1; - } - } - } - return 0; -} - -static int config_include_src(struct conf_config *config, xmlNode **np, - const char *src) -{ - int ret = 0; /* return code. OK so far */ - WRBUF w = wrbuf_alloc(); - xmlNodePtr sib; /* our sibling that we append */ - xmlNodePtr c; /* tmp node */ - - wrbuf_printf(w, " begin include src=\"%s\" ", src); - - /* replace include element with a 'begin' comment */ - sib = xmlNewComment((const xmlChar *) wrbuf_cstr(w)); - xmlReplaceNode(*np, sib); - - xmlFreeNode(*np); - - wrbuf_rewind(w); - conf_dir_path(config, w, src); -#if USE_POSIX_GLOB - { - size_t i; - glob_t glob_res; - glob(wrbuf_cstr(w), 0 /* flags */, 0 /* errfunc */, &glob_res); - - for (i = 0; ret == 0 && i < glob_res.gl_pathc; i++) - { - const char *path = glob_res.gl_pathv[i]; - ret = config_include_one(config, &sib, path); - } - globfree(&glob_res); - } -#else - ret = config_include_one(config, &sib, wrbuf_cstr(w)); -#endif - wrbuf_rewind(w); - wrbuf_printf(w, " end include src=\"%s\" ", src); - c = xmlNewComment((const xmlChar *) wrbuf_cstr(w)); - sib = xmlAddNextSibling(sib, c); - - *np = sib; - wrbuf_destroy(w); - return ret; -} - -static int process_config_includes(struct conf_config *config, xmlNode *n) -{ - for (; n; n = n->next) - { - if (n->type == XML_ELEMENT_NODE) - { - if (!strcmp((const char *) n->name, "include")) - { - xmlChar *src = xmlGetProp(n, (xmlChar *) "src"); - if (src) - { - int ret = config_include_src(config, &n, - (const char *) src); - xmlFree(src); - if (ret) - return ret; - - } - } - else - { - if (process_config_includes(config, n->children)) - return -1; - } - } - } - return 0; -} - struct conf_config *config_create(const char *fname, int verbose) { xmlDoc *doc = xmlParseFile(fname); @@ -1018,6 +960,8 @@ struct conf_config *config_create(const char *fname, int verbose) config->nmem = nmem; config->servers = 0; + config->no_threads = 0; + config->iochan_man = 0; config->confdir = wrbuf_alloc(); if ((p = strrchr(fname, @@ -1034,14 +978,18 @@ struct conf_config *config_create(const char *fname, int verbose) wrbuf_puts(config->confdir, ""); n = xmlDocGetRootElement(doc); - r = process_config_includes(config, n); + r = yaz_xml_include_simple(n, wrbuf_cstr(config->confdir)); if (r == 0) /* OK */ { if (verbose) { yaz_log(YLOG_LOG, "Configuration %s after include processing", fname); +#if LIBXML_VERSION >= 20600 xmlDocFormatDump(yaz_log_file(), doc, 0); +#else + xmlDocDump(yaz_log_file(), doc); +#endif } r = parse_config(config, n); } @@ -1067,6 +1015,8 @@ void server_destroy(struct conf_server *server) pp2_charset_destroy(server->relevance_pct); pp2_charset_destroy(server->sort_pct); pp2_charset_destroy(server->mergekey_pct); + yaz_log(YLOG_LOG, "server_destroy server=%p", server); + http_server_destroy(server->http_server); } void config_destroy(struct conf_config *config) @@ -1074,12 +1024,15 @@ void config_destroy(struct conf_config *config) if (config) { struct conf_server *server = config->servers; + iochan_man_destroy(&config->iochan_man); while (server) { struct conf_server *s_next = server->next; server_destroy(server); server = s_next; } + database_hosts_destroy(&config->database_hosts); + wrbuf_destroy(config->confdir); nmem_destroy(config->nmem); } @@ -1092,25 +1045,40 @@ void config_stop_listeners(struct conf_config *conf) http_close_server(ser); } -void config_start_databases(struct conf_config *conf) +void config_process_events(struct conf_config *conf) { struct conf_server *ser; + + conf->database_hosts = database_hosts_create(); for (ser = conf->servers; ser; ser = ser->next) { struct conf_service *s = ser->service; + + ser->database_hosts = conf->database_hosts; + for (;s ; s = s->next) + { resolve_databases(s); + assert(s->mutex == 0); + pazpar2_mutex_create(&s->mutex, "service"); + } + http_mutex_init(ser); } + iochan_man_events(conf->iochan_man); } int config_start_listeners(struct conf_config *conf, const char *listener_override) { struct conf_server *ser; + + conf->iochan_man = iochan_man_create(conf->no_threads); for (ser = conf->servers; ser; ser = ser->next) { WRBUF w = wrbuf_alloc(); int r; + + ser->iochan_man = conf->iochan_man; if (listener_override) { wrbuf_puts(w, listener_override);