예제 #1
0
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;
}
예제 #2
0
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;
}