Beispiel #1
0
/*
 * Invoked once on module load.
 *
 * This routine should return 0 on success, and -1 otherwise.
 */
int codegen_init(hsignature_t *sig)
{
    const char *url;
    hcfg_t *cfg;

    url = session_getcfg(CFGKEY_TARGET_URL);
    if (!url || url[0] == '\0') {
        session_error("Destination URL for"
                      " generated code objects not specified");
        return -1;
    }

    url = session_getcfg(CFGKEY_SERVER_URL);
    if (!url || url[0] == '\0') {
        session_error("Codegen server URL not specified");
        return -1;
    }

    sockfd = url_connect(url);
    if (sockfd == -1) {
        session_error("Invalid codegen server URL");
        return -1;
    }

    /* In the future, we should rewrite the code generator system to
     * avoid using hmesg_t types.  Until then, generate a fake
     * HMESG_SESSION message to maintain compatibility.
     */
    mesg = HMESG_INITIALIZER;

    hsignature_copy(&mesg.data.session.sig, sig);
    cfg = hcfg_alloc();
    hcfg_set(cfg, CFGKEY_SERVER_URL, session_getcfg(CFGKEY_SERVER_URL));
    hcfg_set(cfg, CFGKEY_TARGET_URL, session_getcfg(CFGKEY_TARGET_URL));
    hcfg_set(cfg, CFGKEY_REPLY_URL, session_getcfg(CFGKEY_REPLY_URL));
    hcfg_set(cfg, CFGKEY_SLAVE_LIST, session_getcfg(CFGKEY_SLAVE_LIST));
    hcfg_set(cfg, CFGKEY_SLAVE_PATH, session_getcfg(CFGKEY_SLAVE_PATH));
    mesg.data.session.cfg = cfg;

    mesg.type = HMESG_SESSION;
    mesg.status = HMESG_STATUS_REQ;
    if (mesg_send(sockfd, &mesg) < 1)
        return -1;

    if (mesg_recv(sockfd, &mesg) < 1)
        return -1;

    if (callback_generate(sockfd, codegen_callback) != 0) {
        session_error("Could not register callback for codegen plugin");
        return -1;
    }

    return 0;
}
Beispiel #2
0
int hcfg_deserialize(hcfg_t *cfg, char *buf)
{
    int count, total;
    unsigned int i, kcount, logsize;
    const char *key, *val;

    if (sscanf(buf, " hcfg:%u %u%n", &kcount, &logsize, &count) < 2)
        goto invalid;
    total = count;

    if (hash_resize(cfg, logsize) < 0)
        goto error;

    for (i = 0; i < kcount; ++i) {
        count = scanstr_serial(&key, buf + total);
        if (count < 0) goto invalid;
        total += count;

        count = scanstr_serial(&val, buf + total);
        if (count < 0) goto invalid;
        total += count;

        if (hcfg_set(cfg, key, val) < 0)
            goto error;
    }
    return total;

  invalid:
    errno = EINVAL;
  error:
    return -1;
}
char *harmony_setcfg(hdesc_t *hdesc, const char *key, const char *val)
{
    char *buf;
    int retval;

    if (hdesc->state < HARMONY_STATE_CONNECTED) {
        /* User must be preparing for a new session since we're not
         * connected yet.  Store the key/value pair in a local cache.
         */
        buf = stralloc( hcfg_get(hdesc->sess.cfg, key) );
        hcfg_set(hdesc->sess.cfg, key, val);
        return buf;
    }

    if (!key) {
        hdesc->errstr = "Invalid key string.";
        errno = EINVAL;
        return NULL;
    }

    buf = sprintf_alloc("%s=%s", key, val ? val : "");
    if (!buf) {
        hdesc->errstr = "Internal memory allocation error.";
        return NULL;
    }

    /* Prepare a Harmony message. */
    hmesg_scrub(&hdesc->mesg);
    hdesc->mesg.data.string = buf;

    retval = send_request(hdesc, HMESG_SETCFG);
    free(buf);

    if (retval < 0)
        return NULL;

    if (hdesc->mesg.status != HMESG_STATUS_OK) {
        hdesc->errstr = "Invalid message received from server.";
        errno = EINVAL;
        return NULL;
    }

    /* It is the user's responsibility to free this memory. */
    return stralloc(hdesc->mesg.data.string);
}
int harmony_join(hdesc_t *hdesc, const char *host, int port, const char *name)
{
    int i, perf_len;
    int apply_argv = (hdesc->state < HARMONY_STATE_CONNECTED);
    char *cfgval;

    /* Verify that we have *at least* one variable bound, and that
     * this descriptor isn't already associated with a tuning
     * session.
     */
    if (hdesc->ptr_len == 0) {
        hdesc->errstr = "No variables bound to Harmony session";
        errno = EINVAL;
        return -1;
    }

    if (hdesc->state >= HARMONY_STATE_READY) {
        hdesc->errstr = "Descriptor already joined with an existing session";
        errno = EINVAL;
        return -1;
    }

    if (hdesc->state == HARMONY_STATE_INIT) {
        hdesc->socket = tcp_connect(host, port);
        if (hdesc->socket < 0) {
            hdesc->errstr = "Error establishing TCP connection with server";
            return -1;
        }

        if (hdesc->id == NULL)
            hdesc->id = default_id(hdesc->socket);
        hdesc->state = HARMONY_STATE_CONNECTED;

        hdesc->sess.sig.name = stralloc(name);
        if (!hdesc->sess.sig.name) {
            hdesc->errstr = "Error allocating memory for signature name";
            return -1;
        }
    }

    /* Prepare a Harmony message. */
    hmesg_scrub(&hdesc->mesg);
    hdesc->mesg.data.join = HSIGNATURE_INITIALIZER;
    if (hsignature_copy(&hdesc->mesg.data.join, &hdesc->sess.sig) < 0) {
        hdesc->errstr = "Internal error copying signature data";
        return -1;
    }

    /* send the client registration message */
    if (send_request(hdesc, HMESG_JOIN) != 0)
        return -1;

    if (hdesc->mesg.status != HMESG_STATUS_OK) {
        hdesc->errstr = "Invalid message received";
        errno = EINVAL;
        return -1;
    }

    hsignature_fini(&hdesc->sess.sig);
    if (hsignature_copy(&hdesc->sess.sig, &hdesc->mesg.data.join) < 0) {
        hdesc->errstr = "Error copying received signature structure";
        return -1;
    }

    /* Apply argv configuration directives now, if necessary. */
    if (apply_argv) {
        for (i = 0; i < hdesc->cmd_len; ++i) {
            char *key, *val, *cpy;
            cpy = stralloc(hdesc->cmd[i]);
            if (hcfg_parse(cpy, &key, &val)) {
                /* This should never fail, but just in case. */
                hdesc->errstr = "Error parsing argv config directive.";
                return -1;
            }
            if (hcfg_set(hdesc->sess.cfg, key, val)) {
                hdesc->errstr = "Error applying argv config directive.";
                return -1;
            }
            free(cpy);
        }
    }

    cfgval = harmony_getcfg(hdesc, CFGKEY_PERF_COUNT);
    if (cfgval) {
        perf_len = atoi(cfgval);
        if (perf_len < 1) {
            hdesc->errstr = "Invalid value for " CFGKEY_PERF_COUNT;
            return -1;
        }
        free(cfgval);
    }
    else {
        perf_len = DEFAULT_PERF_COUNT;
    }

    hdesc->perf = hperf_alloc(perf_len);
    if (!hdesc->perf) {
        hdesc->errstr = "Error allocating performance array.";
        return -1;
    }

    hdesc->state = HARMONY_STATE_READY;
    return 0;
}
int harmony_launch(hdesc_t *hdesc, const char *host, int port)
{
    int i;

    /* Sanity check input */
    if (hdesc->sess.sig.range_len < 1) {
        hdesc->errstr = "No tuning variables defined";
        errno = EINVAL;
        return -1;
    }

    if (!host && !getenv("HARMONY_S_HOST")) {
        char *path;
        const char *home;

        /* Provide a default name, if one isn't defined. */
        if (!hdesc->sess.sig.name) {
            if (hsignature_name(&hdesc->sess.sig, "NONAME"))
                return -1;
        }

        /* Find the Active Harmony installation. */
        home = getenv("HARMONY_HOME");
        if (!home) {
            hdesc->errstr = "No host or HARMONY_HOME specified";
            return -1;
        }

        if (hcfg_set(hdesc->sess.cfg, CFGKEY_HARMONY_HOME, home) != 0) {
            hdesc->errstr = "Could not set " CFGKEY_HARMONY_HOME;
            return -1;
        }

        /* Fork a local tuning session. */
        path = sprintf_alloc("%s/libexec/session-core", home);
        hdesc->socket = socket_launch(path, NULL, NULL);
        free(path);
    }
    else {
        hdesc->socket = tcp_connect(host, port);
    }

    if (hdesc->socket < 0) {
        hdesc->errstr = strerror(errno);
        return -1;
    }

    /* Prepare a default client id, if necessary. */
    if (hdesc->id == NULL)
        hdesc->id = default_id(hdesc->socket);
    hdesc->state = HARMONY_STATE_CONNECTED;

    /* Apply argv configuration directives now, if necessary. */
    for (i = 0; i < hdesc->cmd_len; ++i) {
        char *key, *val, *cpy;
        cpy = stralloc(hdesc->cmd[i]);
        if (hcfg_parse(cpy, &key, &val) == NULL) {
            /* This should never fail, but just in case. */
            hdesc->errstr = "Internal error parsing argv config directive.";
            return -1;
        }
        if (hcfg_set(hdesc->sess.cfg, key, val) != 0) {
            hdesc->errstr = "Internal error applying argv config directive.";
            return -1;
        }
        free(cpy);
    }

    /* Prepare a Harmony message. */
    hmesg_scrub(&hdesc->mesg);
    hsession_init(&hdesc->mesg.data.session);
    hsession_copy(&hdesc->mesg.data.session, &hdesc->sess);

    return send_request(hdesc, HMESG_SESSION);
}
int harmony_layer_list(hdesc_t *hdesc, const char *list)
{
    return hcfg_set(hdesc->sess.cfg, CFGKEY_SESSION_LAYERS, list);
}
int harmony_strategy(hdesc_t *hdesc, const char *strategy)
{
    return hcfg_set(hdesc->sess.cfg, CFGKEY_SESSION_STRATEGY, strategy);
}