Пример #1
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;
    clconfig_info *new_config;
    cccp_provider *cccp = (cccp_provider *)provider;
    vbc = vbucket_config_create();

    if (!vbc) {
        return LCB_CLIENT_ENOMEM;
    }

    if (vbucket_config_parse2(vbc, LIBVBUCKET_SOURCE_MEMORY, data->base, host)) {
        vbucket_config_destroy(vbc);
        return LCB_PROTOCOL_ERROR;
    }

    new_config = lcb_clconfig_create(vbc, data, LCB_CLCONFIG_CCCP);

    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_set_next(provider->parent, new_config, 0);
    return LCB_SUCCESS;
}
Пример #2
0
static VBUCKET_CONFIG_HANDLE parse_cjson(cJSON *config)
{
    cJSON *json;
    struct vbucket_config_st *vb;

    vb = calloc(1, sizeof(struct vbucket_config_st));
    if (vb == NULL) {
        errstr = "Failed to allocate vbucket config struct";
        return NULL;
    }

    /* set optional credentials */
    json = cJSON_GetObjectItem(config, "name");
    if (json != NULL && json->type == cJSON_String && strcmp(json->valuestring, "default") != 0) {
        vb->user = strdup(json->valuestring);
    }
    json = cJSON_GetObjectItem(config, "saslPassword");
    if (json != NULL && json->type == cJSON_String) {
        vb->password = strdup(json->valuestring);
    }

    /* by default it uses vbucket distribution to map keys to servers */
    vb->distribution = VBUCKET_DISTRIBUTION_VBUCKET;

    json = cJSON_GetObjectItem(config, "nodeLocator");
    if (json == NULL) {
        /* special case: it migth be config without envelope */
        if (parse_vbucket_config(vb, config) == NULL) {
            vbucket_config_destroy(vb);
            return NULL;
        }
    } else if (json->type == cJSON_String) {
        if (strcmp(json->valuestring, "vbucket") == 0) {
            vb->distribution = VBUCKET_DISTRIBUTION_VBUCKET;
            if (parse_vbucket_config(vb, config) == NULL) {
                vbucket_config_destroy(vb);
                return NULL;
            }
        } else if (strcmp(json->valuestring, "ketama") == 0) {
            vb->distribution = VBUCKET_DISTRIBUTION_KETAMA;
            if (parse_ketama_config(vb, config) == NULL) {
                vbucket_config_destroy(vb);
                return NULL;
            }
        }
    } else {
        errstr = "Expected string for nodeLocator";
        vbucket_config_destroy(vb);
        return NULL;
    }

    return vb;
}
Пример #3
0
/* Returns true if curr_version could be updated with next_version in
 * a low-impact stable manner (server-list is the same), allowing the
 * same connections to be reused.  Or returns false if the delta was
 * too large for an in-place updating of curr_version with information
 * from next_version.
 *
 * The next_version may be destroyed in this call, and the caller
 * should afterwards only call mcs_free() on the next_version.
 */
