Пример #1
0
/*
 * Thread sends requests back to primary node.
 */
static void *
send_thread(void *arg)
{
	struct hast_resource *res = arg;
	struct nv *nvout;
	struct hio *hio;
	void *data;
	size_t length;

	for (;;) {
		pjdlog_debug(2, "send: Taking request.");
		QUEUE_TAKE(send, hio);
		reqlog(LOG_DEBUG, 2, -1, hio, "send: (%p) Got request: ", hio);
		nvout = nv_alloc();
		/* Copy sequence number. */
		nv_add_uint64(nvout, hio->hio_seq, "seq");
		switch (hio->hio_cmd) {
		case HIO_READ:
			if (hio->hio_error == 0) {
				data = hio->hio_data;
				length = hio->hio_length;
				break;
			}
			/*
			 * We send no data in case of an error.
			 */
			/* FALLTHROUGH */
		case HIO_DELETE:
		case HIO_FLUSH:
		case HIO_WRITE:
			data = NULL;
			length = 0;
			break;
		default:
			PJDLOG_ABORT("Unexpected command (cmd=%hhu).",
			    hio->hio_cmd);
		}
		if (hio->hio_error != 0)
			nv_add_int16(nvout, hio->hio_error, "error");
		if (hast_proto_send(res, res->hr_remoteout, nvout, data,
		    length) < 0) {
			secondary_exit(EX_TEMPFAIL, "Unable to send reply.");
		}
		nv_free(nvout);
		pjdlog_debug(2, "send: (%p) Moving request to the free queue.",
		    hio);
		hio_clear(hio);
		QUEUE_INSERT(free, hio);
	}
	/* NOTREACHED */
	return (NULL);
}
Пример #2
0
/*
 * Thread receives requests from the primary node.
 */
static void *
recv_thread(void *arg)
{
	struct hast_resource *res = arg;
	struct hio *hio;
	struct nv *nv;

	for (;;) {
		pjdlog_debug(2, "recv: Taking free request.");
		QUEUE_TAKE(free, hio);
		pjdlog_debug(2, "recv: (%p) Got request.", hio);
		if (hast_proto_recv_hdr(res->hr_remotein, &nv) < 0) {
			secondary_exit(EX_TEMPFAIL,
			    "Unable to receive request header");
		}
		if (requnpack(res, hio, nv) != 0) {
			nv_free(nv);
			pjdlog_debug(2,
			    "recv: (%p) Moving request to the send queue.",
			    hio);
			QUEUE_INSERT(send, hio);
			continue;
		}
		switch (hio->hio_cmd) {
		case HIO_READ:
			res->hr_stat_read++;
			break;
		case HIO_WRITE:
			res->hr_stat_write++;
			break;
		case HIO_DELETE:
			res->hr_stat_delete++;
			break;
		case HIO_FLUSH:
			res->hr_stat_flush++;
			break;
		case HIO_KEEPALIVE:
			break;
		default:
			PJDLOG_ABORT("Unexpected command (cmd=%hhu).",
			    hio->hio_cmd);
		}
		reqlog(LOG_DEBUG, 2, -1, hio,
		    "recv: (%p) Got request header: ", hio);
		if (hio->hio_cmd == HIO_KEEPALIVE) {
			nv_free(nv);
			pjdlog_debug(2,
			    "recv: (%p) Moving request to the free queue.",
			    hio);
			hio_clear(hio);
			QUEUE_INSERT(free, hio);
			continue;
		} else if (hio->hio_cmd == HIO_WRITE) {
			if (hast_proto_recv_data(res, res->hr_remotein, nv,
			    hio->hio_data, MAXPHYS) < 0) {
				secondary_exit(EX_TEMPFAIL,
				    "Unable to receive request data");
			}
		}
		nv_free(nv);
		pjdlog_debug(2, "recv: (%p) Moving request to the disk queue.",
		    hio);
		QUEUE_INSERT(disk, hio);
	}
	/* NOTREACHED */
	return (NULL);
}
Пример #3
0
/*
 * Thread receives requests from the primary node.
 */
static void *
recv_thread(void *arg)
{
	struct hast_resource *res = arg;
	struct hio *hio, *mshio;
	struct nv *nv;

	for (;;) {
		pjdlog_debug(2, "recv: Taking free request.");
		QUEUE_TAKE(free, hio);
		pjdlog_debug(2, "recv: (%p) Got request.", hio);
		if (hast_proto_recv_hdr(res->hr_remotein, &nv) == -1) {
			secondary_exit(EX_TEMPFAIL,
			    "Unable to receive request header");
		}
		if (requnpack(res, hio, nv) != 0) {
			nv_free(nv);
			pjdlog_debug(2,
			    "recv: (%p) Moving request to the send queue.",
			    hio);
			QUEUE_INSERT(send, hio);
			continue;
		}
		switch (hio->hio_cmd) {
		case HIO_READ:
			res->hr_stat_read++;
			break;
		case HIO_WRITE:
			res->hr_stat_write++;
			break;
		case HIO_DELETE:
			res->hr_stat_delete++;
			break;
		case HIO_FLUSH:
			res->hr_stat_flush++;
			break;
		case HIO_KEEPALIVE:
			break;
		default:
			PJDLOG_ABORT("Unexpected command (cmd=%hhu).",
			    hio->hio_cmd);
		}
		reqlog(LOG_DEBUG, 2, -1, hio,
		    "recv: (%p) Got request header: ", hio);
		if (hio->hio_cmd == HIO_KEEPALIVE) {
			nv_free(nv);
			pjdlog_debug(2,
			    "recv: (%p) Moving request to the free queue.",
			    hio);
			hio_clear(hio);
			QUEUE_INSERT(free, hio);
			continue;
		} else if (hio->hio_cmd == HIO_WRITE) {
			if (hast_proto_recv_data(res, res->hr_remotein, nv,
			    hio->hio_data, MAXPHYS) == -1) {
				secondary_exit(EX_TEMPFAIL,
				    "Unable to receive request data");
			}
			if (hio->hio_memsync) {
				/*
				 * For memsync requests we expect two replies.
				 * Clone the hio so we can handle both of them.
				 */
				pjdlog_debug(2, "recv: Taking free request.");
				QUEUE_TAKE(free, mshio);
				pjdlog_debug(2, "recv: (%p) Got request.",
				    mshio);
				hio_copy(hio, mshio);
				mshio->hio_error = 0;
				/*
				 * We want to keep 'memsync' tag only on the
				 * request going onto send queue (mshio).
				 */
				hio->hio_memsync = false;
				pjdlog_debug(2,
				    "recv: (%p) Moving memsync request to the send queue.",
				    mshio);
				QUEUE_INSERT(send, mshio);
			}
		}
		nv_free(nv);
		pjdlog_debug(2, "recv: (%p) Moving request to the disk queue.",
		    hio);
		QUEUE_INSERT(disk, hio);
	}
	/* NOTREACHED */
	return (NULL);
}