Пример #1
0
static void alloc_monitor_ep(struct monitor_blocking_binding *b)
{
    struct capref retcap = NULL_CAP;
    errval_t err, reterr = SYS_ERR_OK;

    struct monitor_lmp_binding *lmpb =
        malloc(sizeof(struct monitor_lmp_binding));
    assert(lmpb != NULL);

    // setup our end of the binding
    err = monitor_client_lmp_accept(lmpb, get_default_waitset(),
                                    DEFAULT_LMP_BUF_WORDS);
    if (err_is_fail(err)) {
        free(lmpb);
        reterr = err_push(err, LIB_ERR_MONITOR_CLIENT_ACCEPT);
        goto out;
    }

    retcap = lmpb->chan.local_cap;
    monitor_server_init(&lmpb->b);

out:
    err = b->tx_vtbl.alloc_monitor_ep_response(b, NOP_CONT, reterr, retcap);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "failed to send alloc_monitor_ep_reply");
    }
}
Пример #2
0
/**
 * \brief Setup a new idc channel between monitor and domain
 *
 * \bug on error send message back to domain
 */
static void new_monitor_binding_request(struct monitor_binding *b, uintptr_t st)
{
    struct capref retcap = NULL_CAP;
    errval_t err, reterr = SYS_ERR_OK;

    struct monitor_lmp_binding *lmpb =
        malloc(sizeof(struct monitor_lmp_binding));
    assert(lmpb != NULL);

    // setup our end of the binding
    err = monitor_client_lmp_accept(lmpb, get_default_waitset(),
                                    DEFAULT_LMP_BUF_WORDS);
    if (err_is_fail(err)) {
        free(lmpb);
        reterr = err_push(err, LIB_ERR_MONITOR_CLIENT_ACCEPT);
        goto out;
    }

    retcap = lmpb->chan.local_cap;
    monitor_server_init(&lmpb->b);

out:
    new_monitor_binding_reply_cont(b, reterr, retcap, st);
}
Пример #3
0
errval_t monitor_client_setup(struct spawninfo *si)
{
    errval_t err;

    struct monitor_lmp_binding *b =
        malloc(sizeof(struct monitor_lmp_binding));
    assert(b != NULL);

    // setup our end of the binding
    err = monitor_client_lmp_accept(b, get_default_waitset(),
                                    DEFAULT_LMP_BUF_WORDS);
    if (err_is_fail(err)) {
        free(b);
        return err_push(err, LIB_ERR_MONITOR_CLIENT_ACCEPT);
    }

    // copy the endpoint cap to the recipient
    struct capref dest = {
        .cnode = si->rootcn,
        .slot  = ROOTCN_SLOT_MONITOREP,
    };

    err = cap_copy(dest, b->chan.local_cap);
    if (err_is_fail(err)) {
        // TODO: destroy binding
        return err_push(err, LIB_ERR_CAP_COPY);
    }

    // Copy the performance monitoring cap to all spawned processes.
    struct capref src;
    dest.cnode = si->taskcn;
    dest.slot = TASKCN_SLOT_PERF_MON;
    src.cnode = cnode_task;
    src.slot = TASKCN_SLOT_PERF_MON;
    err = cap_copy(dest, src);
    if (err_is_fail(err)) {
        return err_push(err, INIT_ERR_COPY_PERF_MON);
    }

    // copy our receive vtable to the binding
    monitor_server_init(&b->b);

    return SYS_ERR_OK;
}

errval_t monitor_client_setup_mem_serv(void)
{
    /* construct special-case LMP connection to mem_serv */
    static struct monitor_lmp_binding mcb;
    struct waitset *ws = get_default_waitset();
    errval_t err;

    err = monitor_client_lmp_accept(&mcb, ws, DEFAULT_LMP_BUF_WORDS);
    if(err_is_fail(err)) {
        USER_PANIC_ERR(err, "monitor_client_setup_mem_serv");
    }
    assert(err_is_ok(err));

    /* Send the cap for this endpoint to init, who will pass it to the monitor */
    err = lmp_ep_send0(cap_initep, 0, mcb.chan.local_cap);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "lmp_ep_send0 failed");
    }

    // copy our receive vtable to the binding
    monitor_server_init(&mcb.b);

    // XXX: handle messages (ie. block) until the monitor binding is ready
    while (capref_is_null(mcb.chan.remote_cap)) {
        err = event_dispatch(ws);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in event_dispatch waiting for mem_serv binding");
            return err_push(err, LIB_ERR_EVENT_DISPATCH);
        }
    }

    return SYS_ERR_OK;
}

/// Setup a dummy monitor binding that "sends" all requests to the local handlers
errval_t monitor_client_setup_monitor(void)
{
    monitor_loopback_init(&monitor_self_binding);
    monitor_server_init(&monitor_self_binding);
    set_monitor_binding(&monitor_self_binding);
    caplock_init(get_default_waitset());
    idc_init();
    // XXX: Need a waitset here or loopback won't work as expected
    // when binding to the ram_alloc service
    monitor_self_binding.mutex.equeue.waitset = get_default_waitset();

    return SYS_ERR_OK;
}