bool lvb_stable_update(mcs_st *curr_version, mcs_st *next_version) {
    assert(curr_version->kind == MCS_KIND_LIBVBUCKET);
    assert(curr_version->data != NULL);
    assert(next_version->kind == MCS_KIND_LIBVBUCKET);
    assert(next_version->data != NULL);

    bool rv = false;

    VBUCKET_CONFIG_DIFF *diff =
        vbucket_compare((VBUCKET_CONFIG_HANDLE) curr_version->data,
                        (VBUCKET_CONFIG_HANDLE) next_version->data);
    if (diff != NULL) {
        if (!diff->sequence_changed) {
            vbucket_config_destroy((VBUCKET_CONFIG_HANDLE) curr_version->data);
            curr_version->data = next_version->data;
            next_version->data = 0;

            rv = true;
        }

        vbucket_free_diff(diff);
    }

    return rv;
}
Пример #4
0
static void testConfigDiff(void) {
    VBUCKET_CONFIG_HANDLE vb1 = vbucket_config_parse_file(configPath("config-diff1"));
    VBUCKET_CONFIG_HANDLE vb2 = vbucket_config_parse_file(configPath("config-diff2"));
    VBUCKET_CONFIG_DIFF *diff;
    assert(vb2);

    diff = vbucket_compare(vb1, vb2);
    assert(vb1);
    assert(diff);

    assert(diff->sequence_changed);
    assert(diff->n_vb_changes == 1);
    assert(strcmp(diff->servers_added[0], "server4:11211") == 0);
    assert(diff->servers_added[1] == NULL);
    assert(strcmp(diff->servers_removed[0], "server3:11211") == 0);
    assert(diff->servers_removed[1] == NULL);

    vbucket_free_diff(diff);
    vbucket_config_destroy(vb2);

    vb2 = vbucket_config_parse_file(configPath("config-diff3"));
    assert(vb2);

    diff = vbucket_compare(vb1, vb2);
    assert(diff);

    assert(diff->sequence_changed);
    assert(diff->n_vb_changes == -1);
    assert(diff->servers_added[0] == NULL);
    assert(strcmp(diff->servers_removed[0], "server3:11211") == 0);
    assert(diff->servers_removed[1] == NULL);
}
Пример #5
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);
}
Пример #6
0
static void testWrongServer(const char *fname) {
    VBUCKET_CONFIG_HANDLE vb = vbucket_config_parse_file(configPath(fname));
    if (vb == NULL) {
        fprintf(stderr, "vbucket_config_parse_file error: %s\n",
                vbucket_get_error());
        abort();
    }

    /* Starts at 0 */
    assert(vbucket_get_master(vb, 0) == 0);
    /* Does not change when I told it I found the wrong thing */
    assert(vbucket_found_incorrect_master(vb, 0, 1) == 0);
    assert(vbucket_get_master(vb, 0) == 0);
    /* Does change if I tell it I got the right thing and it was wrong. */
    assert(vbucket_found_incorrect_master(vb, 0, 0) == 1);
    assert(vbucket_get_master(vb, 0) == 1);
    /* ...and again */
    assert(vbucket_found_incorrect_master(vb, 0, 1) == 2);
    assert(vbucket_get_master(vb, 0) == 2);
    /* ...and then wraps */
    assert(vbucket_found_incorrect_master(vb, 0, 2) == 0);
    assert(vbucket_get_master(vb, 0) == 0);

    vbucket_config_destroy(vb);
}
Пример #7
0
static void config_callback(lcb_server_t *server, lcb_error_t error, const char *json)
{
    VBUCKET_CONFIG_HANDLE config;
    lcb_t instance = server->instance;

    server->connection.timeout.usec = 0;
    lcb_connection_cancel_timer(&server->connection);

    if (error != LCB_SUCCESS) {
        lcb_error_handler(instance, error, "Failed to receive configration");
        return;
    }

    config = vbucket_config_create();

    if (config == NULL) {
        lcb_error_handler(instance, LCB_CLIENT_ENOMEM,
                          "Failed to allocate memory for configuration");
        return;
    }

    if (vbucket_config_parse2(config, LIBVBUCKET_SOURCE_MEMORY, json, server->connection.host)) {
        vbucket_config_destroy(config);
        lcb_error_handler(instance, LCB_PROTOCOL_ERROR,
                          vbucket_get_error_message(config));
        return;
    }

    lcb_update_vbconfig(instance, config);
}
Пример #8
0
LIBCOUCHBASE_API
libcouchbase_error_t libcouchbase_create_compat(libcouchbase_cluster_t type,
                                                const void *specific,
                                                libcouchbase_t *instance,
                                                struct libcouchbase_io_opt_st *io)
{
    libcouchbase_error_t ret = LIBCOUCHBASE_NOT_SUPPORTED;
    VBUCKET_CONFIG_HANDLE config;

    *instance = libcouchbase_create(NULL, NULL, NULL, NULL, io);
    if (*instance == NULL) {
        return LIBCOUCHBASE_CLIENT_ENOMEM;
    }

    config = vbucket_config_create();
    if (config == NULL) {
        libcouchbase_destroy(*instance);
        *instance = NULL;
        return LIBCOUCHBASE_CLIENT_ENOMEM;
    }

    if (type == LIBCOUCHBASE_MEMCACHED_CLUSTER) {
        ret = create_memcached(specific, config);
    }

    if (ret == LIBCOUCHBASE_SUCCESS) {
        libcouchbase_apply_vbucket_config(*instance, config);
    } else {
        vbucket_config_destroy(config);
        libcouchbase_destroy(*instance);
        *instance = NULL;
    }

