From 216073a7a0d2fdfc9d88c58b1a2ff83fa76d4628 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Mon, 7 Sep 2009 14:07:14 +0200 Subject: [PATCH 1/1] Databases per-service. A service may now have a 'settings' element which defines settings for this service alone. The database(s) are now managed per-service - including memory (NMEM). --- src/database.c | 24 ++++++++++-------------- src/logic.c | 1 - src/parameters.h | 1 - src/pazpar2.c | 14 ++++---------- src/pazpar2_config.c | 41 ++++++++++++++++++++++++++++++++++++----- src/pazpar2_config.h | 6 +++++- src/settings.c | 28 +++++++++++++++++++++++++--- 7 files changed, 80 insertions(+), 35 deletions(-) diff --git a/src/database.c b/src/database.c index d580c65..1834b78 100644 --- a/src/database.c +++ b/src/database.c @@ -46,8 +46,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #endif static struct host *hosts = 0; // The hosts we know about -static struct database *databases = 0; // The databases we know about -static NMEM nmem = 0; static xmlDoc *get_explain_xml(const char *id) { @@ -116,13 +114,11 @@ static struct database *load_database(const char *id, struct setting *idset; yaz_log(YLOG_LOG, "New database: %s", id); - if (!nmem) - nmem = nmem_create(); if (config && config->targetprofiles && (doc = get_explain_xml(id))) { - explain = zr_read_xml(nmem, xmlDocGetRootElement(doc)); + explain = zr_read_xml(service->nmem, xmlDocGetRootElement(doc)); if (!explain) return 0; } @@ -136,30 +132,30 @@ static struct database *load_database(const char *id, dbname = ""; if (!(host = find_host(hostport))) return 0; - db = nmem_malloc(nmem, sizeof(*db)); + db = nmem_malloc(service->nmem, sizeof(*db)); memset(db, 0, sizeof(*db)); db->host = host; - db->url = nmem_strdup(nmem, id); + db->url = nmem_strdup(service->nmem, id); db->databases = xmalloc(2 * sizeof(char *)); - db->databases[0] = nmem_strdup(nmem, dbname); + db->databases[0] = nmem_strdup(service->nmem, dbname); db->databases[1] = 0; db->errors = 0; db->explain = explain; db->settings = 0; - db->settings = nmem_malloc(nmem, sizeof(struct settings*) * + db->settings = nmem_malloc(service->nmem, sizeof(struct settings*) * settings_num(service)); memset(db->settings, 0, sizeof(struct settings*) * settings_num(service)); - idset = nmem_malloc(nmem, sizeof(*idset)); + idset = nmem_malloc(service->nmem, sizeof(*idset)); idset->precedence = 0; idset->name = "pz:id"; idset->target = idset->value = db->url; idset->next = 0; db->settings[PZ_ID] = idset; - db->next = databases; - databases = db; + db->next = service->databases; + service->databases = db; return db; } @@ -172,7 +168,7 @@ struct database *find_database(const char *id, int new, struct database *p; if (!new) { - for (p = databases; p; p = p->next) + for (p = service->databases; p; p = p->next) if (!strcmp(p->url, id)) return p; } @@ -287,7 +283,7 @@ int predef_grep_databases(void *context, struct conf_service *service, struct database *p; int i = 0; - for (p = databases; p; p = p->next) + for (p = service->databases; p; p = p->next) if (database_match_criteria(p->settings, service, cl)) { (*fun)(context, p); diff --git a/src/logic.c b/src/logic.c index fabf8e6..0a0c59b 100644 --- a/src/logic.c +++ b/src/logic.c @@ -78,7 +78,6 @@ struct parameters global_parameters = { "", "", - "", 0, 0, // dump_records 0, // debug_mode diff --git a/src/parameters.h b/src/parameters.h index 3a73c31..2b15221 100644 --- a/src/parameters.h +++ b/src/parameters.h @@ -26,7 +26,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA struct parameters { char proxy_override[128]; char listener_override[128]; - char settings_path_override[128]; struct conf_server *server; int dump_records; int debug_mode; diff --git a/src/pazpar2.c b/src/pazpar2.c index ae091cc..7ab0d8d 100644 --- a/src/pazpar2.c +++ b/src/pazpar2.c @@ -34,23 +34,17 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include +static char *path_override = 0; + void child_handler(void *data) { - struct conf_service *service = global_parameters.server->service; start_proxy(); - init_settings(service); + config_read_settings(path_override); - if (*global_parameters.settings_path_override) - settings_read(service, global_parameters.settings_path_override); - else if (global_parameters.server->settings) - settings_read(service, global_parameters.server->settings); - else - yaz_log(YLOG_WARN, "No settings-directory specified"); global_parameters.odr_in = odr_createmem(ODR_DECODE); global_parameters.odr_out = odr_createmem(ODR_ENCODE); - pazpar2_event_loop(); } @@ -136,7 +130,7 @@ static int sc_main( pidfile = arg; break; case 't': - strcpy(global_parameters.settings_path_override, arg); + path_override = arg; break; case 'T': session_timeout = atoi(arg); diff --git a/src/pazpar2_config.c b/src/pazpar2_config.c index e796e00..fb793dd 100644 --- a/src/pazpar2_config.c +++ b/src/pazpar2_config.c @@ -36,13 +36,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define CONFIG_NOEXTERNS #include "pazpar2_config.h" - +#include "settings.h" static char confdir[256] = "."; struct conf_config *config = 0; +static char *parse_settings(NMEM nmem, xmlNode *node); + static struct conf_metadata * conf_metadata_assign(NMEM nmem, struct conf_metadata * metadata, @@ -106,6 +108,8 @@ struct conf_service * conf_service_create(int num_metadata, int num_sortkeys, service = nmem_malloc(nmem, sizeof(struct conf_service)); service->nmem = nmem; service->next = 0; + service->settings = 0; + service->databases = 0; service->id = service_id ? nmem_strdup(nmem, service_id) : 0; service->num_metadata = num_metadata; @@ -236,7 +240,18 @@ static struct conf_service *parse_service(xmlNode *node, const char *service_id) { if (n->type != XML_ELEMENT_NODE) continue; - if (!strcmp((const char *) n->name, (const char *) "metadata")) + if (!strcmp((const char *) n->name, "settings")) + { + if (service->settings) + { + yaz_log(YLOG_FATAL, "Can't repeat 'settings'"); + return 0; + } + service->settings = parse_settings(service->nmem, n); + if (!service->settings) + return 0; + } + else if (!strcmp((const char *) n->name, (const char *) "metadata")) { xmlChar *xml_name = xmlGetProp(n, (xmlChar *) "name"); xmlChar *xml_brief = xmlGetProp(n, (xmlChar *) "brief"); @@ -451,7 +466,7 @@ static struct conf_server *parse_server(NMEM nmem, xmlNode *node) server->myurl = 0; server->service = 0; server->next = 0; - server->settings = 0; + server->server_settings = 0; server->relevance_pct = 0; server->sort_pct = 0; server->mergekey_pct = 0; @@ -488,12 +503,12 @@ static struct conf_server *parse_server(NMEM nmem, xmlNode *node) } else if (!strcmp((const char *) n->name, "settings")) { - if (server->settings) + if (server->server_settings) { yaz_log(YLOG_FATAL, "Can't repeat 'settings'"); return 0; } - if (!(server->settings = parse_settings(nmem, n))) + if (!(server->server_settings = parse_settings(nmem, n))) return 0; } else if (!strcmp((const char *) n->name, "relevance")) @@ -693,6 +708,22 @@ int read_config(const char *fname) return 0; } +void config_read_settings(const char *path_override) +{ + struct conf_service *s = config->servers->service; + for (;s ; s = s->next) + { + init_settings(s); + if (path_override) + settings_read(s, path_override); + else if (s->settings) + settings_read(s, s->settings); + else if (config->servers->server_settings) + settings_read(s, config->servers->server_settings); + else + yaz_log(YLOG_WARN, "No settings for service"); + } +} /* * Local variables: diff --git a/src/pazpar2_config.h b/src/pazpar2_config.h index fbfe5c6..e3637f8 100644 --- a/src/pazpar2_config.h +++ b/src/pazpar2_config.h @@ -103,7 +103,9 @@ struct conf_service struct setting_dictionary *dictionary; struct conf_service *next; char *id; + char *settings; NMEM nmem; + struct database *databases; }; struct conf_service * conf_service_create(int num_metadata, int num_sortkeys, @@ -132,6 +134,8 @@ int conf_service_metadata_field_id(struct conf_service *service, const char * na int conf_service_sortkey_field_id(struct conf_service *service, const char * name); +void config_read_settings(const char *path_override); + struct conf_service *locate_service(const char *service_id); struct conf_server @@ -141,7 +145,7 @@ struct conf_server char *proxy_host; int proxy_port; char *myurl; - char *settings; + char *server_settings; pp2_charset_t relevance_pct; pp2_charset_t sort_pct; diff --git a/src/settings.c b/src/settings.c index 74f9d50..44de854 100644 --- a/src/settings.c +++ b/src/settings.c @@ -125,7 +125,7 @@ static int isdir(const char *path) if (stat(path, &st) < 0) { - yaz_log(YLOG_FATAL|YLOG_ERRNO, "%s", path); + yaz_log(YLOG_FATAL|YLOG_ERRNO, "stat %s", path); exit(1); } return st.st_mode & S_IFDIR; @@ -314,6 +314,7 @@ static void prepare_dictionary(struct conf_service *service, dictionary->dict[dictionary->num++] = nmem_strdup(service->nmem, set->name); } + struct update_database_context { struct setting *set; struct conf_service *service; @@ -335,7 +336,7 @@ static void update_database(void *context, struct database *db) return; if ((offset = settings_offset_cprefix(service, set->name)) < 0) - abort(); // Should never get here + return ; // First we determine if this setting is overriding any existing settings // with the same name. @@ -415,12 +416,33 @@ static void initialize_soft_settings(struct conf_service *service) } } +static void prepare_target_dictionary(struct conf_service *service, + struct setting *set) +{ + struct setting_dictionary *dictionary = service->dictionary; + + int i; + char *p; + + // If target address is not wildcard, add the database + if (*set->target && !zurl_wildcard(set->target)) + find_database(set->target, 0, service); + + // Determine if we already have a dictionary entry + if (!strncmp(set->name, "pz:", 3) && (p = strchr(set->name + 3, ':'))) + *(p + 1) = '\0'; + for (i = 0; i < dictionary->num; i++) + if (!strcmp(dictionary->dict[i], set->name)) + return; + yaz_log(YLOG_WARN, "setting %s not configured as metadata", set->name); +} + // If we ever decide we need to be able to specify multiple settings directories, // the two calls to read_settings must be split -- so the dictionary is prepared // for the contents of every directory before the databases are updated. void settings_read(struct conf_service *service, const char *path) { - read_settings(path, service, prepare_dictionary); + read_settings(path, service, prepare_target_dictionary); read_settings(path, service, update_databases); } -- 1.7.10.4