static int _unpack_return_code(uint16_t rpc_version, Buf buffer) { uint16_t msg_type = -1; persist_rc_msg_t *msg; dbd_id_rc_msg_t *id_msg; slurmdbd_msg_t resp; int rc = SLURM_ERROR; memset(&resp, 0, sizeof(slurmdbd_msg_t)); if ((rc = unpack_slurmdbd_msg(&resp, slurmdbd_conn->version, buffer)) != SLURM_SUCCESS) { error("%s: unpack message error", __func__); return rc; } switch (resp.msg_type) { case DBD_ID_RC: id_msg = resp.data; rc = id_msg->return_code; slurmdbd_free_id_rc_msg(id_msg); if (rc != SLURM_SUCCESS) error("slurmdbd: DBD_ID_RC is %d", rc); break; case PERSIST_RC: msg = resp.data; rc = msg->rc; if (rc != SLURM_SUCCESS) { if (msg->ret_info == DBD_REGISTER_CTLD && slurm_get_accounting_storage_enforce()) { error("slurmdbd: PERSIST_RC is %d from " "%s(%u): %s", rc, slurmdbd_msg_type_2_str( msg->ret_info, 1), msg->ret_info, msg->comment); fatal("You need to add this cluster " "to accounting if you want to " "enforce associations, or no " "jobs will ever run."); } else debug("slurmdbd: PERSIST_RC is %d from " "%s(%u): %s", rc, slurmdbd_msg_type_2_str( msg->ret_info, 1), msg->ret_info, msg->comment); } slurm_persist_free_rc_msg(msg); break; default: error("slurmdbd: bad message type %d != PERSIST_RC", msg_type); } return rc; }
/* Send an RPC to the SlurmDBD and wait for the return code reply. * The RPC will not be queued if an error occurs. * Returns SLURM_SUCCESS or an error code */ extern int send_slurmdbd_recv_rc_msg(uint16_t rpc_version, slurmdbd_msg_t *req, int *resp_code) { int rc; slurmdbd_msg_t resp; xassert(req); xassert(resp_code); memset(&resp, 0, sizeof(slurmdbd_msg_t)); rc = send_recv_slurmdbd_msg(rpc_version, req, &resp); if (rc != SLURM_SUCCESS) { ; /* error message already sent */ } else if (resp.msg_type != PERSIST_RC) { error("slurmdbd: response is not type PERSIST_RC: %s(%u)", slurmdbd_msg_type_2_str(resp.msg_type, 1), resp.msg_type); rc = SLURM_ERROR; } else { /* resp.msg_type == PERSIST_RC */ persist_rc_msg_t *msg = resp.data; *resp_code = msg->rc; if (msg->rc != SLURM_SUCCESS && msg->rc != ACCOUNTING_FIRST_REG && msg->rc != ACCOUNTING_TRES_CHANGE_DB && msg->rc != ACCOUNTING_NODES_CHANGE_DB) { char *comment = msg->comment; if (!comment) comment = slurm_strerror(msg->rc); if (msg->ret_info == DBD_REGISTER_CTLD && slurm_get_accounting_storage_enforce()) { error("slurmdbd: Issue with call " "%s(%u): %u(%s)", slurmdbd_msg_type_2_str( msg->ret_info, 1), msg->ret_info, msg->rc, comment); fatal("You need to add this cluster " "to accounting if you want to " "enforce associations, or no " "jobs will ever run."); } else debug("slurmdbd: Issue with call " "%s(%u): %u(%s)", slurmdbd_msg_type_2_str( msg->ret_info, 1), msg->ret_info, msg->rc, comment); } slurm_persist_free_rc_msg(msg); } return rc; }
extern int slurm_persist_conn_process_msg(slurm_persist_conn_t *persist_conn, persist_msg_t *persist_msg, char *msg_char, uint32_t msg_size, Buf *out_buffer, bool first) { int rc; Buf recv_buffer = NULL; char *comment = NULL; /* puts msg_char into buffer struct */ recv_buffer = create_buf(msg_char, msg_size); memset(persist_msg, 0, sizeof(persist_msg_t)); rc = slurm_persist_msg_unpack(persist_conn, persist_msg, recv_buffer); xfer_buf_data(recv_buffer); /* delete in_buffer struct * without xfree of msg_char * (done later in this * function). */ if (rc != SLURM_SUCCESS) { comment = xstrdup_printf("Failed to unpack %s message", slurmdbd_msg_type_2_str( persist_msg->msg_type, true)); error("CONN:%u %s", persist_conn->fd, comment); *out_buffer = slurm_persist_make_rc_msg( persist_conn, rc, comment, persist_msg->msg_type); xfree(comment); } /* 2 versions after 17.02 code refering to DBD_INIT can be removed as it will no longer be suppported. */ else if (first && (persist_msg->msg_type != REQUEST_PERSIST_INIT) && (persist_msg->msg_type != DBD_INIT)) { comment = "Initial RPC not REQUEST_PERSIST_INIT"; error("CONN:%u %s type (%d)", persist_conn->fd, comment, persist_msg->msg_type); rc = EINVAL; *out_buffer = slurm_persist_make_rc_msg( persist_conn, rc, comment, REQUEST_PERSIST_INIT); } else if (!first && ((persist_msg->msg_type == REQUEST_PERSIST_INIT) || (persist_msg->msg_type == DBD_INIT))) { comment = "REQUEST_PERSIST_INIT sent after connection established"; error("CONN:%u %s", persist_conn->fd, comment); rc = EINVAL; *out_buffer = slurm_persist_make_rc_msg( persist_conn, rc, comment, REQUEST_PERSIST_INIT); } return rc; }
/* * set_usage_information - set time and table information for getting usage * * OUT usage_table: which usage table to query * IN type: usage type to get * IN/OUT usage_start: start time * IN/OUT usage_end: end time * RET: error code */ extern int set_usage_information(char **usage_table, slurmdbd_msg_type_t type, time_t *usage_start, time_t *usage_end) { time_t start = (*usage_start), end = (*usage_end); time_t my_time = time(NULL); struct tm start_tm; struct tm end_tm; char *my_usage_table = (*usage_table); /* Default is going to be the last day */ if (!end) { if (!slurm_localtime_r(&my_time, &end_tm)) { error("Couldn't get localtime from end %ld", my_time); return SLURM_ERROR; } end_tm.tm_hour = 0; } else { if (!slurm_localtime_r(&end, &end_tm)) { error("Couldn't get localtime from user end %ld", end); return SLURM_ERROR; } } end_tm.tm_sec = 0; end_tm.tm_min = 0; end = slurm_mktime(&end_tm); if (!start) { if (!slurm_localtime_r(&my_time, &start_tm)) { error("Couldn't get localtime from start %ld", my_time); return SLURM_ERROR; } start_tm.tm_hour = 0; start_tm.tm_mday--; } else { if (!slurm_localtime_r(&start, &start_tm)) { error("Couldn't get localtime from user start %ld", start); return SLURM_ERROR; } } start_tm.tm_sec = 0; start_tm.tm_min = 0; start = slurm_mktime(&start_tm); if (end-start < 3600) { end = start + 3600; if (!slurm_localtime_r(&end, &end_tm)) { error("2 Couldn't get localtime from user end %ld", end); return SLURM_ERROR; } } /* check to see if we are off day boundaries or on month * boundaries other wise use the day table. */ //info("%d %d %d", start_tm.tm_hour, end_tm.tm_hour, end-start); if (start_tm.tm_hour || end_tm.tm_hour || (end-start < 86400) || (end > my_time)) { switch (type) { case DBD_GET_ASSOC_USAGE: my_usage_table = assoc_hour_table; break; case DBD_GET_WCKEY_USAGE: my_usage_table = wckey_hour_table; break; case DBD_GET_CLUSTER_USAGE: my_usage_table = cluster_hour_table; break; default: error("Bad type given for hour usage %d %s", type, slurmdbd_msg_type_2_str(type, 1)); break; } } else if (start_tm.tm_mday == 1 && end_tm.tm_mday == 1 && (end-start > 86400)) { switch (type) { case DBD_GET_ASSOC_USAGE: my_usage_table = assoc_month_table; break; case DBD_GET_WCKEY_USAGE: my_usage_table = wckey_month_table; break; case DBD_GET_CLUSTER_USAGE: my_usage_table = cluster_month_table; break; default: error("Bad type given for month usage %d %s", type, slurmdbd_msg_type_2_str(type, 1)); break; } } (*usage_start) = start; (*usage_end) = end; (*usage_table) = my_usage_table; return SLURM_SUCCESS; }
extern List as_mysql_get_txn(mysql_conn_t *mysql_conn, uid_t uid, slurmdb_txn_cond_t *txn_cond) { char *query = NULL; char *assoc_extra = NULL; char *name_extra = NULL; char *extra = NULL; char *tmp = NULL; List txn_list = NULL; ListIterator itr = NULL; char *object = NULL; int set = 0; int i=0; MYSQL_RES *result = NULL; MYSQL_ROW row; List use_cluster_list = as_mysql_cluster_list; bool locked = 0; /* if this changes you will need to edit the corresponding enum */ char *txn_req_inx[] = { "id", "timestamp", "action", "name", "actor", "info", "cluster" }; enum { TXN_REQ_ID, TXN_REQ_TS, TXN_REQ_ACTION, TXN_REQ_NAME, TXN_REQ_ACTOR, TXN_REQ_INFO, TXN_REQ_CLUSTER, TXN_REQ_COUNT }; if (check_connection(mysql_conn) != SLURM_SUCCESS) return NULL; if (!txn_cond) goto empty; /* handle query for associations first */ if (txn_cond->acct_list && list_count(txn_cond->acct_list)) { set = 0; if (assoc_extra) xstrcat(assoc_extra, " && ("); else xstrcat(assoc_extra, " where ("); if (name_extra) xstrcat(name_extra, " && ("); else xstrcat(name_extra, " ("); itr = list_iterator_create(txn_cond->acct_list); while ((object = list_next(itr))) { if (set) { xstrcat(assoc_extra, " || "); xstrcat(name_extra, " || "); } xstrfmtcat(assoc_extra, "acct='%s'", object); xstrfmtcat(name_extra, "(name like '%%\\'%s\\'%%'" " || name='%s')" " || (info like '%%acct=\\'%s\\'%%')", object, object, object); set = 1; } list_iterator_destroy(itr); xstrcat(assoc_extra, ")"); xstrcat(name_extra, ")"); } if (txn_cond->cluster_list && list_count(txn_cond->cluster_list)) { set = 0; if (name_extra) xstrcat(name_extra, " && ("); else xstrcat(name_extra, "("); itr = list_iterator_create(txn_cond->cluster_list); while ((object = list_next(itr))) { if (set) { xstrcat(name_extra, " || "); } xstrfmtcat(name_extra, "(cluster='%s' || " "name like '%%\\'%s\\'%%' || name='%s')" " || (info like '%%cluster=\\'%s\\'%%')", object, object, object, object); set = 1; } list_iterator_destroy(itr); xstrcat(name_extra, ")"); use_cluster_list = txn_cond->cluster_list; } if (txn_cond->user_list && list_count(txn_cond->user_list)) { set = 0; if (assoc_extra) xstrcat(assoc_extra, " && ("); else xstrcat(assoc_extra, " where ("); if (name_extra) xstrcat(name_extra, " && ("); else xstrcat(name_extra, "("); itr = list_iterator_create(txn_cond->user_list); while ((object = list_next(itr))) { if (set) { xstrcat(assoc_extra, " || "); xstrcat(name_extra, " || "); } xstrfmtcat(assoc_extra, "user='******'", object); xstrfmtcat(name_extra, "(name like '%%\\'%s\\'%%'" " || name='%s')" " || (info like '%%user=\\'%s\\'%%')", object, object, object); set = 1; } list_iterator_destroy(itr); xstrcat(assoc_extra, ")"); xstrcat(name_extra, ")"); } if (assoc_extra) { if (!locked && (use_cluster_list == as_mysql_cluster_list)) { slurm_mutex_lock(&as_mysql_cluster_list_lock); locked = 1; } itr = list_iterator_create(use_cluster_list); while ((object = list_next(itr))) { xstrfmtcat(query, "select id_assoc from \"%s_%s\"%s", object, assoc_table, assoc_extra); if (debug_flags & DEBUG_FLAG_DB_QUERY) DB_DEBUG(mysql_conn->conn, "query\n%s", query); if (!(result = mysql_db_query_ret( mysql_conn, query, 0))) { xfree(query); break; } xfree(query); if (mysql_num_rows(result)) { if (extra) xstrfmtcat(extra, " || (cluster='%s' && (", object); else xstrfmtcat(extra, " where (cluster='%s' && (", object); set = 0; while ((row = mysql_fetch_row(result))) { if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "(name like " "'%%id_assoc=%s %%' " "|| name like " "'%%id_assoc=%s)')", row[0], row[0]); set = 1; } xstrcat(extra, "))"); } mysql_free_result(result); } list_iterator_destroy(itr); xfree(assoc_extra); } if (name_extra) { if (extra) xstrfmtcat(extra, " && (%s)", name_extra); else xstrfmtcat(extra, " where (%s)", name_extra); xfree(name_extra); } /*******************************************/ if (txn_cond->action_list && list_count(txn_cond->action_list)) { set = 0; if (extra) xstrcat(extra, " && ("); else xstrcat(extra, " where ("); itr = list_iterator_create(txn_cond->action_list); while ((object = list_next(itr))) { if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "action='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (txn_cond->actor_list && list_count(txn_cond->actor_list)) { set = 0; if (extra) xstrcat(extra, " && ("); else xstrcat(extra, " where ("); itr = list_iterator_create(txn_cond->actor_list); while ((object = list_next(itr))) { if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "actor='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (txn_cond->id_list && list_count(txn_cond->id_list)) { set = 0; if (extra) xstrcat(extra, " && ("); else xstrcat(extra, " where ("); itr = list_iterator_create(txn_cond->id_list); while ((object = list_next(itr))) { char *ptr = NULL; long num = strtol(object, &ptr, 10); if ((num == 0) && ptr && ptr[0]) { error("Invalid value for txn id (%s)", object); xfree(extra); list_iterator_destroy(itr); goto end_it; } if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "id=%s", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (txn_cond->info_list && list_count(txn_cond->info_list)) { set = 0; if (extra) xstrcat(extra, " && ("); else xstrcat(extra, " where ("); itr = list_iterator_create(txn_cond->info_list); while ((object = list_next(itr))) { if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "info like '%%%s%%'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (txn_cond->name_list && list_count(txn_cond->name_list)) { set = 0; if (extra) xstrcat(extra, " && ("); else xstrcat(extra, " where ("); itr = list_iterator_create(txn_cond->name_list); while ((object = list_next(itr))) { if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "name like '%%%s%%'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (txn_cond->time_start && txn_cond->time_end) { if (extra) xstrcat(extra, " && ("); else xstrcat(extra, " where ("); xstrfmtcat(extra, "timestamp < %ld && timestamp >= %ld)", txn_cond->time_end, txn_cond->time_start); } else if (txn_cond->time_start) { if (extra) xstrcat(extra, " && ("); else xstrcat(extra, " where ("); xstrfmtcat(extra, "timestamp >= %ld)", txn_cond->time_start); } else if (txn_cond->time_end) { if (extra) xstrcat(extra, " && ("); else xstrcat(extra, " where ("); xstrfmtcat(extra, "timestamp < %ld)", txn_cond->time_end); } /* make sure we can get the max length out of the database * when grouping the names */ if (txn_cond->with_assoc_info) mysql_db_query(mysql_conn, "set session group_concat_max_len=65536;"); empty: if (!locked && (use_cluster_list == as_mysql_cluster_list)) { slurm_mutex_lock(&as_mysql_cluster_list_lock); locked = 1; } xfree(tmp); xstrfmtcat(tmp, "%s", txn_req_inx[i]); for(i=1; i<TXN_REQ_COUNT; i++) { xstrfmtcat(tmp, ", %s", txn_req_inx[i]); } query = xstrdup_printf("select %s from %s", tmp, txn_table); if (extra) { xstrfmtcat(query, "%s", extra); xfree(extra); } xstrcat(query, " order by timestamp;"); xfree(tmp); if (debug_flags & DEBUG_FLAG_DB_QUERY) DB_DEBUG(mysql_conn->conn, "query\n%s", query); if (!(result = mysql_db_query_ret( mysql_conn, query, 0))) { xfree(query); goto end_it; } xfree(query); txn_list = list_create(slurmdb_destroy_txn_rec); while ((row = mysql_fetch_row(result))) { slurmdb_txn_rec_t *txn = xmalloc(sizeof(slurmdb_txn_rec_t)); list_append(txn_list, txn); txn->action = slurm_atoul(row[TXN_REQ_ACTION]); txn->actor_name = xstrdup(row[TXN_REQ_ACTOR]); txn->id = slurm_atoul(row[TXN_REQ_ID]); txn->set_info = xstrdup(row[TXN_REQ_INFO]); txn->timestamp = slurm_atoul(row[TXN_REQ_TS]); txn->where_query = xstrdup(row[TXN_REQ_NAME]); txn->clusters = xstrdup(row[TXN_REQ_CLUSTER]); if (txn_cond && txn_cond->with_assoc_info && (txn->action == DBD_ADD_ASSOCS || txn->action == DBD_MODIFY_ASSOCS || txn->action == DBD_REMOVE_ASSOCS)) { MYSQL_RES *result2 = NULL; MYSQL_ROW row2; if (txn->clusters) { query = xstrdup_printf( "select " "group_concat(distinct user " "order by user), " "group_concat(distinct acct " "order by acct) " "from \"%s_%s\" where %s", txn->clusters, assoc_table, row[TXN_REQ_NAME]); debug4("%d(%s:%d) query\n%s", mysql_conn->conn, THIS_FILE, __LINE__, query); if (!(result2 = mysql_db_query_ret( mysql_conn, query, 0))) { xfree(query); continue; } xfree(query); if ((row2 = mysql_fetch_row(result2))) { if (row2[0] && row2[0][0]) txn->users = xstrdup(row2[0]); if (row2[1] && row2[1][0]) txn->accts = xstrdup(row2[1]); } mysql_free_result(result2); } else { error("We can't handle associations " "from action %s yet.", slurmdbd_msg_type_2_str(txn->action, 1)); } } } mysql_free_result(result); end_it: if (locked) slurm_mutex_unlock(&as_mysql_cluster_list_lock); return txn_list; }
extern int sacctmgr_list_txn(int argc, char *argv[]) { int rc = SLURM_SUCCESS; slurmdb_txn_cond_t *txn_cond = xmalloc(sizeof(slurmdb_txn_cond_t)); List txn_list = NULL; slurmdb_txn_rec_t *txn = NULL; int i=0; ListIterator itr = NULL; ListIterator itr2 = NULL; int field_count = 0; print_field_t *field = NULL; List format_list = list_create(slurm_destroy_char); List print_fields_list; /* types are of print_field_t */ for (i=0; i<argc; i++) { int command_len = strlen(argv[i]); if (!strncasecmp (argv[i], "Where", MAX(command_len, 5)) || !strncasecmp (argv[i], "Set", MAX(command_len, 3))) i++; _set_cond(&i, argc, argv, txn_cond, format_list); } if(exit_code) { slurmdb_destroy_txn_cond(txn_cond); list_destroy(format_list); return SLURM_ERROR; } if(!list_count(format_list)) { slurm_addto_char_list(format_list, "T,Action,Actor,Where,Info"); if(txn_cond->with_assoc_info) slurm_addto_char_list(format_list, "User,Account,Cluster"); } print_fields_list = sacctmgr_process_format_list(format_list); list_destroy(format_list); if(exit_code) { list_destroy(print_fields_list); return SLURM_ERROR; } txn_list = acct_storage_g_get_txn(db_conn, my_uid, txn_cond); slurmdb_destroy_txn_cond(txn_cond); if(!txn_list) { exit_code=1; fprintf(stderr, " Error with request: %s\n", slurm_strerror(errno)); list_destroy(print_fields_list); return SLURM_ERROR; } itr = list_iterator_create(txn_list); itr2 = list_iterator_create(print_fields_list); print_fields_header(print_fields_list); field_count = list_count(print_fields_list); while((txn = list_next(itr))) { int curr_inx = 1; while((field = list_next(itr2))) { switch(field->type) { case PRINT_ACCT: field->print_routine(field, txn->accts, (curr_inx == field_count)); break; case PRINT_ACTIONRAW: field->print_routine( field, txn->action, (curr_inx == field_count)); break; case PRINT_ACTION: field->print_routine( field, slurmdbd_msg_type_2_str(txn->action, 0), (curr_inx == field_count)); break; case PRINT_ACTOR: field->print_routine(field, txn->actor_name, (curr_inx == field_count)); break; case PRINT_CLUSTER: field->print_routine(field, txn->clusters, (curr_inx == field_count)); break; case PRINT_ID: field->print_routine(field, txn->id, (curr_inx == field_count)); break; case PRINT_INFO: field->print_routine(field, txn->set_info, (curr_inx == field_count)); break; case PRINT_TS: field->print_routine(field, txn->timestamp, (curr_inx == field_count)); break; case PRINT_USER: field->print_routine(field, txn->users, (curr_inx == field_count)); break; case PRINT_WHERE: field->print_routine(field, txn->where_query, (curr_inx == field_count)); break; default: field->print_routine(field, NULL, (curr_inx == field_count)); break; } curr_inx++; } list_iterator_reset(itr2); printf("\n"); } list_iterator_destroy(itr2); list_iterator_destroy(itr); list_destroy(txn_list); list_destroy(print_fields_list); return rc; }
static int _handle_mult_rc_ret(void) { Buf buffer; uint16_t msg_type; persist_rc_msg_t *msg = NULL; dbd_list_msg_t *list_msg = NULL; int rc = SLURM_ERROR; Buf out_buf = NULL; buffer = slurm_persist_recv_msg(slurmdbd_conn); if (buffer == NULL) return rc; safe_unpack16(&msg_type, buffer); switch (msg_type) { case DBD_GOT_MULT_MSG: if (slurmdbd_unpack_list_msg( &list_msg, slurmdbd_conn->version, DBD_GOT_MULT_MSG, buffer) != SLURM_SUCCESS) { error("slurmdbd: unpack message error"); break; } slurm_mutex_lock(&agent_lock); if (agent_list) { ListIterator itr = list_iterator_create(list_msg->my_list); while ((out_buf = list_next(itr))) { Buf b; if ((rc = _unpack_return_code( slurmdbd_conn->version, out_buf)) != SLURM_SUCCESS) break; if ((b = list_dequeue(agent_list))) { free_buf(b); } else { error("slurmdbd: DBD_GOT_MULT_MSG " "unpack message error"); } } list_iterator_destroy(itr); } slurm_mutex_unlock(&agent_lock); slurmdbd_free_list_msg(list_msg); break; case PERSIST_RC: if (slurm_persist_unpack_rc_msg( &msg, buffer, slurmdbd_conn->version) == SLURM_SUCCESS) { rc = msg->rc; if (rc != SLURM_SUCCESS) { if (msg->ret_info == DBD_REGISTER_CTLD && slurm_get_accounting_storage_enforce()) { error("slurmdbd: PERSIST_RC is %d from " "%s(%u): %s", rc, slurmdbd_msg_type_2_str( msg->ret_info, 1), msg->ret_info, msg->comment); fatal("You need to add this cluster " "to accounting if you want to " "enforce associations, or no " "jobs will ever run."); } else debug("slurmdbd: PERSIST_RC is %d from " "%s(%u): %s", rc, slurmdbd_msg_type_2_str( msg->ret_info, 1), msg->ret_info, msg->comment); } slurm_persist_free_rc_msg(msg); } else error("slurmdbd: unpack message error"); break; default: error("slurmdbd: bad message type %d != PERSIST_RC", msg_type); } unpack_error: free_buf(buffer); return rc; }
/* Send an RPC to the SlurmDBD. Do not wait for the reply. The RPC * will be queued and processed later if the SlurmDBD is not responding. * NOTE: slurm_open_slurmdbd_conn() must have been called with callbacks set * * Returns SLURM_SUCCESS or an error code */ extern int send_slurmdbd_msg(uint16_t rpc_version, slurmdbd_msg_t *req) { Buf buffer; int cnt, rc = SLURM_SUCCESS; static time_t syslog_time = 0; static int max_agent_queue = 0; /* * Whatever our max job count is multiplied by 2 plus node count * multiplied by 4 or MAX_AGENT_QUEUE which ever is bigger. */ if (!max_agent_queue) max_agent_queue = MAX(MAX_AGENT_QUEUE, ((slurmctld_conf.max_job_cnt * 2) + (node_record_count * 4))); buffer = slurm_persist_msg_pack( slurmdbd_conn, (persist_msg_t *)req); if (!buffer) /* pack error */ return SLURM_ERROR; slurm_mutex_lock(&agent_lock); if ((agent_tid == 0) || (agent_list == NULL)) { _create_agent(); if ((agent_tid == 0) || (agent_list == NULL)) { slurm_mutex_unlock(&agent_lock); free_buf(buffer); return SLURM_ERROR; } } cnt = list_count(agent_list); if ((cnt >= (max_agent_queue / 2)) && (difftime(time(NULL), syslog_time) > 120)) { /* Record critical error every 120 seconds */ syslog_time = time(NULL); error("slurmdbd: agent queue filling (%d), RESTART SLURMDBD NOW", cnt); syslog(LOG_CRIT, "*** RESTART SLURMDBD NOW ***"); if (slurmdbd_conn->trigger_callbacks.dbd_fail) (slurmdbd_conn->trigger_callbacks.dbd_fail)(); } if (cnt == (max_agent_queue - 1)) cnt -= _purge_step_req(); if (cnt == (max_agent_queue - 1)) cnt -= _purge_job_start_req(); if (cnt < max_agent_queue) { if (list_enqueue(agent_list, buffer) == NULL) fatal("list_enqueue: memory allocation failure"); } else { error("slurmdbd: agent queue is full (%u), discarding %s:%u request", cnt, slurmdbd_msg_type_2_str(req->msg_type, 1), req->msg_type); if (slurmdbd_conn->trigger_callbacks.acct_full) (slurmdbd_conn->trigger_callbacks.acct_full)(); free_buf(buffer); rc = SLURM_ERROR; } slurm_cond_broadcast(&agent_cond); slurm_mutex_unlock(&agent_lock); return rc; }
extern int unpack_slurmdbd_msg(slurmdbd_msg_t *resp, uint16_t rpc_version, Buf buffer) { int rc = SLURM_SUCCESS; slurm_msg_t msg; safe_unpack16(&resp->msg_type, buffer); if (rpc_version < SLURM_MIN_PROTOCOL_VERSION) { error("slurmdbd: Invalid message version=%hu, type:%hu", rpc_version, resp->msg_type); return SLURM_ERROR; } switch (resp->msg_type) { case PERSIST_RC: slurm_msg_t_init(&msg); msg.protocol_version = rpc_version; msg.msg_type = resp->msg_type; rc = unpack_msg(&msg, buffer); resp->data = msg.data; break; case REQUEST_PERSIST_INIT: resp->data = xmalloc(sizeof(slurm_msg_t)); slurm_msg_t_init(resp->data); rc = slurm_unpack_received_msg( (slurm_msg_t *)resp->data, 0, buffer); break; case DBD_ADD_ACCOUNTS: case DBD_ADD_TRES: case DBD_ADD_ASSOCS: case DBD_ADD_CLUSTERS: case DBD_ADD_FEDERATIONS: case DBD_ADD_RES: case DBD_ADD_USERS: case DBD_GOT_ACCOUNTS: case DBD_GOT_TRES: case DBD_GOT_ASSOCS: case DBD_GOT_CLUSTERS: case DBD_GOT_EVENTS: case DBD_GOT_FEDERATIONS: case DBD_GOT_JOBS: case DBD_GOT_LIST: case DBD_GOT_PROBS: case DBD_ADD_QOS: case DBD_GOT_QOS: case DBD_GOT_RESVS: case DBD_GOT_RES: case DBD_ADD_WCKEYS: case DBD_GOT_WCKEYS: case DBD_GOT_TXN: case DBD_GOT_USERS: case DBD_GOT_CONFIG: case DBD_SEND_MULT_JOB_START: case DBD_GOT_MULT_JOB_START: case DBD_SEND_MULT_MSG: case DBD_GOT_MULT_MSG: case DBD_FIX_RUNAWAY_JOB: rc = slurmdbd_unpack_list_msg( (dbd_list_msg_t **)&resp->data, rpc_version, resp->msg_type, buffer); break; case DBD_ADD_ACCOUNT_COORDS: case DBD_REMOVE_ACCOUNT_COORDS: rc = _unpack_acct_coord_msg( (dbd_acct_coord_msg_t **)&resp->data, rpc_version, buffer); break; case DBD_ARCHIVE_LOAD: rc = slurmdb_unpack_archive_rec( &resp->data, rpc_version, buffer); break; case DBD_CLUSTER_TRES: case DBD_FLUSH_JOBS: rc = _unpack_cluster_tres_msg( (dbd_cluster_tres_msg_t **)&resp->data, rpc_version, buffer); break; case DBD_GET_ACCOUNTS: case DBD_GET_TRES: case DBD_GET_ASSOCS: case DBD_GET_CLUSTERS: case DBD_GET_EVENTS: case DBD_GET_FEDERATIONS: case DBD_GET_JOBS_COND: case DBD_GET_PROBS: case DBD_GET_QOS: case DBD_GET_RESVS: case DBD_GET_RES: case DBD_GET_TXN: case DBD_GET_USERS: case DBD_GET_WCKEYS: case DBD_REMOVE_ACCOUNTS: case DBD_REMOVE_ASSOCS: case DBD_REMOVE_CLUSTERS: case DBD_REMOVE_FEDERATIONS: case DBD_REMOVE_QOS: case DBD_REMOVE_RES: case DBD_REMOVE_WCKEYS: case DBD_REMOVE_USERS: case DBD_ARCHIVE_DUMP: rc = _unpack_cond_msg( (dbd_cond_msg_t **)&resp->data, rpc_version, resp->msg_type, buffer); break; case DBD_GET_ASSOC_USAGE: case DBD_GOT_ASSOC_USAGE: case DBD_GET_CLUSTER_USAGE: case DBD_GOT_CLUSTER_USAGE: case DBD_GET_WCKEY_USAGE: case DBD_GOT_WCKEY_USAGE: rc = slurmdbd_unpack_usage_msg( (dbd_usage_msg_t **)&resp->data, rpc_version, resp->msg_type, buffer); break; case DBD_FINI: rc = slurmdbd_unpack_fini_msg((dbd_fini_msg_t **)&resp->data, rpc_version, buffer); break; case DBD_JOB_COMPLETE: rc = _unpack_job_complete_msg( (dbd_job_comp_msg_t **)&resp->data, rpc_version, buffer); break; case DBD_JOB_START: rc = _unpack_job_start_msg( &resp->data, rpc_version, buffer); break; case DBD_ID_RC: rc = slurmdbd_unpack_id_rc_msg( &resp->data, rpc_version, buffer); break; case DBD_JOB_SUSPEND: rc = _unpack_job_suspend_msg( (dbd_job_suspend_msg_t **)&resp->data, rpc_version, buffer); break; case DBD_MODIFY_ACCOUNTS: case DBD_MODIFY_ASSOCS: case DBD_MODIFY_CLUSTERS: case DBD_MODIFY_FEDERATIONS: case DBD_MODIFY_JOB: case DBD_MODIFY_QOS: case DBD_MODIFY_RES: case DBD_MODIFY_USERS: rc = _unpack_modify_msg( (dbd_modify_msg_t **)&resp->data, rpc_version, resp->msg_type, buffer); break; case DBD_NODE_STATE: rc = _unpack_node_state_msg( (dbd_node_state_msg_t **)&resp->data, rpc_version, buffer); break; case DBD_STEP_COMPLETE: rc = _unpack_step_complete_msg( (dbd_step_comp_msg_t **)&resp->data, rpc_version, buffer); break; case DBD_STEP_START: rc = _unpack_step_start_msg( (dbd_step_start_msg_t **)&resp->data, rpc_version, buffer); break; case DBD_REGISTER_CTLD: rc = _unpack_register_ctld_msg( (dbd_register_ctld_msg_t **)&resp->data, rpc_version, buffer); break; case DBD_ROLL_USAGE: rc = _unpack_roll_usage_msg( (dbd_roll_usage_msg_t **)&resp->data, rpc_version, buffer); break; case DBD_ADD_RESV: case DBD_REMOVE_RESV: case DBD_MODIFY_RESV: rc = _unpack_rec_msg( (dbd_rec_msg_t **)&resp->data, rpc_version, resp->msg_type, buffer); break; case DBD_GET_CONFIG: rc = _unpack_config_name( (char **)&resp->data, rpc_version, buffer); break; case DBD_RECONFIG: case DBD_GET_STATS: case DBD_CLEAR_STATS: case DBD_SHUTDOWN: /* No message to unpack */ break; case DBD_GOT_STATS: rc = slurmdb_unpack_stats_msg( (void **)&resp->data, rpc_version, buffer); break; default: error("slurmdbd: Invalid message type unpack %u(%s)", resp->msg_type, slurmdbd_msg_type_2_str(resp->msg_type, 1)); return SLURM_ERROR; } return rc; unpack_error: return SLURM_ERROR; }
extern Buf pack_slurmdbd_msg(slurmdbd_msg_t *req, uint16_t rpc_version) { Buf buffer; if (rpc_version < SLURM_MIN_PROTOCOL_VERSION) { error("slurmdbd: Invalid message version=%hu, type:%hu", rpc_version, req->msg_type); return NULL; } buffer = init_buf(MAX_DBD_MSG_LEN); pack16(req->msg_type, buffer); switch (req->msg_type) { case REQUEST_PERSIST_INIT: slurm_persist_pack_init_req_msg(req->data, buffer); break; case PERSIST_RC: slurm_persist_pack_rc_msg(req->data, buffer, rpc_version); break; case DBD_ADD_ACCOUNTS: case DBD_ADD_TRES: case DBD_ADD_ASSOCS: case DBD_ADD_CLUSTERS: case DBD_ADD_FEDERATIONS: case DBD_ADD_RES: case DBD_ADD_USERS: case DBD_GOT_ACCOUNTS: case DBD_GOT_TRES: case DBD_GOT_ASSOCS: case DBD_GOT_CLUSTERS: case DBD_GOT_EVENTS: case DBD_GOT_FEDERATIONS: case DBD_GOT_JOBS: case DBD_GOT_LIST: case DBD_GOT_PROBS: case DBD_GOT_RES: case DBD_ADD_QOS: case DBD_GOT_QOS: case DBD_GOT_RESVS: case DBD_ADD_WCKEYS: case DBD_GOT_WCKEYS: case DBD_GOT_TXN: case DBD_GOT_USERS: case DBD_GOT_CONFIG: case DBD_SEND_MULT_JOB_START: case DBD_GOT_MULT_JOB_START: case DBD_SEND_MULT_MSG: case DBD_GOT_MULT_MSG: case DBD_FIX_RUNAWAY_JOB: slurmdbd_pack_list_msg( (dbd_list_msg_t *)req->data, rpc_version, req->msg_type, buffer); break; case DBD_ADD_ACCOUNT_COORDS: case DBD_REMOVE_ACCOUNT_COORDS: _pack_acct_coord_msg( (dbd_acct_coord_msg_t *)req->data, rpc_version, buffer); break; case DBD_ARCHIVE_LOAD: slurmdb_pack_archive_rec(req->data, rpc_version, buffer); break; case DBD_CLUSTER_TRES: case DBD_FLUSH_JOBS: _pack_cluster_tres_msg( (dbd_cluster_tres_msg_t *)req->data, rpc_version, buffer); break; case DBD_GET_ACCOUNTS: case DBD_GET_TRES: case DBD_GET_ASSOCS: case DBD_GET_CLUSTERS: case DBD_GET_EVENTS: case DBD_GET_FEDERATIONS: case DBD_GET_JOBS_COND: case DBD_GET_PROBS: case DBD_GET_QOS: case DBD_GET_RESVS: case DBD_GET_RES: case DBD_GET_TXN: case DBD_GET_USERS: case DBD_GET_WCKEYS: case DBD_REMOVE_ACCOUNTS: case DBD_REMOVE_ASSOCS: case DBD_REMOVE_CLUSTERS: case DBD_REMOVE_FEDERATIONS: case DBD_REMOVE_QOS: case DBD_REMOVE_RES: case DBD_REMOVE_WCKEYS: case DBD_REMOVE_USERS: case DBD_ARCHIVE_DUMP: _pack_cond_msg( (dbd_cond_msg_t *)req->data, rpc_version, req->msg_type, buffer); break; case DBD_GET_ASSOC_USAGE: case DBD_GOT_ASSOC_USAGE: case DBD_GET_CLUSTER_USAGE: case DBD_GOT_CLUSTER_USAGE: case DBD_GET_WCKEY_USAGE: case DBD_GOT_WCKEY_USAGE: slurmdbd_pack_usage_msg( (dbd_usage_msg_t *)req->data, rpc_version, req->msg_type, buffer); break; case DBD_FINI: slurmdbd_pack_fini_msg((dbd_fini_msg_t *)req->data, rpc_version, buffer); break; case DBD_JOB_COMPLETE: _pack_job_complete_msg((dbd_job_comp_msg_t *)req->data, rpc_version, buffer); break; case DBD_JOB_START: _pack_job_start_msg(req->data, rpc_version, buffer); break; case DBD_ID_RC: slurmdbd_pack_id_rc_msg(req->data, rpc_version, buffer); break; case DBD_JOB_SUSPEND: _pack_job_suspend_msg( (dbd_job_suspend_msg_t *)req->data, rpc_version, buffer); break; case DBD_MODIFY_ACCOUNTS: case DBD_MODIFY_ASSOCS: case DBD_MODIFY_CLUSTERS: case DBD_MODIFY_FEDERATIONS: case DBD_MODIFY_JOB: case DBD_MODIFY_QOS: case DBD_MODIFY_RES: case DBD_MODIFY_USERS: _pack_modify_msg( (dbd_modify_msg_t *)req->data, rpc_version, req->msg_type, buffer); break; case DBD_NODE_STATE: _pack_node_state_msg( (dbd_node_state_msg_t *)req->data, rpc_version, buffer); break; case DBD_STEP_COMPLETE: _pack_step_complete_msg( (dbd_step_comp_msg_t *)req->data, rpc_version, buffer); break; case DBD_STEP_START: _pack_step_start_msg((dbd_step_start_msg_t *)req->data, rpc_version, buffer); break; case DBD_REGISTER_CTLD: _pack_register_ctld_msg( (dbd_register_ctld_msg_t *)req->data, rpc_version, buffer); break; case DBD_ROLL_USAGE: _pack_roll_usage_msg((dbd_roll_usage_msg_t *)req->data, rpc_version, buffer); break; case DBD_ADD_RESV: case DBD_REMOVE_RESV: case DBD_MODIFY_RESV: _pack_rec_msg( (dbd_rec_msg_t *)req->data, rpc_version, req->msg_type, buffer); break; case DBD_GET_CONFIG: packstr((char *)req->data, buffer); break; case DBD_RECONFIG: case DBD_GET_STATS: case DBD_CLEAR_STATS: case DBD_SHUTDOWN: break; default: error("slurmdbd: Invalid message type pack %u(%s:%u)", req->msg_type, slurmdbd_msg_type_2_str(req->msg_type, 1), req->msg_type); free_buf(buffer); return NULL; } return buffer; }