    return ret;
}
Пример #9
0
static int populate_servers(struct vbucket_config_st *vb, cJSON *c) {
    int i;

    vb->servers = calloc(vb->num_servers, sizeof(struct server_st));
    if (vb->servers == NULL) {
        vbucket_config_destroy(vb);
        errstr = "Failed to allocate servers array";
        return -1;
    }
    for (i = 0; i < vb->num_servers; ++i) {
        char *server;
        cJSON *jServer = cJSON_GetArrayItem(c, i);
        if (jServer == NULL || jServer->type != cJSON_String) {
            errstr = "Expected array of strings for serverList";
            return -1;
        }
        server = strdup(jServer->valuestring);
        if (server == NULL) {
            errstr = "Failed to allocate storage for server string";
            return -1;
        }
        vb->servers[i].authority = server;
    }
    return 0;
}
Пример #10
0
static void testConfigDiffKetamaSame(void) {
    VBUCKET_CONFIG_HANDLE vb1 = vbucket_config_parse_file(configPath("ketama-eight-nodes"));
    VBUCKET_CONFIG_HANDLE vb2 = vbucket_config_parse_file(configPath("ketama-ordered-eight-nodes"));
    VBUCKET_CONFIG_DIFF *diff;
    assert(vb1);
    assert(vb2);
    diff = vbucket_compare(vb1, vb2);
    assert(diff);

    assert(diff->sequence_changed == 0);
    assert(diff->n_vb_changes == 0);
    assert(diff->servers_added[0] == NULL);
    assert(diff->servers_removed[0] == NULL);

    vbucket_free_diff(diff);
    vbucket_config_destroy(vb1);
    vbucket_config_destroy(vb2);
}
Пример #11
0
void lvb_free_data(mcs_st *ptr) {
    assert(ptr->kind == MCS_KIND_LIBVBUCKET);

    if (ptr->data != NULL) {
        vbucket_config_destroy((VBUCKET_CONFIG_HANDLE) ptr->data);
    }

    ptr->data = NULL;
}
Пример #12
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;
}
Пример #13
0
int main(void) {
    char *root = getenv("srcdir");
    DIR *dp;
    const char *host;
    char buffer[PATH_MAX];
    char key[NKEY];
    int idx, i, len;
    struct dirent *de;
    VBUCKET_CONFIG_HANDLE vb;
    unsigned char checksum[16];
    unsigned char expected[16];
    void *ctx;

    if (root != NULL) {
        sprintf(buffer, "%s/tests/config", root);
        dp = opendir(buffer);
        if (dp == NULL) {
            fprintf(stderr, "Skipping ketama check\nFailed to open %s: %s\n",
                    buffer, strerror(errno));
            return 0;
        }

        while ((de = readdir(dp)) != NULL) {
            if (strncmp(de->d_name, "ketama", 6) == 0 && strchr(de->d_name, '.') == NULL) {
                sprintf(buffer, "%s/tests/config/%s", root, de->d_name);
                fprintf(stderr, "Running ketama test for: %s\n", de->d_name);
                vb = vbucket_config_parse_file(buffer);
                assert(vb != NULL);

                /* check if it conforms to libketama results */
                sprintf(buffer, "%s/tests/config/%s.md5sum", root, de->d_name);
                read_checksum(buffer, expected);
                memset(checksum, 0, 16);
                ctx = NULL;

                for (i = 0; i < 1000000; i++) {
                    len = sprintf(key, "%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);
            }
        }
        closedir(dp);
    }

    return 0;
}
Пример #14
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;
}
Пример #15
0
static void testConfigUserPassword(void) {
    VBUCKET_CONFIG_HANDLE vb1;
    VBUCKET_CONFIG_HANDLE vb2;
    VBUCKET_CONFIG_DIFF *diff;

    vb1 = vbucket_config_parse_file(configPath("config-user-password1"));
    assert(vb1);
    assert(strcmp(vbucket_config_get_user(vb1), "theUser") == 0);
    assert(strcmp(vbucket_config_get_password(vb1), "thePassword") == 0);

    vb2 = vbucket_config_parse_file(configPath("config-user-password2"));
    assert(vb2);
    assert(strcmp(vbucket_config_get_user(vb2), "theUserIsDifferent") == 0);
    assert(strcmp(vbucket_config_get_password(vb2), "thePasswordIsDifferent") == 0);

    diff = vbucket_compare(vb1, vb2);
    assert(diff);

    assert(diff->sequence_changed);
    assert(diff->n_vb_changes == 0);
    assert(diff->servers_added[0] == NULL);
    assert(diff->servers_removed[0] == NULL);

    vbucket_free_diff(diff);

    diff = vbucket_compare(vb1, vb1);
    assert(diff);

    assert(diff->sequence_changed == 0);
    assert(diff->n_vb_changes == 0);
    assert(diff->servers_added[0] == NULL);
    assert(diff->servers_removed[0] == NULL);

    vbucket_free_diff(diff);

    vbucket_config_destroy(vb1);
    vbucket_config_destroy(vb2);
}
Пример #16
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;
}
Пример #17
0
LIBCOUCHBASE_API
void libcouchbase_destroy(libcouchbase_t instance)
{
    libcouchbase_size_t ii;
    free(instance->http_uri);

    if (instance->sock != INVALID_SOCKET) {
        instance->io->delete_event(instance->io, instance->sock,
                                   instance->event);
        instance->io->destroy_event(instance->io, instance->event);
        instance->io->close(instance->io, instance->sock);
    }

    if (instance->timeout.event != NULL) {
        instance->io->delete_timer(instance->io, instance->timeout.event);
        instance->io->destroy_timer(instance->io, instance->timeout.event);
        instance->timeout.event = NULL;
    }

    if (instance->ai != NULL) {
        freeaddrinfo(instance->ai);
    }

    if (instance->vbucket_config != NULL) {
        vbucket_config_destroy(instance->vbucket_config);
    }

    for (ii = 0; ii < instance->nservers; ++ii) {
        libcouchbase_server_destroy(instance->servers + ii);
    }
    free(instance->servers);
    free(instance->backup_nodes);

    if (instance->io && instance->io->destructor) {
        instance->io->destructor(instance->io);
    }

    free(instance->vbucket_stream.input.data);
    free(instance->vbucket_stream.chunk.data);
    free(instance->vbucket_stream.header);
    free(instance->vb_server_map);
    free(instance->histogram);

    memset(instance, 0xff, sizeof(*instance));
    free(instance);
}
Пример #18
0
static void testConfig(const char *fname) {
    int whoops = 0;
    const struct key_st *k;
    int i = 0;

    VBUCKET_CONFIG_HANDLE vb = vbucket_config_parse_file(configPath(fname));
    if (vb == NULL) {
        fprintf(stderr, "vbucket_config_parse_file error: %s\n",
                vbucket_get_error());
        abort();
    }

    while ((k = &keys[i++])->key != NULL) {
        int id = vbucket_get_vbucket_by_key(vb, k->key, strlen(k->key));
        if (id != k->vbucket) {
            fprintf(stderr, "Expected vbucket %d for key '%s' but got %d\n",
                    k->vbucket, k->key, id);
            whoops = 1;
        }
    }

    if (whoops) {
        abort();
    }

    assert(vbucket_config_get_num_servers(vb) == 3 || vbucket_config_get_num_servers(vb) == 4);
    assert(vbucket_config_get_num_replicas(vb) == 2);

    for (i = 0; i < 3; ++i) {
        assert(strcmp(vbucket_config_get_server(vb, i), servers[i]) == 0);
    }

    for (i = 0; i < 4; ++i) {
        assert(vbucket_get_master(vb, i) == vbuckets[i].master);
        assert(vbucket_get_replica(vb, i, 0) == vbuckets[i].replicas[0]);
        assert(vbucket_get_replica(vb, i, 1) == vbuckets[i].replicas[1]);
    }

    assert(vbucket_config_get_user(vb) == NULL);
    assert(vbucket_config_get_password(vb) == NULL);

    vbucket_config_destroy(vb);
}
Пример #19
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);
}
Пример #20
0
static void testWrongServerFFT(const char *fname) {
    VBUCKET_CONFIG_HANDLE vb = vbucket_config_parse_file(configPath(fname));
    int rv = 0;
    int nvb = 0;
    int i = 0;

    if (vb == NULL) {
        fprintf(stderr, "vbucket_config_parse_file error: %s\n", vbucket_get_error());
        abort();
    }

    /* found incorrect master should not be the same as get master now */
    nvb = vbucket_config_get_num_vbuckets(vb);
    for (i = 0; i < nvb; i++) {
        rv = vbucket_get_master(vb, i);
        assert(rv != vbucket_found_incorrect_master(vb, i, rv));
    }
    /* the ideal test case should be that we check that the vbucket */
    /* and the fvbucket map are identical at this point. TODO untill */
    /* we have a vbucketlib function that diffs vbuckets and fvbuckets */
    vbucket_config_destroy(vb);
}
Пример #21
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;
}
Пример #22
0
int main(int argc, char **argv) {
    VBUCKET_CONFIG_HANDLE vb = NULL;
    int rval;
    int num_keys_per_vbucket;
    int num_keys_to_generate;
    int num_vbuckets;
    char *** keys;
    int i, j, v, k, total;
    char *key;

    if (argc < 4) {
        printf("vbucketkeygen mapfile <keys per vbucket> <keys to generate>\n\n");
        printf("  vbucketkeygen will output a list of keys that equally\n");
        printf("    distribute amongst every vbucket.\n\n");
        printf("  vbucketkeygen expects a vBucketServerMap JSON mapfile, and\n");
        printf("  will print the keyname and vBucketId.\n");
        printf("  You may use '-' instead for the filename to specify stdin.\n\n");
        printf("  Examples:\n");
        printf("    ./vbucketkeygen file.json 10 10000\n\n");
        printf("    curl http://HOST:8091/pools/default/buckets/default | \\\n");
        printf("       ./vbucketkeygen - 5 10000\n");
        exit(1);
    }


    if (strcmp("-", argv[1]) == 0) {
        char buf[50000];
        if (fgets(buf, sizeof(buf) - 1, stdin) == NULL) {
            fprintf(stderr, "ERROR: vbucketkeygen found no input on stdin\n");
            exit(1);
        }
        buf[sizeof(buf) - 1] = '\0';

        vb = vbucket_config_parse_string(buf);
    } else {
        vb = vbucket_config_parse_file(argv[1]);
    }

    if (vb == NULL) {
        fprintf(stderr, "ERROR: vbucket_config_parse_string error: %s\n", vbucket_get_error());
        exit(1);
    }

    rval = 0;
    num_keys_per_vbucket = atoi(argv[2]);
    num_keys_to_generate = atoi(argv[3]);
    num_vbuckets = vbucket_config_get_num_vbuckets(vb);

    /* allocate memory and set each key to null since strdup will allocate that */
    keys = malloc(sizeof(char***) * num_vbuckets);
    for (i = 0; i < num_vbuckets; i++) {
        keys[i] = malloc(sizeof(char**) * num_keys_per_vbucket);
    }
    for (i = 0; i < num_vbuckets; i++) {
        for (j = 0 ; j < num_keys_per_vbucket ; j++) {
            keys[i][j] = 0;
        }
    }

    /* generate keys and copy them to the keys structure */
    key = malloc(sizeof(char) * (MAX_KEY_SIZE+1));
    for (i = 0; i < num_keys_to_generate; i++) {
        snprintf(key, MAX_KEY_SIZE + 1, "key_%010d", i);
        v = vbucket_get_vbucket_by_key(vb, key, strlen(key));
        for (k = 0; k < num_keys_per_vbucket; k++) {
            if (keys[v][k] == 0) {
                keys[v][k] = strdup(key);
                break;
            }
        }
    }

    /* print out <key> <vbucket> and count up total keys
       so we can check that every vbucket has the correct
       number of keys */
    total = 0;
    for (i = 0; i < num_vbuckets; i++) {
        for (j = 0 ; j < num_keys_per_vbucket ; j++) {
            if (keys[i][j] != 0) {
                printf("%s %d\n", keys[i][j], i);
                total++;
            }
        }
    }

    if (total < (num_vbuckets * num_keys_per_vbucket)) {
        fprintf(stderr, "some vbuckets don't have enough keys\n");
        rval = 1;
    }

    vbucket_config_destroy(vb);

    return rval;
}
Пример #23
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;
}