static errval_t bind_to_octopus(void)
{
    errval_t err;
    struct bind_state st = { .done = false };
    err = octopus_bind(name_serv_iref, bind_continuation, &st,
            get_default_waitset(), IDC_BIND_FLAG_RPC_CAP_TRANSFER);
    while (!st.done) {
        err = event_dispatch(get_default_waitset());
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "ev_disp in bind_to_octopus");
        }
    }

    return st.err;
}

size_t num_monitors_online(void)
{
    errval_t err;
    struct octopus_rpc_client *r = get_octopus_rpc_client();
    if (r == NULL) {
        err = bind_to_octopus();
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "bind_to_octopus");
            debug_printf("no connection to octopus, num_monitors=1\n");
            return 1;
        }
        r = get_octopus_rpc_client();
    }
    assert(r != NULL);

    char* buffer = NULL;
    errval_t error_code;
    octopus_trigger_id_t tid;

    char** names = NULL;
    size_t count = 0;

    static char* spawnds = "r'spawn.[0-9]+' { iref: _ }";
        err = r->vtbl.get_names(r, spawnds, NOP_TRIGGER, &buffer, &tid, &error_code);
    if (err_is_fail(err) || err_is_fail(error_code)) {
        err = err_push(err, SPAWN_ERR_FIND_SPAWNDS);
        goto out;
    }

    err = oct_parse_names(buffer, &names, &count);
    if (err_is_fail(err)) {
        goto out;
    }

out:
    free(buffer);
    oct_free_names(names, count);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "num_spawnds_online");
        debug_printf("error in octopus, setting num_monitors=1\n");
        return 1;
    }
    return count;
}
Exemple #2
0
/**
 * \brief Register with name service
 *
 * \param iface Name of interface to register
 * \param iref IREF to register
 */
errval_t nameservice_register(const char *iface, iref_t iref)
{
    errval_t err = SYS_ERR_OK;

    struct octopus_rpc_client *r = get_octopus_rpc_client();
    if (r == NULL) {
        return LIB_ERR_NAMESERVICE_NOT_BOUND;
    }

    // Format record
    static const char* format = "%s { iref: %d }";
    size_t len = snprintf(NULL, 0, format, iface, iref);
    char* record = malloc(len+1);
    if (record == NULL) {
        return LIB_ERR_MALLOC_FAIL;
    }
    snprintf(record, len+1, format, iface, iref);

    char* ret = NULL;
    octopus_trigger_id_t tid;
    errval_t error_code;
    err = r->vtbl.set(r, record, 0, NOP_TRIGGER, 0, &ret, &tid, &error_code);
    if (err_is_fail(err)) {
        goto out;
    }
    err = error_code;

out:
    free(record);
    return err;
}
Exemple #3
0
/**
 * \brief Retrieve interface references for incoming and outgoing characters
 *        as well as for configuration messages from octopus.
 */
static errval_t get_irefs(struct capref session_id, iref_t *in_iref,
                          iref_t *out_iref, iref_t *conf_iref)
{
    errval_t err;

    struct octopus_rpc_client *r = get_octopus_rpc_client();
    assert(r != NULL);

    char *record;
    errval_t error_code;
    octopus_trigger_id_t tid;
    err = r->vtbl.get_with_idcap(r, session_id, NOP_TRIGGER, &record, &tid,
                                 &error_code);
    if (err_is_fail(err)) {
        err_push(err, TERM_ERR_LOOKUP_SESSION_RECORD);
        goto out;
    }
    err = error_code;
    if (err_is_fail(err)) {
        err_push(err, TERM_ERR_LOOKUP_SESSION_RECORD);
        goto out;
    }

    TERM_DEBUG("Record retrieved from octopus: %s\n", record);

    int64_t session_oct;
    int64_t in_oct;
    int64_t out_oct;
    int64_t conf_oct;
    // oct_read can only parse 64-bit values, we need to parse the irefs as 64bit
    // then cast to 32bit
    err = oct_read(record, "_ { session_iref: %d, in_iref: %d, out_iref: %d, "
                   "conf_iref: %d }", &session_oct, &in_oct, &out_oct,
                    &conf_oct);
    //iref_t session_iref = (iref_t)session_oct;
    *in_iref = (iref_t)in_oct;
    *out_iref = (iref_t)out_oct;
    *conf_iref = (iref_t)conf_oct;
    if (err_is_fail(err)) {
        err_push(err, TERM_ERR_PARSE_SESSION_RECORD);
        goto out;
    }
    if ((*in_iref == NULL_IREF) || (*out_iref == NULL_IREF) ||
        (*conf_iref == NULL_IREF)) {
        err = TERM_ERR_PARSE_SESSION_RECORD;
        goto out;
    }

    TERM_DEBUG("Retrieved interface references from octopus. in_iref: %"
               PRIuIREF ", out_iref: %" PRIuIREF ", conf_iref: %" PRIuIREF
               "\n", *in_iref, *out_iref, *conf_iref);

out:
    free(record);
    return err;
}
Exemple #4
0
/**
 * \brief Retrieve interface references for incoming and outgoing characters
 *        as well as for configuration messages from octopus.
 */
