static int mcache_ping_servers(pr_memcache_t *mcache) { memcached_server_st *alive_server_list; memcached_return res; memcached_st *clone; uint32_t server_count; register unsigned int i; /* We always start with the configured list of servers. */ clone = memcached_clone(NULL, mcache->mc); if (clone == NULL) { errno = ENOMEM; return -1; } memcached_servers_reset(clone); /* Bug#4242: Don't use memcached_server_push() if we're using * libmemcached-1.0.18 or earlier. Doing so leads to a segfault, due to * this libmemcached bug: * * https://bugs.launchpad.net/libmemcached/+bug/1154159 */ #if LIBMEMCACHED_VERSION_HEX > 0x01000018 memcached_server_push(clone, configured_server_list); #endif server_count = memcached_server_count(clone); pr_trace_msg(trace_channel, 16, "pinging %lu memcached %s", (unsigned long) server_count, server_count != 1 ? "servers" : "server"); alive_server_list = NULL; for (i = 0; i < server_count; i++) { memcached_server_instance_st server; server = memcached_server_instance_by_position(clone, i); pr_trace_msg(trace_channel, 17, "pinging server %s:%d", memcached_server_name(server), memcached_server_port(server)); if (libmemcached_util_ping(memcached_server_name(server), memcached_server_port(server), &res) == FALSE) { pr_trace_msg(trace_channel, 4, "error pinging %s:%d: %s", memcached_server_name(server), memcached_server_port(server), memcached_strerror(clone, res)); } else { pr_trace_msg(trace_channel, 17, "server %s:%d is alive", memcached_server_name(server), memcached_server_port(server)); alive_server_list = memcached_server_list_append(alive_server_list, memcached_server_name(server), memcached_server_port(server), &res); if (alive_server_list == NULL) { pr_trace_msg(trace_channel, 1, "error appending server %s:%d to list: %s", memcached_server_name(server), memcached_server_port(server), memcached_strerror(clone, res)); memcached_free(clone); errno = EPERM; return -1; } } } if (alive_server_list != NULL) { memcached_servers_reset(mcache->mc); res = memcached_server_push(mcache->mc, alive_server_list); if (res != MEMCACHED_SUCCESS) { unsigned int count; count = memcached_server_list_count(alive_server_list); pr_trace_msg(trace_channel, 2, "error adding %u alive memcached %s to connection: %s", count, count != 1 ? "servers" : "server", memcached_strerror(mcache->mc, res)); memcached_free(clone); errno = EPERM; return -1; } else { unsigned int count; count = memcached_server_list_count(alive_server_list); pr_trace_msg(trace_channel, 9, "now using %d alive memcached %s", count, count != 1 ? "servers" : "server"); memcached_server_list_free(alive_server_list); } } memcached_free(clone); return 0; }
void server_startup(server_startup_st *construct) { if ((construct->server_list= getenv("MEMCACHED_SERVERS"))) { printf("servers %s\n", construct->server_list); construct->servers= memcached_servers_parse(construct->server_list); construct->server_list= NULL; construct->count= 0; } else { { char server_string_buffer[8096]; char *end_ptr; end_ptr= server_string_buffer; for (uint32_t x= 0; x < construct->count; x++) { int count; int status; in_port_t port; { char *var; char variable_buffer[1024]; snprintf(variable_buffer, sizeof(variable_buffer), "LIBMEMCACHED_PORT_%u", x); if ((var= getenv(variable_buffer))) { port= (in_port_t)atoi(var); } else { port= (in_port_t)(x + TEST_PORT_BASE); } } char buffer[PATH_MAX]; snprintf(buffer, sizeof(buffer), PID_FILE_BASE, x); kill_file(buffer); if (x == 0) { snprintf(buffer, sizeof(buffer), "%s -d -u root -P "PID_FILE_BASE" -t 1 -p %u -U %u -m 128", MEMCACHED_BINARY, x, port, port); } else { snprintf(buffer, sizeof(buffer), "%s -d -u root -P "PID_FILE_BASE" -t 1 -p %u -U %u", MEMCACHED_BINARY, x, port, port); } if (libmemcached_util_ping("localhost", port, NULL)) { fprintf(stderr, "Server on port %u already exists\n", port); } else { status= system(buffer); fprintf(stderr, "STARTING SERVER: %s status:%d\n", buffer, status); } count= sprintf(end_ptr, "localhost:%u,", port); end_ptr+= count; } *end_ptr= 0; int *pids= calloc(construct->count, sizeof(int)); for (uint32_t x= 0; x < construct->count; x++) { char buffer[PATH_MAX]; /* Nothing special for number */ snprintf(buffer, sizeof(buffer), PID_FILE_BASE, x); uint32_t counter= 3000; // Absurd, just to catch run away process while (pids[x] <= 0 && --counter) { FILE *file= fopen(buffer, "r"); if (file) { char pid_buffer[1024]; char *found= fgets(pid_buffer, sizeof(pid_buffer), file); if (found) { pids[x]= atoi(pid_buffer); fclose(file); if (pids[x] > 0) break; } fclose(file); } global_sleep(); } bool was_started= false; if (pids[x] > 0) { counter= 30; while (--counter) { if (kill(pids[x], 0) == 0) { was_started= true; break; } global_sleep(); } } if (was_started == false) { fprintf(stderr, "Failed to open buffer %s(%d)\n", buffer, pids[x]); for (uint32_t y= 0; y < construct->count; y++) { if (pids[y] > 0) kill(pids[y], SIGTERM); } abort(); } } free(pids); construct->server_list= strdup(server_string_buffer); } printf("servers %s\n", construct->server_list); construct->servers= memcached_servers_parse(construct->server_list); } assert(construct->servers); srandom((unsigned int)time(NULL)); for (uint32_t x= 0; x < memcached_server_list_count(construct->servers); x++) { printf("\t%s : %d\n", memcached_server_name(&construct->servers[x]), memcached_server_port(&construct->servers[x])); assert(construct->servers[x].fd == -1); assert(construct->servers[x].cursor_active == 0); } printf("\n"); }