/src/common/read_config.c
C | 3796 lines | 3096 code | 402 blank | 298 comment | 860 complexity | 3b5a181d3bc89b4cb7479660715e6b7c MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
Large files files are truncated, but you can click here to view the full file
- /*****************************************************************************\
- * read_config.c - read the overall slurm configuration file
- *****************************************************************************
- * Copyright (C) 2002-2007 The Regents of the University of California.
- * Copyright (C) 2008-2010 Lawrence Livermore National Security.
- * Portions Copyright (C) 2008 Vijay Ramasubramanian.
- * Portions Copyright (C) 2010 SchedMD <http://www.schedmd.com>.
- * Portions (boards) copyright (C) 2012 Bull, <rod.schultz@bull.com>
- * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
- * Written by Morris Jette <jette1@llnl.gov>.
- * CODE-OCEC-09-009. All rights reserved.
- *
- * This file is part of SLURM, a resource management program.
- * For details, see <http://www.schedmd.com/slurmdocs/>.
- * Please also read the included file: DISCLAIMER.
- *
- * SLURM 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
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * In addition, as a special exception, the copyright holders give permission
- * to link the code of portions of this program with the OpenSSL library under
- * certain conditions as described in each individual source file, and
- * distribute linked combinations including the two. You must obey the GNU
- * General Public License in all respects for all of the code used other than
- * OpenSSL. If you modify file(s) with this exception, you may extend this
- * exception to your version of the file(s), but you are not obligated to do
- * so. If you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files in
- * the program, then also delete it here.
- *
- * SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along
- * with SLURM; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- \*****************************************************************************/
- #ifdef HAVE_CONFIG_H
- # include "config.h"
- #endif
- #include <arpa/inet.h>
- #include <assert.h>
- #include <ctype.h>
- #include <errno.h>
- #include <limits.h>
- #include <netdb.h>
- #include <netinet/in.h>
- #include <pthread.h>
- #include <pwd.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <time.h>
- #include <unistd.h>
- #include "slurm/slurm.h"
- #include "src/common/hostlist.h"
- #include "src/common/log.h"
- #include "src/common/macros.h"
- #include "src/common/node_conf.h"
- #include "src/common/parse_config.h"
- #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"
- #include "src/common/slurm_selecttype_info.h"
- #include "src/common/strlcpy.h"
- #include "src/common/uid.h"
- #include "src/common/util-net.h"
- #include "src/common/xmalloc.h"
- #include "src/common/xstring.h"
- /*
- ** Define slurm-specific aliases for use by plugins, see slurm_xlator.h
- ** for details.
- */
- strong_alias(destroy_config_key_pair, slurm_destroy_config_key_pair);
- strong_alias(sort_key_pairs, slurm_sort_key_pairs);
- /* Instantiation of the "extern slurm_ctl_conf_t slurmcltd_conf"
- * found in slurmctld.h */
- slurm_ctl_conf_t slurmctld_conf;
- static pthread_mutex_t conf_lock = PTHREAD_MUTEX_INITIALIZER;
- static s_p_hashtbl_t *conf_hashtbl = NULL;
- static slurm_ctl_conf_t *conf_ptr = &slurmctld_conf;
- static bool conf_initialized = false;
- static s_p_hashtbl_t *default_frontend_tbl;
- static s_p_hashtbl_t *default_nodename_tbl;
- static s_p_hashtbl_t *default_partition_tbl;
- inline static void _normalize_debug_level(uint16_t *level);
- static void _init_slurm_conf(const char *file_name);
- #define NAME_HASH_LEN 512
- typedef struct names_ll_s {
- char *alias; /* NodeName */
- char *hostname; /* NodeHostname */
- char *address; /* NodeAddr */
- uint16_t port;
- uint16_t cpus;
- uint16_t boards;
- uint16_t sockets;
- uint16_t cores;
- uint16_t threads;
- slurm_addr_t addr;
- bool addr_initialized;
- struct names_ll_s *next_alias;
- struct names_ll_s *next_hostname;
- } names_ll_t;
- static bool nodehash_initialized = false;
- static names_ll_t *host_to_node_hashtbl[NAME_HASH_LEN] = {NULL};
- static names_ll_t *node_to_host_hashtbl[NAME_HASH_LEN] = {NULL};
- static void _destroy_nodename(void *ptr);
- static int _parse_frontend(void **dest, slurm_parser_enum_t type,
- const char *key, const char *value,
- const char *line, char **leftover);
- static int _parse_nodename(void **dest, slurm_parser_enum_t type,
- const char *key, const char *value,
- const char *line, char **leftover);
- static bool _is_valid_path(char *path, char *msg);
- static int _parse_partitionname(void **dest, slurm_parser_enum_t type,
- const char *key, const char *value,
- const char *line, char **leftover);
- static void _destroy_partitionname(void *ptr);
- static int _parse_downnodes(void **dest, slurm_parser_enum_t type,
- const char *key, const char *value,
- const char *line, char **leftover);
- static void _destroy_downnodes(void *ptr);
- static int _defunct_option(void **dest, slurm_parser_enum_t type,
- const char *key, const char *value,
- const char *line, char **leftover);
- static void _validate_and_set_defaults(slurm_ctl_conf_t *conf,
- s_p_hashtbl_t *hashtbl);
- s_p_options_t slurm_conf_options[] = {
- {"AccountingStorageEnforce", S_P_STRING},
- {"AccountingStorageHost", S_P_STRING},
- {"AccountingStorageBackupHost", S_P_STRING},
- {"AccountingStorageLoc", S_P_STRING},
- {"AccountingStoragePass", S_P_STRING},
- {"AccountingStoragePort", S_P_UINT32},
- {"AccountingStorageType", S_P_STRING},
- {"AccountingStorageUser", S_P_STRING},
- {"AccountingStoreJobComment", S_P_BOOLEAN},
- {"AcctGatherEnergyType", S_P_STRING},
- {"AcctGatherNodeFreq", S_P_UINT16},
- {"AuthType", S_P_STRING},
- {"BackupAddr", S_P_STRING},
- {"BackupController", S_P_STRING},
- {"BatchStartTimeout", S_P_UINT16},
- {"CheckpointType", S_P_STRING},
- {"CacheGroups", S_P_UINT16},
- {"ClusterName", S_P_STRING},
- {"CompleteWait", S_P_UINT16},
- {"ControlAddr", S_P_STRING},
- {"ControlMachine", S_P_STRING},
- {"CryptoType", S_P_STRING},
- {"DebugFlags", S_P_STRING},
- {"DefaultStorageHost", S_P_STRING},
- {"DefaultStorageLoc", S_P_STRING},
- {"DefaultStoragePass", S_P_STRING},
- {"DefaultStoragePort", S_P_UINT32},
- {"DefaultStorageType", S_P_STRING},
- {"DefaultStorageUser", S_P_STRING},
- {"DefMemPerCPU", S_P_UINT32},
- {"DefMemPerNode", S_P_UINT32},
- {"DisableRootJobs", S_P_BOOLEAN},
- {"EnforcePartLimits", S_P_BOOLEAN},
- {"Epilog", S_P_STRING},
- {"EpilogMsgTime", S_P_UINT32},
- {"EpilogSlurmctld", S_P_STRING},
- {"FastSchedule", S_P_UINT16},
- {"FirstJobId", S_P_UINT32},
- {"GetEnvTimeout", S_P_UINT16},
- {"GresTypes", S_P_STRING},
- {"GroupUpdateForce", S_P_UINT16},
- {"GroupUpdateTime", S_P_UINT16},
- {"HealthCheckInterval", S_P_UINT16},
- {"HealthCheckProgram", S_P_STRING},
- {"InactiveLimit", S_P_UINT16},
- {"JobAcctGatherType", S_P_STRING},
- {"JobAcctGatherFrequency", S_P_UINT16},
- {"JobCheckpointDir", S_P_STRING},
- {"JobCompHost", S_P_STRING},
- {"JobCompLoc", S_P_STRING},
- {"JobCompPass", S_P_STRING},
- {"JobCompPort", S_P_UINT32},
- {"JobCompType", S_P_STRING},
- {"JobCompUser", S_P_STRING},
- {"JobCredentialPrivateKey", S_P_STRING},
- {"JobCredentialPublicCertificate", S_P_STRING},
- {"JobFileAppend", S_P_UINT16},
- {"JobRequeue", S_P_UINT16},
- {"JobSubmitPlugins", S_P_STRING},
- {"KillOnBadExit", S_P_UINT16},
- {"KillWait", S_P_UINT16},
- {"LaunchType", S_P_STRING},
- {"Licenses", S_P_STRING},
- {"MailProg", S_P_STRING},
- {"MaxJobCount", S_P_UINT32},
- {"MaxJobId", S_P_UINT32},
- {"MaxMemPerCPU", S_P_UINT32},
- {"MaxMemPerNode", S_P_UINT32},
- {"MaxStepCount", S_P_UINT32},
- {"MaxTasksPerNode", S_P_UINT16},
- {"MessageTimeout", S_P_UINT16},
- {"MinJobAge", S_P_UINT16},
- {"MpiDefault", S_P_STRING},
- {"MpiParams", S_P_STRING},
- {"OverTimeLimit", S_P_UINT16},
- {"PluginDir", S_P_STRING},
- {"PlugStackConfig", S_P_STRING},
- {"PreemptMode", S_P_STRING},
- {"PreemptType", S_P_STRING},
- {"PriorityDecayHalfLife", S_P_STRING},
- {"PriorityCalcPeriod", S_P_STRING},
- {"PriorityFavorSmall", S_P_BOOLEAN},
- {"PriorityMaxAge", S_P_STRING},
- {"PriorityUsageResetPeriod", S_P_STRING},
- {"PriorityType", S_P_STRING},
- {"PriorityFlags", S_P_STRING},
- {"PriorityWeightAge", S_P_UINT32},
- {"PriorityWeightFairshare", S_P_UINT32},
- {"PriorityWeightJobSize", S_P_UINT32},
- {"PriorityWeightPartition", S_P_UINT32},
- {"PriorityWeightQOS", S_P_UINT32},
- {"PrivateData", S_P_STRING},
- {"ProctrackType", S_P_STRING},
- {"Prolog", S_P_STRING},
- {"PrologSlurmctld", S_P_STRING},
- {"PropagatePrioProcess", S_P_UINT16},
- {"PropagateResourceLimitsExcept", S_P_STRING},
- {"PropagateResourceLimits", S_P_STRING},
- {"RebootProgram", S_P_STRING},
- {"ReconfigFlags", S_P_STRING},
- {"ResumeProgram", S_P_STRING},
- {"ResumeRate", S_P_UINT16},
- {"ResumeTimeout", S_P_UINT16},
- {"ResvOverRun", S_P_UINT16},
- {"ReturnToService", S_P_UINT16},
- {"SallocDefaultCommand", S_P_STRING},
- {"SchedulerAuth", S_P_STRING, _defunct_option},
- {"SchedulerParameters", S_P_STRING},
- {"SchedulerPort", S_P_UINT16},
- {"SchedulerRootFilter", S_P_UINT16},
- {"SchedulerTimeSlice", S_P_UINT16},
- {"SchedulerType", S_P_STRING},
- {"SelectType", S_P_STRING},
- {"SelectTypeParameters", S_P_STRING},
- {"SlurmUser", S_P_STRING},
- {"SlurmdUser", S_P_STRING},
- {"SlurmctldDebug", S_P_STRING},
- {"SlurmctldLogFile", S_P_STRING},
- {"SlurmctldPidFile", S_P_STRING},
- {"SlurmctldPort", S_P_STRING},
- {"SlurmctldTimeout", S_P_UINT16},
- {"SlurmdDebug", S_P_STRING},
- {"SlurmdLogFile", S_P_STRING},
- {"SlurmdPidFile", S_P_STRING},
- {"SlurmdPort", S_P_UINT32},
- {"SlurmdSpoolDir", S_P_STRING},
- {"SlurmdTimeout", S_P_UINT16},
- {"SlurmSchedLogFile", S_P_STRING},
- {"SlurmSchedLogLevel", S_P_UINT16},
- {"SrunEpilog", S_P_STRING},
- {"SrunProlog", S_P_STRING},
- {"StateSaveLocation", S_P_STRING},
- {"SuspendExcNodes", S_P_STRING},
- {"SuspendExcParts", S_P_STRING},
- {"SuspendProgram", S_P_STRING},
- {"SuspendRate", S_P_UINT16},
- {"SuspendTime", S_P_LONG},
- {"SuspendTimeout", S_P_UINT16},
- {"SwitchType", S_P_STRING},
- {"TaskEpilog", S_P_STRING},
- {"TaskProlog", S_P_STRING},
- {"TaskPlugin", S_P_STRING},
- {"TaskPluginParam", S_P_STRING},
- {"TmpFS", S_P_STRING},
- {"TopologyPlugin", S_P_STRING},
- {"TrackWCKey", S_P_BOOLEAN},
- {"TreeWidth", S_P_UINT16},
- {"UnkillableStepProgram", S_P_STRING},
- {"UnkillableStepTimeout", S_P_UINT16},
- {"UsePAM", S_P_BOOLEAN},
- {"VSizeFactor", S_P_UINT16},
- {"WaitTime", S_P_UINT16},
- {"FrontendName", S_P_ARRAY, _parse_frontend, destroy_frontend},
- {"NodeName", S_P_ARRAY, _parse_nodename, _destroy_nodename},
- {"PartitionName", S_P_ARRAY, _parse_partitionname,
- _destroy_partitionname},
- {"DownNodes", S_P_ARRAY, _parse_downnodes, _destroy_downnodes},
- {NULL}
- };
- static bool _is_valid_path (char *path, char *msg)
- {
- /*
- * Allocate temporary space for walking the list of dirs:
- */
- int pathlen = strlen (path);
- char *buf = xmalloc (pathlen + 2);
- char *p, *entry;
- if (strlcpy (buf, path, pathlen + 1) > pathlen + 1) {
- error ("is_valid_path: Failed to copy path!");
- goto out_false;
- }
- /*
- * Ensure the path ends with a ':'
- */
- if (buf [pathlen - 1] != ':') {
- buf [pathlen] = ':';
- buf [pathlen + 1] = '\0';
- }
- entry = buf;
- while ((p = strchr (entry, ':'))) {
- struct stat st;
- /*
- * NUL terminate colon and advance p
- */
- *(p++) = '\0';
- /*
- * Check to see if current path element is a valid dir
- */
- if (stat (entry, &st) < 0) {
- error ("%s: %s: %m", msg, entry);
- goto out_false;
- }
- else if (!S_ISDIR (st.st_mode)) {
- error ("%s: %s: Not a directory", msg, entry);
- goto out_false;
- }
- /*
- * Otherwise path element is valid, continue..
- */
- entry = p;
- }
- xfree (buf);
- return true;
- out_false:
- xfree (buf);
- return false;
- }
- static int _defunct_option(void **dest, slurm_parser_enum_t type,
- const char *key, const char *value,
- const char *line, char **leftover)
- {
- error("The option \"%s\" is defunct, see man slurm.conf.", key);
- return 0;
- }
- #if (SYSTEM_DIMENSIONS > 1)
- /* Used to get the general name of the machine, used primarily
- * for bluegene systems. Not in general use because some systems
- * have multiple prefix's such as foo[1-1000],bar[1-1000].
- */
- /* Caller must be holding slurm_conf_lock() */
- static void _set_node_prefix(const char *nodenames)
- {
- int i;
- char *tmp;
- xassert(nodenames != NULL);
- for (i = 1; nodenames[i] != '\0'; i++) {
- if((nodenames[i-1] == '[')
- || (nodenames[i-1] <= '9'
- && nodenames[i-1] >= '0'))
- break;
- }
- if(i == 1) {
- error("In your Node definition in your slurm.conf you "
- "gave a nodelist '%s' without a prefix. "
- "Please try something like bg%s.", nodenames, nodenames);
- }
- xfree(conf_ptr->node_prefix);
- if(nodenames[i] == '\0')
- conf_ptr->node_prefix = xstrdup(nodenames);
- else {
- tmp = xmalloc(sizeof(char)*i+1);
- memset(tmp, 0, i+1);
- snprintf(tmp, i, "%s", nodenames);
- conf_ptr->node_prefix = tmp;
- tmp = NULL;
- }
- debug3("Prefix is %s %s %d", conf_ptr->node_prefix, nodenames, i);
- }
- #endif /* SYSTEM_DIMENSIONS > 1 */
- static int _parse_frontend(void **dest, slurm_parser_enum_t type,
- const char *key, const char *value,
- const char *line, char **leftover)
- {
- s_p_hashtbl_t *tbl, *dflt;
- slurm_conf_frontend_t *n;
- char *node_state = NULL;
- static s_p_options_t _frontend_options[] = {
- {"FrontendAddr", S_P_STRING},
- {"Port", S_P_UINT16},
- {"Reason", S_P_STRING},
- {"State", S_P_STRING},
- {NULL}
- };
- #ifndef HAVE_FRONT_END
- fatal("Use of FrontendName in slurm.conf without SLURM being "
- "configured/built with the --enable-front-end option");
- #endif
- tbl = s_p_hashtbl_create(_frontend_options);
- s_p_parse_line(tbl, *leftover, leftover);
- /* s_p_dump_values(tbl, _frontend_options); */
- if (strcasecmp(value, "DEFAULT") == 0) {
- char *tmp;
- if (s_p_get_string(&tmp, "FrontendAddr", tbl)) {
- error("FrontendAddr not allowed with "
- "FrontendName=DEFAULT");
- xfree(tmp);
- s_p_hashtbl_destroy(tbl);
- return -1;
- }
- if (default_frontend_tbl != NULL) {
- s_p_hashtbl_merge(tbl, default_frontend_tbl);
- s_p_hashtbl_destroy(default_frontend_tbl);
- }
- default_frontend_tbl = tbl;
- return 0;
- } else {
- n = xmalloc(sizeof(slurm_conf_frontend_t));
- dflt = default_frontend_tbl;
- n->frontends = xstrdup(value);
- if (!s_p_get_string(&n->addresses, "FrontendAddr", tbl))
- n->addresses = xstrdup(n->frontends);
- if (!s_p_get_uint16(&n->port, "Port", tbl) &&
- !s_p_get_uint16(&n->port, "Port", dflt)) {
- /* This gets resolved in slurm_conf_get_port()
- * and slurm_conf_get_addr(). For now just
- * leave with a value of zero */
- n->port = 0;
- }
- if (!s_p_get_string(&n->reason, "Reason", tbl))
- s_p_get_string(&n->reason, "Reason", dflt);
- if (!s_p_get_string(&node_state, "State", tbl) &&
- !s_p_get_string(&node_state, "State", dflt)) {
- n->node_state = NODE_STATE_UNKNOWN;
- } else {
- n->node_state = state_str2int(node_state,
- (char *) value);
- if (n->node_state == (uint16_t) NO_VAL)
- n->node_state = NODE_STATE_UNKNOWN;
- xfree(node_state);
- }
- *dest = (void *)n;
- s_p_hashtbl_destroy(tbl);
- return 1;
- }
- /* should not get here */
- }
- static int _parse_nodename(void **dest, slurm_parser_enum_t type,
- const char *key, const char *value,
- const char *line, char **leftover)
- {
- s_p_hashtbl_t *tbl, *dflt;
- slurm_conf_node_t *n;
- int computed_procs;
- static s_p_options_t _nodename_options[] = {
- {"Boards", S_P_UINT16},
- {"CoresPerSocket", S_P_UINT16},
- {"CPUs", S_P_UINT16},
- {"Feature", S_P_STRING},
- {"Gres", S_P_STRING},
- {"NodeAddr", S_P_STRING},
- {"NodeHostname", S_P_STRING},
- {"Port", S_P_STRING},
- {"Procs", S_P_UINT16},
- {"RealMemory", S_P_UINT32},
- {"Reason", S_P_STRING},
- {"Sockets", S_P_UINT16},
- {"SocketsPerBoard", S_P_UINT16},
- {"State", S_P_STRING},
- {"ThreadsPerCore", S_P_UINT16},
- {"TmpDisk", S_P_UINT32},
- {"Weight", S_P_UINT32},
- {NULL}
- };
- tbl = s_p_hashtbl_create(_nodename_options);
- s_p_parse_line(tbl, *leftover, leftover);
- /* s_p_dump_values(tbl, _nodename_options); */
- if (strcasecmp(value, "DEFAULT") == 0) {
- char *tmp;
- if (s_p_get_string(&tmp, "NodeHostname", tbl)) {
- error("NodeHostname not allowed with "
- "NodeName=DEFAULT");
- xfree(tmp);
- s_p_hashtbl_destroy(tbl);
- return -1;
- }
- if (s_p_get_string(&tmp, "NodeAddr", tbl)) {
- error("NodeAddr not allowed with NodeName=DEFAULT");
- xfree(tmp);
- s_p_hashtbl_destroy(tbl);
- return -1;
- }
- if (default_nodename_tbl != NULL) {
- s_p_hashtbl_merge(tbl, default_nodename_tbl);
- s_p_hashtbl_destroy(default_nodename_tbl);
- }
- default_nodename_tbl = tbl;
- return 0;
- } else {
- bool no_cpus = false;
- bool no_boards = false;
- bool no_sockets = false;
- bool no_cores = false;
- bool no_threads = false;
- bool no_sockets_per_board = false;
- uint16_t sockets_per_board = 0;
- n = xmalloc(sizeof(slurm_conf_node_t));
- dflt = default_nodename_tbl;
- n->nodenames = xstrdup(value);
- #if (SYSTEM_DIMENSIONS > 1)
- if (conf_ptr->node_prefix == NULL)
- _set_node_prefix(n->nodenames);
- #endif
- if (!s_p_get_string(&n->hostnames, "NodeHostname", tbl))
- n->hostnames = xstrdup(n->nodenames);
- if (!s_p_get_string(&n->addresses, "NodeAddr", tbl))
- n->addresses = xstrdup(n->hostnames);
- if (!s_p_get_uint16(&n->boards, "Boards", tbl)
- && !s_p_get_uint16(&n->boards, "Boards", dflt)) {
- n->boards = 1;
- no_boards = true;
- }
- if (!s_p_get_uint16(&n->cores, "CoresPerSocket", tbl)
- && !s_p_get_uint16(&n->cores, "CoresPerSocket", dflt)) {
- n->cores = 1;
- no_cores = true;
- }
- if (!s_p_get_string(&n->feature, "Feature", tbl))
- s_p_get_string(&n->feature, "Feature", dflt);
- if (!s_p_get_string(&n->gres, "Gres", tbl))
- s_p_get_string(&n->gres, "Gres", dflt);
- if (!s_p_get_string(&n->port_str, "Port", tbl) &&
- !s_p_get_string(&n->port_str, "Port", dflt)) {
- /* This gets resolved in slurm_conf_get_port()
- * and slurm_conf_get_addr(). For now just
- * leave with a value of NULL */
- }
- if (!s_p_get_uint16(&n->cpus, "CPUs", tbl) &&
- !s_p_get_uint16(&n->cpus, "CPUs", dflt) &&
- !s_p_get_uint16(&n->cpus, "Procs", tbl) &&
- !s_p_get_uint16(&n->cpus, "Procs", dflt)) {
- n->cpus = 1;
- no_cpus = true;
- }
- if (!s_p_get_uint32(&n->real_memory, "RealMemory", tbl)
- && !s_p_get_uint32(&n->real_memory, "RealMemory", dflt))
- n->real_memory = 1;
- if (!s_p_get_string(&n->reason, "Reason", tbl))
- s_p_get_string(&n->reason, "Reason", dflt);
- if (!s_p_get_uint16(&n->sockets, "Sockets", tbl)
- && !s_p_get_uint16(&n->sockets, "Sockets", dflt)) {
- n->sockets = 1;
- no_sockets = true;
- }
- if (!s_p_get_uint16(&sockets_per_board, "SocketsPerBoard", tbl)
- && !s_p_get_uint16(&sockets_per_board, "SocketsPerBoard",
- dflt)) {
- sockets_per_board = 1;
- no_sockets_per_board = true;
- }
- if (!s_p_get_string(&n->state, "State", tbl)
- && !s_p_get_string(&n->state, "State", dflt))
- n->state = NULL;
- if (!s_p_get_uint16(&n->threads, "ThreadsPerCore", tbl)
- && !s_p_get_uint16(&n->threads, "ThreadsPerCore", dflt)) {
- n->threads = 1;
- no_threads = true;
- }
- if (!s_p_get_uint32(&n->tmp_disk, "TmpDisk", tbl)
- && !s_p_get_uint32(&n->tmp_disk, "TmpDisk", dflt))
- n->tmp_disk = 0;
- if (!s_p_get_uint32(&n->weight, "Weight", tbl)
- && !s_p_get_uint32(&n->weight, "Weight", dflt))
- n->weight = 1;
- s_p_hashtbl_destroy(tbl);
- if (n->cores == 0) { /* make sure cores is non-zero */
- error("NodeNames=%s CoresPerSocket=0 is invalid, "
- "reset to 1", n->nodenames);
- n->cores = 1;
- }
- if (n->threads == 0) { /* make sure threads is non-zero */
- error("NodeNames=%s ThreadsPerCore=0 is invalid, "
- "reset to 1", n->nodenames);
- n->threads = 1;
- }
- if (!no_sockets_per_board && sockets_per_board==0) {
- /* make sure sockets_per_boards is non-zero */
- error("NodeNames=%s SocketsPerBoards=0 is invalid, "
- "reset to 1", n->nodenames);
- sockets_per_board = 1;
- }
- if (no_boards) {
- /* This case is exactly like if was without boards,
- * Except SocketsPerBoard=# can be used,
- * But it can't be used with Sockets=# */
- n->boards = 1;
- if (!no_sockets && !no_sockets_per_board) {
- error("NodeNames=%s Sockets=# and "
- "SocketsPerBoard=# is invalid"
- ", using SocketsPerBoard",
- n->nodenames);
- n->sockets = sockets_per_board;
- }
- if (!no_sockets_per_board) {
- n->sockets = sockets_per_board;
- }
- if (!no_cpus && /* infer missing Sockets= */
- no_sockets) {
- n->sockets = n->cpus / (n->cores * n->threads);
- }
- if (n->sockets == 0) { /* make sure sockets != 0 */
- error("NodeNames=%s Sockets=0 is invalid, "
- "reset to 1", n->nodenames);
- n->sockets = 1;
- }
- if (no_cpus) { /* infer missing CPUs= */
- n->cpus = n->sockets * n->cores * n->threads;
- }
- /* if only CPUs= and Sockets=
- * specified check for match */
- if (!no_cpus && !no_sockets &&
- no_cores && no_threads &&
- (n->cpus != n->sockets)) {
- n->sockets = n->cpus;
- error("NodeNames=%s CPUs doesn't match "
- "Sockets, setting Sockets to %d",
- n->nodenames, n->sockets);
- }
- computed_procs = n->sockets * n->cores * n->threads;
- if ((n->cpus != n->sockets) &&
- (n->cpus != n->sockets * n->cores) &&
- (n->cpus != computed_procs)) {
- error("NodeNames=%s CPUs=%d doesn't match "
- "Sockets*CoresPerSocket*ThreadsPerCore "
- "(%d), resetting CPUs",
- n->nodenames, n->cpus, computed_procs);
- n->cpus = computed_procs;
- }
- } else {
- /* In this case Boards=# is used.
- * CPUs=# or Procs=# are ignored.
- */
- if (!no_cpus) {
- error("NodeNames=%s CPUs=# or Procs=# "
- "with Boards=# is invalid and "
- "is ignored.", n->nodenames);
- }
- if (n->boards == 0) {
- /* make sure boards is non-zero */
- error("NodeNames=%s Boards=0 is "
- "invalid, reset to 1",
- n->nodenames);
- n->boards = 1;
- }
- if (!no_sockets && !no_sockets_per_board) {
- error("NodeNames=%s Sockets=# and "
- "SocketsPerBoard=# is invalid, "
- "using SocketsPerBoard", n->nodenames);
- n->sockets = n->boards * sockets_per_board;
- } else if (!no_sockets_per_board) {
- n->sockets = n->boards * sockets_per_board;
- } else if (!no_sockets) {
- error("NodeNames=%s Sockets=# with Boards=# is"
- " not recommended, assume "
- "SocketsPerBoard was meant",
- n->nodenames);
- if (n->sockets == 0) {
- /* make sure sockets is non-zero */
- error("NodeNames=%s Sockets=0 is "
- "invalid, reset to 1",
- n->nodenames);
- n->sockets = 1;
- }
- n->sockets = n->boards * n->sockets;
- } else {
- n->sockets = n->boards;
- }
- /* Node boards factored into sockets */
- n->cpus = n->sockets * n->cores * n->threads;
- }
- *dest = (void *)n;
- return 1;
- }
- /* should not get here */
- }
- /* Destroy a front_end record built by slurm_conf_frontend_array() */
- extern void destroy_frontend(void *ptr)
- {
- slurm_conf_frontend_t *n = (slurm_conf_frontend_t *) ptr;
- xfree(n->frontends);
- xfree(n->addresses);
- xfree(n->reason);
- xfree(ptr);
- }
- /*
- * list_find_frontend - find an entry in the front_end list, see list.h for
- * documentation
- * IN key - is feature name or NULL for all features
- * RET 1 if found, 0 otherwise
- */
- extern int list_find_frontend (void *front_end_entry, void *key)
- {
- slurm_conf_frontend_t *front_end_ptr;
- if (key == NULL)
- return 1;
- front_end_ptr = (slurm_conf_frontend_t *) front_end_entry;
- if (strcmp(front_end_ptr->frontends, (char *) key) == 0)
- return 1;
- return 0;
- }
- static void _destroy_nodename(void *ptr)
- {
- slurm_conf_node_t *n = (slurm_conf_node_t *)ptr;
- xfree(n->addresses);
- xfree(n->feature);
- xfree(n->hostnames);
- xfree(n->gres);
- xfree(n->nodenames);
- xfree(n->port_str);
- xfree(n->reason);
- xfree(n->state);
- xfree(ptr);
- }
- int slurm_conf_frontend_array(slurm_conf_frontend_t **ptr_array[])
- {
- int count;
- slurm_conf_frontend_t **ptr;
- if (s_p_get_array((void ***)&ptr, &count, "FrontendName",
- conf_hashtbl)) {
- *ptr_array = ptr;
- return count;
- } else {
- #ifdef HAVE_FRONT_END
- /* No FrontendName in slurm.conf. Take the NodeAddr and
- * NodeHostName from the first node's record and use that to
- * build an equivalent structure to that constructed when
- * FrontendName is configured. This is intended for backward
- * compatability with SLURM version 2.2. */
- static slurm_conf_frontend_t local_front_end;
- static slurm_conf_frontend_t *local_front_end_array[2] =
- {NULL, NULL};
- static char addresses[1024], hostnames[1024];
- if (local_front_end_array[0] == NULL) {
- slurm_conf_node_t **node_ptr;
- int node_count = 0;
- if (!s_p_get_array((void ***)&node_ptr, &node_count,
- "NodeName", conf_hashtbl) ||
- (node_count == 0))
- fatal("No front end nodes configured");
- strncpy(addresses, node_ptr[0]->addresses,
- sizeof(addresses));
- strncpy(hostnames, node_ptr[0]->hostnames,
- sizeof(hostnames));
- local_front_end.addresses = addresses;
- local_front_end.frontends = hostnames;
- if (node_ptr[0]->port_str) {
- local_front_end.port = atoi(node_ptr[0]->
- port_str);
- }
- local_front_end.reason = NULL;
- local_front_end.node_state = NODE_STATE_UNKNOWN;
- local_front_end_array[0] = &local_front_end;
- }
- *ptr_array = local_front_end_array;
- return 1;
- #else
- *ptr_array = NULL;
- return 0;
- #endif
- }
- }
- int slurm_conf_nodename_array(slurm_conf_node_t **ptr_array[])
- {
- int count;
- slurm_conf_node_t **ptr;
- if (s_p_get_array((void ***)&ptr, &count, "NodeName", conf_hashtbl)) {
- *ptr_array = ptr;
- return count;
- } else {
- *ptr_array = NULL;
- return 0;
- }
- }
- static int _parse_partitionname(void **dest, slurm_parser_enum_t type,
- const char *key, const char *value,
- const char *line, char **leftover)
- {
- s_p_hashtbl_t *tbl, *dflt;
- slurm_conf_partition_t *p;
- char *tmp = NULL;
- static s_p_options_t _partition_options[] = {
- {"AllocNodes", S_P_STRING},
- {"AllowGroups", S_P_STRING},
- {"Alternate", S_P_STRING},
- {"DefMemPerCPU", S_P_UINT32},
- {"DefMemPerNode", S_P_UINT32},
- {"Default", S_P_BOOLEAN}, /* YES or NO */
- {"DefaultTime", S_P_STRING},
- {"DisableRootJobs", S_P_BOOLEAN}, /* YES or NO */
- {"GraceTime", S_P_UINT32},
- {"Hidden", S_P_BOOLEAN}, /* YES or NO */
- {"MaxMemPerCPU", S_P_UINT32},
- {"MaxMemPerNode", S_P_UINT32},
- {"MaxTime", S_P_STRING},
- {"MaxNodes", S_P_UINT32}, /* INFINITE or a number */
- {"MinNodes", S_P_UINT32},
- {"Nodes", S_P_STRING},
- {"PreemptMode", S_P_STRING},
- {"Priority", S_P_UINT16},
- {"RootOnly", S_P_BOOLEAN}, /* YES or NO */
- {"ReqResv", S_P_BOOLEAN}, /* YES or NO */
- {"Shared", S_P_STRING}, /* YES, NO, or FORCE */
- {"State", S_P_STRING}, /* UP, DOWN, INACTIVE or DRAIN */
- {NULL}
- };
- tbl = s_p_hashtbl_create(_partition_options);
- s_p_parse_line(tbl, *leftover, leftover);
- /* s_p_dump_values(tbl, _partition_options); */
- if (strcasecmp(value, "DEFAULT") == 0) {
- if (default_partition_tbl != NULL) {
- s_p_hashtbl_merge(tbl, default_partition_tbl);
- s_p_hashtbl_destroy(default_partition_tbl);
- }
- default_partition_tbl = tbl;
- return 0;
- } else {
- p = xmalloc(sizeof(slurm_conf_partition_t));
- dflt = default_partition_tbl;
- p->name = xstrdup(value);
- if (!s_p_get_string(&p->allow_groups, "AllowGroups", tbl))
- s_p_get_string(&p->allow_groups, "AllowGroups", dflt);
- if (p->allow_groups && strcasecmp(p->allow_groups, "ALL")==0) {
- xfree(p->allow_groups);
- p->allow_groups = NULL; /* NULL means allow all */
- }
- if (!s_p_get_string(&p->allow_alloc_nodes, "AllocNodes", tbl)) {
- s_p_get_string(&p->allow_alloc_nodes, "AllocNodes",
- dflt);
- if (p->allow_alloc_nodes &&
- (strcasecmp(p->allow_alloc_nodes, "ALL") == 0)) {
- /* NULL means to allow all submit notes */
- xfree(p->allow_alloc_nodes);
- }
- }
- if (!s_p_get_string(&p->alternate, "Alternate", tbl))
- s_p_get_string(&p->alternate, "Alternate", dflt);
- if (!s_p_get_boolean(&p->default_flag, "Default", tbl)
- && !s_p_get_boolean(&p->default_flag, "Default", dflt))
- p->default_flag = false;
- if (!s_p_get_uint32(&p->def_mem_per_cpu, "DefMemPerNode",
- tbl) &&
- !s_p_get_uint32(&p->def_mem_per_cpu, "DefMemPerNode",
- dflt)) {
- if (s_p_get_uint32(&p->def_mem_per_cpu,
- "DefMemPerCPU", tbl) ||
- s_p_get_uint32(&p->def_mem_per_cpu,
- "DefMemPerCPU", dflt)) {
- p->def_mem_per_cpu |= MEM_PER_CPU;
- } else {
- p->def_mem_per_cpu = 0;
- }
- }
- if (!s_p_get_uint32(&p->max_mem_per_cpu, "MaxMemPerNode",
- tbl) &&
- !s_p_get_uint32(&p->max_mem_per_cpu, "MaxMemPerNode",
- dflt)) {
- if (s_p_get_uint32(&p->max_mem_per_cpu,
- "MaxMemPerCPU", tbl) ||
- s_p_get_uint32(&p->max_mem_per_cpu,
- "MaxMemPerCPU", dflt)) {
- p->max_mem_per_cpu |= MEM_PER_CPU;
- } else {
- p->max_mem_per_cpu = 0;
- }
- }
- if (!s_p_get_boolean((bool *)&p->disable_root_jobs,
- "DisableRootJobs", tbl))
- p->disable_root_jobs = (uint16_t)NO_VAL;
- if (!s_p_get_boolean(&p->hidden_flag, "Hidden", tbl)
- && !s_p_get_boolean(&p->hidden_flag, "Hidden", dflt))
- p->hidden_flag = false;
- if (!s_p_get_string(&tmp, "MaxTime", tbl) &&
- !s_p_get_string(&tmp, "MaxTime", dflt))
- p->max_time = INFINITE;
- else {
- int max_time = time_str2mins(tmp);
- if ((max_time < 0) && (max_time != INFINITE)) {
- error("Bad value \"%s\" for MaxTime", tmp);
- _destroy_partitionname(p);
- s_p_hashtbl_destroy(tbl);
- xfree(tmp);
- return -1;
- }
- p->max_time = max_time;
- xfree(tmp);
- }
- if (!s_p_get_uint32(&p->grace_time, "GraceTime", tbl) &&
- !s_p_get_uint32(&p->grace_time, "GraceTime", dflt))
- p->grace_time = 0;
- if (!s_p_get_string(&tmp, "DefaultTime", tbl) &&
- !s_p_get_string(&tmp, "DefaultTime", dflt))
- p->default_time = NO_VAL;
- else {
- int default_time = time_str2mins(tmp);
- if ((default_time < 0) && (default_time != INFINITE)) {
- error("Bad value \"%s\" for DefaultTime", tmp);
- _destroy_partitionname(p);
- s_p_hashtbl_destroy(tbl);
- xfree(tmp);
- return -1;
- }
- p->default_time = default_time;
- xfree(tmp);
- }
- if (!s_p_get_uint32(&p->max_nodes, "MaxNodes", tbl)
- && !s_p_get_uint32(&p->max_nodes, "MaxNodes", dflt))
- p->max_nodes = INFINITE;
- if (!s_p_get_uint32(&p->min_nodes, "MinNodes", tbl)
- && !s_p_get_uint32(&p->min_nodes, "MinNodes", dflt))
- p->min_nodes = 1;
- if (!s_p_get_string(&p->nodes, "Nodes", tbl)
- && !s_p_get_string(&p->nodes, "Nodes", dflt))
- p->nodes = NULL;
- else {
- int i;
- for (i=0; p->nodes[i]; i++) {
- if (isspace((int)p->nodes[i]))
- p->nodes[i] = ',';
- }
- }
- if (!s_p_get_boolean(&p->root_only_flag, "RootOnly", tbl)
- && !s_p_get_boolean(&p->root_only_flag, "RootOnly", dflt))
- p->root_only_flag = false;
- if (!s_p_get_boolean(&p->req_resv_flag, "ReqResv", tbl)
- && !s_p_get_boolean(&p->req_resv_flag, "ReqResv", dflt))
- p->req_resv_flag = false;
- if (s_p_get_string(&tmp, "PreemptMode", tbl) ||
- s_p_get_string(&tmp, "PreemptMode", dflt)) {
- p->preempt_mode = preempt_mode_num(tmp);
- if (p->preempt_mode == (uint16_t) NO_VAL) {
- error("Bad value \"%s\" for PreemptMode", tmp);
- xfree(tmp);
- return -1;
- }
- xfree(tmp);
- } else
- p->preempt_mode = (uint16_t) NO_VAL;
- if (!s_p_get_uint16(&p->priority, "Priority", tbl) &&
- !s_p_get_uint16(&p->priority, "Priority", dflt))
- p->priority = 1;
- if (s_p_get_string(&tmp, "Shared", tbl) ||
- s_p_get_string(&tmp, "Shared", dflt)) {
- if (strcasecmp(tmp, "NO") == 0)
- p->max_share = 1;
- #ifndef HAVE_XCPU
- /* Only "Shared=NO" is valid on XCPU systems */
- else if (strcasecmp(tmp, "EXCLUSIVE") == 0)
- p->max_share = 0;
- else if (strncasecmp(tmp, "YES:", 4) == 0) {
- int i = strtol(&tmp[4], (char **) NULL, 10);
- if (i <= 1) {
- error("Ignoring bad Shared value: %s",
- tmp);
- p->max_share = 1; /* Shared=NO */
- } else
- p->max_share = i;
- } else if (strcasecmp(tmp, "YES") == 0)
- p->max_share = 4;
- else if (strncasecmp(tmp, "FORCE:", 6) == 0) {
- int i = strtol(&tmp[6], (char **) NULL, 10);
- if (i < 1) {
- error("Ignoring bad Shared value: %s",
- tmp);
- p->max_share = 1; /* Shared=NO */
- } else
- p->max_share = i | SHARED_FORCE;
- } else if (strcasecmp(tmp, "FORCE") == 0)
- p->max_share = 4 | SHARED_FORCE;
- #endif
- else {
- error("Bad value \"%s\" for Shared", tmp);
- _destroy_partitionname(p);
- s_p_hashtbl_destroy(tbl);
- xfree(tmp);
- return -1;
- }
- xfree(tmp);
- } else
- p->max_share = 1;
- if (s_p_get_string(&tmp, "State", tbl) ||
- s_p_get_string(&tmp, "State", dflt)) {
- if (strncasecmp(tmp, "DOWN", 4) == 0)
- p->state_up = PARTITION_DOWN;
- else if (strncasecmp(tmp, "UP", 2) == 0)
- p->state_up = PARTITION_UP;
- else if (strncasecmp(tmp, "DRAIN", 5) == 0)
- p->state_up = PARTITION_DRAIN;
- else if (strncasecmp(tmp, "INACTIVE", 8) == 0)
- p->state_up = PARTITION_INACTIVE;
- else {
- error("Bad value \"%s\" for State", tmp);
- _destroy_partitionname(p);
- s_p_hashtbl_destroy(tbl);
- xfree(tmp);
- return -1;
- }
- xfree(tmp);
- } else
- p->state_up = PARTITION_UP;
- s_p_hashtbl_destroy(tbl);
- *dest = (void *)p;
- return 1;
- }
- /* should not get here */
- }
- static void _destroy_partitionname(void *ptr)
- {
- slurm_conf_partition_t *p = (slurm_conf_partition_t *)ptr;
- xfree(p->allow_alloc_nodes);
- xfree(p->allow_groups);
- xfree(p->alternate);
- xfree(p->name);
- xfree(p->nodes);
- xfree(ptr);
- }
- int slurm_conf_partition_array(slurm_conf_partition_t **ptr_array[])
- {
- int count;
- slurm_conf_partition_t **ptr;
- if (s_p_get_array((void ***)&ptr, &count, "PartitionName",
- conf_hashtbl)) {
- *ptr_array = ptr;
- return count;
- } else {
- *ptr_array = NULL;
- return 0;
- }
- }
- static int _parse_downnodes(void **dest, slurm_parser_enum_t type,
- const char *key, const char *value,
- const char *line, char **leftover)
- {
- s_p_hashtbl_t *tbl;
- slurm_conf_downnodes_t *n;
- static s_p_options_t _downnodes_options[] = {
- {"Reason", S_P_STRING},
- {"State", S_P_STRING},
- {NULL}
- };
- tbl = s_p_hashtbl_create(_downnodes_options);
- s_p_parse_line(tbl, *leftover, leftover);
- /* s_p_dump_values(tbl, _downnodes_options); */
- n = xmalloc(sizeof(slurm_conf_node_t));
- n->nodenames = xstrdup(value);
- if (!s_p_get_string(&n->reason, "Reason", tbl))
- n->reason = xstrdup("Set in slurm.conf");
- if (!s_p_get_string(&n->state, "State", tbl))
- n->state = NULL;
- s_p_hashtbl_destroy(tbl);
- *dest = (void *)n;
- return 1;
- }
- static void _destroy_downnodes(void *ptr)
- {
- slurm_conf_downnodes_t *n = (slurm_conf_downnodes_t *)ptr;
- xfree(n->nodenames);
- xfree(n->reason);
- xfree(n->state);
- xfree(ptr);
- }
- extern int slurm_conf_downnodes_array(slurm_conf_downnodes_t **ptr_array[])
- {
- int count;
- slurm_conf_downnodes_t **ptr;
- if (s_p_get_array((void ***)&ptr, &count, "DownNodes", conf_hashtbl)) {
- *ptr_array = ptr;
- return count;
- } else {
- *ptr_array = NULL;
- return 0;
- }
- }
- static void _free_name_hashtbl(void)
- {
- int i;
- names_ll_t *p, *q;
- for (i=0; i<NAME_HASH_LEN; i++) {
- p = node_to_host_hashtbl[i];
- while (p) {
- xfree(p->alias);
- xfree(p->hostname);
- xfree(p->address);
- q = p->next_alias;
- xfree(p);
- p = q;
- }
- node_to_host_hashtbl[i] = NULL;
- host_to_node_hashtbl[i] = NULL;
- }
- nodehash_initialized = false;
- }
- static void _init_name_hashtbl(void)
- {
- return;
- }
- static int _get_hash_idx(const char *name)
- {
- int index = 0;
- int j;
- if (name == NULL)
- return 0; /* degenerate case */
- /* Multiply each character by its numerical position in the
- * name string to add a bit of entropy, because host names such
- * as cluster[0001-1000] can cause excessive index collisions.
- */
- for (j = 1; *name; name++, j++)
- index += (int)*name * j;
- index %= NAME_HASH_LEN;
- if (index < 0)
- index += NAME_HASH_LEN;
- return index;
- }
- static void _push_to_hashtbls(char *alias, char *hostname,
- char *address, uint16_t port,
- uint16_t cpus, uint16_t boards,
- uint16_t sockets, uint16_t cores,
- uint16_t threads, bool front_end)
- {
- int hostname_idx, alias_idx;
- names_ll_t *p, *new;
- alias_idx = _get_hash_idx(alias);
- hostname_idx = _get_hash_idx(hostname);
- #if !defined(HAVE_FRONT_END) && !defined(MULTIPLE_SLURMD)
- /* Ensure only one slurmd configured on each host */
- p = host_to_node_hashtbl[hostname_idx];
- while (p) {
- if (strcmp(p->hostname, hostname) == 0) {
- error("Duplicated NodeHostName %s in the config file",
- hostname);
- return;
- }
- p = p->next_hostname;
- }
- #endif
- /* Ensure only one instance of each NodeName */
- p = node_to_host_hashtbl[alias_idx];
- while (p) {
- if (strcmp(p->alias, alias)==0) {
- if (front_end)
- fatal("Frontend not configured correctly "
- "in slurm.conf. See man slurm.conf "
- "look for frontendname.");
- fatal("Duplicated NodeName %s in the config file",
- p->alias);
- return;
- }
- p = p->next_alias;
- }
- /* Create the new data structure and link it into the hash tables */
- new = (names_ll_t *)xmalloc(sizeof(names_ll_t));
- new->alias = xstrdup(alias);
- new->hostname = xstrdup(hostname);
- new->address = xstrdup(address);
- new->port = port;
- new->cpus = cpus;
- new->boards = boards;
- new->sockets = sockets;
- new->cores = cores;
- new->threads = threads;
- new->addr_initialized = false;
- /* Put on end of each list */
- new->next_alias = NULL;
- if (node_to_host_hashtbl[alias_idx]) {
- p = node_to_host_hashtbl[alias_idx];
- while (p->next_alias)
- p = p->next_alias;
- p->next_alias = new;
- } else {
- node_to_host_hashtbl[alias_idx] = new;
- }
- new->next_hostname = NULL;
- if (host_to_node_hashtbl[hostname_idx]) {
- p = host_to_node_hashtbl[hostname_idx];
- while (p->next_hostname)
- p = p->next_hostname;
- p->next_hostname = new;
- } else {
- host_to_node_hashtbl[hostname_idx] = new;
- }
- }
- /*
- * Register the given NodeName in the alias table.
- * If node_hostname is NULL, only node_name will be used and
- * no lookup table record is created.
- */
- static int _register_conf_node_aliases(slurm_conf_node_t *node_ptr)
- {
- hostlist_t address_list = NULL;
- hostlist_t alias_list = NULL;
- hostlist_t hostname_list = NULL;
- hostlist_t port_list = NULL;
- char *address = NULL;
- char *alias = NULL;
- char *hostname = NULL;
- char *port_str = NULL;
- int error_code = SLURM_SUCCESS;
- int address_count, alias_count, hostname_count, port_count, port_int;
- uint16_t port = 0;
- if ((node_ptr->nodenames == NULL) || (node_ptr->nodenames[0] == '\0'))
- return -1;
- if ((address_list = hostlist_create(node_ptr->addresses)) == NULL) {
- error("Unable to create NodeAddr list from %s",
- node_ptr->addresses);
- error_code = errno;
- goto cleanup;
- }
- if ((alias_list = hostlist_create(node_ptr->nodenames)) == NULL) {
- error("Unable to create NodeName list from %s",
- node_ptr->nodenames);
- error_code = errno;
- goto cleanup;
- }
- if ((hostname_list = hostlist_create(node_ptr->hostnames)) == NULL) {
- error("Unable to create NodeHostname list from %s",
- node_ptr->hostnames);
- error_code = errno;
- goto cleanup;
- }
- if (node_ptr->port_str && node_ptr->port_str[0] &&
- (node_ptr->port_str[0] != '[') &&
- (strchr(node_ptr->port_str, '-') ||
- strchr(node_ptr->port_str, ','))) {
- xstrfmtcat(port_str, "[%s]", node_ptr->port_str);
- port_list = hostlist_create(port_str);
- xfree(port_str);
- } else {
- port_list = hostlist_create(node_ptr->port_str);
- }
- if (port_list == NULL) {
- error("Unable to create Port list from %s",
- node_ptr->port_str);
- error_code = errno;
- goto cleanup;
- }
- #if (SYSTEM_DIMENSIONS > 1)
- if (conf_ptr->node_prefix == NULL)
- _set_node_prefix(node_ptr->nodenames);
- #endif
- /* some sanity checks */
- address_count = hostlist_count(address_list);
- alias_count = hostlist_count(alias_list);
- hostname_count = hostlist_count(hostname_list);
- port_count = hostlist_count(port_list);
- #ifdef HAVE_FRONT_END
- if ((address_count != alias_count) && (address_count != 1)) {
- error("NodeAddr count must equal that of NodeName "
- "records of there must be no more than one");
- goto cleanup;
- }
- if ((hostname_count != alias_count) && (hostname_count != 1)) {
- error("NodeHostname count must equal that of NodeName "
- "records of there must be no more than one");
- goto cleanup;
- }
- #else
- #ifdef MULTIPLE_SLURMD
- if ((address_count != alias_count) && (address_count != 1)) {
- error("NodeAddr count must equal that of NodeName "
- "records of there must be no more than one");
- goto cleanup;
- }
- #else
- if (address_count < alias_count) {
- error("At least as many NodeAddr are required as NodeName");
- goto cleanup;
- }
- if (hostname_count < alias_count) {
- error("At least as many NodeHostname are required "
- "as NodeName");
- goto cleanup;
- }
- #endif /* MULTIPLE_SLURMD */
- #endif /* HAVE_FRONT_END */
- if ((port_count != alias_count) && (port_count > 1)) {
- error("Port count must equal that of NodeName "
- "records or there must be no more than one");
- goto cleanup;
- }
- /* now build the individual node structures */
- while ((alias = hostlist_shift(alias_list))) {
- if (address_count > 0) {
- address_count--;
- if (address)
- free(address);
- address = hostlist_shift(address_list);
- }
- if (hostname_count > 0) {
- hostname_count--;
- if (hostname)
- free(hostname);
- hostname = hostlist_shift(hostname_list);
- }
- if (port_count > 0) {
- port_count--;
- if (port_str)
- free(port_str);
- port_str = hostlist_shift(port_list);
- port_int = atoi(port_str);
- if ((port_int <= 0) || (port_int > 0xffff))
- fatal("Invalid Port %s", node_ptr->port_str);
- port = port_int;
- }
- _push_to_hashtbls(alias, hostname, address, port,
- node_ptr->cpus, node_ptr->boards,
- node_ptr->sockets, node_ptr->cores,
- node_ptr->threads, 0);
- free(alias);
- }
- if (address)
- free(address);
- if (hostname)
- free(hostname);
- if (port_str)
- free(port_str);
- /* free allocated storage */
- cleanup:
- if (address_list)
- hostlist_destroy(address_list);
- if (alias_list)
- hostlist_destroy(alias_list);
- if (hostname_list)
- hostlist_destroy(hostname_list);
- if (port_list)
- hostlist_destroy(port_list);
- return error_code;
- }
- static int _register_front_ends(slurm_conf_frontend_t *front_end_ptr)
- {
- hostlist_t hostname_list = NULL;
- hostlist_t address_list = NULL;
- char *hostname = NULL;
- char *address = NULL;
- int error_code = SLURM_SUCCESS;
- if ((front_end_ptr->frontends == NULL) ||
- (front_end_ptr->frontends[0] == '\0'))
- return -1;
- if ((hostname_list = hostlist_create(front_end_ptr->frontends))
- == NULL) {
- error("Unable to create FrontendNames list from %s",
- front_end_ptr->frontends);
- error_code = errno;
- goto cleanup;
- }
- if ((address_list = hostlist_create(front_end_ptr->addresses))
- == NULL) {
- error("Unable to create FrontendAddr list from %s",
- front_end_ptr->addresses);
- error_code = errno;
- goto cleanup;
- }
- if (hostlist_count(address_list) != hostlist_count(hostname_list)) {
- error("Node count mismatch between FrontendNames and "
- "FrontendAddr");
- goto cleanup;
- }
- while ((hostname = hostlist_shift(hostname_list))) {
- address = hostlist_shift(address_list);
- _push_to_hashtbls(hostname, hostname, address,
- front_end_ptr->port, 1, 1, 1, 1, 1, 1);
- free(hostname);
- free(address);
- }
- /* free allocated storage */
- cleanup:
- if (hostname_list)
- hostlist_destroy(hostname_list);
- if (address_list)
- hostlist_destroy(address_list);
- return error_code;
- }
- static void _init_slurmd_nodehash(void)
- {
- slurm_conf_node_t **ptr_array;
- slurm_conf_frontend_t **ptr_front_end;
- int count, i;
- if (nodehash_initialized)
- return;
- else
- nodehash_initialized = true;
- if (!conf_initialized) {
- _init_slurm_conf(NULL);
- conf_initialized = true;
- }
- count = slurm_conf_nodename_array(&ptr_array);
- for (i = 0; i < count; i++)
- _register_conf_node_aliases(ptr_array[i]);
- count = slurm_conf_frontend_array(&ptr_front_end);
- for (i = 0; i < count; i++)
- _register_front_ends(ptr_front_end[i]);
- }
- /*
- * Caller needs to call slurm_conf_lock() and hold the lock before
- * calling this function (and call slurm_conf_unlock() afterwards).
- */
- static char *_internal_get_hostname(const char *node_name)
- {
- int idx;
- names_ll_t *p;
- _init_slurmd_nodehash();
- idx = _get_hash_idx(node_name);
- p = node_to_host_hashtbl[idx];
- while (p) {
- if (strcmp(p->alias, node_name) == 0) {
- return xstrdup(p->hostname);
- }
- p = p->next_alias;
- }
- return NULL;
- }
- /*
- * slurm_conf_get_hostname - Return the NodeHostname for given NodeName
- */
- extern char *slurm_conf_get_hostname(const char *node_name)
- {
- char *hostname = NULL;
- slurm_conf_lock();
- hostname = _internal_get_hostname(node_name);
- slurm_conf_unlock();
- return hostname;
- }
- /*
- * slurm_conf_get_nodename - Return the NodeName for given NodeHostname
- *
- * NOTE: Call xfree() to release returned value's memory.
- * NOTE: Caller must NOT be holding slurm_conf_lock().
- */
- extern char *slurm_conf_get_nodename(const char *node_hostname)
- {
- char *alias = NULL;
- int idx;
- names_ll_t *p;
- #ifdef HAVE_FRONT_END
- slurm_conf_frontend_t *front_end_ptr = NULL;
-
- slurm_conf_lock();
- if (!front_end_list) {
- debug("front_end_list is NULL");
- } else {
- front_end_ptr = list_find_first(front_end_list,
- list_find_frontend,
- (char *) node_hostname);
- if (front_end_ptr) {
- alias = xstrdup(front_end_ptr->frontends);
- slurm_conf_unlock();
- return alias;
- }
- }
- #else
- slurm_conf_lock();
- #endif
- _init_slurmd_nodehash();
- idx = _get_hash_idx(node_hostname);
- p = host_to_node_hashtbl[idx];
- while (p) {
- if (strcmp(p->hostname, node_hostname) == 0) {
- alias = xstrdup(p->alias);
- break;
- }
- p = p->next_hostname;
- }
- slurm_conf_unlock();
- return alias;
- }
- /*
- * slurm_conf_get_aliases - Return all the nodes NodeName value
- * associated to a given NodeHostname (usefull in case of multiple-slurmd
- * to get the list of virtual nodes associated with a real node)
- *
- * NOTE: Call xfree() to release returned value's memory.
- * NOTE: Caller must NOT be holding slurm_conf_lock().
- */
- extern char *slurm_conf_get_aliases(const char *node_hostname)
- {
- int idx;
- names_ll_t *p;
- char *aliases = NULL;
- char *s = NULL;
- slurm_conf_lock();
- _init_slurmd_nodehash();
- idx = _get_hash_idx(node_hostname);
- p = host_to_node_hashtbl[idx];
- while (p) {
- if (strcmp(p->hostname, node_hostname) == 0) {
- if ( aliases == NULL )
- aliases = xstrdup(p->alias);
- else {
- s = xstrdup_printf("%s %s",aliases,p->alias);
- xfree(aliases);
- aliases = s;
- }
- }
- p = p->next_hostname;
- }
- slurm_conf_unlock();
- return aliases;
- }
- /*
- * slurm_conf_get_nodeaddr - Return the NodeAddr for given NodeHostname
- *
- * NOTE: Call xfree() to release returned value's memory.
- * NOTE: Caller must NOT be holding slurm_conf_lock().
- */
- extern char *slurm_conf_get_nodeaddr(const char *node_hostname)
- {
- int idx;
- names_ll_t *p;
- slurm_conf_lock();
- _init_slurmd_nodehash();
- idx = _get_hash_idx(node_hostname);
- p = host_to_node_hashtbl[idx];
- while (p) {
- if (strcmp(p->hostname, node_hostname) == 0) {
- char *nodeaddr;
- if (p->address != NULL)
- nodeaddr = xstrdup(p->address);
- else
- nodeaddr = NULL;
- slurm_conf_unlock();
- return nodeaddr;
- }
- p = p->next_hostname;
- }
- slurm_conf_unlock();
- return NULL;
- }
- /*
- * slurm_conf_get_nodename_from_addr - Return the NodeName for given NodeAddr
- *
- * NOTE: Call xfree() to release returned value's memory.
- * NOTE: Caller must NOT be holding slurm_conf_lock().
- */
- extern char *slurm_conf_get_nodename_from_addr(const char *node_addr)
- {
- unsigned char buf[HOSTENT_SIZE];
- struct hostent *hptr;
- unsigned long addr = inet_addr(node_addr);
- char *start_name, *ret_name = NULL, *dot_ptr;
- if (!(hptr = get_host_by_addr((char *)&addr, sizeof(addr), AF_INET,
- buf, sizeof(buf), NULL))) {
- error("No node found with addr %s", node_addr);
- return NULL;
- }
- if (!strcmp(hptr->h_name, "localhost")) {
- start_name = xshort_hostname();
- } else {
- start_name = xstrdup(hptr->h_name);
- dot_ptr = strchr(start_name, '.');
- if (dot_ptr == NULL)
- dot_ptr = start_name + strlen(start_name);
- else
- dot_ptr[0] = '\0';
- }
- ret_name = slurm_conf_get_aliases(start_name);
- xfree(start_name);
- return ret_name;
- }
- /*
- * slurm_conf_get_aliased_nodename - Return the NodeName for the
- * complete hostname string returned by gethostname if there is
- * such a match, otherwise iterate through any aliases returned
- * by get_host_by_name
- */
- extern char *slurm_conf_get_aliased_nodename()
- {
- char hostname_full[1024];
- int error_code;
- char *nodename;
- error_code = gethostname(hostname_full, sizeof(hostname_full));
- /* we shouldn't have any problem here since by the time
- * this function has been called, gethostname_short,
- * which invokes gethostname, has probably already been called
- * successfully, so just return NULL if something weird
- * happens at this point
- */
- if (error_code)
- return NULL;
- nodename = slurm_conf_get_nodename(hostname_full);
- /* if the full hostname did not match a nodename */
- if (nodename == NULL) {
- /* use get_host_by_name; buffer sizes, semantics, etc.
- * cop…
Large files files are truncated, but you can click here to view the full file