/* * 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); }
/* * 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); }
/* * 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); }