|  | /*****************************************************************************\ | 
|  | *  archive_functions.c - functions dealing with archive 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://slurm.schedmd.com/>. | 
|  | *  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 <sys/stat.h> | 
|  |  | 
|  | #include "src/sacctmgr/sacctmgr.h" | 
|  | #include "src/common/proc_args.h" | 
|  | #include "src/common/util-net.h" | 
|  |  | 
|  | static int _set_cond(int *start, int argc, char **argv, | 
|  | slurmdb_archive_cond_t *arch_cond) | 
|  | { | 
|  | int i; | 
|  | int set = 0; | 
|  | int end = 0; | 
|  | int command_len = 0; | 
|  | uint32_t tmp; | 
|  | slurmdb_job_cond_t *job_cond = NULL; | 
|  |  | 
|  | if (!arch_cond) { | 
|  | error("No arch_cond given"); | 
|  | return -1; | 
|  | } | 
|  | if (!arch_cond->job_cond) | 
|  | arch_cond->job_cond = xmalloc(sizeof(slurmdb_job_cond_t)); | 
|  | job_cond = arch_cond->job_cond; | 
|  |  | 
|  | for (i=(*start); i<argc; i++) { | 
|  | int op_type; | 
|  | end = parse_option_end(argv[i], &op_type, &command_len); | 
|  | if (!common_verify_option_syntax(argv[i], op_type, false)) | 
|  | continue; | 
|  |  | 
|  | if (!end && !xstrncasecmp(argv[i], "where", | 
|  | MAX(command_len, 5))) { | 
|  | continue; | 
|  | } else if (!end && !xstrncasecmp(argv[i], "events", | 
|  | MAX(command_len, 1))) { | 
|  | arch_cond->purge_event |= SLURMDB_PURGE_ARCHIVE; | 
|  | set = 1; | 
|  | } else if (!end && !xstrncasecmp(argv[i], "jobs", | 
|  | MAX(command_len, 1))) { | 
|  | arch_cond->purge_job |= SLURMDB_PURGE_ARCHIVE; | 
|  | set = 1; | 
|  | } else if (!end && !xstrncasecmp(argv[i], "reservations", | 
|  | MAX(command_len, 1))) { | 
|  | arch_cond->purge_resv |= SLURMDB_PURGE_ARCHIVE; | 
|  | set = 1; | 
|  | } else if (!end && !xstrncasecmp(argv[i], "steps", | 
|  | MAX(command_len, 1))) { | 
|  | arch_cond->purge_step |= SLURMDB_PURGE_ARCHIVE; | 
|  | set = 1; | 
|  | } else if (!end && !xstrncasecmp(argv[i], "suspend", | 
|  | MAX(command_len, 1))) { | 
|  | arch_cond->purge_suspend |= SLURMDB_PURGE_ARCHIVE; | 
|  | set = 1; | 
|  | } else if (!end && !xstrncasecmp(argv[i], "txn", | 
|  | MAX(command_len, 1))) { | 
|  | arch_cond->purge_txn |= SLURMDB_PURGE_ARCHIVE; | 
|  | set = 1; | 
|  | } else if (!end && !xstrncasecmp(argv[i], "usage", | 
|  | MAX(command_len, 1))) { | 
|  | arch_cond->purge_usage |= SLURMDB_PURGE_ARCHIVE; | 
|  | set = 1; | 
|  | } else if (!end | 
|  | || !xstrncasecmp(argv[i], "Clusters", | 
|  | MAX(command_len, 1))) { | 
|  | if (!job_cond->cluster_list) | 
|  | job_cond->cluster_list = list_create(xfree_ptr); | 
|  | slurm_addto_char_list(job_cond->cluster_list, | 
|  | argv[i]+end); | 
|  | set = 1; | 
|  | } else if (!xstrncasecmp(argv[i], "Accounts", | 
|  | MAX(command_len, 2))) { | 
|  | if (!job_cond->acct_list) | 
|  | job_cond->acct_list = list_create(xfree_ptr); | 
|  | slurm_addto_char_list(job_cond->acct_list, | 
|  | argv[i]+end); | 
|  | set = 1; | 
|  | } else if (!xstrncasecmp(argv[i], "Associations", | 
|  | MAX(command_len, 2))) { | 
|  | if (!job_cond->associd_list) | 
|  | job_cond->associd_list = list_create(xfree_ptr); | 
|  | slurm_addto_char_list(job_cond->associd_list, | 
|  | argv[i]+end); | 
|  | set = 1; | 
|  | } else if (!xstrncasecmp(argv[i], "Directory", | 
|  | MAX(command_len, 2))) { | 
|  | arch_cond->archive_dir = | 
|  | strip_quotes(argv[i]+end, NULL, 0); | 
|  | set = 1; | 
|  | } else if (!xstrncasecmp(argv[i], "End", MAX(command_len, 1))) { | 
|  | job_cond->usage_end = parse_time(argv[i]+end, 1); | 
|  | set = 1; | 
|  | } else if (!xstrncasecmp(argv[i], "Gid", MAX(command_len, 2))) { | 
|  | if (!job_cond->groupid_list) | 
|  | job_cond->groupid_list = list_create(xfree_ptr); | 
|  | slurm_addto_char_list(job_cond->groupid_list, | 
|  | argv[i]+end); | 
|  | set = 1; | 
|  | } else if (!xstrncasecmp(argv[i], "Jobs", | 
|  | MAX(command_len, 1))) { | 
|  | char *end_char = NULL, *start_char = argv[i] + end; | 
|  | slurm_selected_step_t *selected_step = NULL; | 
|  | char *dot = NULL; | 
|  | if (!job_cond->step_list) | 
|  | job_cond->step_list = list_create(xfree_ptr); | 
|  |  | 
|  | while ((end_char = strstr(start_char, ","))) { | 
|  | end_char[0] = '\0'; | 
|  | while (isspace(start_char[0])) | 
|  | start_char++;  /* discard whitespace */ | 
|  | if (start_char[0] == '\0') | 
|  | continue; | 
|  | selected_step = xmalloc( | 
|  | sizeof(slurm_selected_step_t)); | 
|  | selected_step->array_task_id = NO_VAL; | 
|  | selected_step->het_job_offset = NO_VAL; | 
|  | list_append(job_cond->step_list, selected_step); | 
|  |  | 
|  | dot = strstr(start_char, "."); | 
|  | if (dot == NULL) { | 
|  | debug2("No jobstep requested"); | 
|  | selected_step->step_id.step_id = NO_VAL; | 
|  | } else { | 
|  | *dot++ = 0; | 
|  | selected_step->step_id.step_id = | 
|  | atoi(dot); | 
|  | } | 
|  | selected_step->step_id.step_het_comp = NO_VAL; | 
|  | selected_step->step_id.job_id = | 
|  | atoi(start_char); | 
|  | start_char = end_char + 1; | 
|  | } | 
|  |  | 
|  | set = 1; | 
|  | } else if (!xstrncasecmp(argv[i], "Partitions", | 
|  | MAX(command_len, 2))) { | 
|  | if (!job_cond->partition_list) | 
|  | job_cond->partition_list = | 
|  | list_create(xfree_ptr); | 
|  | slurm_addto_char_list(job_cond->partition_list, | 
|  | argv[i]+end); | 
|  | set = 1; | 
|  | } else if (!xstrncasecmp(argv[i], "PurgeEventAfter", | 
|  | MAX(command_len, 10))) { | 
|  | if ((tmp = slurmdb_parse_purge(argv[i]+end)) | 
|  | == NO_VAL) { | 
|  | exit_code = 1; | 
|  | } else { | 
|  | arch_cond->purge_event |= tmp; | 
|  | set = 1; | 
|  | } | 
|  | } else if (!xstrncasecmp(argv[i], "PurgeJobAfter", | 
|  | MAX(command_len, 10))) { | 
|  | if ((tmp = slurmdb_parse_purge(argv[i]+end)) | 
|  | == NO_VAL) { | 
|  | exit_code = 1; | 
|  | } else { | 
|  | arch_cond->purge_job |= tmp; | 
|  | set = 1; | 
|  | } | 
|  | } else if (!xstrncasecmp(argv[i], "PurgeResvAfter", | 
|  | MAX(command_len, 10))) { | 
|  | if ((tmp = slurmdb_parse_purge(argv[i]+end)) | 
|  | == NO_VAL) { | 
|  | exit_code = 1; | 
|  | } else { | 
|  | arch_cond->purge_resv |= tmp; | 
|  | set = 1; | 
|  | } | 
|  | } else if (!xstrncasecmp(argv[i], "PurgeStepAfter", | 
|  | MAX(command_len, 10))) { | 
|  | if ((tmp = slurmdb_parse_purge(argv[i]+end)) | 
|  | == NO_VAL) { | 
|  | exit_code = 1; | 
|  | } else { | 
|  | arch_cond->purge_step |= tmp; | 
|  | set = 1; | 
|  | } | 
|  | } else if (!xstrncasecmp(argv[i], "PurgeSuspendAfter", | 
|  | MAX(command_len, 10))) { | 
|  | if ((tmp = slurmdb_parse_purge(argv[i]+end)) | 
|  | == NO_VAL) { | 
|  | exit_code = 1; | 
|  | } else { | 
|  | arch_cond->purge_suspend |= tmp; | 
|  | set = 1; | 
|  | } | 
|  | } else if (!xstrncasecmp(argv[i], "PurgeTXNAfter", | 
|  | MAX(command_len, 10))) { | 
|  | if ((tmp = slurmdb_parse_purge(argv[i]+end)) | 
|  | == NO_VAL) { | 
|  | exit_code = 1; | 
|  | } else { | 
|  | arch_cond->purge_txn |= tmp; | 
|  | set = 1; | 
|  | } | 
|  | } else if (!xstrncasecmp(argv[i], "PurgeUsageAfter", | 
|  | MAX(command_len, 10))) { | 
|  | if ((tmp = slurmdb_parse_purge(argv[i]+end)) | 
|  | == NO_VAL) { | 
|  | exit_code = 1; | 
|  | } else { | 
|  | arch_cond->purge_usage |= tmp; | 
|  | set = 1; | 
|  | } | 
|  | } else if (!xstrncasecmp(argv[i], "PurgeEventMonths", | 
|  | MAX(command_len, 6))) { | 
|  | if (get_uint(argv[i]+end, &tmp, "PurgeEventMonths") | 
|  | != SLURM_SUCCESS) { | 
|  | exit_code = 1; | 
|  | } else { | 
|  | arch_cond->purge_event |= tmp; | 
|  | arch_cond->purge_event |= SLURMDB_PURGE_MONTHS; | 
|  | set = 1; | 
|  | } | 
|  | } else if (!xstrncasecmp(argv[i], "PurgeJobMonths", | 
|  | MAX(command_len, 6))) { | 
|  | if (get_uint(argv[i]+end, &tmp, "PurgeJobMonths") | 
|  | != SLURM_SUCCESS) { | 
|  | exit_code = 1; | 
|  | } else { | 
|  | arch_cond->purge_job |= tmp; | 
|  | arch_cond->purge_job |= SLURMDB_PURGE_MONTHS; | 
|  | set = 1; | 
|  | } | 
|  | } else if (!xstrncasecmp(argv[i], "PurgeResvMonths", | 
|  | MAX(command_len, 6))) { | 
|  | if (get_uint(argv[i]+end, &tmp, "PurgeResvMonths") | 
|  | != SLURM_SUCCESS) { | 
|  | exit_code = 1; | 
|  | } else { | 
|  | arch_cond->purge_resv |= tmp; | 
|  | arch_cond->purge_resv |= SLURMDB_PURGE_MONTHS; | 
|  | set = 1; | 
|  | } | 
|  | } else if (!xstrncasecmp(argv[i], "PurgeStepMonths", | 
|  | MAX(command_len, 7))) { | 
|  | if (get_uint(argv[i]+end, &tmp, "PurgeStepMonths") | 
|  | != SLURM_SUCCESS) { | 
|  | exit_code = 1; | 
|  | } else { | 
|  | arch_cond->purge_step |= tmp; | 
|  | arch_cond->purge_step |= SLURMDB_PURGE_MONTHS; | 
|  | set = 1; | 
|  | } | 
|  | } else if (!xstrncasecmp(argv[i], "PurgeSuspendMonths", | 
|  | MAX(command_len, 7))) { | 
|  | if (get_uint(argv[i]+end, &tmp, "PurgeSuspendMonths") | 
|  | != SLURM_SUCCESS) { | 
|  | exit_code = 1; | 
|  | } else { | 
|  | arch_cond->purge_suspend |= tmp; | 
|  | arch_cond->purge_suspend | 
|  | |= SLURMDB_PURGE_MONTHS; | 
|  | set = 1; | 
|  | } | 
|  | } else if (!xstrncasecmp(argv[i], "PurgeTXNMonths", | 
|  | MAX(command_len, 6))) { | 
|  | if (get_uint(argv[i]+end, &tmp, "PurgeTXNMonths") | 
|  | != SLURM_SUCCESS) { | 
|  | exit_code = 1; | 
|  | } else { | 
|  | arch_cond->purge_txn |= tmp; | 
|  | arch_cond->purge_txn | 
|  | |= SLURMDB_PURGE_MONTHS; | 
|  | set = 1; | 
|  | } | 
|  | } else if (!xstrncasecmp(argv[i], "PurgeUsageMonths", | 
|  | MAX(command_len, 6))) { | 
|  | if (get_uint(argv[i]+end, &tmp, "PurgeUsageMonths") | 
|  | != SLURM_SUCCESS) { | 
|  | exit_code = 1; | 
|  | } else { | 
|  | arch_cond->purge_usage |= tmp; | 
|  | arch_cond->purge_usage | 
|  | |= SLURMDB_PURGE_MONTHS; | 
|  | set = 1; | 
|  | } | 
|  | } else if (!xstrncasecmp(argv[i], "Start", | 
|  | MAX(command_len, 2))) { | 
|  | job_cond->usage_start = parse_time(argv[i]+end, 1); | 
|  | set = 1; | 
|  | } else if (!xstrncasecmp(argv[i], "Script", | 
|  | MAX(command_len, 2))) { | 
|  | arch_cond->archive_script = | 
|  | strip_quotes(argv[i]+end, NULL, 0); | 
|  | set = 1; | 
|  | } else if (!xstrncasecmp(argv[i], "Users", | 
|  | MAX(command_len, 1))) { | 
|  | if (!job_cond->userid_list) | 
|  | job_cond->userid_list = list_create(xfree_ptr); | 
|  | if (slurm_addto_id_char_list(job_cond->userid_list, | 
|  | argv[i]+end, false) > 0) | 
|  | set = 1; | 
|  | else | 
|  | exit_code = 1; | 
|  | } else { | 
|  | exit_code=1; | 
|  | fprintf(stderr, " Unknown condition: %s\n", argv[i]); | 
|  | } | 
|  | } | 
|  |  | 
|  | (*start) = i; | 
|  |  | 
|  | return set; | 
|  | } | 
|  |  | 
|  | extern int sacctmgr_archive_dump(int argc, char **argv) | 
|  | { | 
|  | char *warning = NULL; | 
|  | int rc = SLURM_SUCCESS; | 
|  | slurmdb_archive_cond_t *arch_cond = | 
|  | xmalloc(sizeof(slurmdb_archive_cond_t)); | 
|  | int i; | 
|  | struct stat st; | 
|  |  | 
|  | for (i = 0; i < argc; i++) { | 
|  | int command_len = strlen(argv[i]); | 
|  | if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5)) | 
|  | || !xstrncasecmp(argv[i], "Set", MAX(command_len, 3))) | 
|  | i++; | 
|  | _set_cond(&i, argc, argv, arch_cond); | 
|  | } | 
|  |  | 
|  | if (!arch_cond->purge_event) | 
|  | arch_cond->purge_event = NO_VAL; | 
|  | if (!arch_cond->purge_job) | 
|  | arch_cond->purge_job = NO_VAL; | 
|  | if (!arch_cond->purge_resv) | 
|  | arch_cond->purge_resv = NO_VAL; | 
|  | if (!arch_cond->purge_step) | 
|  | arch_cond->purge_step = NO_VAL; | 
|  | if (!arch_cond->purge_suspend) | 
|  | arch_cond->purge_suspend = NO_VAL; | 
|  | if (!arch_cond->purge_txn) | 
|  | arch_cond->purge_txn = NO_VAL; | 
|  | if (!arch_cond->purge_usage) | 
|  | arch_cond->purge_usage = NO_VAL; | 
|  |  | 
|  | if (exit_code) { | 
|  | slurmdb_destroy_archive_cond(arch_cond); | 
|  | return SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | if (arch_cond->archive_dir) { | 
|  | if (stat(arch_cond->archive_dir, &st) < 0) { | 
|  | exit_code = errno; | 
|  | fprintf(stderr, " dump: Failed to stat %s: %s\n " | 
|  | "Note: For archive dump, " | 
|  | "the directory must be on " | 
|  | "the calling host.\n", | 
|  | arch_cond->archive_dir, slurm_strerror(errno)); | 
|  | slurmdb_destroy_archive_cond(arch_cond); | 
|  | return SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | if (!(st.st_mode & S_IFDIR)) { | 
|  | errno = EACCES; | 
|  | fprintf(stderr, " dump: " | 
|  | "archive dir %s isn't a directory\n", | 
|  | arch_cond->archive_dir); | 
|  | slurmdb_destroy_archive_cond(arch_cond); | 
|  | return SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | if (access(arch_cond->archive_dir, W_OK) < 0) { | 
|  | errno = EACCES; | 
|  | fprintf(stderr, " dump: " | 
|  | "archive dir %s is not writable\n", | 
|  | arch_cond->archive_dir); | 
|  | slurmdb_destroy_archive_cond(arch_cond); | 
|  | return SLURM_ERROR; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (arch_cond->archive_script) { | 
|  | if (stat(arch_cond->archive_script, &st) < 0) { | 
|  | exit_code = errno; | 
|  | fprintf(stderr, " dump: Failed to stat %s: %s\n " | 
|  | "Note: For archive dump, the script must be on " | 
|  | "the calling host.\n", | 
|  | arch_cond->archive_script, | 
|  | slurm_strerror(errno)); | 
|  | slurmdb_destroy_archive_cond(arch_cond); | 
|  | return SLURM_ERROR; | 
|  | } | 
|  | if (!(st.st_mode & S_IFREG)) { | 
|  | errno = EACCES; | 
|  | fprintf(stderr, " dump: " | 
|  | "archive script %s isn't a regular file\n", | 
|  | arch_cond->archive_script); | 
|  | slurmdb_destroy_archive_cond(arch_cond); | 
|  | return SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | if (access(arch_cond->archive_script, X_OK) < 0) { | 
|  | errno = EACCES; | 
|  | fprintf(stderr, " dump: " | 
|  | "archive script %s is not executable\n", | 
|  | arch_cond->archive_script); | 
|  | slurmdb_destroy_archive_cond(arch_cond); | 
|  | return SLURM_ERROR; | 
|  | } | 
|  | } | 
|  |  | 
|  | warning = "This may result in loss of accounting database records (if Purge* options enabled).\nAre you sure you want to continue?"; | 
|  | if (commit_check(warning)) { | 
|  | rc = slurmdb_archive(db_conn, arch_cond); | 
|  | if (rc != SLURM_SUCCESS) { | 
|  | exit_code = 1; | 
|  | fprintf(stderr, " Problem dumping archive: %s\n", | 
|  | slurm_strerror(rc)); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  | } else { | 
|  | printf(" Changes Discarded\n"); | 
|  | } | 
|  |  | 
|  | slurmdb_destroy_archive_cond(arch_cond); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | extern int sacctmgr_archive_load(int argc, char **argv) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | slurmdb_archive_rec_t *arch_rec = | 
|  | xmalloc(sizeof(slurmdb_archive_rec_t)); | 
|  | int i, command_len = 0; | 
|  |  | 
|  | for (i = 0; i < argc; i++) { | 
|  | int op_type; | 
|  | int end = parse_option_end(argv[i], &op_type, &command_len); | 
|  | if (!common_verify_option_syntax(argv[i], op_type, false)) | 
|  | continue; | 
|  |  | 
|  | if (!end | 
|  | || !xstrncasecmp(argv[i], "File", MAX(command_len, 1))) { | 
|  | arch_rec->archive_file = | 
|  | strip_quotes(argv[i]+end, NULL, 0); | 
|  | if (!is_full_path(arch_rec->archive_file)) { | 
|  | char *file = arch_rec->archive_file; | 
|  | arch_rec->archive_file = | 
|  | make_full_path(arch_rec->archive_file); | 
|  | xfree(file); | 
|  | } | 
|  | } else if (!xstrncasecmp(argv[i], "Insert", | 
|  | MAX(command_len, 2))) { | 
|  | arch_rec->insert = strip_quotes(argv[i]+end, NULL, 1); | 
|  | } else { | 
|  | exit_code = 1; | 
|  | fprintf(stderr, " Unknown option: %s\n", argv[i]); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (exit_code) { | 
|  | slurmdb_destroy_archive_rec(arch_rec); | 
|  | return SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | rc = slurmdb_archive_load(db_conn, arch_rec); | 
|  | if (rc == SLURM_SUCCESS) { | 
|  | if (commit_check("Would you like to commit changes?")) { | 
|  | rc = slurmdb_connection_commit(db_conn, 1); | 
|  | if (rc != SLURM_SUCCESS) | 
|  | fprintf(stderr, | 
|  | "Error committing changes: %s\n", | 
|  | slurm_strerror(rc)); | 
|  | } else { | 
|  | printf(" Changes Discarded\n"); | 
|  | rc = slurmdb_connection_commit(db_conn, 0); | 
|  | if (rc != SLURM_SUCCESS) | 
|  | fprintf(stderr, | 
|  | "Error rolling back changes: %s\n", | 
|  | slurm_strerror(rc)); | 
|  | } | 
|  | } else { | 
|  | exit_code = 1; | 
|  | fprintf(stderr, " Problem loading archive file: %s\n", | 
|  | slurm_strerror(rc)); | 
|  |  | 
|  | if (rc == EACCES || rc == EISDIR || rc == ENOENT) | 
|  | fprintf(stderr, " Note: For archive load, the file must be accessible on the slurmdbd host.\n"); | 
|  |  | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | slurmdb_destroy_archive_rec(arch_rec); | 
|  |  | 
|  | return rc; | 
|  | } |