diff --git a/src/common/parse_config.c b/src/common/parse_config.c index acf7e1424076d2848b016aa385cd323c24e82237..27f756e31db500cd8739f7133568818429444b33 100644 --- a/src/common/parse_config.c +++ b/src/common/parse_config.c @@ -990,6 +990,44 @@ void s_p_hashtbl_merge(s_p_hashtbl_t *to_hashtbl, s_p_hashtbl_t *from_hashtbl) } } +/* + * Returns 1 if the line is parsed cleanly, and 0 otherwise. + */ +int s_p_parse_pair(s_p_hashtbl_t *hashtbl, const char *key, const char *value) +{ + s_p_values_t *p; + char *leftover, *v; + + if ((p = _conf_hashtbl_lookup(hashtbl, key)) == NULL) { + error("Parsing error at unrecognized key: %s", key); + return 0; + } + /* we have value separated from key here so parse it different way */ + while (*value != '\0' && isspace(*value)) + value++; /* skip spaces at start if any */ + if (*value == '"') { /* quoted value */ + v = (char *)value + 1; + leftover = strchr(v, '"'); + if (leftover == NULL) { + error("Parse error in data for key %s: %s", key, value); + return 0; + } + } else { /* unqouted value */ + leftover = v = (char *)value; + while (*leftover != '\0' && !isspace(*leftover)) + leftover++; + } + value = xstrndup(v, leftover - v); + if (*leftover != '\0') + leftover++; + while (*leftover != '\0' && isspace(*leftover)) + leftover++; /* skip trailing spaces */ + _handle_keyvalue_match(p, value, leftover, &leftover); + xfree(value); + + return 1; +} + /* * s_p_get_string * diff --git a/src/common/parse_config.h b/src/common/parse_config.h index d4d6d5a94866d36b69c410fffd8f1e460e858d9c..78d0768b9d18c420bc307589f163f9ee1cccb0d6 100644 --- a/src/common/parse_config.h +++ b/src/common/parse_config.h @@ -188,6 +188,11 @@ void s_p_hashtbl_destroy(s_p_hashtbl_t *hashtbl); int s_p_parse_file(s_p_hashtbl_t *hashtbl, uint32_t *hash_val, char *filename, bool ignore_new); +/* + * Returns 1 if the line is parsed cleanly, and 0 otherwise. + */ +int s_p_parse_pair(s_p_hashtbl_t *hashtbl, const char *key, const char *value); + /* * Returns 1 if the line is parsed cleanly, and 0 otherwise. */ diff --git a/src/common/read_config.c b/src/common/read_config.c index d78e8a5eb0726602ca76d1088b3e13d31b5bc0fe..a1e2914f0801bc6524c042f690f44f8b30f5d6c5 100644 --- a/src/common/read_config.c +++ b/src/common/read_config.c @@ -68,6 +68,7 @@ #include "src/common/parse_spec.h" #include "src/common/parse_time.h" #include "src/common/read_config.h" +#include "src/common/slurm_accounting_storage.h" #include "src/common/slurm_protocol_api.h" #include "src/common/slurm_protocol_defs.h" #include "src/common/slurm_rlimits_info.h" @@ -1984,6 +1985,68 @@ init_slurm_conf (slurm_ctl_conf_t *ctl_conf_ptr) return; } +/* handle config name in form (example) slurmdbd:10.0.0.254:6819 + * + * NOTE: Changes are required in the accounting_storage/slurmdbd plugin in + * order for this to work as desired. Andriy Grytsenko (Massive Solutions + * Limited) has a private accounting_storage plugin with this functionality */ +static int _config_is_storage(s_p_hashtbl_t *hashtbl, char *name) +{ + char *tst, *port; + void *db_conn; + config_key_pair_t *pair; + List config; + ListIterator iter; + int rc = -1; + + tst = strchr(name, ':'); + if (tst == NULL) + return (-1); + port = strrchr(&tst[1], ':'); + if (port == NULL) + return (-1); + conf_ptr->accounting_storage_type = xstrdup_printf("accounting_storage/%.*s", + (int)(tst - name), name); + tst++; + conf_ptr->accounting_storage_host = xstrndup(tst, port - tst); + port++; + debug3("trying retrieve config via %s from host %s on port %s", + conf_ptr->accounting_storage_type, + conf_ptr->accounting_storage_host, port); + conf_ptr->accounting_storage_port = atoi(port); + conf_ptr->plugindir = xstrdup(default_plugin_path); + /* unlock conf_lock and set as initialized before accessing it */ + conf_initialized = true; + pthread_mutex_unlock(&conf_lock); + db_conn = acct_storage_g_get_connection(NULL, 0, false, NULL); + if (db_conn == NULL) + goto end; /* plugin will out error itself */ + config = acct_storage_g_get_config(db_conn); + acct_storage_g_close_connection(&db_conn); /* ignore error code */ + if (config == NULL) { + error("cannot retrieve config from storage"); + goto end; + } + iter = list_iterator_create(config); + while ((pair = list_next(iter)) != NULL) + s_p_parse_pair(hashtbl, pair->name, pair->value); + list_iterator_destroy(iter); + list_destroy(config); + rc = 0; /* done */ + +end: + /* restore status quo now */ + pthread_mutex_lock(&conf_lock); + conf_initialized = false; + xfree(conf_ptr->accounting_storage_type); + xfree(conf_ptr->accounting_storage_host); + xfree(conf_ptr->plugindir); + conf_ptr->accounting_storage_type = NULL; + conf_ptr->accounting_storage_host = NULL; + conf_ptr->plugindir = NULL; + return (rc); +} + /* caller must lock conf_lock */ static void _init_slurm_conf(const char *file_name) { @@ -2003,8 +2066,9 @@ static void _init_slurm_conf(const char *file_name) /* init hash to 0 */ conf_ptr->hash_val = 0; - if (s_p_parse_file(conf_hashtbl, &conf_ptr->hash_val, name, false) - == SLURM_ERROR) + if ((_config_is_storage(conf_hashtbl, name) < 0) && + (s_p_parse_file(conf_hashtbl, &conf_ptr->hash_val, name, false) + == SLURM_ERROR)) fatal("something wrong with opening/reading conf file"); /* s_p_dump_values(conf_hashtbl, slurm_conf_options); */ _validate_and_set_defaults(conf_ptr, conf_hashtbl); diff --git a/src/slurmctld/power_save.c b/src/slurmctld/power_save.c index 755d3dfc5436928710ab0108ecb411462c6239f8..8d08c4e57bc4de754c2831cf7cd942151ba9e699 100644 --- a/src/slurmctld/power_save.c +++ b/src/slurmctld/power_save.c @@ -296,6 +296,7 @@ static pid_t _run_prog(char *prog, char *arg) int i; char program[1024], arg0[1024], arg1[1024], *pname; pid_t child; + slurm_ctl_conf_t *ctlconf; if (prog == NULL) /* disabled, useful for testing */ return -1; @@ -318,6 +319,9 @@ static pid_t _run_prog(char *prog, char *arg) #else setpgrp(); #endif + ctlconf = slurm_conf_lock(); + setenv("SLURM_CONF", ctlconf->slurm_conf, 1); + slurm_conf_unlock(); execl(program, arg0, arg1, NULL); exit(1); } else if (child < 0) {