VBUCKET_CONFIG_DIFF* vbucket_compare(VBUCKET_CONFIG_HANDLE from, VBUCKET_CONFIG_HANDLE to) { VBUCKET_CONFIG_DIFF *rv = calloc(1, sizeof(VBUCKET_CONFIG_DIFF)); int num_servers = (from->num_servers > to->num_servers ? from->num_servers : to->num_servers) + 1; assert(rv); rv->servers_added = calloc(num_servers, sizeof(char*)); rv->servers_removed = calloc(num_servers, sizeof(char*)); /* Compute the added and removed servers */ compute_vb_list_diff(from, to, rv->servers_added); compute_vb_list_diff(to, from, rv->servers_removed); /* Verify the servers are equal in their positions */ if (to->num_servers == from->num_servers) { int i; rv->sequence_changed = false; for (i = 0; i < from->num_servers; i++) { rv->sequence_changed |= (0 != strcmp(vbucket_config_get_server(from, i), vbucket_config_get_server(to, i))); } } else { /* Just say yes */ rv->sequence_changed = true; } /* Consider the sequence changed if the auth credentials changed */ if (from->user != NULL && to->user != NULL) { rv->sequence_changed |= (strcmp(from->user, to->user) != 0); } else { rv->sequence_changed |= ((from->user != NULL) ^ (to->user != NULL)); } if (from->password != NULL && to->password != NULL) { rv->sequence_changed |= (strcmp(from->password, to->password) != 0); } else { rv->sequence_changed |= ((from->password != NULL) ^ (to->password != NULL)); } /* Count the number of vbucket differences */ if (to->num_vbuckets == from->num_vbuckets) { int i; for (i = 0; i < to->num_vbuckets; i++) { rv->n_vb_changes += (vbucket_get_master(from, i) == vbucket_get_master(to, i)) ? 0 : 1; } } else { rv->n_vb_changes = -1; } return rv; }
static void testConfigCouchApiBase(void) { VBUCKET_CONFIG_HANDLE vb = vbucket_config_parse_file(configPath("config-couch-api-base")); assert(vb); assert(strcmp(vbucket_config_get_couch_api_base(vb, 0), "http://192.168.2.123:9500/default") == 0); assert(strcmp(vbucket_config_get_couch_api_base(vb, 1), "http://192.168.2.123:9501/default") == 0); assert(strcmp(vbucket_config_get_couch_api_base(vb, 2), "http://192.168.2.123:9502/default") == 0); assert(strcmp(vbucket_config_get_rest_api_server(vb, 0), "192.168.2.123:9000") == 0); assert(strcmp(vbucket_config_get_rest_api_server(vb, 1), "192.168.2.123:9001") == 0); assert(strcmp(vbucket_config_get_rest_api_server(vb, 2), "192.168.2.123:9002") == 0); assert(strcmp(vbucket_config_get_server(vb, 0), "192.168.2.123:12000") == 0); assert(strcmp(vbucket_config_get_server(vb, 1), "192.168.2.123:12002") == 0); assert(strcmp(vbucket_config_get_server(vb, 2), "192.168.2.123:12004") == 0); }
static void compute_vb_list_diff(VBUCKET_CONFIG_HANDLE from, VBUCKET_CONFIG_HANDLE to, char **out) { int offset = 0; int i, j; for (i = 0; i < to->num_servers; i++) { bool found = false; const char *sn = vbucket_config_get_server(to, i); for (j = 0; !found && j < from->num_servers; j++) { const char *sn2 = vbucket_config_get_server(from, j); found |= (strcmp(sn2, sn) == 0); } if (!found) { out[offset] = strdup(sn); assert(out[offset]); ++offset; } } }
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; }
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); }
static void nodes_updated(clconfig_provider *provider, hostlist_t nodes, VBUCKET_CONFIG_HANDLE vbc) { int ii; cccp_provider *cccp = (cccp_provider *)provider; if (!vbc) { return; } if (vbucket_config_get_num_servers(vbc) < 1) { return; } hostlist_clear(cccp->nodes); for (ii = 0; ii < vbucket_config_get_num_servers(vbc); ii++) { const char *mcaddr = vbucket_config_get_server(vbc, ii); hostlist_add_stringz(cccp->nodes, mcaddr, 11210); } (void)nodes; }
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); }
lcb_error_t lcb_server_initialize(lcb_server_t *server, int servernum) { /* Initialize all members */ lcb_error_t err; char *p; const char *n = vbucket_config_get_server(server->instance->vbucket_config, servernum); err = lcb_connection_init(&server->connection, server->instance->settings.io, &server->instance->settings); if (err != LCB_SUCCESS) { return err; } server->connection.data = server; server->index = servernum; server->authority = strdup(n); strcpy(server->curhost.host, n); p = strchr(server->curhost.host, ':'); *p = '\0'; strcpy(server->curhost.port, p + 1); n = vbucket_config_get_couch_api_base(server->instance->vbucket_config, servernum); server->couch_api_base = (n != NULL) ? strdup(n) : NULL; n = vbucket_config_get_rest_api_server(server->instance->vbucket_config, servernum); server->rest_api_server = strdup(n); server->io_timer = lcb_timer_create_simple(server->instance->settings.io, server, MCSERVER_TIMEOUT(server), tmo_thunk); lcb_timer_disarm(server->io_timer); return LCB_SUCCESS; }
static void nodes_updated(clconfig_provider *provider, hostlist_t nodes, VBUCKET_CONFIG_HANDLE vbc) { int ii; cccp_provider *cccp = (cccp_provider *)provider; if (!vbc) { return; } if (vbucket_config_get_num_servers(vbc) < 1) { return; } hostlist_clear(cccp->nodes); for (ii = 0; ii < vbucket_config_get_num_servers(vbc); ii++) { const char *mcaddr = vbucket_config_get_server(vbc, ii); hostlist_add_stringz(cccp->nodes, mcaddr, LCB_CONFIG_MCD_PORT); } if (PROVIDER_SETTING(provider, randomize_bootstrap_nodes)) { hostlist_randomize(cccp->nodes); } (void)nodes; }
mcs_st *lvb_create(mcs_st *ptr, const char *config) { assert(ptr); memset(ptr, 0, sizeof(*ptr)); ptr->kind = MCS_KIND_LIBVBUCKET; VBUCKET_CONFIG_HANDLE vch = vbucket_config_parse_string(config); if (vch != NULL) { ptr->data = vch; ptr->nservers = vbucket_config_get_num_servers(vch); if (ptr->nservers > 0) { ptr->servers = calloc(sizeof(mcs_server_st), ptr->nservers); if (ptr->servers != NULL) { for (int i = 0; i < ptr->nservers; i++) { ptr->servers[i].fd = -1; } int j = 0; for (; j < ptr->nservers; j++) { const char *hostport = vbucket_config_get_server(vch, j); if (hostport != NULL && strlen(hostport) > 0 && strlen(hostport) < sizeof(ptr->servers[j].hostname) - 1) { strncpy(ptr->servers[j].hostname, hostport, sizeof(ptr->servers[j].hostname) - 1); char *colon = strchr(ptr->servers[j].hostname, ':'); if (colon != NULL) { *colon = '\0'; ptr->servers[j].port = atoi(colon + 1); if (ptr->servers[j].port <= 0) { moxi_log_write("mcs_create failed, could not parse port: %s\n", config); break; } } else { moxi_log_write("mcs_create failed, missing port: %s\n", config); break; } } else { moxi_log_write("mcs_create failed, unknown server: %s\n", config); break; } const char *user = vbucket_config_get_user(vch); if (user != NULL) { ptr->servers[j].usr = strdup(user); } const char *password = vbucket_config_get_password(vch); if (password != NULL) { ptr->servers[j].pwd = strdup(password); } } if (j >= ptr->nservers) { return ptr; } } } } else { moxi_log_write("mcs_create failed, vbucket_config_parse_string: %s\n", config); } mcs_free(ptr); return NULL; }