static errval_t get_irefs(struct capref session_id, iref_t *in_iref,
                          iref_t *out_iref, iref_t *conf_iref)
{
    errval_t err;

    struct octopus_rpc_client *r = get_octopus_rpc_client();
    assert(r != NULL);

    char *record;
    errval_t error_code;
    octopus_trigger_id_t tid;
    err = r->vtbl.get_with_idcap(r, session_id, NOP_TRIGGER, &record, &tid,
                                 &error_code);
    if (err_is_fail(err)) {
        err_push(err, TERM_ERR_LOOKUP_SESSION_RECORD);
        goto out;
    }
    err = error_code;
    if (err_is_fail(err)) {
        err_push(err, TERM_ERR_LOOKUP_SESSION_RECORD);
        goto out;
    }

    TERM_DEBUG("Record retrieved from octopus: %s\n", record);

    iref_t session_iref;
    err = oct_read(record, "_ { session_iref: %d, in_iref: %d, out_iref: %d, "
                   "conf_iref: %d }", &session_iref, in_iref, out_iref,
                   conf_iref);
    if (err_is_fail(err)) {
        err_push(err, TERM_ERR_PARSE_SESSION_RECORD);
        goto out;
    }
    if ((*in_iref == NULL_IREF) || (*out_iref == NULL_IREF) ||
        (*conf_iref == NULL_IREF)) {
        err = TERM_ERR_PARSE_SESSION_RECORD;
        goto out;
    }

    TERM_DEBUG("Retrieved interface references from octopus. in_iref: %"
               PRIuIREF ", out_iref: %" PRIuIREF ", conf_iref: %" PRIuIREF
               "\n", *in_iref, *out_iref, *conf_iref);

out:
    free(record);
    return err;
}
/**
 * \brief registers a found symbol with octopus for later retrieval
 *
 * \param binary    the name of the binary
 * \param idx       index of the symbol to insert
 * \param symname   name of the symbol to insert
 * \param address   address of the sybol to insert
 *
 * \returns SYS_ERR_OK on success
 *          errval on error
 */
errval_t spawn_symval_register(const char *binary,
                               uint32_t idx,
                               const char *symname,
                               genvaddr_t address)
{

    errval_t err = SYS_ERR_OK;

    struct octopus_rpc_client *r = get_octopus_rpc_client();
    if (r == NULL) {
        return LIB_ERR_NAMESERVICE_NOT_BOUND;
    }

    if (symname[0] == '_') {
        symname++;
    }
    // Format record
    static const char* format = "%s.omp.%u { sym: %s, addr: %d }";
    size_t len = snprintf(NULL, 0, format, binary, idx, symname, address);
    char* record = malloc(len + 1);
    if (record == NULL) {
        return LIB_ERR_MALLOC_FAIL;
    }
    snprintf(record, len + 1, format, binary, idx, symname, address);
    // transform to lower case
    for (int i = 0; i < len; ++i) {
        if (record[i] >= 'A' && record[i] <= 'Z') {
            record[i] -= ('A' - 'a');
        }
    }

    char* ret = NULL;
    octopus_trigger_id_t tid;
    errval_t error_code;
    err = r->vtbl.set(r, record, 0, NOP_TRIGGER,
                      0, &ret, &tid, &error_code);
    if (err_is_fail(err)) {
        goto out;
    }
    err = error_code;

out: 
	free(record);
	
    return err;
}
Exemple #6
0
/**
 * \brief Non-blocking name service lookup
 *
 * \param iface     Name of the domain
 * \param retdomid  returns the Xeon Phi Domain ID
 */
