/*****************************************************************************\ * 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 , Danny Auble * CODE-OCEC-09-009. All rights reserved. * * This file is part of Slurm, a resource management program. * For details, see . * 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 #if HAVE_SYS_PRCTL_H #include #endif #include "src/common/slurm_auth.h" #include "src/common/gres.h" #include "src/common/macros.h" #include "src/common/pack.h" #include "src/common/slurmdbd_defs.h" #include "src/common/slurmdbd_pack.h" #include "src/common/slurm_accounting_storage.h" #include "src/common/slurm_jobacct_gather.h" #include "src/common/slurm_protocol_api.h" #include "src/common/slurm_protocol_defs.h" #include "src/common/timers.h" #include "src/common/uid.h" #include "src/common/xstring.h" #include "src/slurmdbd/read_config.h" #include "src/slurmdbd/rpc_mgr.h" #include "src/slurmdbd/proc_req.h" #include "src/slurmdbd/slurmdbd.h" #include "src/slurmctld/slurmctld.h" /* Local functions */ static bool _validate_slurm_user(uint32_t uid); static bool _validate_super_user(uint32_t uid, slurmdbd_conn_t *slurmdbd_conn); static bool _validate_operator(uint32_t uid, slurmdbd_conn_t *slurmdbd_conn); static int _unpack_persist_init(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _add_accounts(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _add_account_coords(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _add_tres(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _add_assocs(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _add_clusters(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _add_federations(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _add_qos(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _add_res(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _add_users(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _add_wckeys(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _add_reservation(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _archive_dump(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _archive_load(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _clear_stats(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _cluster_tres(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _fix_runaway_jobs(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_accounts(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_tres(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_assocs(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_clusters(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_federations(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_config(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_events(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_jobs_cond(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_probs(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_qos(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_res(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_stats(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_txn(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_usage(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_users(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_wckeys(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _get_reservations(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _find_rpc_obj_in_list(void *x, void *key); static int _flush_jobs(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _fini_conn(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer); static int _job_complete(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _job_start(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _job_suspend(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _modify_accounts(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _modify_assocs(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _modify_clusters(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _modify_federations(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _modify_job(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _modify_qos(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _modify_res(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _modify_users(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _modify_wckeys(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _modify_reservation(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _node_state(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); 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 int _reconfig(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _register_ctld(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _remove_accounts(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _remove_account_coords(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _remove_assocs(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _remove_clusters(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _remove_federations(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _remove_qos(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _remove_res(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _remove_users(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _remove_wckeys(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _remove_reservation(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _roll_usage(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _send_mult_job_start(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _send_mult_msg(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _shutdown(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _step_complete(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); static int _step_start(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid); #ifndef NDEBUG /* * Used alongside the testsuite to signal that the RPC should be processed * as an untrusted user, rather than the "real" account. (Which in a lot of * testing is likely SlurmUser, and thus allowed to bypass many security * checks. * * Implemented with a thread-local variable to apply only to the current * RPC handling thread. Set by SLURM_DROP_PRIV bit in the slurm_msg_t flags. */ __thread bool drop_priv = false; #endif /* 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 *out_buffer, uint32_t *uid) { slurmdbd_conn_t *slurmdbd_conn = conn; int rc = SLURM_SUCCESS; char *comment = NULL; slurmdb_rpc_obj_t *rpc_obj; DEF_TIMERS; START_TIMER; switch (msg->msg_type) { case REQUEST_PERSIST_INIT: rc = _unpack_persist_init( slurmdbd_conn, msg, out_buffer, uid); break; case DBD_ADD_ACCOUNTS: rc = _add_accounts(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_ADD_ACCOUNT_COORDS: rc = _add_account_coords(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_ADD_TRES: rc = _add_tres(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_ADD_ASSOCS: rc = _add_assocs(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_ADD_CLUSTERS: rc = _add_clusters(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_ADD_FEDERATIONS: rc = _add_federations(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_ADD_QOS: rc = _add_qos(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_ADD_RES: rc = _add_res(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_ADD_USERS: rc = _add_users(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_ADD_WCKEYS: rc = _add_wckeys(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_ADD_RESV: rc = _add_reservation(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_ARCHIVE_DUMP: rc = _archive_dump(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_ARCHIVE_LOAD: rc = _archive_load(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_CLUSTER_TRES: rc = _cluster_tres(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_ACCOUNTS: rc = _get_accounts(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_TRES: rc = _get_tres(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_ASSOCS: rc = _get_assocs(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_ASSOC_USAGE: case DBD_GET_WCKEY_USAGE: case DBD_GET_CLUSTER_USAGE: rc = _get_usage(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_CLUSTERS: rc = _get_clusters(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_FEDERATIONS: rc = _get_federations(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_CONFIG: rc = _get_config(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_EVENTS: rc = _get_events(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_JOBS_COND: rc = _get_jobs_cond(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_PROBS: rc = _get_probs(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_QOS: rc = _get_qos(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_RES: rc = _get_res(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_TXN: rc = _get_txn(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_WCKEYS: rc = _get_wckeys(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_RESVS: rc = _get_reservations(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_USERS: rc = _get_users(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_FLUSH_JOBS: rc = _flush_jobs(slurmdbd_conn, msg, out_buffer, uid); 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, uid); break; case DBD_JOB_START: rc = _job_start(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_JOB_SUSPEND: rc = _job_suspend(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_MODIFY_ACCOUNTS: rc = _modify_accounts(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_MODIFY_ASSOCS: rc = _modify_assocs(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_MODIFY_CLUSTERS: rc = _modify_clusters(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_MODIFY_FEDERATIONS: rc = _modify_federations(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_MODIFY_JOB: rc = _modify_job(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_MODIFY_QOS: rc = _modify_qos(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_MODIFY_RES: rc = _modify_res(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_MODIFY_USERS: rc = _modify_users(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_MODIFY_WCKEYS: rc = _modify_wckeys(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_MODIFY_RESV: rc = _modify_reservation(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_NODE_STATE: rc = _node_state(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_RECONFIG: /* handle reconfig */ rc = _reconfig(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_REGISTER_CTLD: rc = _register_ctld(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_REMOVE_ACCOUNTS: rc = _remove_accounts(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_REMOVE_ACCOUNT_COORDS: rc = _remove_account_coords(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_REMOVE_ASSOCS: rc = _remove_assocs(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_REMOVE_CLUSTERS: rc = _remove_clusters(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_REMOVE_FEDERATIONS: rc = _remove_federations(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_REMOVE_QOS: rc = _remove_qos(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_REMOVE_RES: rc = _remove_res(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_REMOVE_USERS: rc = _remove_users(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_REMOVE_WCKEYS: rc = _remove_wckeys(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_REMOVE_RESV: rc = _remove_reservation(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_ROLL_USAGE: rc = _roll_usage(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_SEND_MULT_JOB_START: rc = _send_mult_job_start(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_SEND_MULT_MSG: rc = _send_mult_msg(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_STEP_COMPLETE: rc = _step_complete(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_STEP_START: rc = _step_start(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_FIX_RUNAWAY_JOB: rc = _fix_runaway_jobs(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_GET_STATS: rc = _get_stats(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_CLEAR_STATS: rc = _clear_stats(slurmdbd_conn, msg, out_buffer, uid); break; case DBD_SHUTDOWN: rc = _shutdown(slurmdbd_conn, msg, out_buffer, uid); break; default: comment = "Invalid RPC"; error("CONN:%u %s msg_type=%d", slurmdbd_conn->conn->fd, comment, 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:%u Security violation, %s", slurmdbd_conn->conn->fd, slurmdbd_msg_type_2_str(msg->msg_type, 1)); else if (slurmdbd_conn->conn->rem_port && !slurmdbd_conf->commit_delay) { /* 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); } END_TIMER; slurm_mutex_lock(&rpc_mutex); 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, uid))) { rpc_obj = xmalloc(sizeof(slurmdb_rpc_obj_t)); rpc_obj->id = *uid; list_append(rpc_stats.user_list, rpc_obj); } rpc_obj->cnt++; rpc_obj->time += DELTA_TIMER; slurm_mutex_unlock(&rpc_mutex); return rc; } /* * _validate_slurm_user - validate that the uid is authorized to see * privileged data (either user root or SlurmUser) */ static bool _validate_slurm_user(uint32_t uid) { #ifndef NDEBUG if (drop_priv) return false; #endif if ((uid == 0) || (uid == slurmdbd_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(uint32_t uid, slurmdbd_conn_t *dbd_conn) { #ifndef NDEBUG if (drop_priv) return false; #endif if ((uid == 0) || (uid == slurmdbd_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(uint32_t uid, slurmdbd_conn_t *dbd_conn) { #ifndef NDEBUG if (drop_priv) return false; #endif if ((uid == 0) || (uid == slurmdbd_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) { ListIterator 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))) { if (db_conn == slurmdbd_conn) break; if (!xstrcmp(db_conn->conn->cluster_name, slurmdbd_conn->conn->cluster_name) && (db_conn->conn->fd != slurmdbd_conn->conn->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, db_conn->conn->fd, slurmdbd_conn->conn->fd); slurmdbd_conn->conn->rem_port = 0; list_delete_item(itr); } } list_iterator_destroy(itr); if (!slurmdbd_conn) 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, uint32_t *uid) { int rc = SLURM_SUCCESS; *uid = init_msg->uid; #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:%u", init_msg->cluster_name, init_msg->version, init_msg->uid, slurmdbd_conn->conn->rem_host, slurmdbd_conn->conn->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( NULL, slurmdbd_conn->conn->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 *out_buffer, uint32_t *uid) { int rc; slurm_msg_t *smsg = msg->data; persist_init_req_msg_t *req_msg = smsg->data; char *comment = NULL; #ifndef NDEBUG if ((smsg->flags & SLURM_DROP_PRIV)) drop_priv = true; #endif req_msg->uid = g_slurm_auth_get_uid(slurmdbd_conn->conn->auth_cred); /* If the client happens to be a newer version than we are make it so * they talk language I understand. */ if (req_msg->version > SLURM_PROTOCOL_VERSION) req_msg->version = SLURM_PROTOCOL_VERSION; rc = _handle_init_msg(slurmdbd_conn, req_msg, uid); 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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_list_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_ADD_ACCOUNTS: called"); rc = acct_storage_g_add_accounts(slurmdbd_conn->db_conn, *uid, get_msg->my_list); if (rc == ESLURM_ACCESS_DENIED) comment = "Your user doesn't have privilege to perform this action"; *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, rc, comment, DBD_ADD_ACCOUNTS); return rc; } static int _fix_runaway_jobs(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_list_msg_t *get_msg = msg->data; char *comment = NULL; if (!_validate_operator(*uid, slurmdbd_conn)) rc = ESLURM_ACCESS_DENIED; else rc = acct_storage_g_fix_runaway_jobs( slurmdbd_conn->db_conn, *uid, get_msg->my_list); if (rc == ESLURM_ACCESS_DENIED) { comment = "You must have an AdminLevel>=Operator to fix runaway jobs"; error("CONN:%u %s", slurmdbd_conn->conn->fd, 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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_acct_coord_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_ADD_ACCOUNT_COORDS: called"); rc = acct_storage_g_add_coord(slurmdbd_conn->db_conn, *uid, get_msg->acct_list, get_msg->cond); if (rc == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform this action"; error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); } *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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_list_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_ADD_TRES: called"); rc = acct_storage_g_add_tres(slurmdbd_conn->db_conn, *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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_list_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_ADD_ASSOCS: called"); if (!_validate_operator(*uid, slurmdbd_conn)) { ListIterator itr = NULL; ListIterator 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 = *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:%u %s", slurmdbd_conn->conn->fd, comment); rc = SLURM_ERROR; goto end_it; } if (!user.coord_accts || !list_count(user.coord_accts)) { comment = "Your user doesn't have privilege to perform this action"; error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); rc = ESLURM_ACCESS_DENIED; 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) { comment = "Your user doesn't have privilege to perform this action"; error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); rc = ESLURM_ACCESS_DENIED; goto end_it; } } rc = acct_storage_g_add_assocs(slurmdbd_conn->db_conn, *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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_list_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_ADD_CLUSTERS: called"); rc = acct_storage_g_add_clusters(slurmdbd_conn->db_conn, *uid, get_msg->my_list); if (rc == ESLURM_ACCESS_DENIED) comment = "Your user doesn't have privilege to perform this action"; 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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_list_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_ADD_FEDERATIONS: called"); rc = acct_storage_g_add_federations(slurmdbd_conn->db_conn, *uid, get_msg->my_list); if (rc == ESLURM_ACCESS_DENIED) comment = "Your user doesn't have privilege to perform this " "action"; 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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_list_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_ADD_QOS: called"); rc = acct_storage_g_add_qos(slurmdbd_conn->db_conn, *uid, get_msg->my_list); if (rc == ESLURM_ACCESS_DENIED) comment = "Your user doesn't have privilege to perform this action"; 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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_list_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_ADD_RES: called"); rc = acct_storage_g_add_res(slurmdbd_conn->db_conn, *uid, get_msg->my_list); if (rc == ESLURM_ACCESS_DENIED) comment = "Your user doesn't have privilege to perform this action"; 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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_list_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_ADD_USERS: called"); rc = acct_storage_g_add_users(slurmdbd_conn->db_conn, *uid, get_msg->my_list); if (rc == ESLURM_ACCESS_DENIED) comment = "Your user doesn't have privilege to perform this action"; *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, rc, comment, DBD_ADD_USERS); return rc; } static int _add_wckeys(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_list_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_ADD_WCKEYS: called"); rc = acct_storage_g_add_wckeys(slurmdbd_conn->db_conn, *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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_rec_msg_t *rec_msg = msg->data; char *comment = NULL; if (!_validate_slurm_user(*uid)) { comment = "DBD_ADD_RESV message from invalid uid"; error("DBD_ADD_RESV message from invalid uid %u", *uid); rc = ESLURM_ACCESS_DENIED; goto end_it; } debug2("DBD_ADD_RESV: called"); 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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_cond_msg_t *get_msg = msg->data; char *comment = "SUCCESS"; slurmdb_archive_cond_t *arch_cond = NULL; debug2("DBD_ARCHIVE_DUMP: called"); if (!_validate_super_user(*uid, slurmdbd_conn)) { comment = "Your user doesn't have privilege to perform this action"; error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); rc = ESLURM_ACCESS_DENIED; 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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; slurmdb_archive_rec_t *arch_rec = msg->data; char *comment = "SUCCESS"; debug2("DBD_ARCHIVE_LOAD: called"); if (!_validate_super_user(*uid, slurmdbd_conn)) { comment = "Your user doesn't have privilege to perform this action"; error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); rc = ESLURM_ACCESS_DENIED; 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 *out_buffer, uint32_t *uid) { dbd_cluster_tres_msg_t *cluster_tres_msg = msg->data; int rc = SLURM_SUCCESS; char *comment = NULL; if (!_validate_slurm_user(*uid)) { comment = "DBD_CLUSTER_TRES message from invalid uid"; error("DBD_CLUSTER_TRES message from invalid uid %u", *uid); rc = ESLURM_ACCESS_DENIED; goto end_it; } debug2("DBD_CLUSTER_TRES: called for %s(%s)", 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 = "This cluster hasn't been added to accounting yet"; 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 *out_buffer, uint32_t *uid) { dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; debug2("DBD_GET_ACCOUNTS: called"); list_msg.my_list = acct_storage_g_get_accounts(slurmdbd_conn->db_conn, *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 *out_buffer, uint32_t *uid) { dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; debug2("DBD_GET_TRES: called"); list_msg.my_list = acct_storage_g_get_tres( slurmdbd_conn->db_conn, *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 *out_buffer, uint32_t *uid) { dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; debug2("DBD_GET_ASSOCS: called"); list_msg.my_list = acct_storage_g_get_assocs( slurmdbd_conn->db_conn, *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 *out_buffer, uint32_t *uid) { dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; debug2("DBD_GET_CLUSTERS: called"); list_msg.my_list = acct_storage_g_get_clusters( slurmdbd_conn->db_conn, *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 *out_buffer, uint32_t *uid) { dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; debug2("DBD_GET_FEDERATIONS: called"); list_msg.my_list = acct_storage_g_get_federations( slurmdbd_conn->db_conn, *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 *out_buffer, uint32_t *uid) { char *config_name = msg->data; dbd_list_msg_t list_msg = { NULL }; debug2("DBD_GET_CONFIG: called"); 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 *out_buffer, uint32_t *uid) { dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; debug2("DBD_GET_EVENTS: called"); list_msg.my_list = acct_storage_g_get_events( slurmdbd_conn->db_conn, *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_jobs_cond(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid) { 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; debug2("DBD_GET_JOBS_COND: called"); /* fail early if requesting runaways and not super user */ if ((job_cond->flags & JOBCOND_FLAG_RUNAWAY) && !_validate_operator(*uid, slurmdbd_conn)) { debug("Rejecting query of runaways from uid %u", *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(*uid, 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", *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, *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 *out_buffer, uint32_t *uid) { dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; debug2("DBD_GET_PROBS: called"); list_msg.my_list = acct_storage_g_get_problems( slurmdbd_conn->db_conn, *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 *out_buffer, uint32_t *uid) { dbd_cond_msg_t *cond_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; debug2("DBD_GET_QOS: called"); list_msg.my_list = acct_storage_g_get_qos(slurmdbd_conn->db_conn, *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 *out_buffer, uint32_t *uid) { dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; debug2("DBD_GET_RES: called"); list_msg.my_list = acct_storage_g_get_res( slurmdbd_conn->db_conn, *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 *out_buffer, uint32_t *uid) { dbd_cond_msg_t *cond_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; debug2("DBD_GET_TXN: called"); list_msg.my_list = acct_storage_g_get_txn(slurmdbd_conn->db_conn, *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 *out_buffer, uint32_t *uid) { 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; info("DBD_GET_USAGE: called type is %s", 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_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, *uid, get_msg->rec, msg->msg_type, get_msg->start, get_msg->end); if (rc != SLURM_SUCCESS) { comment = "Problem getting usage info"; error("CONN:%u %s", slurmdbd_conn->conn->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 *out_buffer, uint32_t *uid) { 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; debug2("DBD_GET_USERS: called"); user_cond = get_msg->cond; if ((!user_cond->with_assocs && !user_cond->with_wckeys) && ((slurmdbd_conn->conn->version < 8) || (user_cond->assoc_cond->only_defs))) { List cluster_list = user_cond->assoc_cond->cluster_list; /* load up with just this cluster to query against * since befor 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, *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 *out_buffer, uint32_t *uid) { dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; char *comment = NULL; int rc = SLURM_SUCCESS; debug2("DBD_GET_WCKEYS: called"); /* 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(*uid, slurmdbd_conn)) { comment = "Your user doesn't have privilege to perform this action"; error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, ESLURM_ACCESS_DENIED, comment, DBD_GET_WCKEYS); return ESLURM_ACCESS_DENIED; } list_msg.my_list = acct_storage_g_get_wckeys(slurmdbd_conn->db_conn, *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 *out_buffer, uint32_t *uid) { dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; debug2("DBD_GET_RESVS: called"); list_msg.my_list = acct_storage_g_get_reservations( slurmdbd_conn->db_conn, *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 *out_buffer, uint32_t *uid) { dbd_cluster_tres_msg_t *cluster_tres_msg = msg->data; int rc = SLURM_SUCCESS; char *comment = NULL; if (!_validate_slurm_user(*uid)) { comment = "DBD_FLUSH_JOBS message from invalid uid"; error("DBD_FLUSH_JOBS message from invalid uid %u", *uid); rc = ESLURM_ACCESS_DENIED; goto end_it; } debug2("DBD_FLUSH_JOBS: called for %s", 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 *out_buffer) { dbd_fini_msg_t *fini_msg = msg->data; char *comment = NULL; int rc = SLURM_SUCCESS; debug2("DBD_FINI: CLOSE:%u COMMIT:%u", fini_msg->close_conn, fini_msg->commit); 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); *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 *out_buffer, uint32_t *uid) { dbd_job_comp_msg_t *job_comp_msg = msg->data; job_record_t job; struct job_details details; int rc = SLURM_SUCCESS; char *comment = NULL; if (!_validate_slurm_user(*uid)) { comment = "DBD_JOB_COMPLETE message from invalid uid"; error("CONN:%u %s %u", slurmdbd_conn->conn->fd, comment, *uid); rc = ESLURM_ACCESS_DENIED; goto end_it; } memset(&job, 0, sizeof(job_record_t)); memset(&details, 0, sizeof(struct job_details)); 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.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 *out_buffer, uint32_t *uid) { 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(*uid)) { comment = "DBD_JOB_START message from invalid uid"; error("CONN:%u %s %u", slurmdbd_conn->conn->fd, comment, *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_suspend(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid) { dbd_job_suspend_msg_t *job_suspend_msg = msg->data; job_record_t job; struct job_details details; int rc = SLURM_SUCCESS; char *comment = NULL; if (!_validate_slurm_user(*uid)) { comment = "DBD_JOB_SUSPEND message from invalid uid"; error("CONN:%u %s %u", slurmdbd_conn->conn->fd, comment, *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(struct job_details)); 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 *out_buffer, uint32_t *uid) { dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; dbd_modify_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_MODIFY_ACCOUNTS: called"); if (!(list_msg.my_list = acct_storage_g_modify_accounts( slurmdbd_conn->db_conn, *uid, get_msg->cond, get_msg->rec))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *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 *out_buffer, uint32_t *uid) { dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; dbd_modify_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_MODIFY_ASSOCS: called"); /* 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, *uid, get_msg->cond, get_msg->rec))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, rc, comment, DBD_MODIFY_ASSOCS); 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 *out_buffer, uint32_t *uid) { dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; dbd_modify_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_MODIFY_CLUSTERS: called"); if (!(list_msg.my_list = acct_storage_g_modify_clusters( slurmdbd_conn->db_conn, *uid, get_msg->cond, get_msg->rec))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *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 *out_buffer, uint32_t *uid) { dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; dbd_modify_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_MODIFY_FEDERATIONS: called"); if (!(list_msg.my_list = acct_storage_g_modify_federations( slurmdbd_conn->db_conn, *uid, get_msg->cond, get_msg->rec))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform " "this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *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 *out_buffer, uint32_t *uid) { dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; dbd_modify_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_MODIFY_JOB: called"); if (!(list_msg.my_list = acct_storage_g_modify_job( slurmdbd_conn->db_conn, *uid, get_msg->cond, get_msg->rec))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *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 *out_buffer, uint32_t *uid) { dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; dbd_modify_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_MODIFY_QOS: called"); if (!(list_msg.my_list = acct_storage_g_modify_qos( slurmdbd_conn->db_conn, *uid, get_msg->cond, get_msg->rec))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_QOS_PREEMPTION_LOOP) { comment = "QOS Preemption loop detected"; rc = ESLURM_QOS_PREEMPTION_LOOP; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *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 *out_buffer, uint32_t *uid) { dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; dbd_modify_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_MODIFY_RES: called"); if (!(list_msg.my_list = acct_storage_g_modify_res( slurmdbd_conn->db_conn, *uid, get_msg->cond, get_msg->rec))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform " "this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *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 *out_buffer, uint32_t *uid) { 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; debug2("DBD_MODIFY_USERS: called"); user_cond = (slurmdb_user_cond_t *)get_msg->cond; user_rec = (slurmdb_user_rec_t *)get_msg->rec; if (!_validate_operator(*uid, slurmdbd_conn)) { 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) >= 0) && pw_uid == *uid) { same_user = 1; goto is_same_user; } } comment = "Your user doesn't have privilege to perform this action"; error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, ESLURM_ACCESS_DENIED, comment, DBD_MODIFY_USERS); return ESLURM_ACCESS_DENIED; } 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:%u %s", slurmdbd_conn->conn->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(*uid, slurmdbd_conn)) { comment = "You must be a super user to modify a users admin level"; error("CONN:%u %s", slurmdbd_conn->conn->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, *uid, user_cond, user_rec))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *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 *out_buffer, uint32_t *uid) { dbd_list_msg_t list_msg = { NULL }; int rc = SLURM_SUCCESS; dbd_modify_msg_t *get_msg = msg->data; char *comment = NULL; debug2("DBD_MODIFY_WCKEYS: called"); if (!(list_msg.my_list = acct_storage_g_modify_wckeys( slurmdbd_conn->db_conn, *uid, get_msg->cond, get_msg->rec))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_rec_msg_t *rec_msg = msg->data; char *comment = NULL; if (!_validate_slurm_user(*uid)) { comment = "DBD_MODIFY_RESV message from invalid uid"; error("CONN:%u %s %u", slurmdbd_conn->conn->fd, comment, *uid); rc = ESLURM_ACCESS_DENIED; goto end_it; } debug2("DBD_MODIFY_RESV: called"); 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 *out_buffer, uint32_t *uid) { dbd_node_state_msg_t *node_state_msg = msg->data; node_record_t node_ptr; int rc = SLURM_SUCCESS; char *comment = NULL; if (!_validate_slurm_user(*uid)) { comment = "DBD_NODE_STATE message from invalid uid"; error("CONN:%u %s %u", slurmdbd_conn->conn->fd, comment, *uid); rc = ESLURM_ACCESS_DENIED; goto end_it; } memset(&node_ptr, 0, sizeof(node_record_t)); 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_UP; if (node_state_msg->new_state == 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); } else { 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); } 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; struct job_details details; job_array_struct_t array_recs; memset(&job, 0, sizeof(job_record_t)); memset(&details, 0, sizeof(struct job_details)); 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; if (job_start_msg->db_index != NO_VAL64) job.db_index = job_start_msg->db_index; details.begin_time = job_start_msg->eligible_time; job.user_id = job_start_msg->uid; job.group_id = job_start_msg->gid; 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.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; job.resv_id = job_start_msg->resv_id; job.priority = job_start_msg->priority; job.start_protocol_ver = slurmdbd_conn->conn->version; job.start_time = job_start_msg->start_time; 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_alloc = job_start_msg->gres_alloc; job.gres_req = job_start_msg->gres_req; 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", job_start_msg->job_id, job_start_msg->name); } 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->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); 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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; char *comment = NULL; if (!_validate_super_user(*uid, slurmdbd_conn)) { comment = "Your user doesn't have privilege to perform this action"; error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, ESLURM_ACCESS_DENIED, comment, DBD_MODIFY_WCKEYS); return ESLURM_ACCESS_DENIED; } info("Reconfigure request received"); reconfig(); *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 *out_buffer, uint32_t *uid) { dbd_register_ctld_msg_t *register_ctld_msg = msg->data; int rc = SLURM_SUCCESS; char *comment = NULL; slurmdb_cluster_cond_t cluster_q; slurmdb_cluster_rec_t cluster; dbd_list_msg_t list_msg = { NULL }; List cluster_list; if (!_validate_slurm_user(*uid)) { comment = "DBD_REGISTER_CTLD message from invalid uid"; error("CONN:%u %s %u", slurmdbd_conn->conn->fd, comment, *uid); rc = ESLURM_ACCESS_DENIED; goto end_it; } debug2("DBD_REGISTER_CTLD: called for %s(%u)", slurmdbd_conn->conn->cluster_name, register_ctld_msg->port); /* 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:%u %s", slurmdbd_conn->conn->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.plugin_id_select = register_ctld_msg->plugin_id_select; cluster.rpc_version = slurmdbd_conn->conn->version; cluster_list = acct_storage_g_get_clusters(slurmdbd_conn->db_conn, *uid, &cluster_q); if (!cluster_list || errno) { comment = slurm_strerror(errno); rc = errno; } else if (!list_count(cluster_list)) { slurmdb_assoc_rec_t root_assoc; List add_list = list_create(NULL); list_append(add_list, &cluster); slurmdb_init_assoc_rec(&root_assoc, 0); cluster.root_assoc = &root_assoc; cluster.name = slurmdbd_conn->conn->cluster_name; rc = acct_storage_g_add_clusters(slurmdbd_conn->db_conn, *uid, add_list); if (rc == ESLURM_ACCESS_DENIED) comment = "Your user doesn't have privilege to perform this action"; else if (rc != SLURM_SUCCESS) comment = "Failed to add/register cluster."; slurmdb_free_assoc_rec_members(&root_assoc); FREE_NULL_LIST(add_list); } else if ((cluster.flags != NO_VAL) && (cluster.flags & CLUSTER_FLAG_EXT) && !(((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, *uid, &cluster_q, &cluster); if (errno == EFAULT) { comment = "Request to register was incomplete"; rc = SLURM_ERROR; } else if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform this action"; rc = ESLURM_ACCESS_DENIED; } 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; } 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, rc, comment, DBD_REGISTER_CTLD); return rc; } static int _remove_accounts(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; char *comment = NULL; debug2("DBD_REMOVE_ACCOUNTS: called"); if (!(list_msg.my_list = acct_storage_g_remove_accounts( slurmdbd_conn->db_conn, *uid, get_msg->cond))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_acct_coord_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; char *comment = NULL; debug2("DBD_REMOVE_ACCOUNT_COORDS: called"); /* 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, *uid, get_msg->acct_list, get_msg->cond))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; char *comment = NULL; debug2("DBD_REMOVE_ASSOCS: called"); /* 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, *uid, get_msg->cond))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; char *comment = NULL; debug2("DBD_REMOVE_CLUSTERS: called"); if (!(list_msg.my_list = acct_storage_g_remove_clusters( slurmdbd_conn->db_conn, *uid, get_msg->cond))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; char *comment = NULL; debug2("DBD_REMOVE_FEDERATIONS: called"); if (!(list_msg.my_list = acct_storage_g_remove_federations( slurmdbd_conn->db_conn, *uid, get_msg->cond))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform " "this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; char *comment = NULL; debug2("DBD_REMOVE_QOS: called"); if (!(list_msg.my_list = acct_storage_g_remove_qos( slurmdbd_conn->db_conn, *uid, get_msg->cond))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *out_buffer = slurm_persist_make_rc_msg( slurmdbd_conn->conn, rc, comment, DBD_REMOVE_QOS); 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_res(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; char *comment = NULL; debug2("DBD_REMOVE_RES: called"); if (!(list_msg.my_list = acct_storage_g_remove_res( slurmdbd_conn->db_conn, *uid, get_msg->cond))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform " "this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; char *comment = NULL; debug2("DBD_REMOVE_USERS: called"); if (!(list_msg.my_list = acct_storage_g_remove_users( slurmdbd_conn->db_conn, *uid, get_msg->cond))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_cond_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; char *comment = NULL; debug2("DBD_REMOVE_WCKEYS: called"); if (!(list_msg.my_list = acct_storage_g_remove_wckeys( slurmdbd_conn->db_conn, *uid, get_msg->cond))) { if (errno == ESLURM_ACCESS_DENIED) { comment = "Your user doesn't have privilege to perform this action"; rc = ESLURM_ACCESS_DENIED; } else if (errno == SLURM_ERROR) { comment = "Something was wrong with your query"; rc = SLURM_ERROR; } else if (errno == SLURM_NO_CHANGE_IN_DATA) { comment = "Request didn't affect anything"; rc = SLURM_SUCCESS; } else if (errno == ESLURM_DB_CONNECTION) { comment = slurm_strerror(errno); rc = errno; } else { rc = errno; if (!(comment = slurm_strerror(errno))) comment = "Unknown issue"; } error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *out_buffer = slurm_persist_make_rc_msg( slurmdbd_conn->conn, rc, comment, DBD_REMOVE_WCKEYS); 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_reservation(slurmdbd_conn_t *slurmdbd_conn, persist_msg_t *msg, Buf *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; dbd_rec_msg_t *rec_msg = msg->data; char *comment = NULL; if (!_validate_slurm_user(*uid)) { comment = "DBD_REMOVE_RESV message from invalid uid"; error("DBD_REMOVE_RESV message from invalid uid %u", *uid); rc = ESLURM_ACCESS_DENIED; goto end_it; } debug2("DBD_REMOVE_RESV: called"); 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 *out_buffer, uint32_t *uid) { dbd_roll_usage_msg_t *get_msg = msg->data; int rc = SLURM_SUCCESS; char *comment = NULL; List rollup_stats_list = NULL; DEF_TIMERS; info("DBD_ROLL_USAGE: called"); if (!_validate_operator(*uid, slurmdbd_conn)) { comment = "Your user doesn't have privilege to perform this action"; error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); rc = ESLURM_ACCESS_DENIED; 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 *out_buffer, uint32_t *uid) { dbd_list_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; char *comment = NULL; ListIterator itr = NULL; dbd_job_start_msg_t *job_start_msg; dbd_id_rc_msg_t *id_rc_msg; /* DEF_TIMERS; */ if (!_validate_slurm_user(*uid)) { comment = "DBD_SEND_MULT_JOB_START message from invalid uid"; error("%s %u", comment, *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 *out_buffer, uint32_t *uid) { dbd_list_msg_t *get_msg = msg->data; dbd_list_msg_t list_msg = { NULL }; char *comment = NULL; ListIterator itr = NULL; Buf req_buf = NULL, ret_buf = NULL; int rc = SLURM_SUCCESS; /* DEF_TIMERS; */ if (!_validate_slurm_user(*uid)) { comment = "DBD_SEND_MULT_MSG message from invalid uid"; error("%s %u", comment, *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, uid); slurmdbd_free_msg(&sub_msg); } if (ret_buf) list_append(list_msg.my_list, ret_buf); if (rc != SLURM_SUCCESS) 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 *out_buffer, uint32_t *uid) { dbd_step_comp_msg_t *step_comp_msg = msg->data; step_record_t step; job_record_t job; struct job_details details; int rc = SLURM_SUCCESS; char *comment = NULL; if (!_validate_slurm_user(*uid)) { comment = "DBD_STEP_COMPLETE message from invalid uid"; error("%s %u", comment, *uid); rc = ESLURM_ACCESS_DENIED; goto end_it; } debug2("DBD_STEP_COMPLETE: ID:%u.%u SUBMIT:%lu", step_comp_msg->job_id, 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(struct job_details)); 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->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; step.step_id = step_comp_msg->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 *out_buffer, uint32_t *uid) { dbd_step_start_msg_t *step_start_msg = msg->data; step_record_t step; job_record_t job; struct job_details details; slurm_step_layout_t layout; int rc = SLURM_SUCCESS; char *comment = NULL; if (!_validate_slurm_user(*uid)) { comment = "DBD_STEP_START message from invalid uid"; error("%s %u", comment, *uid); rc = ESLURM_ACCESS_DENIED; goto end_it; } debug2("DBD_STEP_START: ID:%u.%u NAME:%s SUBMIT:%lu", step_start_msg->job_id, 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(struct job_details)); 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; job.job_id = step_start_msg->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; step.start_time = step_start_msg->start_time; details.submit_time = step_start_msg->job_submit_time; step.step_id = step_start_msg->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.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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; char *comment = NULL; if (!_validate_super_user(*uid, slurmdbd_conn)) { comment = "Your user doesn't have privilege to perform this action"; error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, ESLURM_ACCESS_DENIED, comment, DBD_GET_STATS); return ESLURM_ACCESS_DENIED; } debug2("Get stats request received from UID %u", *uid); *out_buffer = init_buf(32 * 1024); pack16((uint16_t) DBD_GOT_STATS, *out_buffer); slurm_mutex_lock(&rpc_mutex); 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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; char *comment = NULL; if (!_validate_super_user(*uid, slurmdbd_conn)) { comment = "Your user doesn't have privilege to perform this action"; error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *out_buffer = slurm_persist_make_rc_msg( slurmdbd_conn->conn, ESLURM_ACCESS_DENIED, comment, DBD_CLEAR_STATS); return ESLURM_ACCESS_DENIED; } info("Clear stats request received from UID %u", *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 *out_buffer, uint32_t *uid) { int rc = SLURM_SUCCESS; char *comment = NULL; if (!_validate_super_user(*uid, slurmdbd_conn)) { comment = "Your user doesn't have privilege to perform this action"; error("CONN:%u %s", slurmdbd_conn->conn->fd, comment); *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, ESLURM_ACCESS_DENIED, comment, DBD_SHUTDOWN); return ESLURM_ACCESS_DENIED; } info("Shutdown request received from UID %u", *uid); pthread_kill(signal_handler_thread, SIGTERM); *out_buffer = slurm_persist_make_rc_msg(slurmdbd_conn->conn, rc, comment, DBD_SHUTDOWN); return rc; }