|  | /*****************************************************************************\ | 
|  | *  proc_req.c - functions for processing incoming RPCs. | 
|  | ***************************************************************************** | 
|  | *  Copyright (C) 2008-2010 Lawrence Livermore National Security. | 
|  | *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). | 
|  | *  Written by Morris Jette <jette1@llnl.gov>, 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 "config.h" | 
|  |  | 
|  | #include <signal.h> | 
|  |  | 
|  | #if HAVE_SYS_PRCTL_H | 
|  | #include <sys/prctl.h> | 
|  | #endif | 
|  |  | 
|  | #include "src/common/macros.h" | 
|  | #include "src/common/pack.h" | 
|  | #include "src/common/slurm_protocol_api.h" | 
|  | #include "src/common/slurm_protocol_defs.h" | 
|  | #include "src/common/slurmdbd_defs.h" | 
|  | #include "src/common/slurmdbd_pack.h" | 
|  | #include "src/common/timers.h" | 
|  | #include "src/common/uid.h" | 
|  | #include "src/common/xstring.h" | 
|  |  | 
|  | #include "src/conmgr/conmgr.h" | 
|  |  | 
|  | #include "src/interfaces/accounting_storage.h" | 
|  | #include "src/interfaces/auth.h" | 
|  | #include "src/interfaces/conn.h" | 
|  | #include "src/interfaces/gres.h" | 
|  | #include "src/interfaces/jobacct_gather.h" | 
|  |  | 
|  | #include "src/slurmctld/slurmctld.h" | 
|  |  | 
|  | #include "src/slurmdbd/proc_req.h" | 
|  | #include "src/slurmdbd/read_config.h" | 
|  | #include "src/slurmdbd/rpc_mgr.h" | 
|  | #include "src/slurmdbd/slurmdbd.h" | 
|  |  | 
|  | /* Local functions */ | 
|  | static bool _validate_slurm_user(slurmdbd_conn_t *dbd_conn); | 
|  | static bool _validate_super_user(slurmdbd_conn_t *dbd_conn); | 
|  | static bool _validate_operator(slurmdbd_conn_t *dbd_conn); | 
|  | static int   _find_rpc_obj_in_list(void *x, void *key); | 
|  | static void _process_job_start(slurmdbd_conn_t *slurmdbd_conn, | 
|  | dbd_job_start_msg_t *job_start_msg, | 
|  | dbd_id_rc_msg_t *id_rc_msg); | 
|  |  | 
|  | static char *_internal_rc_to_str(uint32_t rc, slurmdbd_conn_t *dbd_conn, | 
|  | bool new_line) | 
|  | { | 
|  | int fd = conn_g_get_fd(dbd_conn->conn->tls_conn); | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (rc == SLURM_NO_CHANGE_IN_DATA) { | 
|  | if (new_line) | 
|  | comment = "Request didn't affect anything\n"; | 
|  | else | 
|  | comment = "Request didn't affect anything"; | 
|  | debug2("CONN:%d %s", fd, comment); | 
|  | return comment; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Clients of _add_accounts_cond() and _add_users_cond() expect the | 
|  | * comment to have '\n' at the end of the strings. Since these are | 
|  | * string literals, we have the new_line condition to handle these in | 
|  | * one location. | 
|  | */ | 
|  | if (new_line) { | 
|  | if (rc == ESLURM_ACCESS_DENIED) { | 
|  | comment = "Your user doesn't have privilege to perform this action\n"; | 
|  | } else if (rc == SLURM_ERROR) { | 
|  | comment = "Something was wrong with your query\n"; | 
|  | } else if (rc == ESLURM_DB_CONNECTION) { | 
|  | comment = slurm_strerror(rc); | 
|  | } else if (rc == ESLURM_QOS_PREEMPTION_LOOP) { | 
|  | comment = "QOS Preemption loop detected\n"; | 
|  | } else { | 
|  | if (!(comment = slurm_strerror(rc))) | 
|  | comment = "Unknown issue\n"; | 
|  | } | 
|  | } else { | 
|  | if (rc == ESLURM_ACCESS_DENIED) { | 
|  | comment = "Your user doesn't have privilege to perform this action"; | 
|  | } else if (rc == SLURM_ERROR) { | 
|  | comment = "Something was wrong with your query"; | 
|  | } else if (rc == ESLURM_DB_CONNECTION) { | 
|  | comment = slurm_strerror(rc); | 
|  | } else if (rc == ESLURM_QOS_PREEMPTION_LOOP) { | 
|  | comment = "QOS Preemption loop detected"; | 
|  | } else { | 
|  | if (!(comment = slurm_strerror(rc))) | 
|  | comment = "Unknown issue"; | 
|  | } | 
|  | } | 
|  | error("CONN:%d %s", fd, comment); | 
|  |  | 
|  | return comment; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * _validate_slurm_user - validate that the uid is authorized to see | 
|  | *      privileged data (either user root or SlurmUser) | 
|  | */ | 
|  | static bool _validate_slurm_user(slurmdbd_conn_t *dbd_conn) | 
|  | { | 
|  | uint32_t uid = dbd_conn->conn->auth_uid; | 
|  |  | 
|  | if ((uid == 0) || (uid == slurm_conf.slurm_user_id)) | 
|  | return true; | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * _validate_super_user - validate that the uid is authorized at the | 
|  | *      root, SlurmUser, or SLURMDB_ADMIN_SUPER_USER level | 
|  | */ | 
|  | static bool _validate_super_user(slurmdbd_conn_t *dbd_conn) | 
|  | { | 
|  | uint32_t uid = dbd_conn->conn->auth_uid; | 
|  |  | 
|  | if ((uid == 0) || (uid == slurm_conf.slurm_user_id) || | 
|  | assoc_mgr_get_admin_level(dbd_conn, uid) >= SLURMDB_ADMIN_SUPER_USER) | 
|  | return true; | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * _validate_operator - validate that the uid is authorized at the | 
|  | *      root, SlurmUser, or SLURMDB_ADMIN_OPERATOR level | 
|  | */ | 
|  | static bool _validate_operator(slurmdbd_conn_t *dbd_conn) | 
|  | { | 
|  | uint32_t uid = dbd_conn->conn->auth_uid; | 
|  |  | 
|  | if ((uid == 0) || (uid == slurm_conf.slurm_user_id) || | 
|  | assoc_mgr_get_admin_level(dbd_conn, uid) >= SLURMDB_ADMIN_OPERATOR) | 
|  | return true; | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | static void _add_registered_cluster(slurmdbd_conn_t *db_conn) | 
|  | { | 
|  | list_itr_t *itr; | 
|  | slurmdbd_conn_t *slurmdbd_conn; | 
|  |  | 
|  | if (!db_conn->conn->rem_port) { | 
|  | error("%s: trying to register a cluster (%s) with no remote port", | 
|  | __func__, db_conn->conn->cluster_name); | 
|  | return; | 
|  | } | 
|  |  | 
|  | slurm_mutex_lock(®istered_lock); | 
|  | itr = list_iterator_create(registered_clusters); | 
|  | while ((slurmdbd_conn = list_next(itr))) { | 
|  | int new_fd = -1, existing_fd = -1; | 
|  |  | 
|  | if (db_conn == slurmdbd_conn) | 
|  | break; | 
|  |  | 
|  | if (db_conn->conn->tls_conn) { | 
|  | new_fd = conn_g_get_fd(db_conn->conn->tls_conn); | 
|  | } | 
|  |  | 
|  | if (slurmdbd_conn->conn->tls_conn) { | 
|  | existing_fd = | 
|  | conn_g_get_fd(slurmdbd_conn->conn->tls_conn); | 
|  | } | 
|  |  | 
|  | if (!xstrcmp(db_conn->conn->cluster_name, | 
|  | slurmdbd_conn->conn->cluster_name) && | 
|  | (new_fd != existing_fd)) { | 
|  | error("A new registration for cluster %s CONN:%d just came in, but I am already talking to that cluster (CONN:%d), closing other connection.", | 
|  | db_conn->conn->cluster_name, new_fd, existing_fd); | 
|  | slurmdbd_conn->conn->rem_port = 0; | 
|  | list_delete_item(itr); | 
|  | } | 
|  | } | 
|  | list_iterator_destroy(itr); | 
|  | if (!slurmdbd_conn) { | 
|  | slurm_mutex_init(&db_conn->conn_send_lock); | 
|  | slurm_mutex_lock(&db_conn->conn_send_lock); | 
|  | db_conn->conn_send = xmalloc(sizeof(persist_conn_t)); | 
|  | db_conn->conn_send->cluster_name = | 
|  | xstrdup(db_conn->conn->cluster_name); | 
|  | db_conn->conn_send->persist_type = PERSIST_TYPE_ACCT_UPDATE; | 
|  | db_conn->conn_send->my_port = slurmdbd_conf->dbd_port; | 
|  | db_conn->conn_send->rem_host = xstrdup(db_conn->conn->rem_host); | 
|  | db_conn->conn_send->rem_port = db_conn->conn->rem_port; | 
|  | db_conn->conn_send->version = db_conn->conn->version; | 
|  | db_conn->conn_send->shutdown = &shutdown_time; | 
|  | /* we want timeout to be zero */ | 
|  | db_conn->conn_send->timeout = 0; | 
|  | db_conn->conn_send->r_uid = SLURM_AUTH_UID_ANY; | 
|  | db_conn->conn_send->flags |= PERSIST_FLAG_RECONNECT; | 
|  | slurm_mutex_unlock(&db_conn->conn_send_lock); | 
|  | /* | 
|  | * We can't open a pipe back to the slurmctld right | 
|  | * now, the slurmctld might just be starting up and the | 
|  | * rpc_mgr might not be listening yet, so we will handle | 
|  | * this in the mysql plugin on the first commit. | 
|  | */ | 
|  | /* if (slurm_persist_conn_open(db_conn->conn_send) != */ | 
|  | /*     SLURM_SUCCESS) { */ | 
|  | /* 	error("persist_conn_send: Unable to open connection to cluster %s who is actively talking to us.", */ | 
|  | /* 	      db_conn->conn->cluster_name); */ | 
|  | /* } */ | 
|  |  | 
|  | list_append(registered_clusters, db_conn); | 
|  | } | 
|  | slurm_mutex_unlock(®istered_lock); | 
|  | } | 
|  |  | 
|  |  | 
|  | /* replace \" with \` return is the same as what is given */ | 
|  | static char * _replace_double_quotes(char *option) | 
|  | { | 
|  | int i=0; | 
|  |  | 
|  | if (!option) | 
|  | return NULL; | 
|  |  | 
|  | while (option[i]) { | 
|  | if (option[i] == '\"') | 
|  | option[i] = '`'; | 
|  | i++; | 
|  | } | 
|  | return option; | 
|  | } | 
|  |  | 
|  | static int _handle_init_msg(slurmdbd_conn_t *slurmdbd_conn, | 
|  | persist_init_req_msg_t *init_msg) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | int fd = conn_g_get_fd(slurmdbd_conn->conn->tls_conn); | 
|  |  | 
|  | #if HAVE_SYS_PRCTL_H | 
|  | { | 
|  | char *name = xstrdup_printf("p-%s", init_msg->cluster_name); | 
|  | if (prctl(PR_SET_NAME, name, NULL, NULL, NULL) < 0) | 
|  | error("%s: cannot set my name to %s %m", __func__, name); | 
|  | xfree(name); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | debug("REQUEST_PERSIST_INIT: CLUSTER:%s VERSION:%u UID:%u IP:%s CONN:%d", | 
|  | init_msg->cluster_name, init_msg->version, | 
|  | slurmdbd_conn->conn->auth_uid, slurmdbd_conn->conn->rem_host, fd); | 
|  |  | 
|  | slurmdbd_conn->conn->cluster_name = xstrdup(init_msg->cluster_name); | 
|  |  | 
|  | /* When dealing with rollbacks it turns out it is much faster | 
|  | to do the commit once or once in a while instead of | 
|  | autocommit.  The SlurmDBD will periodically do a commit to | 
|  | avoid such a slow down. | 
|  | */ | 
|  | slurmdbd_conn->db_conn = acct_storage_g_get_connection( | 
|  | fd, NULL, true, slurmdbd_conn->conn->cluster_name); | 
|  | slurmdbd_conn->conn->version = init_msg->version; | 
|  | if (errno) | 
|  | rc = errno; | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _unpack_persist_init(slurmdbd_conn_t *slurmdbd_conn, | 
|  | persist_msg_t *msg, buf_t **out_buffer) | 
|  | { | 
|  | int rc; | 
|  | slurm_msg_t *smsg = msg->data; | 
|  | persist_init_req_msg_t *req_msg = smsg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | req_msg->uid = auth_g_get_uid(slurmdbd_conn->conn->auth_cred); | 
|  |  | 
|  | rc = _handle_init_msg(slurmdbd_conn, req_msg); | 
|  |  | 
|  | if (rc != SLURM_SUCCESS) | 
|  | comment = slurm_strerror(rc); | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg_flags( | 
|  | slurmdbd_conn->conn, rc, comment, | 
|  | slurmdbd_conf->persist_conn_rc_flags, | 
|  | req_msg->version); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _add_accounts(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_list_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | rc = acct_storage_g_add_accounts(slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->my_list); | 
|  | if (rc == ESLURM_ACCESS_DENIED) | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_ADD_ACCOUNTS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _add_accounts_cond(slurmdbd_conn_t *slurmdbd_conn, | 
|  | persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_modify_msg_t *modify_msg = msg->data; | 
|  | char *comment = NULL; | 
|  | bool free_comment = true; | 
|  |  | 
|  | /* | 
|  | * All authentication needs to be done inside the plugin since we are | 
|  | * unable to know what accounts this request is talking about | 
|  | * until we process it through the database. | 
|  | */ | 
|  |  | 
|  | if (!(comment = acct_storage_g_add_accounts_cond( | 
|  | slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | modify_msg->cond, | 
|  | modify_msg->rec))) { | 
|  | free_comment = false; | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, true); | 
|  | } else | 
|  | rc = errno; | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | DBD_ADD_ACCOUNTS_COND); | 
|  | if (free_comment) | 
|  | xfree(comment); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _fix_runaway_jobs(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_list_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!_validate_operator(slurmdbd_conn)) | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | else | 
|  | rc = acct_storage_g_fix_runaway_jobs( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->my_list); | 
|  |  | 
|  | if (rc == ESLURM_ACCESS_DENIED) { | 
|  | comment = "You must have an AdminLevel>=Operator to fix runaway jobs"; | 
|  | error("CONN:%d %s", | 
|  | conn_g_get_fd(slurmdbd_conn->conn->tls_conn), | 
|  | comment); | 
|  | } | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | DBD_FIX_RUNAWAY_JOB); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _add_account_coords(slurmdbd_conn_t *slurmdbd_conn, | 
|  | persist_msg_t *msg, buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_acct_coord_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | rc = acct_storage_g_add_coord(slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->acct_list, get_msg->cond); | 
|  |  | 
|  | if (rc == ESLURM_ACCESS_DENIED) | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | DBD_ADD_ACCOUNT_COORDS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _add_tres(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_list_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | rc = acct_storage_g_add_tres(slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->my_list); | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_ADD_TRES); | 
|  |  | 
|  | /* This happens before the slurmctld registers and only when | 
|  | the slurmctld starts up.  So always commit, success or not. | 
|  | (don't ever use autocommit with innodb) | 
|  | */ | 
|  | acct_storage_g_commit(slurmdbd_conn->db_conn, 1); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _add_assocs(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_list_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!_validate_operator(slurmdbd_conn)) { | 
|  | list_itr_t *itr = NULL; | 
|  | list_itr_t *itr2 = NULL; | 
|  | slurmdb_user_rec_t user; | 
|  | slurmdb_coord_rec_t *coord = NULL; | 
|  | slurmdb_assoc_rec_t *object = NULL; | 
|  |  | 
|  | memset(&user, 0, sizeof(slurmdb_user_rec_t)); | 
|  | user.uid = slurmdbd_conn->conn->auth_uid; | 
|  | if (assoc_mgr_fill_in_user( | 
|  | slurmdbd_conn->db_conn, &user, 1, NULL, false) | 
|  | != SLURM_SUCCESS) { | 
|  | comment = "Your user has not been added to the accounting system yet."; | 
|  | error("CONN:%d %s", | 
|  | conn_g_get_fd(slurmdbd_conn->conn->tls_conn), | 
|  | comment); | 
|  | rc = SLURM_ERROR; | 
|  | goto end_it; | 
|  | } | 
|  | if (!user.coord_accts || !list_count(user.coord_accts)) { | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | goto end_it; | 
|  | } | 
|  | itr = list_iterator_create(get_msg->my_list); | 
|  | itr2 = list_iterator_create(user.coord_accts); | 
|  | while ((object = list_next(itr))) { | 
|  | char *account = "root"; | 
|  | if (object->user) | 
|  | account = object->acct; | 
|  | else if (object->parent_acct) | 
|  | account = object->parent_acct; | 
|  | list_iterator_reset(itr2); | 
|  | while ((coord = list_next(itr2))) { | 
|  | if (!xstrcasecmp(coord->name, account)) | 
|  | break; | 
|  | } | 
|  | if (!coord) | 
|  | break; | 
|  | } | 
|  | list_iterator_destroy(itr2); | 
|  | list_iterator_destroy(itr); | 
|  | if (!coord) { | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | goto end_it; | 
|  | } | 
|  | } | 
|  |  | 
|  | rc = acct_storage_g_add_assocs(slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->my_list); | 
|  | end_it: | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_ADD_ASSOCS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _add_clusters(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_list_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | rc = acct_storage_g_add_clusters(slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->my_list); | 
|  | if (rc == ESLURM_ACCESS_DENIED) | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | else if (rc != SLURM_SUCCESS) | 
|  | comment = "Failed to add cluster."; | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_ADD_CLUSTERS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _add_federations(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_list_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | rc = acct_storage_g_add_federations(slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->my_list); | 
|  | if (rc == ESLURM_ACCESS_DENIED) | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | else if (rc != SLURM_SUCCESS) | 
|  | comment = "Failed to add cluster."; | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | DBD_ADD_FEDERATIONS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _add_qos(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_list_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | rc = acct_storage_g_add_qos(slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->my_list); | 
|  | if (rc == ESLURM_ACCESS_DENIED) | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | else if (rc != SLURM_SUCCESS) | 
|  | comment = "Failed to add qos."; | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_ADD_QOS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _add_res(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_list_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  |  | 
|  | rc = acct_storage_g_add_res(slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->my_list); | 
|  | if (rc == ESLURM_ACCESS_DENIED) | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | else if (rc != SLURM_SUCCESS) | 
|  | comment = "Failed to add system resource."; | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_ADD_RES); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _add_users(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_list_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | rc = acct_storage_g_add_users(slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->my_list); | 
|  |  | 
|  | if (rc == ESLURM_ACCESS_DENIED) | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_ADD_USERS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _add_users_cond(slurmdbd_conn_t *slurmdbd_conn, | 
|  | persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_modify_msg_t *modify_msg = msg->data; | 
|  | char *comment = NULL; | 
|  | bool free_comment = true; | 
|  |  | 
|  | /* | 
|  | * All authentication needs to be done inside the plugin since we are | 
|  | * unable to know what users this request is talking about | 
|  | * until we process it through the database. | 
|  | */ | 
|  |  | 
|  | if (!(comment = acct_storage_g_add_users_cond( | 
|  | slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | modify_msg->cond, | 
|  | modify_msg->rec))) { | 
|  | free_comment = false; | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, true); | 
|  | } else | 
|  | rc = errno; | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | DBD_ADD_USERS_COND); | 
|  | if (free_comment) | 
|  | xfree(comment); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _add_wckeys(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_list_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | rc = acct_storage_g_add_wckeys(slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->my_list); | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_ADD_WCKEYS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _add_reservation(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_rec_msg_t *rec_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!_validate_slurm_user(slurmdbd_conn)) { | 
|  | comment = "DBD_ADD_RESV message from invalid uid"; | 
|  | error("DBD_ADD_RESV message from invalid uid %u", | 
|  | slurmdbd_conn->conn->auth_uid); | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | rc = acct_storage_g_add_reservation(slurmdbd_conn->db_conn, | 
|  | rec_msg->rec); | 
|  |  | 
|  | end_it: | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_ADD_RESV); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _archive_dump(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | char *comment = "SUCCESS"; | 
|  | slurmdb_archive_cond_t *arch_cond = NULL; | 
|  |  | 
|  | if (!_validate_super_user(slurmdbd_conn)) { | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | arch_cond = (slurmdb_archive_cond_t *)get_msg->cond; | 
|  | /* set up some defaults */ | 
|  | if (!arch_cond->archive_dir) | 
|  | arch_cond->archive_dir = xstrdup(slurmdbd_conf->archive_dir); | 
|  | if (!arch_cond->archive_script) | 
|  | arch_cond->archive_script = | 
|  | xstrdup(slurmdbd_conf->archive_script); | 
|  |  | 
|  | if (arch_cond->purge_event == NO_VAL) | 
|  | arch_cond->purge_event = slurmdbd_conf->purge_event; | 
|  | if (arch_cond->purge_job == NO_VAL) | 
|  | arch_cond->purge_job = slurmdbd_conf->purge_job; | 
|  | if (arch_cond->purge_resv == NO_VAL) | 
|  | arch_cond->purge_resv = slurmdbd_conf->purge_resv; | 
|  | if (arch_cond->purge_step == NO_VAL) | 
|  | arch_cond->purge_step = slurmdbd_conf->purge_step; | 
|  | if (arch_cond->purge_suspend == NO_VAL) | 
|  | arch_cond->purge_suspend = slurmdbd_conf->purge_suspend; | 
|  | if (arch_cond->purge_txn == NO_VAL) | 
|  | arch_cond->purge_txn = slurmdbd_conf->purge_txn; | 
|  | if (arch_cond->purge_usage == NO_VAL) | 
|  | arch_cond->purge_usage = slurmdbd_conf->purge_usage; | 
|  |  | 
|  | rc = jobacct_storage_g_archive(slurmdbd_conn->db_conn, arch_cond); | 
|  | if (rc != SLURM_SUCCESS) { | 
|  | if (errno == EACCES) | 
|  | comment = "Problem accessing file."; | 
|  | else | 
|  | comment = "Error with request."; | 
|  | } | 
|  | end_it: | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_ARCHIVE_DUMP); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _archive_load(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | slurmdb_archive_rec_t *arch_rec = msg->data; | 
|  | char *comment = "SUCCESS"; | 
|  |  | 
|  | if (!_validate_super_user(slurmdbd_conn)) { | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | rc = jobacct_storage_g_archive_load(slurmdbd_conn->db_conn, arch_rec); | 
|  |  | 
|  | if (rc == ENOENT) | 
|  | comment = "No archive file given to recover."; | 
|  | else if (rc != SLURM_SUCCESS) | 
|  | comment = "Error with request."; | 
|  |  | 
|  | end_it: | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_ARCHIVE_LOAD); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _cluster_tres(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_cluster_tres_msg_t *cluster_tres_msg = msg->data; | 
|  | int rc = SLURM_SUCCESS; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!_validate_slurm_user(slurmdbd_conn)) { | 
|  | comment = "DBD_CLUSTER_TRES message from invalid uid"; | 
|  | error("DBD_CLUSTER_TRES message from invalid uid %u", | 
|  | slurmdbd_conn->conn->auth_uid); | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | debug2("DBD_CLUSTER_TRES: called in CONN %d for %s(%s)", | 
|  | conn_g_get_fd(slurmdbd_conn->conn->tls_conn), | 
|  | slurmdbd_conn->conn->cluster_name, cluster_tres_msg->tres_str); | 
|  |  | 
|  | rc = clusteracct_storage_g_cluster_tres( | 
|  | slurmdbd_conn->db_conn, | 
|  | cluster_tres_msg->cluster_nodes, | 
|  | cluster_tres_msg->tres_str, | 
|  | cluster_tres_msg->event_time, | 
|  | slurmdbd_conn->conn->version); | 
|  | if (rc == ESLURM_ACCESS_DENIED) { | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  | end_it: | 
|  | if (rc == SLURM_SUCCESS) { | 
|  | xfree(slurmdbd_conn->tres_str); | 
|  | slurmdbd_conn->tres_str = cluster_tres_msg->tres_str; | 
|  | cluster_tres_msg->tres_str = NULL; | 
|  | } | 
|  | if (!slurmdbd_conn->conn->rem_port) { | 
|  | debug3("DBD_CLUSTER_TRES: cluster not registered"); | 
|  | slurmdbd_conn->conn->rem_port = | 
|  | clusteracct_storage_g_register_disconn_ctld( | 
|  | slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->rem_host); | 
|  |  | 
|  | _add_registered_cluster(slurmdbd_conn); | 
|  | } | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_CLUSTER_TRES); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _get_accounts(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  |  | 
|  | list_msg.my_list = acct_storage_g_get_accounts( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond); | 
|  |  | 
|  | if (!errno) { | 
|  | if (!list_msg.my_list) | 
|  | list_msg.my_list = list_create(NULL); | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_ACCOUNTS, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_ACCOUNTS, | 
|  | *out_buffer); | 
|  | } else { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | errno, | 
|  | slurm_strerror(errno), | 
|  | DBD_GET_ACCOUNTS); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _get_tres(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  |  | 
|  | list_msg.my_list = acct_storage_g_get_tres( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond); | 
|  |  | 
|  | if (!errno) { | 
|  | if (!list_msg.my_list) | 
|  | list_msg.my_list = list_create(NULL); | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_TRES, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_TRES, *out_buffer); | 
|  | } else { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | errno, | 
|  | slurm_strerror(errno), | 
|  | DBD_GET_TRES); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _get_assocs(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  |  | 
|  | list_msg.my_list = acct_storage_g_get_assocs( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond); | 
|  |  | 
|  | if (!errno) { | 
|  | if (!list_msg.my_list) | 
|  | list_msg.my_list = list_create(NULL); | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_ASSOCS, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_ASSOCS, *out_buffer); | 
|  | } else { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | errno, | 
|  | slurm_strerror(errno), | 
|  | DBD_GET_ASSOCS); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _get_clusters(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  |  | 
|  | list_msg.my_list = acct_storage_g_get_clusters( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond); | 
|  |  | 
|  | if (!errno) { | 
|  | if (!list_msg.my_list) | 
|  | list_msg.my_list = list_create(NULL); | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_CLUSTERS, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_CLUSTERS, | 
|  | *out_buffer); | 
|  | } else { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | errno, | 
|  | slurm_strerror(errno), | 
|  | DBD_GET_CLUSTERS); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _get_federations(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  |  | 
|  | list_msg.my_list = acct_storage_g_get_federations( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond); | 
|  |  | 
|  | if (!errno) { | 
|  | if (!list_msg.my_list) | 
|  | list_msg.my_list = list_create(NULL); | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_FEDERATIONS, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_FEDERATIONS, | 
|  | *out_buffer); | 
|  | } else { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | errno, | 
|  | slurm_strerror(errno), | 
|  | DBD_GET_FEDERATIONS); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _get_config(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | char *config_name = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  |  | 
|  | if (config_name == NULL || | 
|  | xstrcmp(config_name, "slurmdbd.conf") == 0) | 
|  | list_msg.my_list = dump_config(); | 
|  | else if ((list_msg.my_list = acct_storage_g_get_config( | 
|  | slurmdbd_conn->db_conn, config_name)) == NULL) { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | errno, | 
|  | slurm_strerror(errno), | 
|  | DBD_GET_CONFIG); | 
|  | xfree(config_name); | 
|  | return SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_CONFIG, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_CONFIG, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  | xfree(config_name); | 
|  |  | 
|  | return SLURM_SUCCESS; | 
|  | } | 
|  |  | 
|  | static int _get_events(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  |  | 
|  | list_msg.my_list = acct_storage_g_get_events( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond); | 
|  |  | 
|  | if (!errno) { | 
|  | if (!list_msg.my_list) | 
|  | list_msg.my_list = list_create(NULL); | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_EVENTS, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_EVENTS, | 
|  | *out_buffer); | 
|  | } else { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | errno, | 
|  | slurm_strerror(errno), | 
|  | DBD_GET_EVENTS); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _get_instances(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  |  | 
|  | list_msg.my_list = acct_storage_g_get_instances( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond); | 
|  |  | 
|  | if (!errno) { | 
|  | if (!list_msg.my_list) | 
|  | list_msg.my_list = list_create(NULL); | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_INSTANCES, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_INSTANCES, | 
|  | *out_buffer); | 
|  | } else { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | errno, | 
|  | slurm_strerror(errno), | 
|  | DBD_GET_INSTANCES); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _get_jobs_cond(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_cond_msg_t *cond_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | slurmdb_job_cond_t *job_cond = cond_msg->cond; | 
|  | int rc = SLURM_SUCCESS; | 
|  |  | 
|  | /* fail early if requesting runaways and not super user */ | 
|  | if ((job_cond->flags & JOBCOND_FLAG_RUNAWAY) && | 
|  | !_validate_operator(slurmdbd_conn)) { | 
|  | debug("Rejecting query of runaways from uid %u", | 
|  | slurmdbd_conn->conn->auth_uid); | 
|  | *out_buffer = slurm_persist_make_rc_msg( | 
|  | slurmdbd_conn->conn, | 
|  | ESLURM_ACCESS_DENIED, | 
|  | "You must have an AdminLevel>=Operator to fix runaway jobs", | 
|  | DBD_GET_JOBS_COND); | 
|  | return SLURM_ERROR; | 
|  | } | 
|  | /* fail early if too wide a query */ | 
|  | if (!job_cond->step_list && !_validate_operator(slurmdbd_conn) | 
|  | && (slurmdbd_conf->max_time_range != INFINITE)) { | 
|  | time_t start, end; | 
|  |  | 
|  | start = job_cond->usage_start; | 
|  |  | 
|  | if (job_cond->usage_end) | 
|  | end = job_cond->usage_end; | 
|  | else | 
|  | end = time(NULL); | 
|  |  | 
|  | if ((end - start) > slurmdbd_conf->max_time_range) { | 
|  | info("Rejecting query > MaxQueryTimeRange from uid %u", | 
|  | slurmdbd_conn->conn->auth_uid); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | ESLURM_DB_QUERY_TOO_WIDE, | 
|  | slurm_strerror(ESLURM_DB_QUERY_TOO_WIDE), | 
|  | DBD_GET_JOBS_COND); | 
|  | return SLURM_ERROR; | 
|  | } | 
|  | } | 
|  |  | 
|  | list_msg.my_list = jobacct_storage_g_get_jobs_cond( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | job_cond); | 
|  |  | 
|  | if (!errno) { | 
|  | if (!list_msg.my_list) | 
|  | list_msg.my_list = list_create(NULL); | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_JOBS, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_JOBS, *out_buffer); | 
|  | } else { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | errno, | 
|  | slurm_strerror(errno), | 
|  | DBD_GET_JOBS_COND); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _get_probs(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  |  | 
|  | list_msg.my_list = acct_storage_g_get_problems( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond); | 
|  |  | 
|  | if (!errno) { | 
|  | if (!list_msg.my_list) | 
|  | list_msg.my_list = list_create(NULL); | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_PROBS, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_PROBS, *out_buffer); | 
|  | } else { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | errno, | 
|  | slurm_strerror(errno), | 
|  | DBD_GET_PROBS); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _get_qos(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_cond_msg_t *cond_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  |  | 
|  | list_msg.my_list = acct_storage_g_get_qos(slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | cond_msg->cond); | 
|  |  | 
|  | if (errno == ESLURM_ACCESS_DENIED && !list_msg.my_list) | 
|  | list_msg.my_list = list_create(NULL); | 
|  |  | 
|  | if (!errno) { | 
|  | if (!list_msg.my_list) | 
|  | list_msg.my_list = list_create(NULL); | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_QOS, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_QOS, *out_buffer); | 
|  | } else { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | errno, | 
|  | slurm_strerror(errno), | 
|  | DBD_GET_QOS); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _get_res(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  |  | 
|  | list_msg.my_list = acct_storage_g_get_res( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond); | 
|  |  | 
|  | if (!errno) { | 
|  | if (!list_msg.my_list) | 
|  | list_msg.my_list = list_create(NULL); | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_RES, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_RES, | 
|  | *out_buffer); | 
|  | } else { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | errno, | 
|  | slurm_strerror(errno), | 
|  | DBD_GET_RES); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _get_txn(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_cond_msg_t *cond_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  |  | 
|  | list_msg.my_list = acct_storage_g_get_txn(slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | cond_msg->cond); | 
|  |  | 
|  | if (!errno) { | 
|  | if (!list_msg.my_list) | 
|  | list_msg.my_list = list_create(NULL); | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_TXN, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_TXN, *out_buffer); | 
|  | } else { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | errno, | 
|  | slurm_strerror(errno), | 
|  | DBD_GET_TXN); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _get_usage(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_usage_msg_t *get_msg = msg->data; | 
|  | dbd_usage_msg_t got_msg; | 
|  | uint16_t ret_type = 0; | 
|  | int rc = SLURM_SUCCESS; | 
|  | char *comment = NULL; | 
|  | int fd = conn_g_get_fd(slurmdbd_conn->conn->tls_conn); | 
|  |  | 
|  | info("DBD_GET_USAGE: called in CONN %d. Type is %s", | 
|  | fd, slurmdbd_msg_type_2_str(msg->msg_type, 1)); | 
|  |  | 
|  | switch(msg->msg_type) { | 
|  | case DBD_GET_ASSOC_USAGE: | 
|  | ret_type = DBD_GOT_ASSOC_USAGE; | 
|  | break; | 
|  | case DBD_GET_QOS_USAGE: | 
|  | ret_type = DBD_GOT_QOS_USAGE; | 
|  | break; | 
|  | case DBD_GET_WCKEY_USAGE: | 
|  | ret_type = DBD_GOT_WCKEY_USAGE; | 
|  | break; | 
|  | case DBD_GET_CLUSTER_USAGE: | 
|  | ret_type = DBD_GOT_CLUSTER_USAGE; | 
|  | break; | 
|  | default: | 
|  | comment = "Unknown type of usage to get"; | 
|  | error("%s %u", comment, msg->msg_type); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | SLURM_ERROR, comment, | 
|  | msg->msg_type); | 
|  | return SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | rc = acct_storage_g_get_usage(slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->rec, msg->msg_type, | 
|  | get_msg->start, get_msg->end); | 
|  |  | 
|  | if (rc != SLURM_SUCCESS) { | 
|  | comment = "Problem getting usage info"; | 
|  | error("CONN:%d %s", fd, comment); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | msg->msg_type); | 
|  | return rc; | 
|  |  | 
|  | } | 
|  | memset(&got_msg, 0, sizeof(dbd_usage_msg_t)); | 
|  | got_msg.rec = get_msg->rec; | 
|  | get_msg->rec = NULL; | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) ret_type, *out_buffer); | 
|  | slurmdbd_pack_usage_msg(&got_msg, slurmdbd_conn->conn->version, | 
|  | ret_type, *out_buffer); | 
|  |  | 
|  | return SLURM_SUCCESS; | 
|  | } | 
|  |  | 
|  | static int _get_users(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  | slurmdb_user_cond_t * user_cond = NULL; | 
|  |  | 
|  | user_cond = get_msg->cond; | 
|  | if ((!user_cond->with_assocs && !user_cond->with_wckeys) | 
|  | && ((slurmdbd_conn->conn->version < 8) || | 
|  | (user_cond->assoc_cond->flags & | 
|  | ASSOC_COND_FLAG_ONLY_DEFS))) { | 
|  | list_t *cluster_list = user_cond->assoc_cond->cluster_list; | 
|  | /* load up with just this cluster to query against | 
|  | * since before 2.2 we had only 1 default account so | 
|  | * send the default for this cluster. */ | 
|  | if (!cluster_list) { | 
|  | cluster_list = list_create(NULL); | 
|  | list_append(cluster_list, | 
|  | slurmdbd_conn->conn->cluster_name); | 
|  | user_cond->assoc_cond->cluster_list = cluster_list; | 
|  | } | 
|  | } | 
|  |  | 
|  | list_msg.my_list = acct_storage_g_get_users( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | user_cond); | 
|  |  | 
|  | if (!errno) { | 
|  | if (!list_msg.my_list) | 
|  | list_msg.my_list = list_create(NULL); | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_USERS, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_USERS, *out_buffer); | 
|  | } else { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | errno, | 
|  | slurm_strerror(errno), | 
|  | DBD_GET_USERS); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _get_wckeys(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | char *comment = NULL; | 
|  | int rc = SLURM_SUCCESS; | 
|  |  | 
|  | /* We have to check this here, and not in the plugin.  There | 
|  | * are places in the plugin that a non-admin can call this and | 
|  | * it be ok. */ | 
|  | if (!_validate_operator(slurmdbd_conn)) { | 
|  | int rc = ESLURM_ACCESS_DENIED; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, rc, | 
|  | comment, | 
|  | DBD_GET_WCKEYS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | list_msg.my_list = acct_storage_g_get_wckeys( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond); | 
|  |  | 
|  | if (!errno) { | 
|  | if (!list_msg.my_list) | 
|  | list_msg.my_list = list_create(NULL); | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_WCKEYS, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_WCKEYS, *out_buffer); | 
|  | } else { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | errno, | 
|  | slurm_strerror(errno), | 
|  | DBD_GET_WCKEYS); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _get_reservations(slurmdbd_conn_t *slurmdbd_conn, | 
|  | persist_msg_t *msg, buf_t **out_buffer) | 
|  | { | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  |  | 
|  | list_msg.my_list = acct_storage_g_get_reservations( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond); | 
|  |  | 
|  | if (!errno) { | 
|  | if (!list_msg.my_list) | 
|  | list_msg.my_list = list_create(NULL); | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_RESVS, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_RESVS, *out_buffer); | 
|  | } else { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | errno, | 
|  | slurm_strerror(errno), | 
|  | DBD_GET_RESVS); | 
|  | rc = SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _find_rpc_obj_in_list(void *x, void *key) | 
|  | { | 
|  | slurmdb_rpc_obj_t *obj = (slurmdb_rpc_obj_t *)x; | 
|  |  | 
|  | if (obj->id == *(int *)key) | 
|  | return 1; | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int _flush_jobs(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_cluster_tres_msg_t *cluster_tres_msg = msg->data; | 
|  | int rc = SLURM_SUCCESS; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!_validate_slurm_user(slurmdbd_conn)) { | 
|  | comment = "DBD_FLUSH_JOBS message from invalid uid"; | 
|  | error("DBD_FLUSH_JOBS message from invalid uid %u", | 
|  | slurmdbd_conn->conn->auth_uid); | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | debug2("DBD_FLUSH_JOBS: called in CONN %d for %s", | 
|  | conn_g_get_fd(slurmdbd_conn->conn->tls_conn), | 
|  | slurmdbd_conn->conn->cluster_name); | 
|  |  | 
|  | rc = acct_storage_g_flush_jobs_on_cluster( | 
|  | slurmdbd_conn->db_conn, | 
|  | cluster_tres_msg->event_time); | 
|  | end_it: | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_FLUSH_JOBS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _fini_conn(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_fini_msg_t *fini_msg = msg->data; | 
|  | char *comment = NULL; | 
|  | int rc = SLURM_SUCCESS; | 
|  | bool locked = false; | 
|  |  | 
|  |  | 
|  | debug2("DBD_FINI: CLOSE:%u COMMIT:%u", | 
|  | fini_msg->close_conn, fini_msg->commit); | 
|  |  | 
|  | if (slurmdbd_conn->conn->rem_port && slurmdbd_conf->commit_delay) { | 
|  | slurm_mutex_lock(®istered_lock); | 
|  | locked = true; | 
|  | } | 
|  |  | 
|  | if (fini_msg->close_conn == 1) | 
|  | rc = acct_storage_g_close_connection(&slurmdbd_conn->db_conn); | 
|  | else | 
|  | rc = acct_storage_g_commit(slurmdbd_conn->db_conn, | 
|  | fini_msg->commit); | 
|  | if (locked) | 
|  | slurm_mutex_unlock(®istered_lock); | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_FINI); | 
|  | return rc; | 
|  |  | 
|  | } | 
|  |  | 
|  | static int _job_complete(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_job_comp_msg_t *job_comp_msg = msg->data; | 
|  | job_record_t job; | 
|  | job_details_t details; | 
|  | int rc = SLURM_SUCCESS; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!_validate_slurm_user(slurmdbd_conn)) { | 
|  | comment = "DBD_JOB_COMPLETE message from invalid uid"; | 
|  | error("CONN:%d %s %u", | 
|  | conn_g_get_fd(slurmdbd_conn->conn->tls_conn), comment, | 
|  | slurmdbd_conn->conn->auth_uid); | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | memset(&job, 0, sizeof(job_record_t)); | 
|  | memset(&details, 0, sizeof(job_details_t)); | 
|  |  | 
|  | job.admin_comment = job_comp_msg->admin_comment; | 
|  | job.assoc_id = job_comp_msg->assoc_id; | 
|  | job.comment = job_comp_msg->comment; | 
|  | if (job_comp_msg->db_index != NO_VAL64) | 
|  | job.db_index = job_comp_msg->db_index; | 
|  | job.derived_ec = job_comp_msg->derived_ec; | 
|  | job.end_time = job_comp_msg->end_time; | 
|  | job.exit_code = job_comp_msg->exit_code; | 
|  | job.extra = job_comp_msg->extra; | 
|  | job.failed_node = job_comp_msg->failed_node; | 
|  | job.job_id = job_comp_msg->job_id; | 
|  | job.job_state = job_comp_msg->job_state; | 
|  | job.requid = job_comp_msg->req_uid; | 
|  | job.nodes = job_comp_msg->nodes; | 
|  | job.start_time = job_comp_msg->start_time; | 
|  | details.submit_time = job_comp_msg->submit_time; | 
|  | job.start_protocol_ver = slurmdbd_conn->conn->version; | 
|  | job.system_comment = job_comp_msg->system_comment; | 
|  | job.tres_alloc_str = job_comp_msg->tres_alloc_str; | 
|  |  | 
|  | job.details = &details; | 
|  |  | 
|  | if (job.job_state & JOB_RESIZING) { | 
|  | job.resize_time = job_comp_msg->end_time; | 
|  | debug2("DBD_JOB_COMPLETE: RESIZE ID:%u", job_comp_msg->job_id); | 
|  | } else | 
|  | debug2("DBD_JOB_COMPLETE: ID:%u", job_comp_msg->job_id); | 
|  |  | 
|  | rc = jobacct_storage_g_job_complete(slurmdbd_conn->db_conn, &job); | 
|  |  | 
|  | if (rc && errno == 740) /* meaning data is already there */ | 
|  | rc = SLURM_SUCCESS; | 
|  |  | 
|  | /* just in case this gets set we need to clear it */ | 
|  | xfree(job.wckey); | 
|  |  | 
|  | if (!slurmdbd_conn->conn->rem_port) { | 
|  | debug3("DBD_JOB_COMPLETE: cluster not registered"); | 
|  | slurmdbd_conn->conn->rem_port = | 
|  | clusteracct_storage_g_register_disconn_ctld( | 
|  | slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->rem_host); | 
|  |  | 
|  | _add_registered_cluster(slurmdbd_conn); | 
|  | } | 
|  |  | 
|  | end_it: | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_JOB_COMPLETE); | 
|  | return SLURM_SUCCESS; | 
|  | } | 
|  |  | 
|  | static int _job_start(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_job_start_msg_t *job_start_msg = msg->data; | 
|  | dbd_id_rc_msg_t id_rc_msg; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!_validate_slurm_user(slurmdbd_conn)) { | 
|  | comment = "DBD_JOB_START message from invalid uid"; | 
|  | error("CONN:%d %s %u", | 
|  | conn_g_get_fd(slurmdbd_conn->conn->tls_conn), comment, | 
|  | slurmdbd_conn->conn->auth_uid); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | ESLURM_ACCESS_DENIED, | 
|  | comment, | 
|  | DBD_JOB_START); | 
|  | return SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | _process_job_start(slurmdbd_conn, job_start_msg, &id_rc_msg); | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_ID_RC, *out_buffer); | 
|  | slurmdbd_pack_id_rc_msg(&id_rc_msg, | 
|  | slurmdbd_conn->conn->version, *out_buffer); | 
|  | return SLURM_SUCCESS; | 
|  | } | 
|  |  | 
|  | static int _job_heavy(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_job_heavy_msg_t *job_heavy_msg = msg->data; | 
|  | job_record_t job; | 
|  | job_details_t details; | 
|  | char *comment = NULL; | 
|  | int rc; | 
|  |  | 
|  | if (!_validate_slurm_user(slurmdbd_conn)) { | 
|  | comment = "DBD_JOB_HEAVY message from invalid uid"; | 
|  | error("CONN:%d %s %u", | 
|  | conn_g_get_fd(slurmdbd_conn->conn->tls_conn), comment, | 
|  | slurmdbd_conn->conn->auth_uid); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | ESLURM_ACCESS_DENIED, | 
|  | comment, | 
|  | DBD_JOB_HEAVY); | 
|  | return SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | debug2("DBD_JOB_HEAVY: SCRIPT:%s ENV:%s", | 
|  | job_heavy_msg->script ? "yes" : "no", | 
|  | job_heavy_msg->env ? "yes" : "no"); | 
|  |  | 
|  | memset(&job, 0, sizeof(job_record_t)); | 
|  | memset(&details, 0, sizeof(job_details_t)); | 
|  |  | 
|  | if (job_heavy_msg->env) { | 
|  | details.env_sup = xmalloc(sizeof(*details.env_sup)); | 
|  | details.env_sup[0] = job_heavy_msg->env; | 
|  | } | 
|  | details.env_hash = job_heavy_msg->env_hash; | 
|  | details.script = job_heavy_msg->script; | 
|  | details.script_hash = job_heavy_msg->script_hash; | 
|  |  | 
|  | job.details = &details; | 
|  |  | 
|  | rc = jobacct_storage_g_job_heavy(slurmdbd_conn->db_conn, &job); | 
|  |  | 
|  | xfree(details.env_sup); | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | DBD_JOB_HEAVY); | 
|  | return SLURM_SUCCESS; | 
|  | } | 
|  |  | 
|  | static int _job_suspend(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_job_suspend_msg_t *job_suspend_msg = msg->data; | 
|  | job_record_t job; | 
|  | job_details_t details; | 
|  | int rc = SLURM_SUCCESS; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!_validate_slurm_user(slurmdbd_conn)) { | 
|  | comment = "DBD_JOB_SUSPEND message from invalid uid"; | 
|  | error("CONN:%d %s %u", | 
|  | conn_g_get_fd(slurmdbd_conn->conn->tls_conn), comment, | 
|  | slurmdbd_conn->conn->auth_uid); | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | debug2("DBD_JOB_SUSPEND: ID:%u STATE:%s", | 
|  | job_suspend_msg->job_id, | 
|  | job_state_string(job_suspend_msg->job_state)); | 
|  |  | 
|  | memset(&job, 0, sizeof(job_record_t)); | 
|  | memset(&details, 0, sizeof(job_details_t)); | 
|  |  | 
|  | job.assoc_id = job_suspend_msg->assoc_id; | 
|  | if (job_suspend_msg->db_index != NO_VAL64) | 
|  | job.db_index = job_suspend_msg->db_index; | 
|  | job.job_id = job_suspend_msg->job_id; | 
|  | job.job_state = job_suspend_msg->job_state; | 
|  | details.submit_time = job_suspend_msg->submit_time; | 
|  | job.start_protocol_ver = slurmdbd_conn->conn->version; | 
|  | job.suspend_time = job_suspend_msg->suspend_time; | 
|  |  | 
|  | job.details = &details; | 
|  | rc = jobacct_storage_g_job_suspend(slurmdbd_conn->db_conn, &job); | 
|  |  | 
|  | if (rc && errno == 740) /* meaning data is already there */ | 
|  | rc = SLURM_SUCCESS; | 
|  |  | 
|  | /* just in case this gets set we need to clear it */ | 
|  | xfree(job.wckey); | 
|  | end_it: | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | DBD_JOB_SUSPEND); | 
|  | return SLURM_SUCCESS; | 
|  | } | 
|  |  | 
|  | static int _modify_accounts(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_modify_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_modify_accounts( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond, get_msg->rec))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | DBD_MODIFY_ACCOUNTS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _modify_assocs(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_modify_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | /* All authentication needs to be done inside the plugin since we are | 
|  | * unable to know what accounts this request is talking about | 
|  | * until we process it through the database. | 
|  | */ | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_modify_assocs( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond, get_msg->rec)) || | 
|  | (errno != SLURM_SUCCESS)) { | 
|  | rc = errno; | 
|  | if (list_msg.my_list && list_count(list_msg.my_list) && | 
|  | (errno == ESLURM_NO_REMOVE_DEFAULT_QOS)) { | 
|  | comment = list_peek(list_msg.my_list); | 
|  | } else { | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | } | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | DBD_MODIFY_ASSOCS); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _modify_clusters(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_modify_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_modify_clusters( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond, get_msg->rec))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | DBD_MODIFY_CLUSTERS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _modify_federations(slurmdbd_conn_t *slurmdbd_conn, | 
|  | persist_msg_t *msg, buf_t **out_buffer) | 
|  | { | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_modify_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_modify_federations( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond, get_msg->rec))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | DBD_MODIFY_FEDERATIONS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _modify_job(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_modify_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_modify_job( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond, get_msg->rec))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | DBD_MODIFY_JOB); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | if (get_msg->cond && | 
|  | (((slurmdb_job_cond_t *)get_msg->cond)->flags & | 
|  | JOBCOND_FLAG_NO_WAIT)) { | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | DBD_MODIFY_JOB); | 
|  | } else { | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _modify_qos(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_modify_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_modify_qos( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond, get_msg->rec))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | DBD_MODIFY_QOS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _modify_res(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_modify_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_modify_res( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond, get_msg->rec))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | DBD_MODIFY_RES); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _modify_users(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_modify_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  | int same_user = 0; | 
|  | slurmdb_user_cond_t *user_cond = NULL; | 
|  | slurmdb_user_rec_t *user_rec = NULL; | 
|  | int fd = conn_g_get_fd(slurmdbd_conn->conn->tls_conn); | 
|  |  | 
|  | user_cond = (slurmdb_user_cond_t *)get_msg->cond; | 
|  | user_rec = (slurmdb_user_rec_t *)get_msg->rec; | 
|  |  | 
|  | if (!_validate_operator(slurmdbd_conn)) { | 
|  | int rc = ESLURM_ACCESS_DENIED; | 
|  | if (user_cond && user_cond->assoc_cond | 
|  | && user_cond->assoc_cond->user_list | 
|  | && (list_count(user_cond->assoc_cond->user_list) == 1)) { | 
|  | uid_t pw_uid; | 
|  | char *name; | 
|  | name = list_peek (user_cond->assoc_cond->user_list); | 
|  | if ((uid_from_string(name, &pw_uid) == SLURM_SUCCESS) && | 
|  | (pw_uid == slurmdbd_conn->conn->auth_uid)) { | 
|  | same_user = 1; | 
|  | goto is_same_user; | 
|  | } | 
|  | } | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, rc, | 
|  | comment, | 
|  | DBD_MODIFY_USERS); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | is_same_user: | 
|  |  | 
|  | /* same_user can only alter the default account, default wckey | 
|  | * nothing else */ | 
|  | if (same_user) { | 
|  | /* If we add anything else here for the user we will | 
|  | * need to document it | 
|  | */ | 
|  | if ((user_rec->admin_level != SLURMDB_ADMIN_NOTSET)) { | 
|  | comment = "You can only change your own default account, default wckey nothing else"; | 
|  | error("CONN:%d %s", fd, comment); | 
|  | *out_buffer = slurm_persist_make_rc_msg( | 
|  | slurmdbd_conn->conn, | 
|  | ESLURM_ACCESS_DENIED, | 
|  | comment, | 
|  | DBD_MODIFY_USERS); | 
|  |  | 
|  | return ESLURM_ACCESS_DENIED; | 
|  | } | 
|  | } | 
|  |  | 
|  | if ((user_rec->admin_level != SLURMDB_ADMIN_NOTSET) && | 
|  | !_validate_super_user(slurmdbd_conn)) { | 
|  | comment = "You must be a super user to modify a users admin level"; | 
|  | error("CONN:%d %s", fd, comment); | 
|  | *out_buffer = slurm_persist_make_rc_msg( | 
|  | slurmdbd_conn->conn, | 
|  | ESLURM_ACCESS_DENIED, | 
|  | comment, | 
|  | DBD_MODIFY_USERS); | 
|  | return ESLURM_ACCESS_DENIED; | 
|  | } | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_modify_users( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | user_cond, user_rec))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg( | 
|  | slurmdbd_conn->conn, rc, comment, DBD_MODIFY_USERS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _modify_wckeys(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_modify_msg_t *get_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_modify_wckeys( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond, get_msg->rec))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg( | 
|  | slurmdbd_conn->conn, rc, comment, DBD_MODIFY_WCKEYS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _modify_reservation(slurmdbd_conn_t *slurmdbd_conn, | 
|  | persist_msg_t *msg, buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_rec_msg_t *rec_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!_validate_slurm_user(slurmdbd_conn)) { | 
|  | comment = "DBD_MODIFY_RESV message from invalid uid"; | 
|  | error("CONN:%d %s %u", | 
|  | conn_g_get_fd(slurmdbd_conn->conn->tls_conn), comment, | 
|  | slurmdbd_conn->conn->auth_uid); | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | rc = acct_storage_g_modify_reservation(slurmdbd_conn->db_conn, | 
|  | rec_msg->rec); | 
|  |  | 
|  | end_it: | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_MODIFY_RESV); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _node_state(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_node_state_msg_t *node_state_msg = msg->data; | 
|  | node_record_t node_ptr; | 
|  | int rc = SLURM_SUCCESS; | 
|  | char *comment = NULL; | 
|  | int fd = conn_g_get_fd(slurmdbd_conn->conn->tls_conn); | 
|  |  | 
|  | if (!_validate_slurm_user(slurmdbd_conn)) { | 
|  | comment = "DBD_NODE_STATE message from invalid uid"; | 
|  | error("CONN:%d %s %u", | 
|  | fd, comment, slurmdbd_conn->conn->auth_uid); | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | memset(&node_ptr, 0, sizeof(node_record_t)); | 
|  | node_ptr.extra = node_state_msg->extra; | 
|  | node_ptr.instance_id = node_state_msg->instance_id; | 
|  | node_ptr.instance_type = node_state_msg->instance_type; | 
|  | node_ptr.name = node_state_msg->hostlist; | 
|  | node_ptr.tres_str = node_state_msg->tres_str; | 
|  | node_ptr.node_state = node_state_msg->state; | 
|  | node_ptr.reason = node_state_msg->reason; | 
|  | node_ptr.reason_time = node_state_msg->event_time; | 
|  | node_ptr.reason_uid = node_state_msg->reason_uid; | 
|  |  | 
|  | if (!node_ptr.tres_str && | 
|  | (node_state_msg->new_state != DBD_NODE_STATE_UPDATE)) | 
|  | node_state_msg->new_state = DBD_NODE_STATE_UP; | 
|  |  | 
|  | switch (node_state_msg->new_state) { | 
|  | case DBD_NODE_STATE_UP: | 
|  | debug2("DBD_NODE_STATE_UP: NODE:%s REASON:%s TIME:%ld", | 
|  | node_state_msg->hostlist, | 
|  | node_state_msg->reason, | 
|  | (long)node_state_msg->event_time); | 
|  |  | 
|  | /* clusteracct_storage_g_node_up can change the reason | 
|  | * field so copy it to avoid memory issues. | 
|  | */ | 
|  | node_ptr.reason = xstrdup(node_state_msg->reason); | 
|  | rc = clusteracct_storage_g_node_up( | 
|  | slurmdbd_conn->db_conn, | 
|  | &node_ptr, | 
|  | node_state_msg->event_time); | 
|  | xfree(node_ptr.reason); | 
|  | break; | 
|  | case DBD_NODE_STATE_DOWN: | 
|  | debug2("DBD_NODE_STATE_DOWN: NODE:%s STATE:%s REASON:%s UID:%u TIME:%ld", | 
|  | node_state_msg->hostlist, | 
|  | node_state_string(node_state_msg->state), | 
|  | node_state_msg->reason, | 
|  | node_ptr.reason_uid, | 
|  | (long)node_state_msg->event_time); | 
|  | rc = clusteracct_storage_g_node_down( | 
|  | slurmdbd_conn->db_conn, | 
|  | &node_ptr, | 
|  | node_state_msg->event_time, | 
|  | node_state_msg->reason, node_ptr.reason_uid); | 
|  | break; | 
|  | case DBD_NODE_STATE_UPDATE: | 
|  | debug2("DBD_NODE_STATE_UPDATE: NODE:%s", | 
|  | node_state_msg->hostlist); | 
|  | rc = clusteracct_storage_g_node_update( | 
|  | slurmdbd_conn->db_conn, | 
|  | &node_ptr); | 
|  | break; | 
|  | default: | 
|  | comment = "DBD_NODE_STATE message has invalid new_state"; | 
|  | error("CONN:%d %s %u", | 
|  | fd, comment, slurmdbd_conn->conn->auth_uid); | 
|  | rc = SLURM_ERROR; | 
|  | break; | 
|  | } | 
|  |  | 
|  | end_it: | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_NODE_STATE); | 
|  | return SLURM_SUCCESS; | 
|  | } | 
|  |  | 
|  | static void _process_job_start(slurmdbd_conn_t *slurmdbd_conn, | 
|  | dbd_job_start_msg_t *job_start_msg, | 
|  | dbd_id_rc_msg_t *id_rc_msg) | 
|  | { | 
|  | job_record_t job, *job_ptr; | 
|  | job_details_t details; | 
|  | job_array_struct_t array_recs; | 
|  |  | 
|  | memset(&job, 0, sizeof(job_record_t)); | 
|  | memset(&details, 0, sizeof(job_details_t)); | 
|  | memset(&array_recs, 0, sizeof(job_array_struct_t)); | 
|  | memset(id_rc_msg, 0, sizeof(dbd_id_rc_msg_t)); | 
|  |  | 
|  | job.total_nodes = job_start_msg->alloc_nodes; | 
|  | job.account = _replace_double_quotes(job_start_msg->account); | 
|  | job.array_job_id = job_start_msg->array_job_id; | 
|  | job.array_task_id = job_start_msg->array_task_id; | 
|  | array_recs.task_id_str = job_start_msg->array_task_str; | 
|  | array_recs.max_run_tasks = job_start_msg->array_max_tasks; | 
|  | array_recs.task_cnt = job_start_msg->array_task_pending; | 
|  | job.assoc_id = job_start_msg->assoc_id; | 
|  | /* | 
|  | * When 24.11 is no longer supported this check will go away, the | 
|  | * db_index will not be NO_VAL64 then. | 
|  | */ | 
|  | if (job_start_msg->db_index != NO_VAL64) | 
|  | job.db_index = job_start_msg->db_index; | 
|  | details.begin_time = job_start_msg->eligible_time; | 
|  | details.env_hash = job_start_msg->env_hash; | 
|  | job.user_id = job_start_msg->uid; | 
|  | job.group_id = job_start_msg->gid; | 
|  | job.container = _replace_double_quotes(job_start_msg->container); | 
|  | job.het_job_id = job_start_msg->het_job_id; | 
|  | job.het_job_offset = job_start_msg->het_job_offset; | 
|  | job.job_id = job_start_msg->job_id; | 
|  | job.job_state = job_start_msg->job_state; | 
|  | job.licenses = _replace_double_quotes(job_start_msg->licenses); | 
|  | job.mcs_label = _replace_double_quotes(job_start_msg->mcs_label); | 
|  | job.name = _replace_double_quotes(job_start_msg->name); | 
|  | job.nodes = job_start_msg->nodes; | 
|  | job.network = job_start_msg->node_inx; | 
|  | job.partition = job_start_msg->partition; | 
|  | details.min_cpus = job_start_msg->req_cpus; | 
|  | details.pn_min_memory = job_start_msg->req_mem; | 
|  | job.qos_id = job_start_msg->qos_id; | 
|  | details.qos_req = job_start_msg->qos_req; | 
|  | details.resv_req = job_start_msg->resv_req; | 
|  | job.restart_cnt = job_start_msg->restart_cnt; | 
|  | job.resv_id = job_start_msg->resv_id; | 
|  | job.priority = job_start_msg->priority; | 
|  | details.script_hash = job_start_msg->script_hash; | 
|  | job.start_protocol_ver = slurmdbd_conn->conn->version; | 
|  | job.start_time = job_start_msg->start_time; | 
|  | details.segment_size = job_start_msg->segment_size; | 
|  | details.std_err = job_start_msg->std_err; | 
|  | details.std_in = job_start_msg->std_in; | 
|  | details.std_out = job_start_msg->std_out; | 
|  | details.submit_line = job_start_msg->submit_line; | 
|  | job.time_limit = job_start_msg->timelimit; | 
|  | job.tres_alloc_str = job_start_msg->tres_alloc_str; | 
|  | job.tres_req_str = job_start_msg->tres_req_str; | 
|  | job.gres_used = job_start_msg->gres_used; | 
|  | job.wckey = _replace_double_quotes(job_start_msg->wckey); | 
|  | details.work_dir = _replace_double_quotes(job_start_msg->work_dir); | 
|  | details.submit_time = job_start_msg->submit_time; | 
|  | job.db_flags = job_start_msg->db_flags; | 
|  | details.features = _replace_double_quotes(job_start_msg->constraints); | 
|  | job.state_reason_prev_db = job_start_msg->state_reason_prev; | 
|  |  | 
|  | job.array_recs = &array_recs; | 
|  | job.details = &details; | 
|  | job_ptr = &job; | 
|  |  | 
|  | if (job.job_state & JOB_RESIZING) { | 
|  | job.resize_time = job_start_msg->eligible_time; | 
|  | debug2("DBD_JOB_START: RESIZE CALL ID:%u NAME:%s INX:%"PRIu64, | 
|  | job_start_msg->job_id, job_start_msg->name, | 
|  | job.db_index); | 
|  | } else if (job.start_time && !IS_JOB_PENDING(job_ptr)) { | 
|  | debug2("DBD_JOB_START: START CALL ID:%u NAME:%s INX:%"PRIu64, | 
|  | job_start_msg->job_id, job_start_msg->name, | 
|  | job.db_index); | 
|  | } else { | 
|  | debug2("DBD_JOB_START: ELIGIBLE CALL ID:%u NAME:%s INX:%"PRIu64, | 
|  | job_start_msg->job_id, job_start_msg->name, | 
|  | job.db_index); | 
|  | } | 
|  | id_rc_msg->return_code = jobacct_storage_g_job_start( | 
|  | slurmdbd_conn->db_conn, &job); | 
|  | id_rc_msg->job_id = job.job_id; | 
|  | id_rc_msg->flags = job.bit_flags; | 
|  | id_rc_msg->db_index = job.db_index; | 
|  |  | 
|  | /* just in case job.wckey was set because we didn't send one */ | 
|  | if (!job_start_msg->wckey) | 
|  | xfree(job.wckey); | 
|  |  | 
|  | xfree(details.env_sup); | 
|  |  | 
|  | if (!slurmdbd_conn->conn->rem_port) { | 
|  | debug3("DBD_JOB_START: cluster not registered"); | 
|  | slurmdbd_conn->conn->rem_port = | 
|  | clusteracct_storage_g_register_disconn_ctld( | 
|  | slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->rem_host); | 
|  |  | 
|  | _add_registered_cluster(slurmdbd_conn); | 
|  | } | 
|  | } | 
|  |  | 
|  | static int _reconfig(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!_validate_super_user(slurmdbd_conn)) { | 
|  | int rc = ESLURM_ACCESS_DENIED; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, rc, | 
|  | comment, | 
|  | DBD_MODIFY_WCKEYS); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | info("Reconfigure request received"); | 
|  | reconfig(NULL); | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_RECONFIG); | 
|  | return rc; | 
|  |  | 
|  | } | 
|  |  | 
|  | static int _register_ctld(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_register_ctld_msg_t *register_ctld_msg = msg->data; | 
|  | int rc = SLURM_SUCCESS; | 
|  | uint32_t id_rc = 0; | 
|  | char *comment = NULL; | 
|  | slurmdb_cluster_cond_t cluster_q; | 
|  | slurmdb_cluster_rec_t cluster; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | list_t *cluster_list; | 
|  | int fd = conn_g_get_fd(slurmdbd_conn->conn->tls_conn); | 
|  |  | 
|  | if (!_validate_slurm_user(slurmdbd_conn)) { | 
|  | comment = "DBD_REGISTER_CTLD message from invalid uid"; | 
|  | error("CONN:%d %s %u", | 
|  | fd, comment, slurmdbd_conn->conn->auth_uid); | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | debug2("DBD_REGISTER_CTLD: called in CONN %d for %s(%u), cluster_id=%u", | 
|  | fd, slurmdbd_conn->conn->cluster_name, register_ctld_msg->port, register_ctld_msg->cluster_id); | 
|  |  | 
|  | /* Just to make sure we don't allow a NULL cluster name to attempt | 
|  | to connect.  This should never happen, but here just for | 
|  | sanity check. | 
|  | */ | 
|  | if (!slurmdbd_conn->conn->cluster_name) { | 
|  | comment = "Must have a cluster name to register it"; | 
|  | error("CONN:%d %s", fd, comment); | 
|  | rc = ESLURM_BAD_NAME; | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | debug2("slurmctld at ip:%s, port:%d", | 
|  | slurmdbd_conn->conn->rem_host, register_ctld_msg->port); | 
|  |  | 
|  | slurmdb_init_cluster_cond(&cluster_q, 0); | 
|  | slurmdb_init_cluster_rec(&cluster, 0); | 
|  |  | 
|  | cluster_q.cluster_list = list_create(NULL); | 
|  | list_append(cluster_q.cluster_list, slurmdbd_conn->conn->cluster_name); | 
|  | cluster.control_host = slurmdbd_conn->conn->rem_host; | 
|  | cluster.control_port = register_ctld_msg->port; | 
|  | cluster.dimensions = register_ctld_msg->dimensions; | 
|  | cluster.flags = register_ctld_msg->flags; | 
|  | cluster.rpc_version = slurmdbd_conn->conn->version; | 
|  |  | 
|  | if ((cluster.flags != NO_VAL) && | 
|  | (cluster.flags & CLUSTER_FLAG_EXT)) | 
|  | slurmdbd_conn->conn->flags |= PERSIST_FLAG_EXT_DBD; | 
|  |  | 
|  | cluster_list = acct_storage_g_get_clusters( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | &cluster_q); | 
|  | if (!cluster_list || errno) { | 
|  | comment = slurm_strerror(errno); | 
|  | rc = errno; | 
|  | } else if (!list_count(cluster_list)) { | 
|  | list_t *add_list = list_create(NULL); | 
|  | list_append(add_list, &cluster); | 
|  |  | 
|  | cluster.name = slurmdbd_conn->conn->cluster_name; | 
|  | cluster.flags |= CLUSTER_FLAG_REGISTER; | 
|  | cluster.id = register_ctld_msg->cluster_id; | 
|  |  | 
|  | rc = acct_storage_g_add_clusters(slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | add_list); | 
|  | if (rc == ESLURM_ACCESS_DENIED) | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  |  | 
|  | else if (rc != SLURM_SUCCESS) | 
|  | comment = "Failed to add/register cluster."; | 
|  | slurmdb_destroy_assoc_rec(cluster.root_assoc); | 
|  | FREE_NULL_LIST(add_list); | 
|  | } else if ((slurmdbd_conn->conn->flags & PERSIST_FLAG_EXT_DBD) && | 
|  | !(((slurmdb_cluster_rec_t *)list_peek(cluster_list))->flags & | 
|  | CLUSTER_FLAG_EXT)) { | 
|  | comment = "Can't register to non-external cluster"; | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | } | 
|  | FREE_NULL_LIST(cluster_list); | 
|  | if (rc) | 
|  | goto end_it; | 
|  |  | 
|  | list_msg.my_list = acct_storage_g_modify_clusters( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | &cluster_q, &cluster); | 
|  | if (errno == EFAULT) { | 
|  | comment = "Request to register was incomplete"; | 
|  | rc = SLURM_ERROR; | 
|  | } else if (errno == ESLURM_ACCESS_DENIED) { | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | } else if (errno == ESLURM_DB_CONNECTION) { | 
|  | comment = slurm_strerror(errno); | 
|  | rc = errno; | 
|  | } else if (!list_msg.my_list || !list_count(list_msg.my_list)) { | 
|  | comment = "This cluster hasn't been added to accounting yet"; | 
|  | rc = SLURM_ERROR; | 
|  | } else if (cluster.id) { | 
|  | id_rc = cluster.id; | 
|  | id_rc |= RC_AS_CLUSTER_ID; | 
|  | } | 
|  |  | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  | FREE_NULL_LIST(cluster_q.cluster_list); | 
|  |  | 
|  | end_it: | 
|  |  | 
|  | if (rc == SLURM_SUCCESS) { | 
|  | slurmdbd_conn->conn->rem_port = register_ctld_msg->port; | 
|  |  | 
|  | _add_registered_cluster(slurmdbd_conn); | 
|  | } | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, id_rc, | 
|  | comment, DBD_REGISTER_CTLD); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _remove_accounts(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_remove_accounts( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg( | 
|  | slurmdbd_conn->conn, rc, comment, DBD_REMOVE_ACCOUNTS); | 
|  | return rc; | 
|  | } | 
|  | list_msg.return_code = errno; | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _remove_account_coords(slurmdbd_conn_t *slurmdbd_conn, | 
|  | persist_msg_t *msg, buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_acct_coord_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | char *comment = NULL; | 
|  |  | 
|  | /* All authentication needs to be done inside the plugin since we are | 
|  | * unable to know what accounts this request is talking about | 
|  | * until we process it through the database. | 
|  | */ | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_remove_coord( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->acct_list, get_msg->cond))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg( | 
|  | slurmdbd_conn->conn, rc, comment, | 
|  | DBD_REMOVE_ACCOUNT_COORDS); | 
|  | return rc; | 
|  | } | 
|  | list_msg.return_code = SLURM_SUCCESS; | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _remove_assocs(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | char *comment = NULL; | 
|  |  | 
|  | /* All authentication needs to be done inside the plugin since we are | 
|  | * unable to know what accounts this request is talking about | 
|  | * until we process it through the database. | 
|  | */ | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_remove_assocs( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg( | 
|  | slurmdbd_conn->conn, rc, comment, DBD_REMOVE_ASSOCS); | 
|  | return rc; | 
|  | } | 
|  | list_msg.return_code = errno; | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  |  | 
|  | } | 
|  |  | 
|  | static int _remove_clusters(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_remove_clusters( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg( | 
|  | slurmdbd_conn->conn, rc, comment, DBD_REMOVE_CLUSTERS); | 
|  | return rc; | 
|  | } | 
|  | list_msg.return_code = errno; | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _remove_federations(slurmdbd_conn_t *slurmdbd_conn, | 
|  | persist_msg_t *msg, buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_remove_federations( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, | 
|  | DBD_REMOVE_FEDERATIONS); | 
|  | return rc; | 
|  | } | 
|  | list_msg.return_code = errno; | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _remove_qos(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_remove_qos( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg( | 
|  | slurmdbd_conn->conn, rc, comment, DBD_REMOVE_QOS); | 
|  | return rc; | 
|  | } | 
|  | list_msg.return_code = errno; | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _remove_res(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_remove_res( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg( | 
|  | slurmdbd_conn->conn, rc, comment, DBD_REMOVE_RES); | 
|  | return rc; | 
|  | } | 
|  | list_msg.return_code = errno; | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _remove_users(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_remove_users( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg( | 
|  | slurmdbd_conn->conn, rc, comment, DBD_REMOVE_USERS); | 
|  | return rc; | 
|  | } | 
|  | list_msg.return_code = errno; | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _remove_wckeys(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_cond_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!(list_msg.my_list = acct_storage_g_remove_wckeys( | 
|  | slurmdbd_conn->db_conn, slurmdbd_conn->conn->auth_uid, | 
|  | get_msg->cond))) { | 
|  | rc = errno; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg( | 
|  | slurmdbd_conn->conn, rc, comment, DBD_REMOVE_WCKEYS); | 
|  | return rc; | 
|  | } | 
|  | list_msg.return_code = errno; | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_LIST, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_LIST, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _remove_reservation(slurmdbd_conn_t *slurmdbd_conn, | 
|  | persist_msg_t *msg, buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | dbd_rec_msg_t *rec_msg = msg->data; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!_validate_slurm_user(slurmdbd_conn)) { | 
|  | comment = "DBD_REMOVE_RESV message from invalid uid"; | 
|  | error("DBD_REMOVE_RESV message from invalid uid %u", | 
|  | slurmdbd_conn->conn->auth_uid); | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | rc = acct_storage_g_remove_reservation(slurmdbd_conn->db_conn, | 
|  | rec_msg->rec); | 
|  |  | 
|  | end_it: | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_REMOVE_RESV); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _roll_usage(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_roll_usage_msg_t *get_msg = msg->data; | 
|  | int rc = SLURM_SUCCESS; | 
|  | char *comment = NULL; | 
|  | list_t *rollup_stats_list = NULL; | 
|  | DEF_TIMERS; | 
|  |  | 
|  | info("DBD_ROLL_USAGE: called in CONN %d", | 
|  | conn_g_get_fd(slurmdbd_conn->conn->tls_conn)); | 
|  |  | 
|  | if (!_validate_operator(slurmdbd_conn)) { | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | START_TIMER; | 
|  | rc = acct_storage_g_roll_usage(slurmdbd_conn->db_conn, | 
|  | get_msg->start, get_msg->end, | 
|  | get_msg->archive_data, | 
|  | &rollup_stats_list); | 
|  | END_TIMER; | 
|  | handle_rollup_stats(rollup_stats_list, DELTA_TIMER, 1); | 
|  | FREE_NULL_LIST(rollup_stats_list); | 
|  |  | 
|  | end_it: | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_ROLL_USAGE); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _send_mult_job_start(slurmdbd_conn_t *slurmdbd_conn, | 
|  | persist_msg_t *msg, buf_t **out_buffer) | 
|  | { | 
|  | dbd_list_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | char *comment = NULL; | 
|  | list_itr_t *itr = NULL; | 
|  | dbd_job_start_msg_t *job_start_msg; | 
|  | dbd_id_rc_msg_t *id_rc_msg; | 
|  | /* DEF_TIMERS; */ | 
|  |  | 
|  | if (!_validate_slurm_user(slurmdbd_conn)) { | 
|  | comment = "DBD_SEND_MULT_JOB_START message from invalid uid"; | 
|  | error("%s %u", comment, slurmdbd_conn->conn->auth_uid); | 
|  | *out_buffer = slurm_persist_make_rc_msg( | 
|  | slurmdbd_conn->conn, | 
|  | ESLURM_ACCESS_DENIED, comment, | 
|  | DBD_SEND_MULT_JOB_START); | 
|  | return SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | list_msg.my_list = list_create(slurmdbd_free_id_rc_msg); | 
|  | /* START_TIMER; */ | 
|  | itr = list_iterator_create(get_msg->my_list); | 
|  | while ((job_start_msg = list_next(itr))) { | 
|  | id_rc_msg = xmalloc(sizeof(dbd_id_rc_msg_t)); | 
|  | list_append(list_msg.my_list, id_rc_msg); | 
|  |  | 
|  | _process_job_start(slurmdbd_conn, job_start_msg, id_rc_msg); | 
|  | } | 
|  | list_iterator_destroy(itr); | 
|  | /* END_TIMER; */ | 
|  | /* info("%d multi job took %s", */ | 
|  | /*      list_count(get_msg->my_list), TIME_STR); */ | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_MULT_JOB_START, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_MULT_JOB_START, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return SLURM_SUCCESS; | 
|  | } | 
|  |  | 
|  | static int _send_mult_msg(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_list_msg_t *get_msg = msg->data; | 
|  | dbd_list_msg_t list_msg = { NULL }; | 
|  | char *comment = NULL; | 
|  | list_itr_t *itr = NULL; | 
|  | buf_t *req_buf = NULL, *ret_buf = NULL; | 
|  | int rc = SLURM_SUCCESS; | 
|  | /* DEF_TIMERS; */ | 
|  |  | 
|  | if (!_validate_slurm_user(slurmdbd_conn)) { | 
|  | comment = "DBD_SEND_MULT_MSG message from invalid uid"; | 
|  | error("%s %u", comment, slurmdbd_conn->conn->auth_uid); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | ESLURM_ACCESS_DENIED, | 
|  | comment, | 
|  | DBD_SEND_MULT_MSG); | 
|  | return SLURM_ERROR; | 
|  | } | 
|  |  | 
|  | list_msg.my_list = list_create(slurmdbd_free_buffer); | 
|  | /* START_TIMER; */ | 
|  | itr = list_iterator_create(get_msg->my_list); | 
|  | while ((req_buf = list_next(itr))) { | 
|  | persist_msg_t sub_msg; | 
|  |  | 
|  | ret_buf = NULL; | 
|  |  | 
|  | rc = slurm_persist_conn_process_msg( | 
|  | slurmdbd_conn->conn, &sub_msg, | 
|  | get_buf_data(req_buf), | 
|  | size_buf(req_buf), &ret_buf, 0); | 
|  |  | 
|  | if (rc == SLURM_SUCCESS) { | 
|  | rc = proc_req(slurmdbd_conn, &sub_msg, &ret_buf); | 
|  | slurmdbd_free_msg(&sub_msg); | 
|  | } | 
|  |  | 
|  | if (ret_buf) | 
|  | list_append(list_msg.my_list, ret_buf); | 
|  | if ((rc != SLURM_SUCCESS) && | 
|  | (rc != SLURM_NO_CHANGE_IN_DATA)) | 
|  | break; | 
|  | } | 
|  | list_iterator_destroy(itr); | 
|  | /* END_TIMER; */ | 
|  | /* info("%d multi took %s", list_count(get_msg->my_list), TIME_STR); */ | 
|  |  | 
|  | *out_buffer = init_buf(1024); | 
|  | pack16((uint16_t) DBD_GOT_MULT_MSG, *out_buffer); | 
|  | slurmdbd_pack_list_msg(&list_msg, slurmdbd_conn->conn->version, | 
|  | DBD_GOT_MULT_MSG, *out_buffer); | 
|  | FREE_NULL_LIST(list_msg.my_list); | 
|  |  | 
|  | return SLURM_SUCCESS; | 
|  | } | 
|  |  | 
|  | static int _step_complete(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_step_comp_msg_t *step_comp_msg = msg->data; | 
|  | step_record_t step; | 
|  | job_record_t job; | 
|  | job_details_t details; | 
|  | int rc = SLURM_SUCCESS; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!_validate_slurm_user(slurmdbd_conn)) { | 
|  | comment = "DBD_STEP_COMPLETE message from invalid uid"; | 
|  | error("%s %u", comment, slurmdbd_conn->conn->auth_uid); | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | debug2("DBD_STEP_COMPLETE: %ps SUBMIT:%lu", | 
|  | &step_comp_msg->step_id, | 
|  | (unsigned long) step_comp_msg->job_submit_time); | 
|  |  | 
|  | memset(&step, 0, sizeof(step_record_t)); | 
|  | memset(&job, 0, sizeof(job_record_t)); | 
|  | memset(&details, 0, sizeof(job_details_t)); | 
|  |  | 
|  | job.assoc_id = step_comp_msg->assoc_id; | 
|  | if (step_comp_msg->db_index != NO_VAL64) | 
|  | job.db_index = step_comp_msg->db_index; | 
|  | job.end_time = step_comp_msg->end_time; | 
|  | step.exit_code = step_comp_msg->exit_code; | 
|  | step.jobacct = step_comp_msg->jobacct; | 
|  | job.job_id = step_comp_msg->step_id.job_id; | 
|  | step.requid = step_comp_msg->req_uid; | 
|  | job.start_protocol_ver = slurmdbd_conn->conn->version; | 
|  | job.start_time = step_comp_msg->start_time; | 
|  | job.tres_alloc_str = step_comp_msg->job_tres_alloc_str; | 
|  | step.state = step_comp_msg->state; | 
|  |  | 
|  | memcpy(&step.step_id, &step_comp_msg->step_id, sizeof(step.step_id)); | 
|  |  | 
|  | details.submit_time = step_comp_msg->job_submit_time; | 
|  | details.num_tasks = step_comp_msg->total_tasks; | 
|  |  | 
|  | job.details = &details; | 
|  | step.job_ptr = &job; | 
|  |  | 
|  | rc = jobacct_storage_g_step_complete(slurmdbd_conn->db_conn, &step); | 
|  |  | 
|  | if (rc && errno == 740) /* meaning data is already there */ | 
|  | rc = SLURM_SUCCESS; | 
|  | /* just in case this gets set we need to clear it */ | 
|  | xfree(job.wckey); | 
|  |  | 
|  | if (!slurmdbd_conn->conn->rem_port) { | 
|  | debug3("DBD_STEP_COMPLETE: cluster not registered"); | 
|  | slurmdbd_conn->conn->rem_port = | 
|  | clusteracct_storage_g_register_disconn_ctld( | 
|  | slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->rem_host); | 
|  |  | 
|  | _add_registered_cluster(slurmdbd_conn); | 
|  | } | 
|  |  | 
|  | end_it: | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_STEP_COMPLETE); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _step_start(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | dbd_step_start_msg_t *step_start_msg = msg->data; | 
|  | step_record_t step; | 
|  | job_record_t job; | 
|  | job_details_t details; | 
|  | slurm_step_layout_t layout; | 
|  | int rc = SLURM_SUCCESS; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!_validate_slurm_user(slurmdbd_conn)) { | 
|  | comment = "DBD_STEP_START message from invalid uid"; | 
|  | error("%s %u", comment, slurmdbd_conn->conn->auth_uid); | 
|  | rc = ESLURM_ACCESS_DENIED; | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | debug2("DBD_STEP_START: %ps NAME:%s SUBMIT:%lu", | 
|  | &step_start_msg->step_id, | 
|  | step_start_msg->name, | 
|  | (unsigned long) step_start_msg->job_submit_time); | 
|  |  | 
|  | memset(&step, 0, sizeof(step_record_t)); | 
|  | memset(&job, 0, sizeof(job_record_t)); | 
|  | memset(&details, 0, sizeof(job_details_t)); | 
|  | memset(&layout, 0, sizeof(slurm_step_layout_t)); | 
|  |  | 
|  | job.assoc_id = step_start_msg->assoc_id; | 
|  | if (step_start_msg->db_index != NO_VAL64) | 
|  | job.db_index = step_start_msg->db_index; | 
|  | step.container = _replace_double_quotes(step_start_msg->container); | 
|  | job.job_id = step_start_msg->step_id.job_id; | 
|  | step.name = step_start_msg->name; | 
|  | job.nodes = step_start_msg->nodes; | 
|  | step.network = step_start_msg->node_inx; | 
|  | job.start_protocol_ver = slurmdbd_conn->conn->version; | 
|  | /* | 
|  | * Set job.start_time to be the same as step.start_time. If the | 
|  | * job_db_inx hasn't be created yet we need the start time or we will | 
|  | * cause re-rolling to happen at details.submit_time. When dealing with | 
|  | * job arrays that could be a long time in the past. | 
|  | */ | 
|  | job.start_time = step.start_time = step_start_msg->start_time; | 
|  | details.submit_time = step_start_msg->job_submit_time; | 
|  | step.time_limit = step_start_msg->time_limit; | 
|  |  | 
|  | memcpy(&step.step_id, &step_start_msg->step_id, sizeof(step.step_id)); | 
|  |  | 
|  | details.num_tasks = step_start_msg->total_tasks; | 
|  | step.cpu_freq_min = step_start_msg->req_cpufreq_min; | 
|  | step.cpu_freq_max = step_start_msg->req_cpufreq_max; | 
|  | step.cpu_freq_gov = step_start_msg->req_cpufreq_gov; | 
|  | step.cwd = step_start_msg->cwd; | 
|  | step.std_err = step_start_msg->std_err; | 
|  | step.std_in = step_start_msg->std_in; | 
|  | step.std_out = step_start_msg->std_out; | 
|  | step.submit_line = step_start_msg->submit_line; | 
|  | step.tres_alloc_str = step_start_msg->tres_alloc_str; | 
|  |  | 
|  | layout.node_cnt = step_start_msg->node_cnt; | 
|  | layout.task_dist = step_start_msg->task_dist; | 
|  |  | 
|  | job.details = &details; | 
|  | step.job_ptr = &job; | 
|  | step.step_layout = &layout; | 
|  |  | 
|  | rc = jobacct_storage_g_step_start(slurmdbd_conn->db_conn, &step); | 
|  |  | 
|  | if (rc && errno == 740) /* meaning data is already there */ | 
|  | rc = SLURM_SUCCESS; | 
|  |  | 
|  | /* just in case this gets set we need to clear it */ | 
|  | xfree(job.wckey); | 
|  |  | 
|  | if (!slurmdbd_conn->conn->rem_port) { | 
|  | debug3("DBD_STEP_START: cluster not registered"); | 
|  | slurmdbd_conn->conn->rem_port = | 
|  | clusteracct_storage_g_register_disconn_ctld( | 
|  | slurmdbd_conn->db_conn, | 
|  | slurmdbd_conn->conn->rem_host); | 
|  |  | 
|  | _add_registered_cluster(slurmdbd_conn); | 
|  | } | 
|  |  | 
|  | end_it: | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_STEP_START); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _get_stats(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!_validate_super_user(slurmdbd_conn)) { | 
|  | int rc = ESLURM_ACCESS_DENIED; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, rc, | 
|  | comment, DBD_GET_STATS); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | debug2("Get stats request received from UID %u", | 
|  | slurmdbd_conn->conn->auth_uid); | 
|  |  | 
|  | /* Assume rpc_stats is present to hold lock as beifly as possible */ | 
|  | *out_buffer = init_buf(32 * 1024); | 
|  | pack16((uint16_t) DBD_GOT_STATS, *out_buffer); | 
|  | slurm_mutex_lock(&rpc_mutex); | 
|  | if (!rpc_stats) { | 
|  | slurm_mutex_unlock(&rpc_mutex); | 
|  | free_buf(*out_buffer); | 
|  | rc = ESLURM_NO_RPC_STATS; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, rc, | 
|  | comment, DBD_GET_STATS); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  | slurmdb_pack_stats_msg(rpc_stats, slurmdbd_conn->conn->version, | 
|  | *out_buffer); | 
|  | slurm_mutex_unlock(&rpc_mutex); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _clear_stats(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!_validate_super_user(slurmdbd_conn)) { | 
|  | int rc = ESLURM_ACCESS_DENIED; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, rc, | 
|  | comment, | 
|  | DBD_CLEAR_STATS); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | info("Clear stats request received from UID %u", | 
|  | slurmdbd_conn->conn->auth_uid); | 
|  |  | 
|  | init_dbd_stats(); | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_CLEAR_STATS); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | static int _shutdown(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, | 
|  | buf_t **out_buffer) | 
|  | { | 
|  | int rc = SLURM_SUCCESS; | 
|  | char *comment = NULL; | 
|  |  | 
|  | if (!_validate_super_user(slurmdbd_conn)) { | 
|  | int rc = ESLURM_ACCESS_DENIED; | 
|  | comment = _internal_rc_to_str(rc, slurmdbd_conn, false); | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, rc, | 
|  | comment, DBD_SHUTDOWN); | 
|  |  | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | info("Shutdown request received from UID %u", | 
|  | slurmdbd_conn->conn->auth_uid); | 
|  | shutdown_threads(); | 
|  |  | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, DBD_SHUTDOWN); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | /* Process an incoming RPC | 
|  | * slurmdbd_conn IN/OUT - in will that the conn.fd set before | 
|  | *       calling and db_conn and conn.version will be filled in with the init. | 
|  | * msg IN - incoming message | 
|  | * msg_size IN - size of msg in bytes | 
|  | * first IN - set if first message received on the socket | 
|  | * buffer OUT - outgoing response, must be freed by caller | 
|  | * uid IN/OUT - user ID who initiated the RPC | 
|  | * RET SLURM_SUCCESS or error code */ | 
|  | extern int proc_req(void *conn, persist_msg_t *msg, buf_t **out_buffer) | 
|  | { | 
|  | slurmdbd_conn_t *slurmdbd_conn = conn; | 
|  | int rc = SLURM_SUCCESS; | 
|  | char *comment = NULL; | 
|  | slurmdb_rpc_obj_t *rpc_obj; | 
|  | int fd = conn_g_get_fd(slurmdbd_conn->conn->tls_conn); | 
|  |  | 
|  | DEF_TIMERS; | 
|  | START_TIMER; | 
|  |  | 
|  | if (!slurmdbd_conn->conn->auth_ids_set) | 
|  | fatal("%s: auth_ids_set is false, this should never happen", | 
|  | __func__); | 
|  |  | 
|  | if (slurm_conf.debug_flags & DEBUG_FLAG_PROTOCOL) { | 
|  | char *p = slurmdbd_msg_type_2_str(msg->msg_type, 1); | 
|  | if (slurmdbd_conn->conn->cluster_name) { | 
|  | info("%s: received opcode %s from persist conn on (%s)%s uid %u", | 
|  | __func__, p, slurmdbd_conn->conn->cluster_name, | 
|  | slurmdbd_conn->conn->rem_host, | 
|  | slurmdbd_conn->conn->auth_uid); | 
|  | } else { | 
|  | info("%s: received opcode %s from %s uid %u", | 
|  | __func__, p, slurmdbd_conn->conn->rem_host, | 
|  | slurmdbd_conn->conn->auth_uid); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (slurm_conf.debug_flags & DEBUG_FLAG_AUDIT_RPCS) { | 
|  | slurm_addr_t cli_addr; | 
|  | (void) slurm_get_peer_addr(fd, &cli_addr); | 
|  | log_flag(AUDIT_RPCS, "msg_type=%s uid=%u client=[%pA] protocol=%u", | 
|  | slurmdbd_msg_type_2_str(msg->msg_type, 1), | 
|  | slurmdbd_conn->conn->auth_uid, | 
|  | &cli_addr, slurmdbd_conn->conn->version); | 
|  | } | 
|  |  | 
|  | switch (msg->msg_type) { | 
|  | case REQUEST_PERSIST_INIT: | 
|  | rc = _unpack_persist_init(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_ADD_ACCOUNTS: | 
|  | rc = _add_accounts(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_ADD_ACCOUNTS_COND: | 
|  | rc = _add_accounts_cond(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_ADD_ACCOUNT_COORDS: | 
|  | rc = _add_account_coords(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_ADD_TRES: | 
|  | rc = _add_tres(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_ADD_ASSOCS: | 
|  | rc = _add_assocs(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_ADD_CLUSTERS: | 
|  | rc = _add_clusters(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_ADD_FEDERATIONS: | 
|  | rc = _add_federations(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_ADD_QOS: | 
|  | rc = _add_qos(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_ADD_RES: | 
|  | rc = _add_res(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_ADD_USERS: | 
|  | rc = _add_users(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_ADD_USERS_COND: | 
|  | rc = _add_users_cond(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_ADD_WCKEYS: | 
|  | rc = _add_wckeys(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_ADD_RESV: | 
|  | rc = _add_reservation(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_ARCHIVE_DUMP: | 
|  | rc = _archive_dump(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_ARCHIVE_LOAD: | 
|  | rc = _archive_load(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_CLUSTER_TRES: | 
|  | rc = _cluster_tres(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_ACCOUNTS: | 
|  | rc = _get_accounts(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_TRES: | 
|  | rc = _get_tres(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_ASSOCS: | 
|  | rc = _get_assocs(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_ASSOC_USAGE: | 
|  | case DBD_GET_WCKEY_USAGE: | 
|  | case DBD_GET_ASSOC_NG_USAGE: | 
|  | case DBD_GET_CLUSTER_USAGE: | 
|  | rc = _get_usage(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_CLUSTERS: | 
|  | rc = _get_clusters(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_FEDERATIONS: | 
|  | rc = _get_federations(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_CONFIG: | 
|  | rc = _get_config(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_EVENTS: | 
|  | rc = _get_events(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_INSTANCES: | 
|  | rc = _get_instances(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_JOBS_COND: | 
|  | rc = _get_jobs_cond(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_PROBS: | 
|  | rc = _get_probs(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_QOS: | 
|  | rc = _get_qos(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_RES: | 
|  | rc = _get_res(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_TXN: | 
|  | rc = _get_txn(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_WCKEYS: | 
|  | rc = _get_wckeys(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_RESVS: | 
|  | rc = _get_reservations(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_USERS: | 
|  | rc = _get_users(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_FLUSH_JOBS: | 
|  | rc = _flush_jobs(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_FINI: | 
|  | rc = _fini_conn(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_JOB_COMPLETE: | 
|  | rc = _job_complete(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_JOB_START: | 
|  | rc = _job_start(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_JOB_HEAVY: | 
|  | rc = _job_heavy(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_JOB_SUSPEND: | 
|  | rc = _job_suspend(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_MODIFY_ACCOUNTS: | 
|  | rc = _modify_accounts(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_MODIFY_ASSOCS: | 
|  | rc = _modify_assocs(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_MODIFY_CLUSTERS: | 
|  | rc = _modify_clusters(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_MODIFY_FEDERATIONS: | 
|  | rc = _modify_federations(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_MODIFY_JOB: | 
|  | rc = _modify_job(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_MODIFY_QOS: | 
|  | rc = _modify_qos(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_MODIFY_RES: | 
|  | rc = _modify_res(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_MODIFY_USERS: | 
|  | rc = _modify_users(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_MODIFY_WCKEYS: | 
|  | rc = _modify_wckeys(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_MODIFY_RESV: | 
|  | rc = _modify_reservation(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_NODE_STATE: | 
|  | rc = _node_state(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_RECONFIG: | 
|  | /* handle reconfig */ | 
|  | rc = _reconfig(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_REGISTER_CTLD: | 
|  | rc = _register_ctld(slurmdbd_conn, msg, out_buffer); | 
|  | /* | 
|  | * We don't want/need to send updates to this cluster that just | 
|  | * registered since it's rpc manager might not be up yet. | 
|  | */ | 
|  | slurmdbd_conn->conn->flags |= PERSIST_FLAG_DONT_UPDATE_CLUSTER; | 
|  | break; | 
|  | case DBD_REMOVE_ACCOUNTS: | 
|  | rc = _remove_accounts(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_REMOVE_ACCOUNT_COORDS: | 
|  | rc = _remove_account_coords(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_REMOVE_ASSOCS: | 
|  | rc = _remove_assocs(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_REMOVE_CLUSTERS: | 
|  | rc = _remove_clusters(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_REMOVE_FEDERATIONS: | 
|  | rc = _remove_federations(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_REMOVE_QOS: | 
|  | rc = _remove_qos(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_REMOVE_RES: | 
|  | rc = _remove_res(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_REMOVE_USERS: | 
|  | rc = _remove_users(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_REMOVE_WCKEYS: | 
|  | rc = _remove_wckeys(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_REMOVE_RESV: | 
|  | rc = _remove_reservation(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_ROLL_USAGE: | 
|  | rc = _roll_usage(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_SEND_MULT_JOB_START: | 
|  | rc = _send_mult_job_start(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_SEND_MULT_MSG: | 
|  | rc = _send_mult_msg(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_STEP_COMPLETE: | 
|  | rc = _step_complete(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_STEP_START: | 
|  | rc = _step_start(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_FIX_RUNAWAY_JOB: | 
|  | rc = _fix_runaway_jobs(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_GET_STATS: | 
|  | rc = _get_stats(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_CLEAR_STATS: | 
|  | rc = _clear_stats(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | case DBD_SHUTDOWN: | 
|  | rc = _shutdown(slurmdbd_conn, msg, out_buffer); | 
|  | break; | 
|  | default: | 
|  | comment = "Invalid RPC"; | 
|  | error("CONN:%d %s msg_type=%s", | 
|  | fd, comment, rpc_num2string(msg->msg_type)); | 
|  | rc = EINVAL; | 
|  | *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, | 
|  | rc, comment, 0); | 
|  | break; | 
|  | } | 
|  |  | 
|  | if (rc == ESLURM_ACCESS_DENIED) | 
|  | error("CONN:%d Security violation, %s", | 
|  | fd, slurmdbd_msg_type_2_str(msg->msg_type, 1)); | 
|  | else if (slurmdbd_conn->conn->rem_port && | 
|  | (!slurmdbd_conf->commit_delay || | 
|  | (msg->msg_type == DBD_REGISTER_CTLD))) { | 
|  | /* If we are dealing with the slurmctld do the | 
|  | commit (SUCCESS or NOT) afterwards since we | 
|  | do transactions for performance reasons. | 
|  | (don't ever use autocommit with innodb) | 
|  | */ | 
|  | acct_storage_g_commit(slurmdbd_conn->db_conn, 1); | 
|  | } | 
|  | /* | 
|  | * Clear DONT_UPDATE flag now so that it's tied to this transaction | 
|  | * only. Can't clear in p_commit() because if CommitDelay is set, we may | 
|  | * not send needed updates later. | 
|  | */ | 
|  | slurmdbd_conn->conn->flags &= ~PERSIST_FLAG_DONT_UPDATE_CLUSTER; | 
|  |  | 
|  | END_TIMER; | 
|  |  | 
|  | slurm_mutex_lock(&rpc_mutex); | 
|  | if (!rpc_stats) { | 
|  | slurm_mutex_unlock(&rpc_mutex); | 
|  | return rc; | 
|  | } | 
|  |  | 
|  | if (!(rpc_obj = | 
|  | list_find_first(rpc_stats->rpc_list, | 
|  | _find_rpc_obj_in_list, &msg->msg_type))) { | 
|  | rpc_obj = xmalloc(sizeof(slurmdb_rpc_obj_t)); | 
|  | rpc_obj->id = msg->msg_type; | 
|  | list_append(rpc_stats->rpc_list, rpc_obj); | 
|  | } | 
|  | rpc_obj->cnt++; | 
|  | rpc_obj->time += DELTA_TIMER; | 
|  |  | 
|  | if (!(rpc_obj = list_find_first(rpc_stats->user_list, | 
|  | _find_rpc_obj_in_list, | 
|  | &slurmdbd_conn->conn->auth_uid))) { | 
|  | rpc_obj = xmalloc(sizeof(slurmdb_rpc_obj_t)); | 
|  | rpc_obj->id = slurmdbd_conn->conn->auth_uid; | 
|  | list_append(rpc_stats->user_list, rpc_obj); | 
|  | } | 
|  | rpc_obj->cnt++; | 
|  | rpc_obj->time += DELTA_TIMER; | 
|  |  | 
|  | slurm_mutex_unlock(&rpc_mutex); | 
|  |  | 
|  | return rc; | 
|  | } |