2 * Copyright (C) 2006-2009 Brian Aker
5 * Use and distribution licensed under the BSD license. See
6 * the COPYING file in the parent directory for full text.
13 Startup, and shutdown the memcached servers.
16 #define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT+10
18 #define PID_FILE_BASE "/tmp/%ulibmemcached_memc.pid"
32 #include <libmemcached/memcached.h>
33 #include <libmemcached/util.h>
35 #include <libtest/server.h>
37 static struct timespec global_sleep_value
= { .tv_sec
= 0, .tv_nsec
= 50000 };
39 static void global_sleep(void)
44 nanosleep(&global_sleep_value
, NULL
);
48 static void kill_file(const char *file_buffer
)
52 while ((fp
= fopen(file_buffer
, "r")))
54 char pid_buffer
[1024];
56 if (fgets(pid_buffer
, sizeof(pid_buffer
), fp
) != NULL
)
58 pid_t pid
= (pid_t
)atoi(pid_buffer
);
61 if (kill(pid
, SIGTERM
) == -1)
63 remove(file_buffer
); // If this happens we may be dealing with a dead server that left its pid file.
68 while ((kill(pid
, 0) == 0) && --counter
)
82 void server_startup(server_startup_st
*construct
)
84 if ((construct
->server_list
= getenv("MEMCACHED_SERVERS")))
86 printf("servers %s\n", construct
->server_list
);
87 construct
->servers
= memcached_servers_parse(construct
->server_list
);
88 construct
->server_list
= NULL
;
94 char server_string_buffer
[8096];
96 end_ptr
= server_string_buffer
;
98 for (uint32_t x
= 0; x
< construct
->count
; x
++)
105 char variable_buffer
[1024];
107 snprintf(variable_buffer
, sizeof(variable_buffer
), "LIBMEMCACHED_PORT_%u", x
);
109 if ((var
= getenv(variable_buffer
)))
111 port
= (in_port_t
)atoi(var
);
115 port
= (in_port_t
)(x
+ TEST_PORT_BASE
);
119 char buffer
[PATH_MAX
];
120 snprintf(buffer
, sizeof(buffer
), PID_FILE_BASE
, x
);
125 snprintf(buffer
, sizeof(buffer
), "%s -d -u root -P "PID_FILE_BASE
" -t 1 -p %u -U %u -m 128",
126 MEMCACHED_BINARY
, x
, port
, port
);
130 snprintf(buffer
, sizeof(buffer
), "%s -d -u root -P "PID_FILE_BASE
" -t 1 -p %u -U %u",
131 MEMCACHED_BINARY
, x
, port
, port
);
133 if (libmemcached_util_ping("localhost", port
, NULL
))
135 fprintf(stderr
, "Server on port %u already exists\n", port
);
139 status
= system(buffer
);
140 fprintf(stderr
, "STARTING SERVER: %s status:%d\n", buffer
, status
);
143 size_t remaining_length
= sizeof(server_string_buffer
) - (size_t)(end_ptr
-server_string_buffer
);
144 count
= snprintf(end_ptr
, remaining_length
, "localhost:%u,", port
);
146 if ((size_t)count
>= remaining_length
|| count
< 0)
148 fprintf(stderr
, "server names grew to be larger then buffer allowed\n");
156 int *pids
= calloc(construct
->count
, sizeof(int));
157 for (uint32_t x
= 0; x
< construct
->count
; x
++)
159 char buffer
[PATH_MAX
]; /* Nothing special for number */
161 snprintf(buffer
, sizeof(buffer
), PID_FILE_BASE
, x
);
163 uint32_t counter
= 3000; // Absurd, just to catch run away process
164 while (pids
[x
] <= 0 && --counter
)
166 FILE *file
= fopen(buffer
, "r");
169 char pid_buffer
[1024];
170 char *found
= fgets(pid_buffer
, sizeof(pid_buffer
), file
);
174 pids
[x
]= atoi(pid_buffer
);
185 bool was_started
= false;
191 if (kill(pids
[x
], 0) == 0)
200 if (was_started
== false)
202 fprintf(stderr
, "Failed to open buffer %s(%d)\n", buffer
, pids
[x
]);
203 for (uint32_t y
= 0; y
< construct
->count
; y
++)
206 kill(pids
[y
], SIGTERM
);
213 construct
->server_list
= strdup(server_string_buffer
);
215 printf("servers %s\n", construct
->server_list
);
216 construct
->servers
= memcached_servers_parse(construct
->server_list
);
219 assert(construct
->servers
);
221 srandom((unsigned int)time(NULL
));
223 for (uint32_t x
= 0; x
< memcached_server_list_count(construct
->servers
); x
++)
225 printf("\t%s : %d\n", memcached_server_name(&construct
->servers
[x
]), memcached_server_port(&construct
->servers
[x
]));
226 assert(construct
->servers
[x
].fd
== -1);
227 assert(construct
->servers
[x
].cursor_active
== 0);
233 void server_shutdown(server_startup_st
*construct
)
235 if (construct
->server_list
)
237 for (uint32_t x
= 0; x
< construct
->count
; x
++)
239 char file_buffer
[PATH_MAX
]; /* Nothing special for number */
240 snprintf(file_buffer
, sizeof(file_buffer
), PID_FILE_BASE
, x
);
241 kill_file(file_buffer
);
244 free(construct
->server_list
);