extern int launch_p_setup_srun_opt(char **rest, opt_t *opt_local) { int command_pos = 0; if (opt_local->test_only) { error("--test-only not supported with aprun"); exit (1); } else if (opt_local->no_alloc) { error("--no-allocate not supported with aprun"); exit (1); } if (opt_local->slurmd_debug != LOG_LEVEL_QUIET) { error("--slurmd-debug not supported with aprun"); opt_local->slurmd_debug = LOG_LEVEL_QUIET; } opt_local->argc += 2; opt_local->argv = (char **) xmalloc(opt_local->argc * sizeof(char *)); opt_local->argv[command_pos++] = xstrdup("aprun"); /* Set default job name to the executable name rather than * "aprun" */ if (!opt_local->job_name_set_cmd && (1 < opt_local->argc)) { opt_local->job_name_set_cmd = true; opt_local->job_name = xstrdup(rest[0]); } if (opt_local->cpus_per_task) { opt_local->argc += 2; xrealloc(opt_local->argv, opt_local->argc * sizeof(char *)); opt_local->argv[command_pos++] = xstrdup("-d"); opt_local->argv[command_pos++] = xstrdup_printf( "%u", opt_local->cpus_per_task); } if (opt_local->exclusive) { opt_local->argc += 2; xrealloc(opt_local->argv, opt_local->argc * sizeof(char *)); opt_local->argv[command_pos++] = xstrdup("-F"); opt_local->argv[command_pos++] = xstrdup("exclusive"); } else if (opt_local->shared == 1) { opt_local->argc += 2; xrealloc(opt_local->argv, opt_local->argc * sizeof(char *)); opt_local->argv[command_pos++] = xstrdup("-F"); opt_local->argv[command_pos++] = xstrdup("share"); } if (opt_local->cpu_bind_type & CPU_BIND_ONE_THREAD_PER_CORE) { opt_local->argc += 2; xrealloc(opt_local->argv, opt_local->argc * sizeof(char *)); opt_local->argv[command_pos++] = xstrdup("-j"); opt_local->argv[command_pos++] = xstrdup("1"); } if (opt_local->nodelist) { char *nids = _get_nids(opt_local); if (nids) { opt_local->argc += 2; xrealloc(opt_local->argv, opt_local->argc * sizeof(char *)); opt_local->argv[command_pos++] = xstrdup("-L"); opt_local->argv[command_pos++] = xstrdup(nids); xfree(nids); } } if (opt_local->mem_per_cpu != NO_VAL64) { opt_local->argc += 2; xrealloc(opt_local->argv, opt_local->argc * sizeof(char *)); opt_local->argv[command_pos++] = xstrdup("-m"); opt_local->argv[command_pos++] = xstrdup_printf("%"PRIu64"", opt_local->mem_per_cpu); } if (opt_local->ntasks_per_node != NO_VAL) { opt_local->argc += 2; xrealloc(opt_local->argv, opt_local->argc * sizeof(char *)); opt_local->argv[command_pos++] = xstrdup("-N"); opt_local->argv[command_pos++] = xstrdup_printf( "%u", opt_local->ntasks_per_node); if (!opt_local->ntasks && opt_local->min_nodes) opt_local->ntasks = opt_local->ntasks_per_node * opt_local->min_nodes; } else if (opt_local->nodes_set && opt_local->min_nodes) { uint32_t tasks_per_node; opt_local->ntasks = MAX(opt_local->ntasks, opt_local->min_nodes); tasks_per_node = (opt_local->ntasks + opt_local->min_nodes - 1) / opt_local->min_nodes; opt_local->argc += 2; xrealloc(opt_local->argv, opt_local->argc * sizeof(char *)); opt_local->argv[command_pos++] = xstrdup("-N"); opt_local->argv[command_pos++] = xstrdup_printf("%u", tasks_per_node); } if (opt_local->ntasks && !opt_local->multi_prog) { opt_local->argc += 2; xrealloc(opt_local->argv, opt_local->argc * sizeof(char *)); opt_local->argv[command_pos++] = xstrdup("-n"); opt_local->argv[command_pos++] = xstrdup_printf("%u", opt_local->ntasks); } if ((_verbose < 3) || opt_local->quiet) { opt_local->argc += 1; xrealloc(opt_local->argv, opt_local->argc * sizeof(char *)); opt_local->argv[command_pos++] = xstrdup("-q"); } if (opt_local->ntasks_per_socket != NO_VAL) { opt_local->argc += 2; xrealloc(opt_local->argv, opt_local->argc * sizeof(char *)); opt_local->argv[command_pos++] = xstrdup("-S"); opt_local->argv[command_pos++] = xstrdup_printf( "%u", opt_local->ntasks_per_socket); } if (opt_local->sockets_per_node != NO_VAL) { opt_local->argc += 2; xrealloc(opt_local->argv, opt_local->argc * sizeof(char *)); opt_local->argv[command_pos++] = xstrdup("-sn"); opt_local->argv[command_pos++] = xstrdup_printf( "%u", opt_local->sockets_per_node); } if (opt_local->mem_bind_type & MEM_BIND_LOCAL) { opt_local->argc += 1; xrealloc(opt_local->argv, opt_local->argc * sizeof(char *)); opt_local->argv[command_pos++] = xstrdup("-ss"); } if (opt_local->time_limit_str) { opt_local->argc += 2; xrealloc(opt_local->argv, opt_local->argc * sizeof(char *)); opt_local->argv[command_pos++] = xstrdup("-t"); opt_local->argv[command_pos++] = xstrdup_printf( "%d", time_str2secs(opt_local->time_limit_str)); } if (opt_local->launcher_opts) { char *save_ptr = NULL, *tok; char *tmp = xstrdup(opt_local->launcher_opts); tok = strtok_r(tmp, " ", &save_ptr); while (tok) { opt_local->argc++; xrealloc(opt_local->argv, opt_local->argc * sizeof(char *)); opt_local->argv[command_pos++] = xstrdup(tok); tok = strtok_r(NULL, " ", &save_ptr); } xfree(tmp); } /* These are srun options that are not supported by aprun, but here just in case in the future they add them. if (opt_local->disable_status) { xstrcat(cmd_line, " --disable-status"); } if (opt_local->epilog) { xstrfmtcat(cmd_line, " --epilog=", opt_local->epilog); } if (kill_on_bad_exit) { xstrcat(cmd_line, " --kill-on-bad-exit"); } if (label) { xstrcat(cmd_line, " --label"); } if (opt_local->mpi_type) { xstrfmtcat(cmd_line, " --mpi=", opt_local->mpi_type); } if (opt_local->msg_timeout) { xstrfmtcat(cmd_line, " --msg-timeout=", opt_local->msg_timeout); } if (no_allocate) { xstrcat(cmd_line, " --no-allocate"); } if (opt_local->open_mode) { xstrcat(cmd_line, " --open-mode=", opt_local->open_mode); } if (preserve_env) { xstrcat(cmd_line, " --preserve_env"); } if (opt_local->prolog) { xstrcat(cmd_line, " --prolog=", opt_local->prolog ); } if (opt_local->propagate) { xstrcat(cmd_line, " --propagate", opt_local->propagate ); } if (pty) { xstrcat(cmd_line, " --pty"); } if (quit_on_interrupt) { xstrcat(cmd_line, " --quit-on-interrupt"); } if (opt_local->relative) { xstrfmtcat(cmd_line, " --relative=", opt_local->relative); } if (restart_dir) { xstrfmtcat(cmd_line, " --restart-dir=", opt_local->restart_dir); } if (resv_port) { xstrcat(cmd_line, "--resv-port"); } if (opt_local->slurm_debug) { xstrfmtcat(cmd_line, " --slurmd-debug=", opt_local->slurm_debug); } if (opttask_epilog) { xstrfmtcat(cmd_line, " --task-epilog=", opt_local->task_epilog); } if (opt_local->task_prolog) { xstrfmtcat(cmd_line, " --task-prolog", opt_local->task_prolog); } if (test_only) { xstrcat(cmd_line, " --test-only"); } if (unbuffered) { xstrcat(cmd_line, " --unbuffered"); } */ if (opt_local->multi_prog) { _handle_multi_prog(rest[0], &command_pos, opt_local); /* just so we don't tack on the script to the aprun line */ command_pos = opt_local->argc; } return command_pos; }
/* * read_slurmdbd_conf - load the SlurmDBD configuration from the slurmdbd.conf * file. Store result into global variable slurmdbd_conf. * This function can be called more than once. * RET SLURM_SUCCESS if no error, otherwise an error code */ extern int read_slurmdbd_conf(void) { s_p_options_t options[] = { {"ArchiveDir", S_P_STRING}, {"ArchiveEvents", S_P_BOOLEAN}, {"ArchiveJobs", S_P_BOOLEAN}, {"ArchiveResvs", S_P_BOOLEAN}, {"ArchiveScript", S_P_STRING}, {"ArchiveSteps", S_P_BOOLEAN}, {"ArchiveSuspend", S_P_BOOLEAN}, {"ArchiveTXN", S_P_BOOLEAN}, {"ArchiveUsage", S_P_BOOLEAN}, {"AuthInfo", S_P_STRING}, {"AuthType", S_P_STRING}, {"CommitDelay", S_P_UINT16}, {"DbdAddr", S_P_STRING}, {"DbdBackupHost", S_P_STRING}, {"DbdHost", S_P_STRING}, {"DbdPort", S_P_UINT16}, {"DebugFlags", S_P_STRING}, {"DebugLevel", S_P_STRING}, {"DebugLevelSyslog", S_P_STRING}, {"DefaultQOS", S_P_STRING}, {"JobPurge", S_P_UINT32}, {"LogFile", S_P_STRING}, {"LogTimeFormat", S_P_STRING}, {"MaxQueryTimeRange", S_P_STRING}, {"MessageTimeout", S_P_UINT16}, {"PidFile", S_P_STRING}, {"PluginDir", S_P_STRING}, {"PrivateData", S_P_STRING}, {"PurgeEventAfter", S_P_STRING}, {"PurgeJobAfter", S_P_STRING}, {"PurgeResvAfter", S_P_STRING}, {"PurgeStepAfter", S_P_STRING}, {"PurgeSuspendAfter", S_P_STRING}, {"PurgeTXNAfter", S_P_STRING}, {"PurgeUsageAfter", S_P_STRING}, {"PurgeEventMonths", S_P_UINT32}, {"PurgeJobMonths", S_P_UINT32}, {"PurgeStepMonths", S_P_UINT32}, {"PurgeSuspendMonths", S_P_UINT32}, {"PurgeTXNMonths", S_P_UINT32}, {"PurgeUsageMonths", S_P_UINT32}, {"SlurmUser", S_P_STRING}, {"StepPurge", S_P_UINT32}, {"StorageBackupHost", S_P_STRING}, {"StorageHost", S_P_STRING}, {"StorageLoc", S_P_STRING}, {"StoragePass", S_P_STRING}, {"StoragePort", S_P_UINT16}, {"StorageType", S_P_STRING}, {"StorageUser", S_P_STRING}, {"TCPTimeout", S_P_UINT16}, {"TrackWCKey", S_P_BOOLEAN}, {"TrackSlurmctldDown", S_P_BOOLEAN}, {NULL} }; s_p_hashtbl_t *tbl = NULL; char *conf_path = NULL; char *temp_str = NULL; struct stat buf; /* Set initial values */ slurm_mutex_lock(&conf_mutex); if (slurmdbd_conf == NULL) { slurmdbd_conf = xmalloc(sizeof(slurm_dbd_conf_t)); boot_time = time(NULL); } slurmdbd_conf->debug_level = LOG_LEVEL_INFO; _clear_slurmdbd_conf(); /* Get the slurmdbd.conf path and validate the file */ conf_path = get_extra_conf_path("slurmdbd.conf"); if ((conf_path == NULL) || (stat(conf_path, &buf) == -1)) { info("No slurmdbd.conf file (%s)", conf_path); } else { bool a_events = false, a_jobs = false, a_resv = false; bool a_steps = false, a_suspend = false, a_txn = false; bool a_usage = false; debug("Reading slurmdbd.conf file %s", conf_path); tbl = s_p_hashtbl_create(options); if (s_p_parse_file(tbl, NULL, conf_path, false) == SLURM_ERROR) { fatal("Could not open/read/parse slurmdbd.conf file %s", conf_path); } if (!s_p_get_string(&slurmdbd_conf->archive_dir, "ArchiveDir", tbl)) slurmdbd_conf->archive_dir = xstrdup(DEFAULT_SLURMDBD_ARCHIVE_DIR); s_p_get_boolean(&a_events, "ArchiveEvents", tbl); s_p_get_boolean(&a_jobs, "ArchiveJobs", tbl); s_p_get_boolean(&a_resv, "ArchiveResvs", tbl); s_p_get_string(&slurmdbd_conf->archive_script, "ArchiveScript", tbl); s_p_get_boolean(&a_steps, "ArchiveSteps", tbl); s_p_get_boolean(&a_suspend, "ArchiveSuspend", tbl); s_p_get_boolean(&a_txn, "ArchiveTXN", tbl); s_p_get_boolean(&a_usage, "ArchiveUsage", tbl); s_p_get_string(&slurmdbd_conf->auth_info, "AuthInfo", tbl); s_p_get_string(&slurmdbd_conf->auth_type, "AuthType", tbl); s_p_get_uint16(&slurmdbd_conf->commit_delay, "CommitDelay", tbl); s_p_get_string(&slurmdbd_conf->dbd_backup, "DbdBackupHost", tbl); s_p_get_string(&slurmdbd_conf->dbd_host, "DbdHost", tbl); s_p_get_string(&slurmdbd_conf->dbd_addr, "DbdAddr", tbl); s_p_get_uint16(&slurmdbd_conf->dbd_port, "DbdPort", tbl); if (s_p_get_string(&temp_str, "DebugFlags", tbl)) { if (debug_str2flags(temp_str, &slurmdbd_conf->debug_flags) != SLURM_SUCCESS) fatal("DebugFlags invalid: %s", temp_str); xfree(temp_str); } else /* Default: no DebugFlags */ slurmdbd_conf->debug_flags = 0; if (s_p_get_string(&temp_str, "DebugLevel", tbl)) { slurmdbd_conf->debug_level = log_string2num(temp_str); if (slurmdbd_conf->debug_level == NO_VAL16) fatal("Invalid DebugLevel %s", temp_str); xfree(temp_str); } s_p_get_string(&slurmdbd_conf->default_qos, "DefaultQOS", tbl); if (s_p_get_uint32(&slurmdbd_conf->purge_job, "JobPurge", tbl)) { if (!slurmdbd_conf->purge_job) slurmdbd_conf->purge_job = NO_VAL; else slurmdbd_conf->purge_job |= SLURMDB_PURGE_MONTHS; } s_p_get_string(&slurmdbd_conf->log_file, "LogFile", tbl); if (s_p_get_string(&temp_str, "DebugLevelSyslog", tbl)) { slurmdbd_conf->syslog_debug = log_string2num(temp_str); if (slurmdbd_conf->syslog_debug == NO_VAL16) fatal("Invalid DebugLevelSyslog %s", temp_str); xfree(temp_str); } if (s_p_get_string(&temp_str, "LogTimeFormat", tbl)) { if (xstrcasestr(temp_str, "iso8601_ms")) slurmdbd_conf->log_fmt = LOG_FMT_ISO8601_MS; else if (xstrcasestr(temp_str, "iso8601")) slurmdbd_conf->log_fmt = LOG_FMT_ISO8601; else if (xstrcasestr(temp_str, "rfc5424_ms")) slurmdbd_conf->log_fmt = LOG_FMT_RFC5424_MS; else if (xstrcasestr(temp_str, "rfc5424")) slurmdbd_conf->log_fmt = LOG_FMT_RFC5424; else if (xstrcasestr(temp_str, "clock")) slurmdbd_conf->log_fmt = LOG_FMT_CLOCK; else if (xstrcasestr(temp_str, "short")) slurmdbd_conf->log_fmt = LOG_FMT_SHORT; else if (xstrcasestr(temp_str, "thread_id")) slurmdbd_conf->log_fmt = LOG_FMT_THREAD_ID; xfree(temp_str); } else slurmdbd_conf->log_fmt = LOG_FMT_ISO8601_MS; if (s_p_get_string(&temp_str, "MaxQueryTimeRange", tbl)) { slurmdbd_conf->max_time_range = time_str2secs(temp_str); xfree(temp_str); } else { slurmdbd_conf->max_time_range = INFINITE; } if (!s_p_get_uint16(&slurmdbd_conf->msg_timeout, "MessageTimeout", tbl)) slurmdbd_conf->msg_timeout = DEFAULT_MSG_TIMEOUT; else if (slurmdbd_conf->msg_timeout > 100) { info("WARNING: MessageTimeout is too high for " "effective fault-tolerance"); } s_p_get_string(&slurmdbd_conf->pid_file, "PidFile", tbl); s_p_get_string(&slurmdbd_conf->plugindir, "PluginDir", tbl); slurmdbd_conf->private_data = 0; /* default visible to all */ if (s_p_get_string(&temp_str, "PrivateData", tbl)) { if (xstrcasestr(temp_str, "account")) slurmdbd_conf->private_data |= PRIVATE_DATA_ACCOUNTS; if (xstrcasestr(temp_str, "job")) slurmdbd_conf->private_data |= PRIVATE_DATA_JOBS; if (xstrcasestr(temp_str, "event")) slurmdbd_conf->private_data |= PRIVATE_DATA_EVENTS; if (xstrcasestr(temp_str, "node")) slurmdbd_conf->private_data |= PRIVATE_DATA_NODES; if (xstrcasestr(temp_str, "partition")) slurmdbd_conf->private_data |= PRIVATE_DATA_PARTITIONS; if (xstrcasestr(temp_str, "reservation")) slurmdbd_conf->private_data |= PRIVATE_DATA_RESERVATIONS; if (xstrcasestr(temp_str, "usage")) slurmdbd_conf->private_data |= PRIVATE_DATA_USAGE; if (xstrcasestr(temp_str, "user")) slurmdbd_conf->private_data |= PRIVATE_DATA_USERS; if (xstrcasestr(temp_str, "all")) slurmdbd_conf->private_data = 0xffff; xfree(temp_str); } if (s_p_get_string(&temp_str, "PurgeEventAfter", tbl)) { /* slurmdb_parse_purge will set SLURMDB_PURGE_FLAGS */ if ((slurmdbd_conf->purge_event = slurmdb_parse_purge(temp_str)) == NO_VAL) { fatal("Bad value \"%s\" for PurgeEventAfter", temp_str); } xfree(temp_str); } if (s_p_get_string(&temp_str, "PurgeJobAfter", tbl)) { /* slurmdb_parse_purge will set SLURMDB_PURGE_FLAGS */ if ((slurmdbd_conf->purge_job = slurmdb_parse_purge(temp_str)) == NO_VAL) { fatal("Bad value \"%s\" for PurgeJobAfter", temp_str); } xfree(temp_str); } if (s_p_get_string(&temp_str, "PurgeResvAfter", tbl)) { /* slurmdb_parse_purge will set SLURMDB_PURGE_FLAGS */ if ((slurmdbd_conf->purge_resv = slurmdb_parse_purge(temp_str)) == NO_VAL) { fatal("Bad value \"%s\" for PurgeResvAfter", temp_str); } xfree(temp_str); } if (s_p_get_string(&temp_str, "PurgeStepAfter", tbl)) { /* slurmdb_parse_purge will set SLURMDB_PURGE_FLAGS */ if ((slurmdbd_conf->purge_step = slurmdb_parse_purge(temp_str)) == NO_VAL) { fatal("Bad value \"%s\" for PurgeStepAfter", temp_str); } xfree(temp_str); } if (s_p_get_string(&temp_str, "PurgeSuspendAfter", tbl)) { /* slurmdb_parse_purge will set SLURMDB_PURGE_FLAGS */ if ((slurmdbd_conf->purge_suspend = slurmdb_parse_purge(temp_str)) == NO_VAL) { fatal("Bad value \"%s\" for PurgeSuspendAfter", temp_str); } xfree(temp_str); } if (s_p_get_string(&temp_str, "PurgeTXNAfter", tbl)) { /* slurmdb_parse_purge will set SLURMDB_PURGE_FLAGS */ if ((slurmdbd_conf->purge_txn = slurmdb_parse_purge(temp_str)) == NO_VAL) { fatal("Bad value \"%s\" for PurgeTXNAfter", temp_str); } xfree(temp_str); } if (s_p_get_string(&temp_str, "PurgeUsageAfter", tbl)) { /* slurmdb_parse_purge will set SLURMDB_PURGE_FLAGS */ if ((slurmdbd_conf->purge_usage = slurmdb_parse_purge(temp_str)) == NO_VAL) { fatal("Bad value \"%s\" for PurgeUsageAfter", temp_str); } xfree(temp_str); } if (s_p_get_uint32(&slurmdbd_conf->purge_event, "PurgeEventMonths", tbl)) { if (!slurmdbd_conf->purge_event) slurmdbd_conf->purge_event = NO_VAL; else slurmdbd_conf->purge_event |= SLURMDB_PURGE_MONTHS; } if (s_p_get_uint32(&slurmdbd_conf->purge_job, "PurgeJobMonths", tbl)) { if (!slurmdbd_conf->purge_job) slurmdbd_conf->purge_job = NO_VAL; else slurmdbd_conf->purge_job |= SLURMDB_PURGE_MONTHS; } if (s_p_get_uint32(&slurmdbd_conf->purge_step, "PurgeStepMonths", tbl)) { if (!slurmdbd_conf->purge_step) slurmdbd_conf->purge_step = NO_VAL; else slurmdbd_conf->purge_step |= SLURMDB_PURGE_MONTHS; } if (s_p_get_uint32(&slurmdbd_conf->purge_suspend, "PurgeSuspendMonths", tbl)) { if (!slurmdbd_conf->purge_suspend) slurmdbd_conf->purge_suspend = NO_VAL; else slurmdbd_conf->purge_suspend |= SLURMDB_PURGE_MONTHS; } if (s_p_get_uint32(&slurmdbd_conf->purge_txn, "PurgeTXNMonths", tbl)) { if (!slurmdbd_conf->purge_txn) slurmdbd_conf->purge_txn = NO_VAL; else slurmdbd_conf->purge_txn |= SLURMDB_PURGE_MONTHS; } if (s_p_get_uint32(&slurmdbd_conf->purge_usage, "PurgeUsageMonths", tbl)) { if (!slurmdbd_conf->purge_usage) slurmdbd_conf->purge_usage = NO_VAL; else slurmdbd_conf->purge_usage |= SLURMDB_PURGE_MONTHS; } s_p_get_string(&slurmdbd_conf->slurm_user_name, "SlurmUser", tbl); if (s_p_get_uint32(&slurmdbd_conf->purge_step, "StepPurge", tbl)) { if (!slurmdbd_conf->purge_step) slurmdbd_conf->purge_step = NO_VAL; else slurmdbd_conf->purge_step |= SLURMDB_PURGE_MONTHS; } s_p_get_string(&slurmdbd_conf->storage_backup_host, "StorageBackupHost", tbl); s_p_get_string(&slurmdbd_conf->storage_host, "StorageHost", tbl); s_p_get_string(&slurmdbd_conf->storage_loc, "StorageLoc", tbl); s_p_get_string(&slurmdbd_conf->storage_pass, "StoragePass", tbl); s_p_get_uint16(&slurmdbd_conf->storage_port, "StoragePort", tbl); s_p_get_string(&slurmdbd_conf->storage_type, "StorageType", tbl); s_p_get_string(&slurmdbd_conf->storage_user, "StorageUser", tbl); if (!s_p_get_uint16(&slurmdbd_conf->tcp_timeout, "TCPTimeout", tbl)) slurmdbd_conf->tcp_timeout = DEFAULT_TCP_TIMEOUT; if (!s_p_get_boolean((bool *)&slurmdbd_conf->track_wckey, "TrackWCKey", tbl)) slurmdbd_conf->track_wckey = false; if (!s_p_get_boolean((bool *)&slurmdbd_conf->track_ctld, "TrackSlurmctldDown", tbl)) slurmdbd_conf->track_ctld = false; if (a_events && slurmdbd_conf->purge_event) slurmdbd_conf->purge_event |= SLURMDB_PURGE_ARCHIVE; if (a_jobs && slurmdbd_conf->purge_job) slurmdbd_conf->purge_job |= SLURMDB_PURGE_ARCHIVE; if (a_resv && slurmdbd_conf->purge_resv) slurmdbd_conf->purge_resv |= SLURMDB_PURGE_ARCHIVE; if (a_steps && slurmdbd_conf->purge_step) slurmdbd_conf->purge_step |= SLURMDB_PURGE_ARCHIVE; if (a_suspend && slurmdbd_conf->purge_suspend) slurmdbd_conf->purge_suspend |= SLURMDB_PURGE_ARCHIVE; if (a_txn && slurmdbd_conf->purge_txn) slurmdbd_conf->purge_txn |= SLURMDB_PURGE_ARCHIVE; if (a_usage && slurmdbd_conf->purge_usage) slurmdbd_conf->purge_usage |= SLURMDB_PURGE_ARCHIVE; s_p_hashtbl_destroy(tbl); } xfree(conf_path); if (slurmdbd_conf->auth_type == NULL) slurmdbd_conf->auth_type = xstrdup(DEFAULT_SLURMDBD_AUTHTYPE); if (slurmdbd_conf->dbd_host == NULL) { error("slurmdbd.conf lacks DbdHost parameter, " "using 'localhost'"); slurmdbd_conf->dbd_host = xstrdup("localhost"); } if (slurmdbd_conf->dbd_addr == NULL) slurmdbd_conf->dbd_addr = xstrdup(slurmdbd_conf->dbd_host); if (slurmdbd_conf->pid_file == NULL) slurmdbd_conf->pid_file = xstrdup(DEFAULT_SLURMDBD_PIDFILE); if (slurmdbd_conf->dbd_port == 0) slurmdbd_conf->dbd_port = SLURMDBD_PORT; if (slurmdbd_conf->plugindir == NULL) slurmdbd_conf->plugindir = xstrdup(default_plugin_path); if (slurmdbd_conf->slurm_user_name) { uid_t pw_uid; if (uid_from_string (slurmdbd_conf->slurm_user_name, &pw_uid) < 0) fatal("Invalid user for SlurmUser %s, ignored", slurmdbd_conf->slurm_user_name); else slurmdbd_conf->slurm_user_id = pw_uid; } else { slurmdbd_conf->slurm_user_name = xstrdup("root"); slurmdbd_conf->slurm_user_id = 0; } if (slurmdbd_conf->storage_type == NULL) fatal("StorageType must be specified"); if (!xstrcmp(slurmdbd_conf->storage_type, "accounting_storage/slurmdbd")) { fatal("StorageType=%s is invalid in slurmdbd.conf", slurmdbd_conf->storage_type); } if (!slurmdbd_conf->storage_host) slurmdbd_conf->storage_host = xstrdup(DEFAULT_STORAGE_HOST); if (!slurmdbd_conf->storage_user) slurmdbd_conf->storage_user = xstrdup(getlogin()); if (!xstrcmp(slurmdbd_conf->storage_type, "accounting_storage/mysql")) { if (!slurmdbd_conf->storage_port) slurmdbd_conf->storage_port = DEFAULT_MYSQL_PORT; if (!slurmdbd_conf->storage_loc) slurmdbd_conf->storage_loc = xstrdup(DEFAULT_ACCOUNTING_DB); } else { if (!slurmdbd_conf->storage_port) slurmdbd_conf->storage_port = DEFAULT_STORAGE_PORT; if (!slurmdbd_conf->storage_loc) slurmdbd_conf->storage_loc = xstrdup(DEFAULT_STORAGE_LOC); } if (slurmdbd_conf->archive_dir) { if (stat(slurmdbd_conf->archive_dir, &buf) < 0) fatal("Failed to stat the archive directory %s: %m", slurmdbd_conf->archive_dir); if (!(buf.st_mode & S_IFDIR)) fatal("archive directory %s isn't a directory", slurmdbd_conf->archive_dir); if (access(slurmdbd_conf->archive_dir, W_OK) < 0) fatal("archive directory %s is not writable", slurmdbd_conf->archive_dir); } if (slurmdbd_conf->archive_script) { if (stat(slurmdbd_conf->archive_script, &buf) < 0) fatal("Failed to stat the archive script %s: %m", slurmdbd_conf->archive_dir); if (!(buf.st_mode & S_IFREG)) fatal("archive script %s isn't a regular file", slurmdbd_conf->archive_script); if (access(slurmdbd_conf->archive_script, X_OK) < 0) fatal("archive script %s is not executable", slurmdbd_conf->archive_script); } if (!slurmdbd_conf->purge_event) slurmdbd_conf->purge_event = NO_VAL; if (!slurmdbd_conf->purge_job) slurmdbd_conf->purge_job = NO_VAL; if (!slurmdbd_conf->purge_resv) slurmdbd_conf->purge_resv = NO_VAL; if (!slurmdbd_conf->purge_step) slurmdbd_conf->purge_step = NO_VAL; if (!slurmdbd_conf->purge_suspend) slurmdbd_conf->purge_suspend = NO_VAL; if (!slurmdbd_conf->purge_txn) slurmdbd_conf->purge_txn = NO_VAL; if (!slurmdbd_conf->purge_usage) slurmdbd_conf->purge_usage = NO_VAL; slurm_mutex_unlock(&conf_mutex); return SLURM_SUCCESS; }
/* * scontrol_update_job - update the slurm job configuration per the supplied * arguments * IN argc - count of arguments * IN argv - list of arguments * RET 0 if no slurm error, errno otherwise. parsing error prints * error message and returns 0 */ extern int scontrol_update_job(int argc, char **argv) { bool update_size = false; int i, update_cnt = 0, rc = SLURM_SUCCESS, rc2; char *tag, *val; int taglen, vallen; job_desc_msg_t job_msg; job_array_resp_msg_t *resp = NULL; uint32_t job_uid = NO_VAL; slurm_init_job_desc_msg (&job_msg); for (i = 0; i < argc; i++) { char *add_info = NULL; tag = argv[i]; val = strchr(argv[i], '='); if (val) { taglen = val - argv[i]; if ((taglen > 0) && ((val[-1] == '+') || (val[-1] == '-'))) { add_info = val - 1; taglen--; } val++; vallen = strlen(val); } else if (xstrncasecmp(tag, "Nice", MAX(strlen(tag), 2)) == 0){ /* "Nice" is the only tag that might not have an equal sign, so it is handled specially. */ job_msg.nice = NICE_OFFSET + 100; update_cnt++; continue; } else if (!val && argv[i + 1]) { tag = argv[i]; taglen = strlen(tag); val = argv[++i]; vallen = strlen(val); } else { exit_code = 1; fprintf (stderr, "Invalid input: %s\n", argv[i]); fprintf (stderr, "Request aborted\n"); return -1; } if (xstrncasecmp(tag, "JobId", MAX(taglen, 3)) == 0) { job_msg.job_id_str = val; } else if (xstrncasecmp(tag, "AdminComment", MAX(taglen, 3)) == 0) { if (add_info) { if (add_info[0] == '-') { error("Invalid syntax, AdminComment can not be subtracted from."); exit_code = 1; return 0; } job_msg.admin_comment = add_info; /* * Mark as unset so we know we handled this * correctly as there is a check later to make * sure we know we got a +-. */ add_info = NULL; } else job_msg.admin_comment = val; update_cnt++; } else if (xstrncasecmp(tag, "ArrayTaskThrottle", MAX(taglen, 10)) == 0) { int throttle; throttle = strtoll(val, (char **) NULL, 10); if (throttle < 0) { error("Invalid ArrayTaskThrottle value"); exit_code = 1; return 0; } job_msg.array_inx = val; update_cnt++; } else if (xstrncasecmp(tag, "Comment", MAX(taglen, 3)) == 0) { job_msg.comment = val; update_cnt++; } else if (xstrncasecmp(tag, "Clusters", MAX(taglen, 8)) == 0) { job_msg.clusters = val; update_cnt++; } else if (xstrncasecmp(tag, "ClusterFeatures", MAX(taglen, 8)) == 0) { job_msg.cluster_features = val; update_cnt++; } else if (xstrncasecmp(tag, "DelayBoot", MAX(taglen, 5)) == 0) { int time_sec = time_str2secs(val); if (time_sec == NO_VAL) { error("Invalid DelayBoot value"); exit_code = 1; return 0; } job_msg.delay_boot = time_sec; update_cnt++; } else if (xstrncasecmp(tag, "TimeLimit", MAX(taglen, 5)) == 0) { uint32_t job_current_time, time_limit; if (val && ((val[0] == '+') || (val[0] == '-'))) { if (add_info) { error("Invalid syntax, variations of +=- are not accepted."); exit_code = 1; return 0; } add_info = val; val++; } time_limit = time_str2mins(val); if (time_limit == NO_VAL) { error("Invalid TimeLimit value"); exit_code = 1; return 0; } if (add_info) { if (!job_msg.job_id_str) { error("JobId must precede TimeLimit " "increment or decrement"); exit_code = 1; return 0; } job_current_time = _get_job_time(job_msg. job_id_str); if (job_current_time == NO_VAL) { exit_code = 1; return 0; } if (add_info[0] == '+') { time_limit += job_current_time; } else if (time_limit > job_current_time) { error("TimeLimit decrement larger than" " current time limit (%u > %u)", time_limit, job_current_time); exit_code = 1; return 0; } else { time_limit = job_current_time - time_limit; } /* * Mark as unset so we know we handled this * correctly as there is a check later to make * sure we know we got a +-. */ add_info = NULL; } job_msg.time_limit = time_limit; update_cnt++; } else if (xstrncasecmp(tag, "TimeMin", MAX(taglen, 5)) == 0) { int time_min = time_str2mins(val); if ((time_min < 0) && (time_min != INFINITE)) { error("Invalid TimeMin value"); exit_code = 1; return 0; } job_msg.time_min = time_min; update_cnt++; } else if (xstrncasecmp(tag, "Priority", MAX(taglen, 2)) == 0) { if (parse_uint32(val, &job_msg.priority)) { error ("Invalid Priority value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "Nice", MAX(taglen, 2)) == 0) { long long tmp_nice; tmp_nice = strtoll(val, (char **)NULL, 10); if (llabs(tmp_nice) > (NICE_OFFSET - 3)) { error("Nice value out of range (+/- %u). Value " "ignored", NICE_OFFSET - 3); exit_code = 1; return 0; } job_msg.nice = NICE_OFFSET + tmp_nice; update_cnt++; } else if (!xstrncasecmp(tag, "CPUsPerTask", MAX(taglen, 9))) { if (parse_uint16(val, &job_msg.cpus_per_task)) { error("Invalid CPUsPerTask value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (!xstrncasecmp(tag, "CpusPerTres", MAX(taglen, 9))) { job_msg.cpus_per_tres = val; update_cnt++; } else if (xstrncasecmp(tag, "NumCPUs", MAX(taglen, 6)) == 0) { int min_cpus, max_cpus=0; if (!get_resource_arg_range(val, "NumCPUs", &min_cpus, &max_cpus, false) || (min_cpus <= 0) || (max_cpus && (max_cpus < min_cpus))) { error ("Invalid NumCPUs value: %s", val); exit_code = 1; return 0; } job_msg.min_cpus = min_cpus; if (max_cpus) job_msg.max_cpus = max_cpus; update_cnt++; } /* ReqProcs was removed in Slurm version 2.1 */ else if ((xstrncasecmp(tag, "NumTasks", MAX(taglen, 8)) == 0) || (xstrncasecmp(tag, "ReqProcs", MAX(taglen, 8)) == 0)) { if (parse_uint32(val, &job_msg.num_tasks)) { error ("Invalid NumTasks value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "Requeue", MAX(taglen, 4)) == 0) { if (parse_uint16(val, &job_msg.requeue)) { error ("Invalid Requeue value: %s", val); exit_code = 1; return 0; } update_cnt++; } /* ReqNodes was replaced by NumNodes in Slurm version 2.1 */ else if ((xstrncasecmp(tag, "ReqNodes", MAX(taglen, 8)) == 0) || (xstrncasecmp(tag, "NumNodes", MAX(taglen, 8)) == 0)) { int min_nodes, max_nodes, rc; if (xstrcmp(val, "0") == 0) { job_msg.min_nodes = 0; } else if (xstrcasecmp(val, "ALL") == 0) { job_msg.min_nodes = INFINITE; } else { min_nodes = (int) job_msg.min_nodes; max_nodes = (int) job_msg.max_nodes; rc = get_resource_arg_range( val, "requested node count", &min_nodes, &max_nodes, false); if (!rc) return rc; job_msg.min_nodes = (uint32_t) min_nodes; job_msg.max_nodes = (uint32_t) max_nodes; } update_size = true; update_cnt++; } else if (xstrncasecmp(tag, "ReqSockets", MAX(taglen, 4)) == 0) { if (parse_uint16(val, &job_msg.sockets_per_node)) { error ("Invalid ReqSockets value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "ReqCores", MAX(taglen, 4)) == 0) { if (parse_uint16(val, &job_msg.cores_per_socket)) { error ("Invalid ReqCores value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "TasksPerNode", MAX(taglen, 2))==0) { if (parse_uint16(val, &job_msg.ntasks_per_node)) { error ("Invalid TasksPerNode value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "ReqThreads", MAX(taglen, 4)) == 0) { if (parse_uint16(val, &job_msg.threads_per_core)) { error ("Invalid ReqThreads value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "MinCPUsNode", MAX(taglen, 4)) == 0) { if (parse_uint16(val, &job_msg.pn_min_cpus)) { error ("Invalid MinCPUsNode value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "MinMemoryNode", MAX(taglen, 10)) == 0) { if (parse_uint64(val, &job_msg.pn_min_memory)) { error ("Invalid MinMemoryNode value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "MinMemoryCPU", MAX(taglen, 10)) == 0) { if (parse_uint64(val, &job_msg.pn_min_memory)) { error ("Invalid MinMemoryCPU value: %s", val); exit_code = 1; return 0; } job_msg.pn_min_memory |= MEM_PER_CPU; update_cnt++; } else if (xstrncasecmp(tag, "MinTmpDiskNode", MAX(taglen, 5)) == 0) { if (parse_uint32(val, &job_msg.pn_min_tmp_disk)) { error ("Invalid MinTmpDiskNode value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "Partition", MAX(taglen, 2)) == 0) { job_msg.partition = val; update_cnt++; } else if (xstrncasecmp(tag, "QOS", MAX(taglen, 2)) == 0) { job_msg.qos = val; update_cnt++; } else if (xstrncasecmp(tag, "ReservationName", MAX(taglen, 3)) == 0) { job_msg.reservation = val; update_cnt++; } else if (!xstrncasecmp(tag, "Name", MAX(taglen, 2)) || !xstrncasecmp(tag, "JobName", MAX(taglen, 4))) { job_msg.name = val; update_cnt++; } else if (xstrncasecmp(tag, "WCKey", MAX(taglen, 1)) == 0) { job_msg.wckey = val; update_cnt++; } else if (xstrncasecmp(tag, "StdOut", MAX(taglen, 6)) == 0) { job_msg.std_out = val; update_cnt++; } else if (xstrncasecmp(tag, "Switches", MAX(taglen, 5)) == 0) { char *sep_char; job_msg.req_switch = (uint32_t) strtol(val, &sep_char, 10); update_cnt++; if (sep_char && sep_char[0] == '@') { job_msg.wait4switch = time_str2mins(sep_char+1) * 60; } } else if (xstrncasecmp(tag, "wait-for-switch", MAX(taglen, 5)) == 0) { if (parse_uint32(val, &job_msg.wait4switch)) { error ("Invalid wait-for-switch value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (!xstrncasecmp(tag, "OverSubscribe", MAX(taglen, 2)) || !xstrncasecmp(tag, "Shared", MAX(taglen, 2))) { if (xstrncasecmp(val, "YES", MAX(vallen, 1)) == 0) job_msg.shared = 1; else if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0) job_msg.shared = 0; else if (parse_uint16(val, &job_msg.shared)) { error("Invalid OverSubscribe value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "Contiguous", MAX(taglen, 3)) == 0) { if (xstrncasecmp(val, "YES", MAX(vallen, 1)) == 0) job_msg.contiguous = 1; else if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0) job_msg.contiguous = 0; else if (parse_uint16(val, &job_msg.contiguous)) { error ("Invalid Contiguous value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "CoreSpec", MAX(taglen, 4)) == 0) { if (!xstrcmp(val, "-1") || !xstrcmp(val, "*")) job_msg.core_spec = INFINITE16; else if (parse_uint16(val, &job_msg.core_spec)) { error ("Invalid CoreSpec value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (!xstrncasecmp(tag, "MemPerTres", MAX(taglen, 5))) { job_msg.mem_per_tres = val; update_cnt++; } else if (xstrncasecmp(tag, "ThreadSpec", MAX(taglen, 4)) == 0) { if (!xstrcmp(val, "-1") || !xstrcmp(val, "*")) job_msg.core_spec = INFINITE16; else if (parse_uint16(val, &job_msg.core_spec)) { error ("Invalid ThreadSpec value: %s", val); exit_code = 1; return 0; } else job_msg.core_spec |= CORE_SPEC_THREAD; update_cnt++; } else if (!xstrncasecmp(tag, "TresBind", MAX(taglen, 5))) { job_msg.tres_bind = val; update_cnt++; } else if (!xstrncasecmp(tag, "TresFreq", MAX(taglen, 5))) { job_msg.tres_freq = val; update_cnt++; } else if (!xstrncasecmp(tag, "TresPerJob", MAX(taglen, 8))) { job_msg.tres_per_job = val; update_cnt++; } else if (!xstrncasecmp(tag, "TresPerNode", MAX(taglen, 8))) { /* "gres" replaced by "tres_per_node" in v18.08 */ if (job_msg.tres_per_node) xstrfmtcat(job_msg.tres_per_node, ",%s", val); else job_msg.tres_per_node = xstrdup(val); update_cnt++; } else if (!xstrncasecmp(tag, "TresPerSocket", MAX(taglen, 8))) { job_msg.tres_per_socket = val; update_cnt++; } else if (!xstrncasecmp(tag, "TresPerTask", MAX(taglen, 8))) { job_msg.tres_per_task = val; update_cnt++; } else if (xstrncasecmp(tag, "ExcNodeList", MAX(taglen, 3)) == 0){ job_msg.exc_nodes = val; update_cnt++; } else if (!xstrncasecmp(tag, "NodeList", MAX(taglen, 8)) || !xstrncasecmp(tag, "ReqNodeList", MAX(taglen, 8))) { job_msg.req_nodes = val; update_size = true; update_cnt++; } else if (xstrncasecmp(tag, "Features", MAX(taglen, 1)) == 0) { job_msg.features = val; update_cnt++; } else if (xstrncasecmp(tag, "Gres", MAX(taglen, 2)) == 0) { /* "gres" replaced by "tres_per_node" in v18.08 */ if (!xstrcasecmp(val, "help") || !xstrcasecmp(val, "list")) { print_gres_help(); } else if (job_msg.tres_per_node) { xstrfmtcat(job_msg.tres_per_node, ",%s", val); } else { job_msg.tres_per_node = xstrdup(val); update_cnt++; } } else if (xstrncasecmp(tag, "Account", MAX(taglen, 1)) == 0) { job_msg.account = val; update_cnt++; } else if (xstrncasecmp(tag, "BurstBuffer", MAX(taglen, 1)) == 0) { job_msg.burst_buffer = val; update_cnt++; } else if (xstrncasecmp(tag, "Dependency", MAX(taglen, 1)) == 0) { job_msg.dependency = val; update_cnt++; } else if (xstrncasecmp(tag, "Licenses", MAX(taglen, 1)) == 0) { job_msg.licenses = val; update_cnt++; } else if (!xstrncasecmp(tag, "EligibleTime", MAX(taglen, 2)) || !xstrncasecmp(tag, "StartTime", MAX(taglen, 2))) { if ((job_msg.begin_time = parse_time(val, 0))) { if (job_msg.begin_time < time(NULL)) job_msg.begin_time = time(NULL); update_cnt++; } } else if (!xstrncasecmp(tag, "EndTime", MAX(taglen, 2))) { job_msg.end_time = parse_time(val, 0); update_cnt++; } else if (!xstrncasecmp(tag, "Reboot", MAX(taglen, 3))) { if (xstrncasecmp(val, "YES", MAX(vallen, 1)) == 0) job_msg.reboot = 1; else if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0) job_msg.reboot = 0; else if (parse_uint16(val, &job_msg.reboot)) { error ("Invalid reboot value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (!xstrncasecmp(tag, "UserID", MAX(taglen, 3))) { uid_t user_id = 0; if (uid_from_string(val, &user_id) < 0) { exit_code = 1; fprintf (stderr, "Invalid UserID: %s\n", val); fprintf (stderr, "Request aborted\n"); return 0; } job_uid = (uint32_t) user_id; } else if (!xstrncasecmp(tag, "Deadline", MAX(taglen, 3))) { if ((job_msg.deadline = parse_time(val, 0))) { update_cnt++; } } else { exit_code = 1; fprintf (stderr, "Update of this parameter is not " "supported: %s\n", argv[i]); fprintf (stderr, "Request aborted\n"); return 0; } if (add_info) { error("Option %s does not accept [+|-]= syntax", tag); exit_code = 1; return 0; } } if (update_cnt == 0) { exit_code = 1; fprintf (stderr, "No changes specified\n"); return 0; } /* If specified, override uid with effective uid provided by * -u <uid> or --uid=<uid> */ if (euid != NO_VAL) job_msg.user_id = euid; if (!job_msg.job_id_str && job_msg.name) { /* Translate name to job ID string */ job_msg.job_id_str = _job_name2id(job_msg.name, job_uid); if (!job_msg.job_id_str) { exit_code = 1; return 0; } } if (!job_msg.job_id_str) { error("No job ID specified"); exit_code = 1; return 0; } if (update_size && !_is_single_job(job_msg.job_id_str)) { exit_code = 1; return 0; } if (_is_job_id(job_msg.job_id_str)) { job_msg.job_id_str = _next_job_id(); while (job_msg.job_id_str) { rc2 = slurm_update_job2(&job_msg, &resp); if (update_size && (rc2 == SLURM_SUCCESS)) { /* See check above for one job ID */ job_msg.job_id = slurm_atoul(job_msg.job_id_str); _update_job_size(job_msg.job_id); } if (rc2 != SLURM_SUCCESS) { rc2 = slurm_get_errno(); rc = MAX(rc, rc2); exit_code = 1; if (quiet_flag != 1) { fprintf(stderr, "%s for job %s\n", slurm_strerror(slurm_get_errno()), job_msg.job_id_str); } } else if (resp) { for (i = 0; i < resp->job_array_count; i++) { if ((resp->error_code[i] == SLURM_SUCCESS) && (resp->job_array_count == 1)) continue; exit_code = 1; if (quiet_flag == 1) continue; fprintf(stderr, "%s: %s\n", resp->job_array_id[i], slurm_strerror(resp-> error_code[i])); } slurm_free_job_array_resp(resp); resp = NULL; } job_msg.job_id_str = _next_job_id(); } } else if (job_msg.job_id_str) { exit_code = 1; rc = ESLURM_INVALID_JOB_ID; slurm_seterrno(rc); if (quiet_flag != 1) { fprintf(stderr, "%s for job %s\n", slurm_strerror(rc), job_msg.job_id_str); } } return rc; }