| /*****************************************************************************\ |
| * file_functions.c - functions dealing with files that are generated in the |
| * accounting system. |
| ***************************************************************************** |
| * Copyright (C) 2008 Lawrence Livermore National Security. |
| * Copyright (C) 2002-2007 The Regents of the University of California. |
| * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). |
| * Written by Danny Auble <da@llnl.gov> |
| * CODE-OCEC-09-009. All rights reserved. |
| * |
| * This file is part of SLURM, a resource management program. |
| * For details, see <https://computing.llnl.gov/linux/slurm/>. |
| * 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. |
| \*****************************************************************************/ |
| |
| #include "src/sacctmgr/sacctmgr.h" |
| #include "src/common/uid.h" |
| |
| typedef struct { |
| slurmdb_admin_level_t admin; |
| uint16_t classification; |
| List coord_list; /* char *list */ |
| char *def_acct; |
| uint32_t def_qos_id; |
| char *def_wckey; |
| char *desc; |
| uint32_t fairshare; |
| |
| uint64_t grp_cpu_mins; |
| uint32_t grp_cpus; |
| uint32_t grp_jobs; |
| uint32_t grp_nodes; |
| uint32_t grp_submit_jobs; |
| uint32_t grp_wall; |
| |
| uint64_t max_cpu_mins_pj; |
| uint32_t max_cpus_pj; |
| uint32_t max_jobs; |
| uint32_t max_nodes_pj; |
| uint32_t max_submit_jobs; |
| uint32_t max_wall_pj; |
| |
| char *name; |
| char *org; |
| char *part; |
| List qos_list; |
| List wckey_list; |
| } sacctmgr_file_opts_t; |
| |
| typedef enum { |
| MOD_CLUSTER, |
| MOD_ACCT, |
| MOD_USER |
| } sacctmgr_mod_type_t; |
| |
| static int _init_sacctmgr_file_opts(sacctmgr_file_opts_t *file_opts) |
| { |
| if (!file_opts) |
| return SLURM_ERROR; |
| |
| memset(file_opts, 0, sizeof(sacctmgr_file_opts_t)); |
| |
| file_opts->admin = SLURMDB_ADMIN_NOTSET; |
| |
| file_opts->fairshare = NO_VAL; |
| |
| file_opts->def_qos_id = NO_VAL; |
| |
| file_opts->grp_cpu_mins = (uint64_t)NO_VAL; |
| file_opts->grp_cpus = NO_VAL; |
| file_opts->grp_jobs = NO_VAL; |
| file_opts->grp_nodes = NO_VAL; |
| file_opts->grp_submit_jobs = NO_VAL; |
| file_opts->grp_wall = NO_VAL; |
| |
| file_opts->max_cpu_mins_pj = (uint64_t)NO_VAL; |
| file_opts->max_cpus_pj = NO_VAL; |
| file_opts->max_jobs = NO_VAL; |
| file_opts->max_nodes_pj = NO_VAL; |
| file_opts->max_submit_jobs = NO_VAL; |
| file_opts->max_wall_pj = NO_VAL; |
| |
| return SLURM_SUCCESS; |
| } |
| |
| static int _strip_continuation(char *buf, int len) |
| { |
| char *ptr; |
| int bs = 0; |
| |
| for (ptr = buf+len-1; ptr >= buf; ptr--) { |
| if (*ptr == '\\') |
| bs++; |
| else if (isspace(*ptr) && bs == 0) |
| continue; |
| else |
| break; |
| } |
| /* Check for an odd number of contiguous backslashes at |
| the end of the line */ |
| if (bs % 2 == 1) { |
| ptr = ptr + bs; |
| *ptr = '\0'; |
| return (ptr - buf); |
| } else { |
| return len; /* no continuation */ |
| } |
| } |
| |
| /* Strip comments from a line by terminating the string |
| * where the comment begins. |
| * Everything after a non-escaped "#" is a comment. |
| */ |
| static void _strip_comments(char *line) |
| { |
| int i; |
| int len = strlen(line); |
| int bs_count = 0; |
| |
| for (i = 0; i < len; i++) { |
| /* if # character is preceded by an even number of |
| * escape characters '\' */ |
| if (line[i] == '#' && (bs_count%2) == 0) { |
| line[i] = '\0'; |
| break; |
| } else if (line[i] == '\\') { |
| bs_count++; |
| } else { |
| bs_count = 0; |
| } |
| } |
| } |
| |
| /* |
| * Strips any escape characters, "\". If you WANT a back-slash, |
| * it must be escaped, "\\". |
| */ |
| static void _strip_escapes(char *line) |
| { |
| int i, j; |
| int len = strlen(line); |
| |
| for (i = 0, j = 0; i < len+1; i++, j++) { |
| if (line[i] == '\\') |
| i++; |
| line[j] = line[i]; |
| } |
| } |
| |
| /* |
| * Reads the next line from the "file" into buffer "buf". |
| * |
| * Concatonates together lines that are continued on |
| * the next line by a trailing "\". Strips out comments, |
| * replaces escaped "\#" with "#", and replaces "\\" with "\". |
| */ |
| static int _get_next_line(char *buf, int buf_size, FILE *file) |
| { |
| char *ptr = buf; |
| int leftover = buf_size; |
| int read_size, new_size; |
| int lines = 0; |
| |
| while (fgets(ptr, leftover, file)) { |
| lines++; |
| _strip_comments(ptr); |
| read_size = strlen(ptr); |
| new_size = _strip_continuation(ptr, read_size); |
| if (new_size < read_size) { |
| ptr += new_size; |
| leftover -= new_size; |
| } else { /* no continuation */ |
| break; |
| } |
| } |
| /* _strip_cr_nl(buf); */ /* not necessary */ |
| _strip_escapes(buf); |
| |
| return lines; |
| } |
| |
| static void _destroy_sacctmgr_file_opts(void *object) |
| { |
| sacctmgr_file_opts_t *file_opts = (sacctmgr_file_opts_t *)object; |
| |
| if (file_opts) { |
| if (file_opts->coord_list) |
| list_destroy(file_opts->coord_list); |
| xfree(file_opts->def_acct); |
| xfree(file_opts->def_wckey); |
| xfree(file_opts->desc); |
| xfree(file_opts->name); |
| xfree(file_opts->org); |
| xfree(file_opts->part); |
| if (file_opts->qos_list) { |
| list_destroy(file_opts->qos_list); |
| file_opts->qos_list = NULL; |
| } |
| if (file_opts->wckey_list) { |
| list_destroy(file_opts->wckey_list); |
| file_opts->wckey_list = NULL; |
| } |
| xfree(file_opts); |
| } |
| } |
| |
| static sacctmgr_file_opts_t *_parse_options(char *options) |
| { |
| int start=0, i=0, end=0, mins, quote = 0; |
| char *sub = NULL; |
| sacctmgr_file_opts_t *file_opts = xmalloc(sizeof(sacctmgr_file_opts_t)); |
| char *option = NULL; |
| char quote_c = '\0'; |
| int command_len = 0; |
| int option2 = 0; |
| |
| _init_sacctmgr_file_opts(file_opts); |
| |
| while (options[i]) { |
| quote = 0; |
| start=i; |
| |
| while (options[i] && options[i] != ':' && options[i] != '\n') { |
| if (options[i] == '"' || options[i] == '\'') { |
| if (quote) { |
| if (options[i] == quote_c) |
| quote = 0; |
| } else { |
| quote = 1; |
| quote_c = options[i]; |
| } |
| } |
| i++; |
| } |
| if (quote) { |
| while (options[i] && options[i] != quote_c) |
| i++; |
| if (!options[i]) |
| fatal("There is a problem with option " |
| "%s with quotes.", option); |
| i++; |
| } |
| |
| if (i-start <= 0) |
| goto next_col; |
| |
| sub = xstrndup(options+start, i-start); |
| end = parse_option_end(sub); |
| command_len = end - 1; |
| if (sub[end] == '=') { |
| option2 = (int)sub[end-1]; |
| end++; |
| } |
| |
| option = strip_quotes(sub+end, NULL, 1); |
| |
| if (!end) { |
| if (file_opts->name) { |
| exit_code=1; |
| fprintf(stderr, " Bad format on %s: " |
| "End your option with " |
| "an '=' sign\n", sub); |
| _destroy_sacctmgr_file_opts(file_opts); |
| break; |
| } |
| file_opts->name = xstrdup(option); |
| } else if (end && !strlen(option)) { |
| debug("blank field given for %s discarding", sub); |
| } else if (!strncasecmp (sub, "AdminLevel", |
| MAX(command_len, 2))) { |
| file_opts->admin = str_2_slurmdb_admin_level(option); |
| } else if (!strncasecmp (sub, "Coordinator", |
| MAX(command_len, 2))) { |
| if (!file_opts->coord_list) |
| file_opts->coord_list = |
| list_create(slurm_destroy_char); |
| slurm_addto_char_list(file_opts->coord_list, option); |
| } else if (!strncasecmp (sub, "Classification", |
| MAX(command_len, 2))) { |
| file_opts->classification = |
| str_2_classification(option); |
| } else if (!strncasecmp (sub, "DefaultAccount", |
| MAX(command_len, 8))) { |
| file_opts->def_acct = xstrdup(option); |
| } else if (!strncasecmp (sub, "DefaultQOS", |
| MAX(command_len, 8))) { |
| if (!g_qos_list) { |
| g_qos_list = acct_storage_g_get_qos( |
| db_conn, my_uid, NULL); |
| } |
| |
| file_opts->def_qos_id = str_2_slurmdb_qos( |
| g_qos_list, option); |
| |
| if (file_opts->def_qos_id == NO_VAL) { |
| fprintf(stderr, |
| "You gave a bad qos '%s'. " |
| "Use 'list qos' to get " |
| "complete list.\n", |
| option); |
| _destroy_sacctmgr_file_opts(file_opts); |
| break; |
| } |
| } else if (!strncasecmp (sub, "DefaultWCKey", |
| MAX(command_len, 8))) { |
| file_opts->def_wckey = xstrdup(option); |
| if (!file_opts->wckey_list) |
| file_opts->wckey_list = |
| list_create(slurm_destroy_char); |
| slurm_addto_char_list(file_opts->wckey_list, option); |
| } else if (!strncasecmp (sub, "Description", |
| MAX(command_len, 3))) { |
| file_opts->desc = xstrdup(option); |
| } else if (!strncasecmp (sub, "FairShare", |
| MAX(command_len, 1)) |
| || !strncasecmp (sub, "Shares", |
| MAX(command_len, 1))) { |
| if (get_uint(option, &file_opts->fairshare, |
| "FairShare") != SLURM_SUCCESS) { |
| exit_code=1; |
| fprintf(stderr, |
| " Bad FairShare value: %s\n", option); |
| _destroy_sacctmgr_file_opts(file_opts); |
| break; |
| } |
| } else if (!strncasecmp (sub, "GrpCPUMins", |
| MAX(command_len, 7))) { |
| if (get_uint64(option, &file_opts->grp_cpu_mins, |
| "GrpCPUMins") != SLURM_SUCCESS) { |
| exit_code=1; |
| fprintf(stderr, |
| " Bad GrpCPUMins value: %s\n", option); |
| _destroy_sacctmgr_file_opts(file_opts); |
| break; |
| } |
| } else if (!strncasecmp (sub, "GrpCPUs", MAX(command_len, 7))) { |
| if (get_uint(option, &file_opts->grp_cpus, |
| "GrpCPUs") != SLURM_SUCCESS) { |
| exit_code=1; |
| fprintf(stderr, |
| " Bad GrpCPUs value: %s\n", option); |
| _destroy_sacctmgr_file_opts(file_opts); |
| break; |
| } |
| } else if (!strncasecmp (sub, "GrpJobs", MAX(command_len, 4))) { |
| if (get_uint(option, &file_opts->grp_jobs, |
| "GrpJobs") != SLURM_SUCCESS) { |
| exit_code=1; |
| fprintf(stderr, |
| " Bad GrpJobs value: %s\n", option); |
| _destroy_sacctmgr_file_opts(file_opts); |
| break; |
| } |
| } else if (!strncasecmp (sub, "GrpNodes", |
| MAX(command_len, 4))) { |
| if (get_uint(option, &file_opts->grp_nodes, |
| "GrpNodes") != SLURM_SUCCESS) { |
| exit_code=1; |
| fprintf(stderr, |
| " Bad GrpNodes value: %s\n", option); |
| _destroy_sacctmgr_file_opts(file_opts); |
| break; |
| } |
| } else if (!strncasecmp (sub, "GrpSubmitJobs", |
| MAX(command_len, 4))) { |
| if (get_uint(option, &file_opts->grp_submit_jobs, |
| "GrpSubmitJobs") != SLURM_SUCCESS) { |
| exit_code=1; |
| fprintf(stderr, |
| " Bad GrpJobs value: %s\n", option); |
| _destroy_sacctmgr_file_opts(file_opts); |
| break; |
| } |
| } else if (!strncasecmp (sub, "GrpWall", MAX(command_len, 4))) { |
| mins = time_str2mins(option); |
| if (mins >= 0) { |
| file_opts->grp_wall |
| = (uint32_t) mins; |
| } else if (strcmp(option, "-1")) { |
| file_opts->grp_wall = INFINITE; |
| } else { |
| exit_code=1; |
| fprintf(stderr, |
| " Bad GrpWall time format: %s\n", |
| option); |
| _destroy_sacctmgr_file_opts(file_opts); |
| break; |
| } |
| } else if (!strncasecmp (sub, "MaxCPUMinsPerJob", |
| MAX(command_len, 7)) |
| || !strncasecmp (sub, "MaxProcSecPerJob", |
| MAX(command_len, 4))) { |
| if (get_uint64(option, &file_opts->max_cpu_mins_pj, |
| "MaxCPUMins") != SLURM_SUCCESS) { |
| exit_code=1; |
| fprintf(stderr, |
| " Bad MaxCPUMins value: %s\n", option); |
| _destroy_sacctmgr_file_opts(file_opts); |
| break; |
| } |
| } else if (!strncasecmp (sub, "MaxCPUsPerJob", |
| MAX(command_len, 7))) { |
| if (get_uint(option, &file_opts->max_cpus_pj, |
| "MaxCPUs") != SLURM_SUCCESS) { |
| exit_code=1; |
| fprintf(stderr, |
| " Bad MaxCPUs value: %s\n", option); |
| _destroy_sacctmgr_file_opts(file_opts); |
| break; |
| } |
| } else if (!strncasecmp (sub, "MaxJobs", MAX(command_len, 4))) { |
| if (get_uint(option, &file_opts->max_jobs, |
| "MaxJobs") != SLURM_SUCCESS) { |
| exit_code=1; |
| fprintf(stderr, |
| " Bad MaxJobs value: %s\n", option); |
| _destroy_sacctmgr_file_opts(file_opts); |
| break; |
| } |
| } else if (!strncasecmp (sub, "MaxNodesPerJob", |
| MAX(command_len, 4))) { |
| if (get_uint(option, &file_opts->max_nodes_pj, |
| "MaxNodes") != SLURM_SUCCESS) { |
| exit_code=1; |
| fprintf(stderr, |
| " Bad MaxNodes value: %s\n", option); |
| _destroy_sacctmgr_file_opts(file_opts); |
| break; |
| } |
| } else if (!strncasecmp (sub, "MaxSubmitJobs", |
| MAX(command_len, 4))) { |
| if (get_uint(option, &file_opts->max_submit_jobs, |
| "MaxSubmitJobs") != SLURM_SUCCESS) { |
| exit_code=1; |
| fprintf(stderr, |
| " Bad MaxJobs value: %s\n", option); |
| _destroy_sacctmgr_file_opts(file_opts); |
| break; |
| } |
| } else if (!strncasecmp (sub, "MaxWallDurationPerJob", |
| MAX(command_len, 4))) { |
| mins = time_str2mins(option); |
| if (mins >= 0) { |
| file_opts->max_wall_pj |
| = (uint32_t) mins; |
| } else if (strcmp(option, "-1")) { |
| file_opts->max_wall_pj = INFINITE; |
| } else { |
| exit_code=1; |
| fprintf(stderr, |
| " Bad MaxWall time format: %s\n", |
| option); |
| _destroy_sacctmgr_file_opts(file_opts); |
| break; |
| } |
| } else if (!strncasecmp (sub, "Organization", |
| MAX(command_len, 1))) { |
| file_opts->org = xstrdup(option); |
| } else if (!strncasecmp (sub, "Partition", |
| MAX(command_len, 1))) { |
| file_opts->part = xstrdup(option); |
| } else if (!strncasecmp (sub, "QosLevel", MAX(command_len, 1)) |
| || !strncasecmp (sub, "Expedite", |
| MAX(command_len, 1))) { |
| if (!file_opts->qos_list) { |
| file_opts->qos_list = |
| list_create(slurm_destroy_char); |
| } |
| |
| if (!g_qos_list) { |
| g_qos_list = acct_storage_g_get_qos( |
| db_conn, my_uid, NULL); |
| } |
| |
| slurmdb_addto_qos_char_list(file_opts->qos_list, |
| g_qos_list, |
| option, option2); |
| } else if (!strncasecmp (sub, "WCKeys", |
| MAX(command_len, 2))) { |
| if (!file_opts->wckey_list) |
| file_opts->wckey_list = |
| list_create(slurm_destroy_char); |
| slurm_addto_char_list(file_opts->wckey_list, option); |
| } else { |
| exit_code=1; |
| fprintf(stderr, " Unknown option: %s\n", sub); |
| } |
| |
| xfree(sub); |
| xfree(option); |
| |
| next_col: |
| if (options[i] == ':') |
| i++; |
| else |
| break; |
| } |
| |
| xfree(sub); |
| xfree(option); |
| |
| if (!file_opts->name) { |
| exit_code=1; |
| fprintf(stderr, " No name given\n"); |
| _destroy_sacctmgr_file_opts(file_opts); |
| file_opts = NULL; |
| } else if (exit_code) { |
| _destroy_sacctmgr_file_opts(file_opts); |
| file_opts = NULL; |
| } |
| |
| return file_opts; |
| } |
| |
| static int _print_out_assoc(List assoc_list, bool user, bool add) |
| { |
| List format_list = NULL; |
| List print_fields_list = NULL; |
| ListIterator itr, itr2; |
| print_field_t *field = NULL; |
| slurmdb_association_rec_t *assoc = NULL; |
| int rc = SLURM_SUCCESS; |
| char *tmp_char = NULL; |
| |
| if (!assoc_list || !list_count(assoc_list)) |
| return rc; |
| |
| format_list = list_create(slurm_destroy_char); |
| if (user) |
| slurm_addto_char_list(format_list, |
| "User,Account"); |
| else |
| slurm_addto_char_list(format_list, |
| "Account,ParentName"); |
| slurm_addto_char_list(format_list, |
| "Share,GrpCPUM,GrpCPUs," |
| "GrpJ,GrpN,GrpS,GrpW,MaxCPUM,MaxCPUs," |
| "MaxJ,MaxS,MaxN,MaxW,QOS,DefaultQOS"); |
| |
| print_fields_list = sacctmgr_process_format_list(format_list); |
| list_destroy(format_list); |
| |
| print_fields_header(print_fields_list); |
| |
| itr = list_iterator_create(assoc_list); |
| itr2 = list_iterator_create(print_fields_list); |
| while ((assoc = list_next(itr))) { |
| while ((field = list_next(itr2))) { |
| switch(field->type) { |
| case PRINT_ACCT: |
| field->print_routine(field, |
| assoc->acct); |
| break; |
| case PRINT_DQOS: |
| if (!g_qos_list) |
| g_qos_list = acct_storage_g_get_qos( |
| db_conn, |
| my_uid, |
| NULL); |
| |
| tmp_char = slurmdb_qos_str( |
| g_qos_list, |
| assoc->def_qos_id); |
| field->print_routine( |
| field, |
| tmp_char); |
| break; |
| case PRINT_FAIRSHARE: |
| field->print_routine(field, |
| assoc->shares_raw); |
| break; |
| case PRINT_GRPCM: |
| field->print_routine( |
| field, |
| assoc->grp_cpu_mins); |
| break; |
| case PRINT_GRPC: |
| field->print_routine(field, |
| assoc->grp_cpus); |
| break; |
| case PRINT_GRPJ: |
| field->print_routine(field, |
| assoc->grp_jobs); |
| break; |
| case PRINT_GRPN: |
| field->print_routine(field, |
| assoc->grp_nodes); |
| break; |
| case PRINT_GRPS: |
| field->print_routine(field, |
| assoc->grp_submit_jobs); |
| break; |
| case PRINT_GRPW: |
| field->print_routine( |
| field, |
| assoc->grp_wall); |
| break; |
| case PRINT_MAXCM: |
| field->print_routine( |
| field, |
| assoc->max_cpu_mins_pj); |
| break; |
| case PRINT_MAXC: |
| field->print_routine(field, |
| assoc->max_cpus_pj); |
| break; |
| case PRINT_MAXJ: |
| field->print_routine(field, |
| assoc->max_jobs); |
| break; |
| case PRINT_MAXN: |
| field->print_routine(field, |
| assoc->max_nodes_pj); |
| break; |
| case PRINT_MAXS: |
| field->print_routine(field, |
| assoc->max_submit_jobs); |
| break; |
| case PRINT_MAXW: |
| field->print_routine( |
| field, |
| assoc->max_wall_pj); |
| break; |
| case PRINT_PNAME: |
| field->print_routine(field, |
| assoc->parent_acct); |
| break; |
| case PRINT_PART: |
| field->print_routine(field, |
| assoc->partition); |
| break; |
| case PRINT_QOS: |
| if (!g_qos_list) |
| g_qos_list = acct_storage_g_get_qos( |
| db_conn, my_uid, NULL); |
| |
| field->print_routine( |
| field, |
| g_qos_list, |
| assoc->qos_list); |
| break; |
| case PRINT_USER: |
| field->print_routine(field, |
| assoc->user); |
| break; |
| default: |
| field->print_routine( |
| field, NULL); |
| break; |
| } |
| } |
| list_iterator_reset(itr2); |
| printf("\n"); |
| } |
| list_iterator_destroy(itr); |
| list_iterator_destroy(itr2); |
| list_destroy(print_fields_list); |
| if (add) |
| rc = acct_storage_g_add_associations(db_conn, |
| my_uid, assoc_list); |
| printf("--------------------------------------------------------------\n\n"); |
| |
| return rc; |
| } |
| |
| static int _mod_assoc(sacctmgr_file_opts_t *file_opts, |
| slurmdb_association_rec_t *assoc, |
| sacctmgr_mod_type_t mod_type, |
| char *parent) |
| { |
| int changed = 0; |
| slurmdb_association_rec_t mod_assoc; |
| slurmdb_association_cond_t assoc_cond; |
| char *type = NULL; |
| char *name = NULL; |
| char *my_info = NULL; |
| |
| switch(mod_type) { |
| case MOD_CLUSTER: |
| type = "Cluster"; |
| name = assoc->cluster; |
| break; |
| case MOD_ACCT: |
| type = "Account"; |
| name = assoc->acct; |
| break; |
| case MOD_USER: |
| type = "User"; |
| name = assoc->user; |
| break; |
| default: |
| return 0; |
| break; |
| } |
| slurmdb_init_association_rec(&mod_assoc, 0); |
| memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t)); |
| |
| if ((file_opts->fairshare != NO_VAL) |
| && (assoc->shares_raw != file_opts->fairshare)) { |
| mod_assoc.shares_raw = file_opts->fairshare; |
| changed = 1; |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8d -> %d\n", |
| " Changed fairshare", |
| type, name, |
| assoc->shares_raw, |
| file_opts->fairshare); |
| } |
| |
| if ((file_opts->grp_cpu_mins != NO_VAL) |
| && (assoc->grp_cpu_mins != file_opts->grp_cpu_mins)) { |
| mod_assoc.grp_cpu_mins = file_opts->grp_cpu_mins; |
| changed = 1; |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s " |
| "%8"PRIu64" -> %"PRIu64"\n", |
| " Changed GrpCPUMins", |
| type, name, |
| assoc->grp_cpu_mins, |
| file_opts->grp_cpu_mins); |
| } |
| |
| if ((file_opts->grp_cpus != NO_VAL) |
| && (assoc->grp_cpus != file_opts->grp_cpus)) { |
| mod_assoc.grp_cpus = file_opts->grp_cpus; |
| changed = 1; |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8d -> %d\n", |
| " Changed GrpCpus", |
| type, name, |
| assoc->grp_cpus, |
| file_opts->grp_cpus); |
| } |
| |
| if ((file_opts->grp_jobs != NO_VAL) |
| && (assoc->grp_jobs != file_opts->grp_jobs)) { |
| mod_assoc.grp_jobs = file_opts->grp_jobs; |
| changed = 1; |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8d -> %d\n", |
| " Changed GrpJobs", |
| type, name, |
| assoc->grp_jobs, |
| file_opts->grp_jobs); |
| } |
| |
| if ((file_opts->grp_nodes != NO_VAL) |
| && (assoc->grp_nodes != file_opts->grp_nodes)) { |
| mod_assoc.grp_nodes = file_opts->grp_nodes; |
| changed = 1; |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8d -> %d\n", |
| " Changed GrpNodes", |
| type, name, |
| assoc->grp_nodes, |
| file_opts->grp_nodes); |
| } |
| |
| if ((file_opts->grp_submit_jobs != NO_VAL) |
| && (assoc->grp_submit_jobs != file_opts->grp_submit_jobs)) { |
| mod_assoc.grp_submit_jobs = file_opts->grp_submit_jobs; |
| changed = 1; |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8d -> %d\n", |
| " Changed GrpSubmitJobs", |
| type, name, |
| assoc->grp_submit_jobs, |
| file_opts->grp_submit_jobs); |
| } |
| |
| if ((file_opts->grp_wall != NO_VAL) |
| && (assoc->grp_wall != file_opts->grp_wall)) { |
| mod_assoc.grp_wall = file_opts->grp_wall; |
| changed = 1; |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8d -> %d\n", |
| " Changed GrpWallDuration", |
| type, name, |
| assoc->grp_wall, |
| file_opts->grp_wall); |
| } |
| |
| if ((file_opts->max_cpu_mins_pj != (uint64_t)NO_VAL) |
| && (assoc->max_cpu_mins_pj != file_opts->max_cpu_mins_pj)) { |
| mod_assoc.max_cpu_mins_pj = |
| file_opts->max_cpu_mins_pj; |
| changed = 1; |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s " |
| "%8"PRIu64" -> %"PRIu64"\n", |
| " Changed MaxCPUMinsPerJob", |
| type, name, |
| assoc->max_cpu_mins_pj, |
| file_opts->max_cpu_mins_pj); |
| } |
| |
| if ((file_opts->max_cpus_pj != NO_VAL) |
| && (assoc->max_cpus_pj != file_opts->max_cpus_pj)) { |
| mod_assoc.max_cpus_pj = file_opts->max_cpus_pj; |
| changed = 1; |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8d -> %d\n", |
| " Changed MaxCpusPerJob", |
| type, name, |
| assoc->max_cpus_pj, |
| file_opts->max_cpus_pj); |
| } |
| |
| if ((file_opts->max_jobs != NO_VAL) |
| && (assoc->max_jobs != file_opts->max_jobs)) { |
| mod_assoc.max_jobs = file_opts->max_jobs; |
| changed = 1; |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8d -> %d\n", |
| " Changed MaxJobs", |
| type, name, |
| assoc->max_jobs, |
| file_opts->max_jobs); |
| } |
| |
| if ((file_opts->max_nodes_pj != NO_VAL) |
| && (assoc->max_nodes_pj != file_opts->max_nodes_pj)) { |
| mod_assoc.max_nodes_pj = file_opts->max_nodes_pj; |
| changed = 1; |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8d -> %d\n", |
| " Changed MaxNodesPerJob", |
| type, name, |
| assoc->max_nodes_pj, |
| file_opts->max_nodes_pj); |
| } |
| |
| if ((file_opts->max_submit_jobs != NO_VAL) |
| && (assoc->max_submit_jobs != file_opts->max_submit_jobs)) { |
| mod_assoc.max_submit_jobs = file_opts->max_submit_jobs; |
| changed = 1; |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8d -> %d\n", |
| " Changed MaxSubmitJobs", |
| type, name, |
| assoc->max_submit_jobs, |
| file_opts->max_submit_jobs); |
| } |
| |
| if ((file_opts->max_wall_pj != NO_VAL) |
| && (assoc->max_wall_pj != file_opts->max_wall_pj)) { |
| mod_assoc.max_wall_pj = file_opts->max_wall_pj; |
| changed = 1; |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8d -> %d\n", |
| " Changed MaxWallDurationPerJob", |
| type, name, |
| assoc->max_wall_pj, |
| file_opts->max_wall_pj); |
| } |
| if (assoc->parent_acct && parent |
| && strcmp(assoc->parent_acct, parent)) { |
| mod_assoc.parent_acct = parent; |
| changed = 1; |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8s -> %s\n", |
| " Changed Parent", |
| type, name, |
| assoc->parent_acct, |
| parent); |
| } |
| |
| if (assoc->qos_list && list_count(assoc->qos_list) |
| && file_opts->qos_list && list_count(file_opts->qos_list)) { |
| ListIterator now_qos_itr = |
| list_iterator_create(assoc->qos_list), |
| new_qos_itr = list_iterator_create(file_opts->qos_list); |
| char *now_qos = NULL, *new_qos = NULL; |
| |
| if (!mod_assoc.qos_list) |
| mod_assoc.qos_list = list_create(slurm_destroy_char); |
| while ((new_qos = list_next(new_qos_itr))) { |
| while ((now_qos = list_next(now_qos_itr))) { |
| if (!strcmp(new_qos, now_qos)) |
| break; |
| } |
| list_iterator_reset(now_qos_itr); |
| if (!now_qos) |
| list_append(mod_assoc.qos_list, |
| xstrdup(new_qos)); |
| } |
| list_iterator_destroy(new_qos_itr); |
| list_iterator_destroy(now_qos_itr); |
| if (mod_assoc.qos_list && list_count(mod_assoc.qos_list)) |
| new_qos = get_qos_complete_str(g_qos_list, |
| mod_assoc.qos_list); |
| if (new_qos) { |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8s\n", |
| " Added QOS", |
| type, name, |
| new_qos); |
| xfree(new_qos); |
| changed = 1; |
| } else { |
| list_destroy(mod_assoc.qos_list); |
| mod_assoc.qos_list = NULL; |
| } |
| } else if (file_opts->qos_list && list_count(file_opts->qos_list)) { |
| char *new_qos = get_qos_complete_str(g_qos_list, |
| file_opts->qos_list); |
| |
| if (new_qos) { |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8s\n", |
| " Added QOS", |
| type, name, |
| new_qos); |
| xfree(new_qos); |
| mod_assoc.qos_list = file_opts->qos_list; |
| file_opts->qos_list = NULL; |
| changed = 1; |
| } |
| } |
| |
| if (changed) { |
| List ret_list = NULL; |
| |
| assoc_cond.cluster_list = list_create(NULL); |
| list_push(assoc_cond.cluster_list, assoc->cluster); |
| |
| assoc_cond.acct_list = list_create(NULL); |
| list_push(assoc_cond.acct_list, assoc->acct); |
| |
| if (mod_type == MOD_USER) { |
| assoc_cond.user_list = list_create(NULL); |
| list_push(assoc_cond.user_list, assoc->user); |
| if (assoc->partition) { |
| assoc_cond.partition_list = list_create(NULL); |
| list_push(assoc_cond.partition_list, |
| assoc->partition); |
| } |
| } |
| |
| notice_thread_init(); |
| ret_list = acct_storage_g_modify_associations( |
| db_conn, my_uid, |
| &assoc_cond, |
| &mod_assoc); |
| notice_thread_fini(); |
| |
| if (mod_assoc.qos_list) |
| list_destroy(mod_assoc.qos_list); |
| |
| list_destroy(assoc_cond.cluster_list); |
| list_destroy(assoc_cond.acct_list); |
| if (assoc_cond.user_list) |
| list_destroy(assoc_cond.user_list); |
| if (assoc_cond.partition_list) |
| list_destroy(assoc_cond.partition_list); |
| |
| /* if (ret_list && list_count(ret_list)) { */ |
| /* char *object = NULL; */ |
| /* ListIterator itr = list_iterator_create(ret_list); */ |
| /* printf(" Modified account defaults for " */ |
| /* "associations...\n"); */ |
| /* while ((object = list_next(itr))) */ |
| /* printf(" %s\n", object); */ |
| /* list_iterator_destroy(itr); */ |
| /* } */ |
| |
| if (ret_list) { |
| printf("%s", my_info); |
| list_destroy(ret_list); |
| } else |
| changed = 0; |
| xfree(my_info); |
| } |
| |
| return changed; |
| } |
| |
| static int _mod_cluster(sacctmgr_file_opts_t *file_opts, |
| slurmdb_cluster_rec_t *cluster, char *parent) |
| { |
| int changed = 0; |
| char *my_info = NULL; |
| slurmdb_cluster_rec_t mod_cluster; |
| slurmdb_cluster_cond_t cluster_cond; |
| |
| slurmdb_init_cluster_rec(&mod_cluster, 0); |
| slurmdb_init_cluster_cond(&cluster_cond, 0); |
| |
| if (file_opts->classification |
| && (file_opts->classification != cluster->classification)) { |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8s -> %s\n", |
| " Changed Classification", "Cluster", |
| cluster->name, |
| get_classification_str(cluster->classification), |
| get_classification_str(file_opts->classification)); |
| mod_cluster.classification = file_opts->classification; |
| changed = 1; |
| } |
| |
| if (changed) { |
| List ret_list = NULL; |
| |
| cluster_cond.cluster_list = list_create(NULL); |
| |
| list_append(cluster_cond.cluster_list, cluster->name); |
| |
| notice_thread_init(); |
| ret_list = acct_storage_g_modify_clusters(db_conn, my_uid, |
| &cluster_cond, |
| &mod_cluster); |
| notice_thread_fini(); |
| |
| list_destroy(cluster_cond.cluster_list); |
| |
| /* if (ret_list && list_count(ret_list)) { */ |
| /* char *object = NULL; */ |
| /* ListIterator itr = list_iterator_create(ret_list); */ |
| /* printf(" Modified account defaults for " */ |
| /* "associations...\n"); */ |
| /* while ((object = list_next(itr))) */ |
| /* printf(" %s\n", object); */ |
| /* list_iterator_destroy(itr); */ |
| /* } */ |
| |
| if (ret_list) { |
| printf("%s", my_info); |
| list_destroy(ret_list); |
| } else |
| changed = 0; |
| xfree(my_info); |
| } |
| if (!cluster->root_assoc || !cluster->root_assoc->cluster) { |
| error("Cluster %s doesn't appear to have a root association. " |
| "Try removing this cluster and then re-run load.", |
| cluster->name); |
| exit(1); |
| } |
| |
| changed += _mod_assoc(file_opts, cluster->root_assoc, |
| MOD_CLUSTER, parent); |
| |
| return changed; |
| } |
| |
| static int _mod_acct(sacctmgr_file_opts_t *file_opts, |
| slurmdb_account_rec_t *acct, char *parent) |
| { |
| int changed = 0; |
| char *desc = NULL, *org = NULL, *my_info = NULL; |
| slurmdb_account_rec_t mod_acct; |
| slurmdb_account_cond_t acct_cond; |
| slurmdb_association_cond_t assoc_cond; |
| |
| memset(&mod_acct, 0, sizeof(slurmdb_account_rec_t)); |
| memset(&acct_cond, 0, sizeof(slurmdb_account_cond_t)); |
| memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t)); |
| |
| if (file_opts->desc) |
| desc = xstrdup(file_opts->desc); |
| |
| if (desc && strcmp(desc, acct->description)) { |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8s -> %s\n", |
| " Changed description", "Account", |
| acct->name, |
| acct->description, |
| desc); |
| mod_acct.description = desc; |
| changed = 1; |
| } else |
| xfree(desc); |
| |
| if (file_opts->org) |
| org = xstrdup(file_opts->org); |
| |
| if (org && strcmp(org, acct->organization)) { |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8s -> %s\n", |
| " Changed organization", "Account", |
| acct->name, |
| acct->organization, |
| org); |
| mod_acct.organization = org; |
| changed = 1; |
| } else |
| xfree(org); |
| |
| if (changed) { |
| List ret_list = NULL; |
| |
| assoc_cond.acct_list = list_create(NULL); |
| list_append(assoc_cond.acct_list, acct->name); |
| acct_cond.assoc_cond = &assoc_cond; |
| |
| notice_thread_init(); |
| ret_list = acct_storage_g_modify_accounts(db_conn, my_uid, |
| &acct_cond, |
| &mod_acct); |
| notice_thread_fini(); |
| |
| list_destroy(assoc_cond.acct_list); |
| |
| /* if (ret_list && list_count(ret_list)) { */ |
| /* char *object = NULL; */ |
| /* ListIterator itr = list_iterator_create(ret_list); */ |
| /* printf(" Modified account defaults for " */ |
| /* "associations...\n"); */ |
| /* while ((object = list_next(itr))) */ |
| /* printf(" %s\n", object); */ |
| /* list_iterator_destroy(itr); */ |
| /* } */ |
| |
| if (ret_list) { |
| printf("%s", my_info); |
| list_destroy(ret_list); |
| } else |
| changed = 0; |
| xfree(my_info); |
| } |
| xfree(desc); |
| xfree(org); |
| return changed; |
| } |
| |
| static int _mod_user(sacctmgr_file_opts_t *file_opts, |
| slurmdb_user_rec_t *user, char *cluster, char *parent) |
| { |
| int rc; |
| int set = 0; |
| int changed = 0; |
| char *def_acct = NULL, *def_wckey = NULL, *my_info = NULL; |
| slurmdb_user_rec_t mod_user; |
| slurmdb_user_cond_t user_cond; |
| List ret_list = NULL; |
| slurmdb_association_cond_t assoc_cond; |
| |
| if (!user || !user->name) { |
| fatal(" We need a user name in _mod_user"); |
| } |
| |
| memset(&mod_user, 0, sizeof(slurmdb_user_rec_t)); |
| memset(&user_cond, 0, sizeof(slurmdb_user_cond_t)); |
| memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t)); |
| |
| assoc_cond.user_list = list_create(NULL); |
| list_append(assoc_cond.user_list, user->name); |
| user_cond.assoc_cond = &assoc_cond; |
| |
| if (file_opts->def_acct) |
| def_acct = xstrdup(file_opts->def_acct); |
| |
| if (def_acct && |
| (!user->default_acct || strcmp(def_acct, user->default_acct))) { |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8s -> %s\n", |
| " Changed Default Account", "User", |
| user->name, |
| user->default_acct, |
| def_acct); |
| mod_user.default_acct = def_acct; |
| changed = 1; |
| } |
| |
| if (file_opts->def_wckey) |
| def_wckey = xstrdup(file_opts->def_wckey); |
| |
| if (def_wckey && |
| (!user->default_wckey || strcmp(def_wckey, user->default_wckey))) { |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8s -> %s\n", |
| " Changed Default WCKey", "User", |
| user->name, |
| user->default_wckey, |
| def_wckey); |
| mod_user.default_wckey = def_wckey; |
| changed = 1; |
| } |
| |
| if (user->admin_level != SLURMDB_ADMIN_NOTSET |
| && file_opts->admin != SLURMDB_ADMIN_NOTSET |
| && user->admin_level != file_opts->admin) { |
| xstrfmtcat(my_info, |
| "%-30.30s for %-7.7s %-10.10s %8s -> %s\n", |
| " Changed Admin Level", "User", |
| user->name, |
| slurmdb_admin_level_str( |
| user->admin_level), |
| slurmdb_admin_level_str( |
| file_opts->admin)); |
| mod_user.admin_level = file_opts->admin; |
| changed = 1; |
| } |
| |
| if (changed) { |
| notice_thread_init(); |
| ret_list = acct_storage_g_modify_users( |
| db_conn, my_uid, |
| &user_cond, |
| &mod_user); |
| notice_thread_fini(); |
| |
| /* if (ret_list && list_count(ret_list)) { */ |
| /* char *object = NULL; */ |
| /* ListIterator itr = list_iterator_create(ret_list); */ |
| /* printf(" Modified user defaults for " */ |
| /* "associations...\n"); */ |
| /* while ((object = list_next(itr))) */ |
| /* printf(" %s\n", object); */ |
| /* list_iterator_destroy(itr); */ |
| /* } */ |
| |
| if (ret_list) { |
| printf("%s", my_info); |
| list_destroy(ret_list); |
| set = 1; |
| } |
| xfree(my_info); |
| } |
| xfree(def_acct); |
| xfree(def_wckey); |
| |
| if ((!user->coord_accts || !list_count(user->coord_accts)) |
| && (file_opts->coord_list |
| && list_count(file_opts->coord_list))) { |
| ListIterator coord_itr = NULL; |
| char *temp_char = NULL; |
| slurmdb_coord_rec_t *coord = NULL; |
| int first = 1; |
| notice_thread_init(); |
| rc = acct_storage_g_add_coord(db_conn, my_uid, |
| file_opts->coord_list, |
| &user_cond); |
| notice_thread_fini(); |
| |
| user->coord_accts = list_create(slurmdb_destroy_coord_rec); |
| coord_itr = list_iterator_create(file_opts->coord_list); |
| printf(" Making User '%s' coordinator for account(s)", |
| user->name); |
| while ((temp_char = list_next(coord_itr))) { |
| coord = xmalloc(sizeof(slurmdb_coord_rec_t)); |
| coord->name = xstrdup(temp_char); |
| coord->direct = 1; |
| list_push(user->coord_accts, coord); |
| |
| if (first) { |
| printf(" %s", temp_char); |
| first = 0; |
| } else |
| printf(", %s", temp_char); |
| } |
| list_iterator_destroy(coord_itr); |
| printf("\n"); |
| set = 1; |
| } else if ((user->coord_accts && list_count(user->coord_accts)) |
| && (file_opts->coord_list |
| && list_count(file_opts->coord_list))) { |
| ListIterator coord_itr = NULL; |
| ListIterator char_itr = NULL; |
| char *temp_char = NULL; |
| slurmdb_coord_rec_t *coord = NULL; |
| List add_list = list_create(NULL); |
| |
| coord_itr = list_iterator_create(user->coord_accts); |
| char_itr = list_iterator_create(file_opts->coord_list); |
| |
| while ((temp_char = list_next(char_itr))) { |
| while ((coord = list_next(coord_itr))) { |
| if (!coord->direct) |
| continue; |
| if (!strcmp(coord->name, temp_char)) { |
| break; |
| } |
| } |
| if (!coord) { |
| printf(" Making User '%s' coordinator of " |
| "account '%s'\n", |
| user->name, |
| temp_char); |
| |
| list_append(add_list, temp_char); |
| } |
| list_iterator_reset(coord_itr); |
| } |
| |
| list_iterator_destroy(char_itr); |
| list_iterator_destroy(coord_itr); |
| |
| if (list_count(add_list)) { |
| notice_thread_init(); |
| rc = acct_storage_g_add_coord(db_conn, my_uid, |
| add_list, |
| &user_cond); |
| notice_thread_fini(); |
| set = 1; |
| } |
| list_destroy(add_list); |
| } |
| |
| if ((!user->wckey_list || !list_count(user->wckey_list)) |
| && (file_opts->wckey_list |
| && list_count(file_opts->wckey_list))) { |
| ListIterator wckey_itr = NULL; |
| char *temp_char = NULL; |
| slurmdb_wckey_rec_t *wckey = NULL; |
| int first = 1; |
| |
| user->wckey_list = list_create(slurmdb_destroy_wckey_rec); |
| wckey_itr = list_iterator_create(file_opts->wckey_list); |
| printf(" Adding WCKey(s) "); |
| while ((temp_char = list_next(wckey_itr))) { |
| wckey = xmalloc(sizeof(slurmdb_wckey_rec_t)); |
| wckey->name = xstrdup(temp_char); |
| wckey->cluster = xstrdup(cluster); |
| wckey->user = xstrdup(user->name); |
| if (!strcmp(wckey->name, user->default_wckey)) |
| wckey->is_def = 1; |
| list_push(user->wckey_list, wckey); |
| |
| if (first) { |
| printf("'%s'", temp_char); |
| first = 0; |
| } else |
| printf(", '%s'", temp_char); |
| } |
| list_iterator_destroy(wckey_itr); |
| printf(" for user '%s'\n", user->name); |
| set = 1; |
| notice_thread_init(); |
| rc = acct_storage_g_add_wckeys(db_conn, my_uid, |
| user->wckey_list); |
| notice_thread_fini(); |
| } else if ((user->wckey_list && list_count(user->wckey_list)) |
| && (file_opts->wckey_list |
| && list_count(file_opts->wckey_list))) { |
| ListIterator wckey_itr = NULL; |
| ListIterator char_itr = NULL; |
| char *temp_char = NULL; |
| slurmdb_wckey_rec_t *wckey = NULL; |
| List add_list = list_create(slurmdb_destroy_wckey_rec); |
| |
| wckey_itr = list_iterator_create(user->wckey_list); |
| char_itr = list_iterator_create(file_opts->wckey_list); |
| |
| while ((temp_char = list_next(char_itr))) { |
| while ((wckey = list_next(wckey_itr))) { |
| if (!strcmp(wckey->name, temp_char)) |
| break; |
| } |
| if (!wckey) { |
| printf(" Adding WCKey '%s' to User '%s'\n", |
| temp_char, user->name); |
| wckey = xmalloc(sizeof(slurmdb_wckey_rec_t)); |
| wckey->name = xstrdup(temp_char); |
| wckey->cluster = xstrdup(cluster); |
| wckey->user = xstrdup(user->name); |
| if (!strcmp(wckey->name, user->default_wckey)) |
| wckey->is_def = 1; |
| |
| list_append(add_list, wckey); |
| } |
| list_iterator_reset(wckey_itr); |
| } |
| |
| list_iterator_destroy(char_itr); |
| list_iterator_destroy(wckey_itr); |
| |
| if (list_count(add_list)) { |
| notice_thread_init(); |
| rc = acct_storage_g_add_wckeys(db_conn, my_uid, |
| add_list); |
| notice_thread_fini(); |
| set = 1; |
| } |
| list_transfer(user->wckey_list, add_list); |
| list_destroy(add_list); |
| } |
| |
| list_destroy(assoc_cond.user_list); |
| |
| return set; |
| } |
| |
| static slurmdb_user_rec_t *_set_user_up(sacctmgr_file_opts_t *file_opts, |
| char *cluster, char *parent) |
| { |
| slurmdb_user_rec_t *user = xmalloc(sizeof(slurmdb_user_rec_t)); |
| |
| user->assoc_list = NULL; |
| user->name = xstrdup(file_opts->name); |
| |
| if (file_opts->def_acct) |
| user->default_acct = xstrdup(file_opts->def_acct); |
| else |
| user->default_acct = xstrdup(parent); |
| |
| if (file_opts->def_wckey) |
| user->default_wckey = xstrdup(file_opts->def_wckey); |
| else |
| user->default_wckey = xstrdup(""); |
| |
| user->admin_level = file_opts->admin; |
| |
| if (file_opts->coord_list) { |
| slurmdb_user_cond_t user_cond; |
| slurmdb_association_cond_t assoc_cond; |
| ListIterator coord_itr = NULL; |
| char *temp_char = NULL; |
| slurmdb_coord_rec_t *coord = NULL; |
| |
| memset(&user_cond, 0, sizeof(slurmdb_user_cond_t)); |
| memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t)); |
| assoc_cond.user_list = list_create(NULL); |
| list_append(assoc_cond.user_list, user->name); |
| user_cond.assoc_cond = &assoc_cond; |
| |
| notice_thread_init(); |
| acct_storage_g_add_coord(db_conn, my_uid, |
| file_opts->coord_list, |
| &user_cond); |
| notice_thread_fini(); |
| list_destroy(assoc_cond.user_list); |
| user->coord_accts = list_create(slurmdb_destroy_coord_rec); |
| coord_itr = list_iterator_create(file_opts->coord_list); |
| while ((temp_char = list_next(coord_itr))) { |
| coord = xmalloc(sizeof(slurmdb_coord_rec_t)); |
| coord->name = xstrdup(temp_char); |
| coord->direct = 1; |
| list_push(user->coord_accts, coord); |
| } |
| list_iterator_destroy(coord_itr); |
| } |
| |
| if (file_opts->wckey_list) { |
| ListIterator wckey_itr = NULL; |
| char *temp_char = NULL; |
| slurmdb_wckey_rec_t *wckey = NULL; |
| |
| user->wckey_list = list_create(slurmdb_destroy_wckey_rec); |
| wckey_itr = list_iterator_create(file_opts->wckey_list); |
| while ((temp_char = list_next(wckey_itr))) { |
| wckey = xmalloc(sizeof(slurmdb_wckey_rec_t)); |
| wckey->name = xstrdup(temp_char); |
| wckey->user = xstrdup(user->name); |
| wckey->cluster = xstrdup(cluster); |
| if (!strcmp(wckey->name, user->default_wckey)) |
| wckey->is_def = 1; |
| list_push(user->wckey_list, wckey); |
| } |
| list_iterator_destroy(wckey_itr); |
| notice_thread_init(); |
| acct_storage_g_add_wckeys(db_conn, my_uid, user->wckey_list); |
| notice_thread_fini(); |
| } |
| return user; |
| } |
| |
| |
| static slurmdb_account_rec_t *_set_acct_up(sacctmgr_file_opts_t *file_opts, |
| char *parent) |
| { |
| slurmdb_account_rec_t *acct = xmalloc(sizeof(slurmdb_account_rec_t)); |
| acct->assoc_list = NULL; |
| acct->name = xstrdup(file_opts->name); |
| if (file_opts->desc) |
| acct->description = xstrdup(file_opts->desc); |
| else |
| acct->description = xstrdup(file_opts->name); |
| if (file_opts->org) |
| acct->organization = xstrdup(file_opts->org); |
| else if (strcmp(parent, "root")) |
| acct->organization = xstrdup(parent); |
| else |
| acct->organization = xstrdup(file_opts->name); |
| /* info("adding account %s (%s) (%s)", */ |
| /* acct->name, acct->description, */ |
| /* acct->organization); */ |
| |
| return acct; |
| } |
| |
| static slurmdb_association_rec_t *_set_assoc_up(sacctmgr_file_opts_t *file_opts, |
| sacctmgr_mod_type_t mod_type, |
| char *cluster, char *parent) |
| { |
| slurmdb_association_rec_t *assoc = NULL; |
| |
| if (!cluster) { |
| error("No cluster name was given for _set_assoc_up"); |
| return NULL; |
| } |
| |
| if (!parent && (mod_type != MOD_CLUSTER)) { |
| error("No parent was given for _set_assoc_up"); |
| return NULL; |
| } |
| |
| assoc = xmalloc(sizeof(slurmdb_association_rec_t)); |
| slurmdb_init_association_rec(assoc, 0); |
| |
| switch(mod_type) { |
| case MOD_CLUSTER: |
| assoc->acct = xstrdup(parent); |
| assoc->cluster = xstrdup(cluster); |
| break; |
| case MOD_ACCT: |
| assoc->acct = xstrdup(file_opts->name); |
| assoc->cluster = xstrdup(cluster); |
| assoc->parent_acct = xstrdup(parent); |
| break; |
| case MOD_USER: |
| assoc->acct = xstrdup(parent); |
| assoc->cluster = xstrdup(cluster); |
| assoc->partition = xstrdup(file_opts->part); |
| assoc->user = xstrdup(file_opts->name); |
| if (!strcmp(assoc->acct, file_opts->def_acct)) |
| assoc->is_def = 1; |
| break; |
| default: |
| error("Unknown mod type for _set_assoc_up %d", mod_type); |
| slurmdb_destroy_association_rec(assoc); |
| assoc = NULL; |
| break; |
| } |
| |
| assoc->shares_raw = file_opts->fairshare; |
| |
| assoc->def_qos_id = file_opts->def_qos_id; |
| |
| assoc->grp_cpu_mins = file_opts->grp_cpu_mins; |
| assoc->grp_cpus = file_opts->grp_cpus; |
| assoc->grp_jobs = file_opts->grp_jobs; |
| assoc->grp_nodes = file_opts->grp_nodes; |
| assoc->grp_submit_jobs = file_opts->grp_submit_jobs; |
| assoc->grp_wall = file_opts->grp_wall; |
| |
| assoc->max_cpu_mins_pj = file_opts->max_cpu_mins_pj; |
| assoc->max_cpus_pj = file_opts->max_cpus_pj; |
| assoc->max_jobs = file_opts->max_jobs; |
| assoc->max_nodes_pj = file_opts->max_nodes_pj; |
| assoc->max_submit_jobs = file_opts->max_submit_jobs; |
| assoc->max_wall_pj = file_opts->max_wall_pj; |
| |
| if (file_opts->qos_list && list_count(file_opts->qos_list)) |
| assoc->qos_list = copy_char_list(file_opts->qos_list); |
| |
| |
| return assoc; |
| } |
| |
| static int _print_file_slurmdb_hierarchical_rec_childern( |
| FILE *fd, List slurmdb_hierarchical_rec_list, |
| List user_list, List acct_list) |
| { |
| ListIterator itr = NULL; |
| slurmdb_hierarchical_rec_t *slurmdb_hierarchical_rec = NULL; |
| char *line = NULL; |
| slurmdb_user_rec_t *user_rec = NULL; |
| slurmdb_account_rec_t *acct_rec = NULL; |
| |
| itr = list_iterator_create(slurmdb_hierarchical_rec_list); |
| while ((slurmdb_hierarchical_rec = list_next(itr))) { |
| if (slurmdb_hierarchical_rec->assoc->user) { |
| user_rec = sacctmgr_find_user_from_list( |
| user_list, |
| slurmdb_hierarchical_rec->assoc->user); |
| line = xstrdup_printf( |
| "User - %s", |
| slurmdb_hierarchical_rec->sort_name); |
| if (slurmdb_hierarchical_rec->assoc->partition) |
| xstrfmtcat(line, ":Partition='%s'", |
| slurmdb_hierarchical_rec-> |
| assoc->partition); |
| if (user_rec) { |
| xstrfmtcat(line, ":DefaultAccount='%s'", |
| user_rec->default_acct); |
| if (user_rec->default_wckey |
| && user_rec->default_wckey[0]) |
| xstrfmtcat(line, ":DefaultWCKey='%s'", |
| user_rec->default_wckey); |
| |
| if (user_rec->admin_level > SLURMDB_ADMIN_NONE) |
| xstrfmtcat(line, ":AdminLevel='%s'", |
| slurmdb_admin_level_str( |
| user_rec-> |
| admin_level)); |
| if (user_rec->coord_accts |
| && list_count(user_rec->coord_accts)) { |
| ListIterator itr2 = NULL; |
| slurmdb_coord_rec_t *coord = NULL; |
| int first_coord = 1; |
| list_sort(user_rec->coord_accts, |
| (ListCmpF)sort_coord_list); |
| itr2 = list_iterator_create( |
| user_rec->coord_accts); |
| while ((coord = list_next(itr2))) { |
| /* We only care about |
| * the direct accounts here |
| */ |
| if (!coord->direct) |
| continue; |
| if (first_coord) { |
| xstrfmtcat( |
| line, |
| ":Coordinator" |
| "='%s", |
| coord->name); |
| first_coord = 0; |
| } else { |
| xstrfmtcat(line, ",%s", |
| coord->name); |
| } |
| } |
| if (!first_coord) |
| xstrcat(line, "'"); |
| list_iterator_destroy(itr2); |
| } |
| |
| if (user_rec->wckey_list |
| && list_count(user_rec->wckey_list)) { |
| ListIterator itr2 = NULL; |
| slurmdb_wckey_rec_t *wckey = NULL; |
| int first_wckey = 1; |
| itr2 = list_iterator_create( |
| user_rec->wckey_list); |
| while ((wckey = list_next(itr2))) { |
| /* Avoid sending |
| non-legitimate wckeys. |
| */ |
| if (!wckey->name || |
| !wckey->name[0] || |
| wckey->name[0] == '*') |
| continue; |
| if (first_wckey) { |
| xstrfmtcat( |
| line, |
| ":WCKeys='%s", |
| wckey->name); |
| first_wckey = 0; |
| } else { |
| xstrfmtcat(line, ",%s", |
| wckey->name); |
| } |
| } |
| if (!first_wckey) |
| xstrcat(line, "'"); |
| list_iterator_destroy(itr2); |
| } |
| } |
| } else { |
| acct_rec = sacctmgr_find_account_from_list( |
| acct_list, |
| slurmdb_hierarchical_rec->assoc->acct); |
| line = xstrdup_printf( |
| "Account - %s", |
| slurmdb_hierarchical_rec->sort_name); |
| if (acct_rec) { |
| xstrfmtcat(line, ":Description='%s'", |
| acct_rec->description); |
| xstrfmtcat(line, ":Organization='%s'", |
| acct_rec->organization); |
| } |
| } |
| |
| print_file_add_limits_to_line(&line, |
| slurmdb_hierarchical_rec->assoc); |
| |
| if (fprintf(fd, "%s\n", line) < 0) { |
| exit_code=1; |
| fprintf(stderr, " Can't write to file"); |
| xfree(line); |
| return SLURM_ERROR; |
| } |
| info("%s", line); |
| xfree(line); |
| } |
| list_iterator_destroy(itr); |
| print_file_slurmdb_hierarchical_rec_list(fd, |
| slurmdb_hierarchical_rec_list, |
| user_list, acct_list); |
| |
| return SLURM_SUCCESS; |
| } |
| |
| extern int print_file_add_limits_to_line(char **line, |
| slurmdb_association_rec_t *assoc) |
| { |
| if (!assoc) |
| return SLURM_ERROR; |
| |
| if (assoc->def_qos_id && (assoc->def_qos_id != NO_VAL)) { |
| char *tmp_char; |
| if (!g_qos_list) |
| g_qos_list = acct_storage_g_get_qos( |
| db_conn, my_uid, NULL); |
| if ((tmp_char = slurmdb_qos_str(g_qos_list, assoc->def_qos_id))) |
| xstrfmtcat(*line, ":DefaultQOS='%s'", tmp_char); |
| } |
| if (assoc->shares_raw != INFINITE) |
| xstrfmtcat(*line, ":Fairshare=%u", assoc->shares_raw); |
| |
| if (assoc->grp_cpu_mins != (uint64_t)INFINITE) |
| xstrfmtcat(*line, ":GrpCPUMins=%"PRIu64, assoc->grp_cpu_mins); |
| |
| if (assoc->grp_cpus != INFINITE) |
| xstrfmtcat(*line, ":GrpCPUs=%u", assoc->grp_cpus); |
| |
| if (assoc->grp_jobs != INFINITE) |
| xstrfmtcat(*line, ":GrpJobs=%u", assoc->grp_jobs); |
| |
| if (assoc->grp_nodes != INFINITE) |
| xstrfmtcat(*line, ":GrpNodes=%u", assoc->grp_nodes); |
| |
| if (assoc->grp_submit_jobs != INFINITE) |
| xstrfmtcat(*line, ":GrpSubmitJobs=%u", assoc->grp_submit_jobs); |
| |
| if (assoc->grp_wall != INFINITE) |
| xstrfmtcat(*line, ":GrpWall=%u", assoc->grp_wall); |
| |
| if (assoc->max_cpu_mins_pj != (uint64_t)INFINITE) |
| xstrfmtcat(*line, ":MaxCPUMinsPerJob=%"PRIu64, |
| assoc->max_cpu_mins_pj); |
| |
| if (assoc->max_cpus_pj != INFINITE) |
| xstrfmtcat(*line, ":MaxCPUsPerJob=%u", assoc->max_cpus_pj); |
| |
| if (assoc->max_jobs != INFINITE) |
| xstrfmtcat(*line, ":MaxJobs=%u", assoc->max_jobs); |
| |
| if (assoc->max_nodes_pj != INFINITE) |
| xstrfmtcat(*line, ":MaxNodesPerJob=%u", assoc->max_nodes_pj); |
| |
| if (assoc->max_submit_jobs != INFINITE) |
| xstrfmtcat(*line, ":MaxSubmitJobs=%u", assoc->max_submit_jobs); |
| |
| if (assoc->max_wall_pj != INFINITE) |
| xstrfmtcat(*line, ":MaxWallDurationPerJob=%u", |
| assoc->max_wall_pj); |
| |
| if (assoc->qos_list && list_count(assoc->qos_list)) { |
| char *temp_char = NULL; |
| if (!g_qos_list) |
| g_qos_list = acct_storage_g_get_qos( |
| db_conn, my_uid, NULL); |
| |
| temp_char = get_qos_complete_str(g_qos_list, assoc->qos_list); |
| xstrfmtcat(*line, ":QOS='%s'", temp_char); |
| xfree(temp_char); |
| } |
| |
| return SLURM_SUCCESS; |
| } |
| |
| |
| extern int print_file_slurmdb_hierarchical_rec_list( |
| FILE *fd, |
| List slurmdb_hierarchical_rec_list, |
| List user_list, |
| List acct_list) |
| { |
| ListIterator itr = NULL; |
| slurmdb_hierarchical_rec_t *slurmdb_hierarchical_rec = NULL; |
| |
| itr = list_iterator_create(slurmdb_hierarchical_rec_list); |
| while ((slurmdb_hierarchical_rec = list_next(itr))) { |
| /* info("got here %d with %d from %s %s", */ |
| /* depth, list_count(slurmdb_hierarchical_rec->childern), */ |
| /* slurmdb_hierarchical_rec->assoc->acct, |
| slurmdb_hierarchical_rec->assoc->user); */ |
| if (!list_count(slurmdb_hierarchical_rec->childern)) |
| continue; |
| if (fprintf(fd, "Parent - %s\n", |
| slurmdb_hierarchical_rec->assoc->acct) < 0) { |
| error("Can't write to file"); |
| return SLURM_ERROR; |
| } |
| info("%s - %s", "Parent", |
| slurmdb_hierarchical_rec->assoc->acct); |
| /* info("sending %d from %s", */ |
| /* list_count(slurmdb_hierarchical_rec->childern), */ |
| /* slurmdb_hierarchical_rec->assoc->acct); */ |
| _print_file_slurmdb_hierarchical_rec_childern( |
| fd, slurmdb_hierarchical_rec->childern, |
| user_list, acct_list); |
| } |
| list_iterator_destroy(itr); |
| |
| return SLURM_SUCCESS; |
| } |
| |
| extern void load_sacctmgr_cfg_file (int argc, char *argv[]) |
| { |
| DEF_TIMERS; |
| char line[BUFFER_SIZE]; |
| FILE *fd = NULL; |
| char *parent = NULL; |
| char *file_name = NULL; |
| char *cluster_name = NULL; |
| char *user_name = NULL; |
| char object[25]; |
| int start = 0, len = 0, i = 0; |
| int lc=0, num_lines=0; |
| int start_clean=0; |
| int cluster_name_set=0; |
| int rc = SLURM_SUCCESS; |
| |
| sacctmgr_file_opts_t *file_opts = NULL; |
| slurmdb_association_rec_t *assoc = NULL, *assoc2 = NULL; |
| slurmdb_account_rec_t *acct = NULL, *acct2 = NULL; |
| slurmdb_cluster_rec_t *cluster = NULL; |
| slurmdb_user_rec_t *user = NULL, *user2 = NULL; |
| slurmdb_user_cond_t user_cond; |
| |
| List curr_assoc_list = NULL; |
| List curr_acct_list = NULL; |
| List curr_cluster_list = NULL; |
| List curr_user_list = NULL; |
| |
| /* This will be freed in their local counter parts */ |
| List mod_acct_list = NULL; |
| List acct_list = NULL; |
| List slurmdb_assoc_list = NULL; |
| List mod_user_list = NULL; |
| List user_list = NULL; |
| List user_assoc_list = NULL; |
| List mod_assoc_list = NULL; |
| |
| ListIterator itr; |
| ListIterator itr2; |
| |
| List print_fields_list; |
| List format_list = NULL; |
| print_field_t *field = NULL; |
| |
| int set = 0, command_len = 0; |
| |
| if (readonly_flag) { |
| exit_code = 1; |
| fprintf(stderr, "Can't run this command in readonly mode.\n"); |
| return; |
| } |
| |
| /* reset the connection to get the most recent stuff */ |
| acct_storage_g_commit(db_conn, 0); |
| |
| for (i=0; i<argc; i++) { |
| int option = 0; |
| int end = parse_option_end(argv[i]); |
| if (!end) |
| command_len=strlen(argv[i]); |
| else { |
| command_len=end-1; |
| if (argv[i][end] == '=') { |
| option = (int)argv[i][end-1]; |
| end++; |
| } |
| } |
| if (!end && !strncasecmp(argv[i], "clean", |
| MAX(command_len, 3))) { |
| start_clean = 1; |
| } else if (!end || !strncasecmp (argv[i], "File", |
| MAX(command_len, 1))) { |
| if (file_name) { |
| exit_code=1; |
| fprintf(stderr, |
| " File name already set to %s\n", |
| file_name); |
| continue; |
| } |
| file_name = xstrdup(argv[i]+end); |
| } else if (!strncasecmp (argv[i], "Cluster", |
| MAX(command_len, 3))) { |
| if (cluster_name) { |
| exit_code=1; |
| fprintf(stderr, |
| " Can only do one cluster at a time. " |
| "Already doing %s\n", cluster_name); |
| continue; |
| } |
| cluster_name = xstrdup(argv[i]+end); |
| cluster_name_set = 1; |
| } else { |
| exit_code=1; |
| fprintf(stderr, " Unknown option: %s\n", argv[i]); |
| } |
| } |
| |
| if (!file_name) { |
| exit_code=1; |
| xfree(cluster_name); |
| fprintf(stderr, |
| " No filename given, specify one with file=''\n"); |
| return; |
| |
| } |
| |
| fd = fopen(file_name, "r"); |
| xfree(file_name); |
| if (fd == NULL) { |
| exit_code=1; |
| fprintf(stderr, " Unable to read \"%s\": %m\n", argv[0]); |
| xfree(cluster_name); |
| return; |
| } |
| |
| curr_acct_list = acct_storage_g_get_accounts(db_conn, my_uid, NULL); |
| |
| /* These are new info so they need to be freed here */ |
| acct_list = list_create(slurmdb_destroy_account_rec); |
| slurmdb_assoc_list = list_create(slurmdb_destroy_association_rec); |
| user_list = list_create(slurmdb_destroy_user_rec); |
| user_assoc_list = list_create(slurmdb_destroy_association_rec); |
| |
| mod_acct_list = list_create(slurmdb_destroy_account_rec); |
| mod_user_list = list_create(slurmdb_destroy_user_rec); |
| mod_assoc_list = list_create(slurmdb_destroy_association_rec); |
| |
| format_list = list_create(slurm_destroy_char); |
| |
| while ((num_lines = _get_next_line(line, BUFFER_SIZE, fd)) > 0) { |
| lc += num_lines; |
| /* skip empty lines */ |
| if (line[0] == '\0') { |
| continue; |
| } |
| len = strlen(line); |
| |
| memset(object, 0, sizeof(object)); |
| |
| /* first find the object */ |
| start=0; |
| for(i=0; i<len; i++) { |
| if (line[i] == '-') { |
| start = i; |
| if (line[i-1] == ' ') |
| i--; |
| if (i<sizeof(object)) |
| strncpy(object, line, i); |
| break; |
| } |
| } |
| if (!object[0]) |
| continue; |
| |
| while (line[start] != ' ' && start<len) |
| start++; |
| if (start>=len) { |
| exit_code=1; |
| fprintf(stderr, " Nothing after object " |
| "name '%s'. line(%d)\n", |
| object, lc); |
| rc = SLURM_ERROR; |
| break; |
| } |
| start++; |
| |
| if (!strcasecmp("Machine", object) |
| || !strcasecmp("Cluster", object)) { |
| slurmdb_association_cond_t assoc_cond; |
| |
| if (cluster_name && !cluster_name_set) { |
| exit_code=1; |
| fprintf(stderr, " You can only add one cluster " |
| "at a time.\n"); |
| rc = SLURM_ERROR; |
| break; |
| } |
| |
| file_opts = _parse_options(line+start); |
| |
| if (!file_opts) { |
| exit_code=1; |
| fprintf(stderr, |
| " error: Problem with line(%d)\n", lc); |
| rc = SLURM_ERROR; |
| break; |
| } |
| |
| if (!cluster_name_set) |
| cluster_name = xstrdup(file_opts->name); |
| |
| /* we have to do this here since this is the |
| first place we have the cluster_name |
| */ |
| memset(&user_cond, 0, sizeof(slurmdb_user_cond_t)); |
| user_cond.with_coords = 1; |
| user_cond.with_assocs = 1; |
| user_cond.with_wckeys = 1; |
| |
| memset(&assoc_cond, 0, |
| sizeof(slurmdb_association_cond_t)); |
| assoc_cond.cluster_list = list_create(NULL); |
| assoc_cond.with_raw_qos = 1; |
| assoc_cond.without_parent_limits = 1; |
| list_append(assoc_cond.cluster_list, cluster_name); |
| user_cond.assoc_cond = &assoc_cond; |
| curr_user_list = acct_storage_g_get_users( |
| db_conn, my_uid, &user_cond); |
| |
| user_cond.assoc_cond = NULL; |
| assoc_cond.only_defs = 0; |
| |
| /* make sure this person running is an admin */ |
| user_name = uid_to_string(my_uid); |
| if (!(user = sacctmgr_find_user_from_list( |
| curr_user_list, user_name))) { |
| exit_code=1; |
| fprintf(stderr, " Your uid (%u) is not in the " |
| "accounting system, can't load file.\n", |
| my_uid); |
| if (curr_user_list) |
| list_destroy(curr_user_list); |
| xfree(user_name); |
| return; |
| |
| } else { |
| if (my_uid != slurm_get_slurm_user_id() |
| && my_uid != 0 |
| && (user->admin_level |
| < SLURMDB_ADMIN_SUPER_USER)) { |
| exit_code=1; |
| fprintf(stderr, |
| " Your user does not have " |
| "sufficient " |
| "privileges to load files.\n"); |
| if (curr_user_list) |
| list_destroy(curr_user_list); |
| xfree(user_name); |
| return; |
| } |
| } |
| xfree(user_name); |
| |
| if (start_clean) { |
| slurmdb_cluster_cond_t cluster_cond; |
| List ret_list = NULL; |
| |
| if (!commit_check("You requested to flush " |
| "the cluster before " |
| "adding it again.\n" |
| "Are you sure you want " |
| "to continue?")) { |
| printf("Aborted\n"); |
| break; |
| } |
| |
| slurmdb_init_cluster_cond(&cluster_cond, 0); |
| cluster_cond.cluster_list = list_create(NULL); |
| list_append(cluster_cond.cluster_list, |
| cluster_name); |
| |
| notice_thread_init(); |
| ret_list = acct_storage_g_remove_clusters( |
| db_conn, my_uid, &cluster_cond); |
| notice_thread_fini(); |
| list_destroy(cluster_cond.cluster_list); |
| |
| if (!ret_list) { |
| exit_code=1; |
| fprintf(stderr, " There was a problem " |
| "removing the cluster.\n"); |
| rc = SLURM_ERROR; |
| break; |
| } |
| /* This needs to be commited or |
| problems may arise */ |
| acct_storage_g_commit(db_conn, 1); |
| } |
| curr_cluster_list = acct_storage_g_get_clusters( |
| db_conn, my_uid, NULL); |
| |
| if (cluster_name) |
| printf("For cluster %s\n", cluster_name); |
| |
| if (!(cluster = sacctmgr_find_cluster_from_list( |
| curr_cluster_list, cluster_name))) { |
| List temp_assoc_list = list_create(NULL); |
| List cluster_list = list_create( |
| slurmdb_destroy_cluster_rec); |
| |
| cluster = xmalloc( |
| sizeof(slurmdb_cluster_rec_t)); |
| slurmdb_init_cluster_rec(cluster, 0); |
| list_append(cluster_list, cluster); |
| cluster->name = xstrdup(cluster_name); |
| if (file_opts->classification) { |
| cluster->classification = |
| file_opts->classification; |
| printf("Classification: %s\n", |
| get_classification_str( |
| cluster-> |
| classification)); |
| } |
| |
| cluster->root_assoc = _set_assoc_up( |
| file_opts, MOD_CLUSTER, |
| cluster_name, "root"); |
| list_append(temp_assoc_list, |
| cluster->root_assoc); |
| |
| rc = _print_out_assoc(temp_assoc_list, 0, 0); |
| list_destroy(temp_assoc_list); |
| notice_thread_init(); |
| |
| rc = acct_storage_g_add_clusters( |
| db_conn, my_uid, cluster_list); |
| notice_thread_fini(); |
| list_destroy(cluster_list); |
| |
| if (rc != SLURM_SUCCESS) { |
| exit_code=1; |
| fprintf(stderr, |
| " Problem adding cluster: %s\n", |
| slurm_strerror(rc)); |
| rc = SLURM_ERROR; |
| _destroy_sacctmgr_file_opts(file_opts); |
| break; |
| } |
| /* This needs to be commited or |
| problems may arise */ |
| acct_storage_g_commit(db_conn, 1); |
| set = 1; |
| } else { |
| set = _mod_cluster(file_opts, |
| cluster, parent); |
| } |
| |
| _destroy_sacctmgr_file_opts(file_opts); |
| |
| /* assoc_cond if set up above */ |
| curr_assoc_list = acct_storage_g_get_associations( |
| db_conn, my_uid, &assoc_cond); |
| list_destroy(assoc_cond.cluster_list); |
| |
| if (!curr_assoc_list) { |
| exit_code=1; |
| fprintf(stderr, " Problem getting associations " |
| "for this cluster\n"); |
| rc = SLURM_ERROR; |
| break; |
| } |
| //info("got %d assocs", list_count(curr_assoc_list)); |
| continue; |
| } else if (!cluster_name) { |
| exit_code=1; |
| fprintf(stderr, " You need to specify a cluster name " |
| "first with 'Cluster - $NAME' in your file\n"); |
| break; |
| } |
| |
| if (!strcasecmp("Parent", object)) { |
| xfree(parent); |
| |
| i = start; |
| while (line[i] != '\n' && i<len) |
| i++; |
| |
| if (i >= len) { |
| exit_code=1; |
| fprintf(stderr, " No parent name " |
| "given line(%d)\n", |
| lc); |
| rc = SLURM_ERROR; |
| break; |
| } |
| parent = xstrndup(line+start, i-start); |
| //info("got parent %s", parent); |
| if (!sacctmgr_find_account_base_assoc_from_list( |
| curr_assoc_list, parent, cluster_name) |
| && !sacctmgr_find_account_base_assoc_from_list( |
| slurmdb_assoc_list, parent, cluster_name)) { |
| exit_code=1; |
| fprintf(stderr, " line(%d) You need to add " |
| "this parent (%s) as a child before " |
| "you can add childern to it.\n", |
| lc, parent); |
| break; |
| } |
| continue; |
| } else if (!parent) { |
| parent = xstrdup("root"); |
| printf(" No parent given creating off root, " |
| "If incorrect specify 'Parent - name' " |
| "before any childern in your file\n"); |
| } |
| |
| if (!strcasecmp("Project", object) |
| || !strcasecmp("Account", object)) { |
| file_opts = _parse_options(line+start); |
| |
| if (!file_opts) { |
| exit_code=1; |
| fprintf(stderr, " Problem with line(%d)\n", lc); |
| rc = SLURM_ERROR; |
| break; |
| } |
| |
| //info("got a project %s of %s", file_opts->name, parent); |
| if (!(acct = sacctmgr_find_account_from_list( |
| curr_acct_list, file_opts->name)) |
| && !sacctmgr_find_account_from_list( |
| acct_list, file_opts->name)) { |
| acct = _set_acct_up(file_opts, parent); |
| list_append(acct_list, acct); |
| /* don't add anything to the |
| curr_acct_list */ |
| |
| assoc = _set_assoc_up(file_opts, MOD_ACCT, |
| cluster_name, parent); |
| |
| list_append(slurmdb_assoc_list, assoc); |
| /* don't add anything to the |
| curr_assoc_list */ |
| } else if (!(assoc = |
| sacctmgr_find_account_base_assoc_from_list( |
| curr_assoc_list, file_opts->name, |
| cluster_name)) && |
| !sacctmgr_find_account_base_assoc_from_list( |
| slurmdb_assoc_list, file_opts->name, |
| cluster_name)) { |
| acct2 = sacctmgr_find_account_from_list( |
| mod_acct_list, file_opts->name); |
| |
| if (!acct2) { |
| acct2 = xmalloc( |
| sizeof(slurmdb_account_rec_t)); |
| list_append(mod_acct_list, acct2); |
| acct2->name = xstrdup(file_opts->name); |
| if (_mod_acct(file_opts, acct, parent)) |
| set = 1; |
| } else { |
| debug2("already modified this account"); |
| } |
| |
| assoc = _set_assoc_up(file_opts, MOD_ACCT, |
| cluster_name, parent); |
| |
| list_append(slurmdb_assoc_list, assoc); |
| /* don't add anything to the |
| curr_assoc_list */ |
| } else if (assoc) { |
| acct2 = sacctmgr_find_account_from_list( |
| mod_acct_list, file_opts->name); |
| |
| if (!acct2) { |
| acct2 = xmalloc( |
| sizeof(slurmdb_account_rec_t)); |
| list_append(mod_acct_list, acct2); |
| acct2->name = xstrdup(file_opts->name); |
| if (_mod_acct(file_opts, acct, parent)) |
| set = 1; |
| } else { |
| debug2("already modified this account"); |
| } |
| |
| assoc2 = sacctmgr_find_association_from_list( |
| mod_assoc_list, |
| NULL, file_opts->name, |
| cluster_name, |
| NULL); |
| |
| if (!assoc2) { |
| assoc2 = xmalloc( |
| sizeof(slurmdb_association_rec_t)); |
| slurmdb_init_association_rec(assoc2, 0); |
| list_append(mod_assoc_list, assoc2); |
| assoc2->cluster = xstrdup(cluster_name); |
| assoc2->acct = xstrdup(file_opts->name); |
| assoc2->parent_acct = |
| xstrdup(assoc->parent_acct); |
| if (_mod_assoc(file_opts, |
| assoc, MOD_ACCT, parent)) |
| set = 1; |
| } else { |
| debug2("already modified this assoc"); |
| } |
| } |
| _destroy_sacctmgr_file_opts(file_opts); |
| continue; |
| } else if (!strcasecmp("User", object)) { |
| file_opts = _parse_options(line+start); |
| |
| if (!file_opts) { |
| exit_code=1; |
| fprintf(stderr, " Problem with line(%d)\n", lc); |
| rc = SLURM_ERROR; |
| break; |
| } |
| |
| if (!(user = sacctmgr_find_user_from_list( |
| curr_user_list, file_opts->name)) |
| && !sacctmgr_find_user_from_list( |
| user_list, file_opts->name)) { |
| |
| user = _set_user_up(file_opts, cluster_name, |
| parent); |
| list_append(user_list, user); |
| /* don't add anything to the |
| curr_user_list */ |
| |
| assoc = _set_assoc_up(file_opts, MOD_USER, |
| cluster_name, parent); |
| |
| list_append(user_assoc_list, assoc); |
| /* don't add anything to the |
| curr_assoc_list */ |
| } else if (!(assoc = |
| sacctmgr_find_association_from_list( |
| curr_assoc_list, |
| file_opts->name, parent, |
| cluster_name, file_opts->part)) |
| && !sacctmgr_find_association_from_list( |
| user_assoc_list, |
| file_opts->name, parent, |
| cluster_name, |
| file_opts->part)) { |
| |
| /* This means the user was added |
| * during this round but this is a new |
| * association we are adding |
| */ |
| if (!user) |
| goto new_association; |
| |
| /* This means there could be a change |
| * on the user. |
| */ |
| user2 = sacctmgr_find_user_from_list( |
| mod_user_list, file_opts->name); |
| if (!user2) { |
| user2 = xmalloc( |
| sizeof(slurmdb_user_rec_t)); |
| list_append(mod_user_list, user2); |
| user2->name = xstrdup(file_opts->name); |
| if (_mod_user(file_opts, user, |
| cluster_name, parent)) |
| set = 1; |
| } else { |
| debug2("already modified this user"); |
| } |
| new_association: |
| assoc = _set_assoc_up(file_opts, MOD_USER, |
| cluster_name, parent); |
| |
| list_append(user_assoc_list, assoc); |
| /* don't add anything to the |
| curr_assoc_list */ |
| } else if (assoc) { |
| user2 = sacctmgr_find_user_from_list( |
| mod_user_list, file_opts->name); |
| if (!user2) { |
| user2 = xmalloc( |
| sizeof(slurmdb_user_rec_t)); |
| list_append(mod_user_list, user2); |
| user2->name = xstrdup(file_opts->name); |
| if (_mod_user(file_opts, user, |
| cluster_name, parent)) |
| set = 1; |
| } else { |
| debug2("already modified this user"); |
| } |
| |
| assoc2 = sacctmgr_find_association_from_list( |
| mod_assoc_list, |
| file_opts->name, parent, |
| cluster_name, |
| file_opts->part); |
| |
| if (!assoc2) { |
| assoc2 = xmalloc( |
| sizeof(slurmdb_association_rec_t)); |
| slurmdb_init_association_rec(assoc2, 0); |
| list_append(mod_assoc_list, assoc2); |
| assoc2->cluster = xstrdup(cluster_name); |
| assoc2->acct = xstrdup(parent); |
| assoc2->user = xstrdup(file_opts->name); |
| assoc2->partition = |
| xstrdup(file_opts->part); |
| if (_mod_assoc(file_opts, |
| assoc, MOD_USER, parent)) |
| set = 1; |
| } else { |
| debug2("already modified this assoc"); |
| } |
| } |
| //info("got a user %s", file_opts->name); |
| _destroy_sacctmgr_file_opts(file_opts); |
| continue; |
| } else { |
| exit_code=1; |
| fprintf(stderr, |
| " Misformatted line(%d): %s\n", lc, line); |
| rc = SLURM_ERROR; |
| break; |
| } |
| } |
| fclose(fd); |
| xfree(cluster_name); |
| xfree(parent); |
| |
| START_TIMER; |
| if (rc == SLURM_SUCCESS && list_count(acct_list)) { |
| printf("Accounts\n"); |
| slurm_addto_char_list(format_list, |
| "Name,Description,Organization,QOS"); |
| |
| print_fields_list = sacctmgr_process_format_list(format_list); |
| list_flush(format_list); |
| |
| print_fields_header(print_fields_list); |
| |
| itr = list_iterator_create(acct_list); |
| itr2 = list_iterator_create(print_fields_list); |
| while ((acct = list_next(itr))) { |
| while ((field = list_next(itr2))) { |
| switch(field->type) { |
| case PRINT_DESC: |
| field->print_routine( |
| field, acct->description); |
| break; |
| case PRINT_NAME: |
| field->print_routine( |
| field, acct->name); |
| break; |
| case PRINT_ORG: |
| field->print_routine( |
| field, acct->organization); |
| break; |
| default: |
| field->print_routine( |
| field, NULL); |
| break; |
| } |
| } |
| list_iterator_reset(itr2); |
| printf("\n"); |
| } |
| list_iterator_destroy(itr); |
| list_iterator_destroy(itr2); |
| list_destroy(print_fields_list); |
| rc = acct_storage_g_add_accounts(db_conn, my_uid, acct_list); |
| printf("-----------------------------" |
| "----------------------\n\n"); |
| set = 1; |
| } |
| |
| if (rc == SLURM_SUCCESS && list_count(slurmdb_assoc_list)) { |
| printf("Account Associations\n"); |
| rc = _print_out_assoc(slurmdb_assoc_list, 0, 1); |
| set = 1; |
| } |
| if (rc == SLURM_SUCCESS && list_count(user_list)) { |
| printf("Users\n"); |
| |
| slurm_addto_char_list(format_list, |
| "Name,DefaultA,DefaultW,QOS,Admin,Coord"); |
| |
| print_fields_list = sacctmgr_process_format_list(format_list); |
| list_flush(format_list); |
| print_fields_header(print_fields_list); |
| |
| itr = list_iterator_create(user_list); |
| itr2 = list_iterator_create(print_fields_list); |
| while ((user = list_next(itr))) { |
| while ((field = list_next(itr2))) { |
| switch(field->type) { |
| case PRINT_ADMIN: |
| field->print_routine( |
| field, |
| slurmdb_admin_level_str( |
| user->admin_level)); |
| break; |
| case PRINT_COORDS: |
| field->print_routine( |
| field, |
| user->coord_accts); |
| break; |
| case PRINT_DACCT: |
| field->print_routine( |
| field, |
| user->default_acct); |
| break; |
| case PRINT_DWCKEY: |
| field->print_routine( |
| field, |
| user->default_wckey); |
| break; |
| case PRINT_NAME: |
| field->print_routine( |
| field, user->name); |
| break; |
| case PRINT_WCKEYS: |
| field->print_routine( |
| field, user->wckey_list); |
| break; |
| default: |
| field->print_routine( |
| field, NULL); |
| break; |
| } |
| } |
| list_iterator_reset(itr2); |
| printf("\n"); |
| } |
| list_iterator_destroy(itr); |
| list_iterator_destroy(itr2); |
| list_destroy(print_fields_list); |
| |
| rc = acct_storage_g_add_users(db_conn, my_uid, user_list); |
| printf("---------------------------" |
| "------------------------\n\n"); |
| set = 1; |
| } |
| |
| if (rc == SLURM_SUCCESS && list_count(user_assoc_list)) { |
| printf("User Associations\n"); |
| rc = _print_out_assoc(user_assoc_list, 1, 1); |
| set = 1; |
| } |
| END_TIMER2("add cluster"); |
| |
| if (set) |
| info("Done adding cluster in %s", TIME_STR); |
| |
| if (rc == SLURM_SUCCESS) { |
| if (set) { |
| if (commit_check("Would you like to commit changes?")) { |
| acct_storage_g_commit(db_conn, 1); |
| } else { |
| printf(" Changes Discarded\n"); |
| acct_storage_g_commit(db_conn, 0); |
| } |
| } else { |
| printf(" Nothing new added.\n"); |
| } |
| } else { |
| exit_code=1; |
| fprintf(stderr, " Problem with requests: %s\n", |
| slurm_strerror(rc)); |
| } |
| |
| list_destroy(format_list); |
| list_destroy(mod_acct_list); |
| list_destroy(acct_list); |
| list_destroy(slurmdb_assoc_list); |
| list_destroy(mod_user_list); |
| list_destroy(user_list); |
| list_destroy(user_assoc_list); |
| list_destroy(mod_assoc_list); |
| if (curr_acct_list) |
| list_destroy(curr_acct_list); |
| if (curr_assoc_list) |
| list_destroy(curr_assoc_list); |
| if (curr_cluster_list) |
| list_destroy(curr_cluster_list); |
| if (curr_user_list) |
| list_destroy(curr_user_list); |
| } |