errval_t domain_lookup(const char *iface,
                       xphi_dom_id_t *retdomid)
{
    errval_t err;

    struct octopus_rpc_client *r = get_octopus_rpc_client();
    if (r == NULL) {
        return LIB_ERR_NAMESERVICE_NOT_BOUND;
    }

    char* record = NULL;
    octopus_trigger_id_t tid;
    errval_t error_code;
    err = r->vtbl.get(r, iface, NOP_TRIGGER, &record, &tid, &error_code);
    if (err_is_fail(err)) {
        goto out;
    }
    err = error_code;
    if (err_is_fail(err)) {
        if (err_no(err) == OCT_ERR_NO_RECORD) {
            err = err_push(err, XEON_PHI_ERR_CLIENT_DOMAIN_VOID);
        }
        goto out;
    }

    xphi_dom_id_t domid = 0;
    err = oct_read(record, "_ { domid: %d }", &domid);
    if (err_is_fail(err) || domid == 0) {
        err = err_push(err, XEON_PHI_ERR_CLIENT_DOMAIN_VOID);
        goto out;
    }

    if (retdomid != NULL) {
        *retdomid = domid;
    }

    out: free(record);
    return err;
}
Exemple #7
0
/**
 * \brief Non-blocking name service lookup
 *
 * \param iface Name of interface for which to query name server
 * \param retiref Returns pointer to IREF on success
 */
errval_t nameservice_lookup(const char *iface, iref_t *retiref)
{
    errval_t err;

    struct octopus_rpc_client *r = get_octopus_rpc_client();
    if (r == NULL) {
        return LIB_ERR_NAMESERVICE_NOT_BOUND;
    }

    char* record = NULL;
    octopus_trigger_id_t tid;
    errval_t error_code;
    err = r->vtbl.get(r, iface, NOP_TRIGGER, &record, &tid, &error_code);
    if (err_is_fail(err)) {
        goto out;
    }
    err = error_code;
    if (err_is_fail(err)) {
        if (err_no(err) == OCT_ERR_NO_RECORD) {
            err = err_push(err, LIB_ERR_NAMESERVICE_UNKNOWN_NAME);
        }
        goto out;
    }

    uint64_t iref_number = 0;
    err = oct_read(record, "_ { iref: %d }", &iref_number);
    if (err_is_fail(err) || iref_number == 0) {
        err = err_push(err, LIB_ERR_NAMESERVICE_INVALID_NAME);
        goto out;
    }
    if (retiref != NULL) {
        *retiref = iref_number;
    }

out:
    free(record);
    return err;
}
/**
 * \brief executes a lookup query on octopus to obtain the symbol
 *
 * \param binary    name of the binary to query
 * \param idx       index of the symbol to query
 * \param ret_name  returns the name of the symbol
 * \param ret_addr  returns the address of the symbol
 *
 * \return
 */
errval_t spawn_symval_lookup(const char *binary,
                             uint32_t idx,
                             char **ret_name,
                             genvaddr_t *ret_addr)
{
    errval_t err;

    size_t len;

    len = snprintf(NULL, 0, "%s.omp.%"PRIu32, binary, idx);
    char *omp_entry = malloc(len+1);
    if (omp_entry == NULL) {
        return LIB_ERR_MALLOC_FAIL;
    }
    snprintf(omp_entry, len+1, "%s.omp.%"PRIu32, binary, idx);

    struct octopus_rpc_client *r = get_octopus_rpc_client();
    if (r == NULL) {
        return LIB_ERR_NAMESERVICE_NOT_BOUND;
    }

    // transform to lower case
    for (int i = 0; i < len; ++i) {
        if (omp_entry[i] >= 'A' && omp_entry[i] <= 'Z') {
            omp_entry[i] -= ('A' - 'a');
        }
    }

    char* record = NULL;
    octopus_trigger_id_t tid;
    errval_t error_code;
    err = r->vtbl.get(r, omp_entry, NOP_TRIGGER,
                      &record, &tid, &error_code);
    if (err_is_fail(err)) {
        goto out;
    }
    err = error_code;
    if (err_is_fail(err)) {
        if (err_no(err) == OCT_ERR_NO_RECORD) {
            err = err_push(err, LIB_ERR_NAMESERVICE_UNKNOWN_NAME);
        }
        goto out;
    }

    uint64_t addr = 0;
    char *symname = NULL;
    err = oct_read(record, "_ { sym: %s, addr: %d }", &symname, &addr);
    if (err_is_fail(err) || symname == NULL) {
        err = err_push(err, LIB_ERR_NAMESERVICE_INVALID_NAME);
        goto out;
    }
    if (ret_addr != NULL) {
        *ret_addr = addr;
    }
    if (ret_name != NULL) {
        *ret_name = strdup(symname);
    }

    out: free(record);
    free(omp_entry);
    return err;
}