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; }
static int _process_service_connection( slurm_persist_conn_t *persist_conn, void *arg) { uint32_t nw_size = 0, msg_size = 0, uid = NO_VAL; char *msg_char = NULL; ssize_t msg_read = 0, offset = 0; bool first = true, fini = false; Buf buffer = NULL; int rc = SLURM_SUCCESS; xassert(persist_conn->callback_proc); xassert(persist_conn->shutdown); debug2("Opened connection %d from %s", persist_conn->fd, persist_conn->rem_host); if (persist_conn->flags & PERSIST_FLAG_ALREADY_INITED) first = false; while (!(*persist_conn->shutdown) && !fini) { if (!_conn_readable(persist_conn)) break; /* problem with this socket */ msg_read = read(persist_conn->fd, &nw_size, sizeof(nw_size)); if (msg_read == 0) /* EOF */ break; if (msg_read != sizeof(nw_size)) { error("Could not read msg_size from " "connection %d(%s) uid(%d)", persist_conn->fd, persist_conn->rem_host, uid); break; } msg_size = ntohl(nw_size); if ((msg_size < 2) || (msg_size > MAX_MSG_SIZE)) { error("Invalid msg_size (%u) from " "connection %d(%s) uid(%d)", msg_size, persist_conn->fd, persist_conn->rem_host, uid); break; } msg_char = xmalloc(msg_size); offset = 0; while (msg_size > offset) { if (!_conn_readable(persist_conn)) break; /* problem with this socket */ msg_read = read(persist_conn->fd, (msg_char + offset), (msg_size - offset)); if (msg_read <= 0) { error("read(%d): %m", persist_conn->fd); break; } offset += msg_read; } if (msg_size == offset) { persist_msg_t msg; rc = slurm_persist_conn_process_msg( persist_conn, &msg, msg_char, msg_size, &buffer, first); if (rc == SLURM_SUCCESS) { rc = (persist_conn->callback_proc)( arg, &msg, &buffer, &uid); _persist_free_msg_members(persist_conn, &msg); if (rc != SLURM_SUCCESS && rc != ACCOUNTING_FIRST_REG && rc != ACCOUNTING_TRES_CHANGE_DB && rc != ACCOUNTING_NODES_CHANGE_DB) { error("Processing last message from " "connection %d(%s) uid(%d)", persist_conn->fd, persist_conn->rem_host, uid); if (rc == ESLURM_ACCESS_DENIED || rc == SLURM_PROTOCOL_VERSION_ERROR) fini = true; } } first = false; } else { buffer = slurm_persist_make_rc_msg( persist_conn, SLURM_ERROR, "Bad offset", 0); fini = true; } xfree(msg_char); if (buffer) { if (slurm_persist_send_msg(persist_conn, buffer) != SLURM_SUCCESS) { /* This is only an issue on persistent * connections, and really isn't that big of a * deal as the slurmctld will just send the * message again. */ if (persist_conn->rem_port) debug("Problem sending response to " "connection %d(%s) uid(%d)", persist_conn->fd, persist_conn->rem_host, uid); fini = true; } free_buf(buffer); } } debug2("Closed connection %d uid(%d)", persist_conn->fd, uid); return rc; }