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); }
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; }
/** 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; }
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; }
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); }
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; }
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; }
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; }