Example #1
0
static void testWrongNumVbuckets(const char *fname) {
    VBUCKET_CONFIG_HANDLE vb = vbucket_config_create();
    assert(vb != NULL);
    assert(vbucket_config_parse(vb, LIBVBUCKET_SOURCE_FILE, configPath(fname)) != 0);
    assert(strcmp(vbucket_get_error_message(vb), "Number of vBuckets must be a power of two > 0 and <= 65536") == 0);
    vbucket_config_destroy(vb);
}
Example #2
0
static VBUCKET_CONFIG_HANDLE backwards_compat(vbucket_source_t source, const char *data)
{
    VBUCKET_CONFIG_HANDLE ret = vbucket_config_create();
    if (ret == NULL) {
        return NULL;
    }

    if (vbucket_config_parse(ret, source, data) != 0) {
        errstr = strdup(ret->errmsg);
        vbucket_config_destroy(ret);
        ret = NULL;
    }

    return ret;
}
Example #3
0
/** Update the configuration from a server. */
lcb_error_t lcb_cccp_update(clconfig_provider *provider,
                            const char *host,
                            lcb_string *data)
{
    VBUCKET_CONFIG_HANDLE vbc;
    lcb_string sanitized;
    int rv;
    clconfig_info *new_config;
    cccp_provider *cccp = (cccp_provider *)provider;
    vbc = vbucket_config_create();

    if (!vbc) {
        return LCB_CLIENT_ENOMEM;
    }

    lcb_string_init(&sanitized);
    sanitize_config(data, host, &sanitized);
    rv = vbucket_config_parse(vbc, LIBVBUCKET_SOURCE_MEMORY, sanitized.base);

    if (rv) {
        lcb_string_release(&sanitized);
        vbucket_config_destroy(vbc);
        lcb_string_release(&sanitized);
        return LCB_PROTOCOL_ERROR;
    }

    new_config = lcb_clconfig_create(vbc, &sanitized, LCB_CLCONFIG_CCCP);
    lcb_string_release(&sanitized);

    if (!new_config) {
        vbucket_config_destroy(vbc);
        return LCB_CLIENT_ENOMEM;
    }

    if (cccp->config) {
        lcb_clconfig_decref(cccp->config);
    }

    /** TODO: Figure out the comparison vector */
    new_config->cmpclock = gethrtime();
    cccp->config = new_config;
    lcb_confmon_provider_success(provider, new_config);
    return LCB_SUCCESS;
}
Example #4
0
static lcb_error_t set_next_config(struct htvb_st *vbs)
{
    VBUCKET_CONFIG_HANDLE new_config = NULL;

    new_config = vbucket_config_create();
    if (!new_config) {
        return LCB_CLIENT_ENOMEM;
    }

    if (vbucket_config_parse(new_config, LIBVBUCKET_SOURCE_MEMORY, vbs->input.base)) {
        vbucket_config_destroy(new_config);
        return LCB_PROTOCOL_ERROR;
    }

    if (vbs->config) {
        /** We have a previous configuration... */
        VBUCKET_CHANGE_STATUS chstatus = VBUCKET_NO_CHANGES;
        VBUCKET_CONFIG_DIFF *diff = NULL;
        VBUCKET_CONFIG_HANDLE old_config = vbs->config->vbc;
        diff = vbucket_compare(old_config, new_config);
        if (diff) {
            chstatus = vbucket_what_changed(diff);
            vbucket_free_diff(diff);
        }

        if (chstatus == VBUCKET_NO_CHANGES) {
            vbs->config->cmpclock = gethrtime();
            vbucket_config_destroy(new_config);
            return LCB_SUCCESS;

        }
    }

    if (vbs->config) {
        lcb_clconfig_decref(vbs->config);
    }

    vbs->config = lcb_clconfig_create(new_config, &vbs->input, LCB_CLCONFIG_HTTP);
    vbs->config->cmpclock = gethrtime();
    vbs->generation++;
    return LCB_SUCCESS;
}
Example #5
0
int main(void) {
    char *root = getenv("srcdir");
    const char *host;
    char buffer[FILENAME_MAX];
    char key[NKEY];
    int idx, i, len, ff;
    VBUCKET_CONFIG_HANDLE vb;
    unsigned char checksum[16];
    unsigned char expected[16];
    void *ctx;

    if (root != NULL) {
        for (ff = 0; test_cases[ff] != NULL; ++ff) {
            snprintf(buffer, FILENAME_MAX, "%s/tests/config/%s", root, test_cases[ff]);
            fprintf(stderr, "Running ketama test for: %s\n", test_cases[ff]);
            vb = vbucket_config_create();
            assert(vbucket_config_parse(vb, LIBVBUCKET_SOURCE_FILE, buffer) == 0);
            /* check if it conforms to libketama results */
            snprintf(buffer, FILENAME_MAX,"%s/tests/config/%s.md5sum", root, test_cases[ff]);
            read_checksum(buffer, expected);
            memset(checksum, 0, 16);
            ctx = NULL;

            for (i = 0; i < 1000000; i++) {
                len = snprintf(key, NKEY, "%d", i);
                vbucket_map(vb, key, len, NULL, &idx);
                host = vbucket_config_get_server(vb, idx);
                ctx = hash_md5_update(ctx, host, strlen(host));
            }
            hash_md5_final(ctx, checksum);

            for (i = 0; i < 16; i++) {
                assert(checksum[i] == expected[i]);
            }

            vbucket_config_destroy(vb);
        }
    }

    exit(EXIT_SUCCESS);
}
Example #6
0
static lcb_error_t set_next_config(struct htvb_st *vbs)
{
    VBUCKET_CONFIG_HANDLE new_config = NULL;

    new_config = vbucket_config_create();
    if (!new_config) {
        return LCB_CLIENT_ENOMEM;
    }

    if (vbucket_config_parse(new_config, LIBVBUCKET_SOURCE_MEMORY, vbs->input.base)) {
        vbucket_config_destroy(new_config);
        return LCB_PROTOCOL_ERROR;
    }

    if (vbs->config) {
        lcb_clconfig_decref(vbs->config);
    }

    vbs->config = lcb_clconfig_create(new_config, &vbs->input, LCB_CLCONFIG_HTTP);
    vbs->config->cmpclock = gethrtime();
    vbs->generation++;
    return LCB_SUCCESS;
}
Example #7
0
static int load_cache(file_provider *provider)
{
    lcb_string str;
    char line[1024];
    lcb_ssize_t nr;
    int fail;
    FILE *fp = NULL;
    VBUCKET_CONFIG_HANDLE config = NULL;
    char *end;
    struct stat st;
    int status = -1;

    lcb_string_init(&str);

    if (provider->filename == NULL) {
        return -1;
    }

    fp = fopen(provider->filename, "r");
    if (fp == NULL) {
        LOG(provider, ERROR, "Couldn't open filename");
        return -1;
    }

    if (fstat(fileno(fp), &st)) {
        provider->last_errno = errno;
        goto GT_DONE;
    }

    if (provider->last_mtime == st.st_mtime) {
        LOG(provider, INFO, "Rejecting file. Modification time too old");
        goto GT_DONE;
    }

    config = vbucket_config_create();
    if (config == NULL) {
        goto GT_DONE;
    }

    lcb_string_init(&str);

    while ((nr = fread(line, 1, sizeof(line), fp)) > 0) {
        if (lcb_string_append(&str, line, nr)) {
            goto GT_DONE;
        }
    }

    if (ferror(fp)) {
        goto GT_DONE;
    }

    fclose(fp);
    fp = NULL;

    if (!str.nused) {
        status = -1;
        goto GT_DONE;
    }

    end = strstr(str.base, CONFIG_CACHE_MAGIC);
    if (end == NULL) {
        LOG(provider, ERROR, "Couldn't find magic in file");
        remove(provider->filename);
        status = -1;
        goto GT_DONE;
    }

    fail = vbucket_config_parse(config, LIBVBUCKET_SOURCE_MEMORY, str.base);
    if (fail) {
        status = -1;
        LOG(provider, ERROR, "Couldn't parse configuration");
        remove(provider->filename);
        goto GT_DONE;
    }

    if (vbucket_config_get_distribution_type(config) != VBUCKET_DISTRIBUTION_VBUCKET) {
        status = -1;
        LOG(provider, ERROR, "Not applying cached memcached config");
        goto GT_DONE;
    }

    if (provider->config) {
        lcb_clconfig_decref(provider->config);
    }

    provider->config = lcb_clconfig_create(config,
                                           &str,
                                           LCB_CLCONFIG_FILE);
    provider->config->cmpclock = gethrtime();
    provider->config->origin = provider->base.type;
    provider->last_mtime = st.st_mtime;
    status = 0;
    config = NULL;

    GT_DONE:
    if (fp != NULL) {
        fclose(fp);
    }

    if (config != NULL) {
        vbucket_config_destroy(config);
    }

    lcb_string_release(&str);
    return status;
}
Example #8
0
static libcouchbase_error_t create_memcached(const struct libcouchbase_memcached_st *user,
                                             VBUCKET_CONFIG_HANDLE vbconfig)
{
    ringbuffer_t buffer;
    char *copy = strdup(user->serverlist);
    char head[1024];
    int first;
    char *ptr = copy;
    int fail;
    libcouchbase_ssize_t offset = 0;

    if (copy == NULL) {
        return LIBCOUCHBASE_CLIENT_ENOMEM;
    }

    if (ringbuffer_initialize(&buffer, 1024) == -1) {
        free(copy);
        return LIBCOUCHBASE_CLIENT_ENOMEM;
    }

    head[0] = '\0';
    offset += snprintf(head + offset, sizeof(head) - offset, "%s", "{");
    offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                       "\"bucketType\":\"memcached\",");
    offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                       "\"nodeLocator\":\"ketama\",");
    if (user->username != NULL) {
        offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                           "\"authType\":\"sasl\",");
        offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                           "\"name\":\"");
        offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                           user->username);
        offset += snprintf(head + offset, sizeof(head) - offset, "%s", "\",");
        if (user->password != NULL) {
            offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                               "\"saslPassword\":\"");
            offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                               user->password);
            offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                               "\",");
        }
    }

    offset += snprintf(head + offset, sizeof(head) - offset, "%s",
                       "\"nodes\": [");
    ringbuffer_write(&buffer, head, strlen(head));

    /* Let's add the hosts... */
    first = 1;
    do {
        char *tok;
        char *next = strchr(ptr, ';');
        const char *port = "11211";
        libcouchbase_ssize_t length;

        if (next != NULL) {
            *next = '\0';
        }

        tok = strchr(ptr, ':');
        if (tok != NULL) {
            *tok = '\0';
            port = tok + 1;
            if ((tok = strchr(ptr, ':')) != NULL) {
                *tok = '\0'; /* Remove weight for now */
            }
        }

        length = snprintf(head, sizeof(head),
                          "%c{\"hostname\":\"%s\",\"ports\":{\"direct\":%s}}",
                          first ? ' ' : ',', ptr, port);
        first = 0;

        if (ringbuffer_ensure_capacity(&buffer, length) == -1) {
            free(copy);
            return LIBCOUCHBASE_CLIENT_ENOMEM;
        }

        ringbuffer_write(&buffer, head, length);

        if (next != NULL) {
            ptr = next + 1;
        } else {
            ptr = NULL;
        }
    } while (ptr != NULL);

    if (ringbuffer_ensure_capacity(&buffer, 3) == -1) {
        free(copy);
        return LIBCOUCHBASE_CLIENT_ENOMEM;
    }

    ringbuffer_write(&buffer, "]}", 3); /* Include '\0' */

    /* Now let's parse the config! */
    fail = vbucket_config_parse(vbconfig, LIBVBUCKET_SOURCE_MEMORY,
                                (char *)ringbuffer_get_read_head(&buffer));
    free(copy);
    ringbuffer_destruct(&buffer);

    if (fail) {
        /* Hmm... internal error! */
        return LIBCOUCHBASE_EINTERNAL;
    }

    return LIBCOUCHBASE_SUCCESS;
}