*
*/
-#include "config.h"
+#include "mem_config.h"
+
+#include <libmemcached/memcached.h>
#include <ctype.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <pwd.h>
#include <strings.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+
#include "ms_setting.h"
#include "ms_conn.h"
#define RAND_CHAR_SIZE (10 * 1024 * 1024) /* 10M character table */
#define RESERVED_RAND_CHAR_SIZE (2 * 1024 * 1024) /* reserved 2M to avoid pointer sloping over */
+#define DEFAULT_CONFIG_NAME ".memslap.cnf"
+
#define DEFAULT_THREADS_NUM 1 /* default start one thread */
#define DEFAULT_CONNS_NUM 16 /* default each thread with 16 connections */
#define DEFAULT_EXE_NUM 0 /* default execute number is 0 */
/* read setting from configuration file */
static void ms_get_serverlist(char *str);
-static int ms_get_cpu_count(void);
+static uint32_t ms_get_cpu_count(void);
ms_conf_type_t ms_get_conf_type(char *line);
static int ms_is_line_data(char *line);
static int ms_read_is_data(char *line, ssize_t nread);
static void ms_setting_slapmode_init_pre(void);
static void ms_setting_slapmode_init_post(void);
+#if !defined(HAVE_GETLINE)
+#include <limits.h>
+static ssize_t getline (char **line, size_t *line_size, FILE *fp)
+{
+ char delim= '\n';
+ ssize_t result= 0;
+ size_t cur_len= 0;
+
+ if (line == NULL || line_size == NULL || fp == NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (*line == NULL || *line_size == 0)
+ {
+ char *new_line;
+ *line_size = 120;
+ new_line= (char *) realloc (*line, *line_size);
+ if (new_line == NULL)
+ {
+ result= -1;
+ return result;
+ }
+ *line= new_line;
+ }
+
+ for (;;)
+ {
+ int i= getc(fp);
+ if (i == EOF)
+ {
+ result = -1;
+ break;
+ }
+
+ /* Make enough space for len+1 (for final NUL) bytes. */
+ if (cur_len + 1 >= *line_size)
+ {
+ size_t needed_max=
+ SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
+ size_t needed= (2 * (*line_size)) + 1;
+ char *new_line;
+
+ if (needed_max < needed)
+ needed= needed_max;
+ if (cur_len + 1 >= needed)
+ {
+ result= -1;
+ errno= EOVERFLOW;
+ return result;
+ }
+
+ new_line= (char *)realloc(*line, needed);
+ if (new_line == NULL)
+ {
+ result= -1;
+ return result;
+ }
+
+ *line= new_line;
+ *line_size= needed;
+ }
+
+ (*line)[cur_len]= (char)i;
+ cur_len++;
+
+ if (i == delim)
+ break;
+ }
+ (*line)[cur_len] = '\0';
+ if (cur_len != 0)
+ return (ssize_t)cur_len;
+ return result;
+}
+#endif
/**
* parse the server list string, and build the servers
*/
static void ms_get_serverlist(char *str)
{
- char *string;
- int64_t port;
- char *begin_ptr;
- char *end_ptr= str + strlen(str);
ms_mcd_server_t *srvs= NULL;
- char buffer[512];
- char *ptr= NULL;
/**
* Servers list format is like this. For example:
* "localhost:11108, localhost:11109"
*/
- for (begin_ptr= str, string= index(str, ',');
- begin_ptr != end_ptr;
- string= index(begin_ptr, ','))
- {
- port= 0;
-
- if (string)
- {
- memcpy(buffer, begin_ptr, (size_t)(string - begin_ptr));
- buffer[(unsigned int)(string - begin_ptr)]= '\0';
- begin_ptr= string + 1;
- }
- else
- {
- size_t length= strlen(begin_ptr);
- memcpy(buffer, begin_ptr, length);
- buffer[length]= '\0';
- begin_ptr= end_ptr;
- }
-
- ptr= index(buffer, ':');
-
- if (ptr != NULL)
- {
- ptr[0]= '\0';
- ptr++;
- port= strtol(ptr, (char **)NULL, 10);
- }
+ memcached_server_st *server_pool;
+ server_pool = memcached_servers_parse(str);
+ for (uint32_t loop= 0; loop < memcached_server_list_count(server_pool); loop++)
+ {
assert(ms_setting.srv_cnt < ms_setting.total_srv_cnt);
- strcpy(ms_setting.servers[ms_setting.srv_cnt].srv_host_name, buffer);
- ms_setting.servers[ms_setting.srv_cnt].srv_port= (int)port;
+ strcpy(ms_setting.servers[ms_setting.srv_cnt].srv_host_name, server_pool[loop].hostname);
+ ms_setting.servers[ms_setting.srv_cnt].srv_port= server_pool[loop].port;
ms_setting.servers[ms_setting.srv_cnt].disconn_cnt= 0;
ms_setting.servers[ms_setting.srv_cnt].reconn_cnt= 0;
ms_setting.srv_cnt++;
if (ms_setting.srv_cnt >= ms_setting.total_srv_cnt)
{
- srvs= (ms_mcd_server_t *)realloc(
- ms_setting.servers,
- (uint64_t)ms_setting.total_srv_cnt
- * sizeof(ms_mcd_server_t) * 2);
+ srvs= (ms_mcd_server_t *)realloc( ms_setting.servers,
+ (size_t)ms_setting.total_srv_cnt * sizeof(ms_mcd_server_t) * 2);
if (srvs == NULL)
{
fprintf(stderr, "Can't reallocate servers structure.\n");
ms_setting.servers= srvs;
ms_setting.total_srv_cnt*= 2;
}
-
- if (isspace(*begin_ptr))
- begin_ptr++;
}
+
+ memcached_server_free(server_pool);
} /* ms_get_serverlist */
/**
* used to get the CPU count of the current system
*
- * @return return the cpu count if get, else return 1
+ * @return return the cpu count if get, else return EXIT_FAILURE
*/
-static int ms_get_cpu_count()
+static uint32_t ms_get_cpu_count()
{
#ifdef HAVE__SC_NPROCESSORS_ONLN
return sysconf(_SC_NPROCESSORS_CONF);
#endif
/* the system with one cpu at least */
- return 1;
+ return EXIT_FAILURE;
} /* ms_get_cpu_count */
*
* @param line, string of one line
*
- * @return if success, return 1, else return 0
+ * @return if success, return EXIT_FAILURE, else return EXIT_SUCCESS
*/
static int ms_is_line_data(char *line)
{
begin_ptr++;
}
if ((begin_ptr[0] == '\0') || (begin_ptr[0] == '#'))
- return 0;
+ return EXIT_SUCCESS;
- return 1;
+ return EXIT_FAILURE;
} /* ms_is_line_data */
* @param line, string of one line
* @param nread, length of the line
*
- * @return if it's EOF or not line data, return 0, else return 1
+ * @return if it's EOF or not line data, return EXIT_SUCCESS, else return EXIT_FAILURE
*/
static int ms_read_is_data(char *line, ssize_t nread)
{
if ((nread == EOF) || ! ms_is_line_data(line))
- return 0;
+ return EXIT_SUCCESS;
- return 1;
+ return EXIT_FAILURE;
} /* ms_read_is_data */
*/
static void ms_no_config_file()
{
- FILE *fd= fopen("config", "w+");
+ char userpath[PATH_MAX];
+ struct passwd *usr= NULL;
+ FILE *fd;
+
+ usr= getpwuid(getuid());
+
+ snprintf(userpath, PATH_MAX, "%s/%s", usr->pw_dir, DEFAULT_CONFIG_NAME);
+
+ if (access (userpath, F_OK | R_OK) == 0)
+ goto exit;
+ fd= fopen(userpath, "w+");
+
+ if (fd == NULL)
+ {
+ fprintf(stderr, "Could not create default configure file %s\n", userpath);
+ perror(strerror(errno));
+ exit(1);
+ }
fprintf(fd, "%s", DEFAULT_CONGIF_STR);
fclose(fd);
- ms_setting.cfg_file= strdup("config");
+exit:
+ ms_setting.cfg_file= strdup(userpath);
} /* ms_no_config_file */
FILE *f;
size_t start_len, end_len;
double proportion;
- size_t frequence;
char *line= NULL;
size_t read_len;
ssize_t nread;
int end_of_file= 0;
ms_key_distr_t *key_distr= NULL;
ms_value_distr_t *val_distr= NULL;
- bool no_cfg= false;
if (cfg_file == NULL)
{
ms_no_config_file();
cfg_file= ms_setting.cfg_file;
- no_cfg= true;
}
/*read key value configure file*/
if ((((nread= getline(&line, &read_len, f)) == 1)
|| ! ms_read_is_data(line, nread)) && (nread != EOF)) /* bypass blank line */
continue;
+
if (nread == EOF)
{
fprintf(stderr, "Bad configuration file, no configuration find.\n");
if (nread != EOF)
{
- if (sscanf(line, "%lu %lu %lf ", &start_len,
+ if (sscanf(line, "%zu %zu %lf ", &start_len,
&end_len, &proportion) != 3)
{
conf_type= ms_get_conf_type(line);
{
key_distr= (ms_key_distr_t *)realloc(
ms_setting.key_distr,
- (uint64_t)ms_setting.
+ (size_t)ms_setting.
total_key_rng_cnt * sizeof(ms_key_distr_t) * 2);
if (key_distr == NULL)
{
if (nread != EOF)
{
- if (sscanf(line, "%lu %lu %lf %lu", &start_len, &end_len,
- &proportion, &frequence) != 3)
+ if (sscanf(line, "%zu %zu %lf", &start_len, &end_len,
+ &proportion) != 3)
{
conf_type= ms_get_conf_type(line);
break;
{
val_distr= (ms_value_distr_t *)realloc(
ms_setting.value_distr,
- (uint64_t)ms_setting.
+ (size_t)ms_setting.
total_val_rng_cnt * sizeof(ms_value_distr_t) * 2);
if (val_distr == NULL)
{
if (nread != EOF)
{
- if (sscanf(line, "%d %lf\n", &cmd_type, &proportion) != 2)
+ if (sscanf(line, "%d %lf", &cmd_type, &proportion) != 2)
{
conf_type= ms_get_conf_type(line);
break;
}
+ if (cmd_type >= CMD_NULL)
+ {
+ continue;
+ }
ms_setting.cmd_distr[ms_setting.cmd_used_count].cmd_type=
cmd_type;
ms_setting.cmd_distr[ms_setting.cmd_used_count].cmd_prop=
fclose(f);
- if (no_cfg)
- {
- remove(ms_setting.cfg_file);
- }
-
if (line != NULL)
+ {
free(line);
+ }
} /* ms_parse_cfg_file */
* @param distr, pointer of distribution structure array
* @param length, length of the array
*
- * @return always return 0
+ * @return always return EXIT_SUCCESS
*/
static int ms_shuffle_distr(ms_distr_t *distr, int length)
{
} /* switch */
}
- return 0;
+ return EXIT_SUCCESS;
} /* ms_shuffle_distr */
exit(1);
}
- if (! ms_setting.binary_prot
+ if (! ms_setting.binary_prot_
&& ((start_len > MAX_KEY_SIZE) || (end_len > MAX_KEY_SIZE)))
{
fprintf(stderr, "key length must be less than 250 bytes.\n");
*/
static void ms_print_setting()
{
+ fprintf(stdout, "servers : %s\n", ms_setting.srv_str);
fprintf(stdout, "threads count: %d\n", ms_setting.nthreads);
fprintf(stdout, "concurrency: %d\n", ms_setting.nconns);
if (ms_setting.run_time > 0)
}
else
{
- fprintf(stdout, "execute number: %ld\n", ms_setting.exec_num);
+ fprintf(stdout, "execute number: %" PRId64 "\n", ms_setting.exec_num);
}
- fprintf(stdout, "windows size: %ldk\n",
+ fprintf(stdout, "windows size: %" PRId64 "k\n",
(int64_t)(ms_setting.win_size / 1024));
fprintf(stdout, "set proportion: set_prop=%.2f\n",
ms_setting.cmd_distr[CMD_SET].cmd_prop);
ms_setting.reconnect= false;
ms_setting.verbose= false;
ms_setting.facebook_test= false;
- ms_setting.binary_prot= false;
+ ms_setting.binary_prot_= false;
ms_setting.stat_freq= 0;
ms_setting.srv_str= NULL;
ms_setting.cfg_file= NULL;
ms_setting.run_time= DEFAULT_RUN_TIME;
ms_setting.total_srv_cnt= MCD_SRVS_NUM_INIT;
ms_setting.servers= (ms_mcd_server_t *)malloc(
- (uint64_t)ms_setting.total_srv_cnt
+ (size_t)ms_setting.total_srv_cnt
* sizeof(ms_mcd_server_t));
if (ms_setting.servers == NULL)
{
static void ms_setting_slapmode_init_post()
{
ms_setting.total_key_rng_cnt= KEY_RANGE_COUNT_INIT;
- ms_setting.key_distr= (ms_key_distr_t *)malloc(
- (uint64_t)ms_setting.total_key_rng_cnt
- * sizeof(ms_key_distr_t));
+ ms_setting.key_distr=
+ (ms_key_distr_t *)malloc((size_t)ms_setting.total_key_rng_cnt * sizeof(ms_key_distr_t));
+
if (ms_setting.key_distr == NULL)
{
fprintf(stderr, "Can't allocate key distribution structure.\n");
}
ms_setting.total_val_rng_cnt= VALUE_RANGE_COUNT_INIT;
- ms_setting.value_distr= (ms_value_distr_t *)malloc(
- (uint64_t)ms_setting.total_val_rng_cnt
- * sizeof(
- ms_value_distr_t));
+
+ ms_setting.value_distr=
+ (ms_value_distr_t *)malloc((size_t)ms_setting.total_val_rng_cnt * sizeof( ms_value_distr_t));
+
if (ms_setting.value_distr == NULL)
{
fprintf(stderr, "Can't allocate value distribution structure.\n");
exit(1);
}
- if ((ms_setting.udp
- || ms_setting.facebook_test) && ms_setting.binary_prot)
- {
- fprintf(stderr, "Binary protocol doesn't support UDP now.\n");
- exit(1);
- }
-
if ((ms_setting.rep_write_srv > 0) && (ms_setting.srv_cnt < 2))
{
fprintf(stderr, "Please specify 2 servers at least for replication\n");
exit(1);
}
- if ((ms_setting.rep_write_srv > 0) && (ms_setting.sock_per_conn > 1))
- {
- fprintf(stderr, "Replication doesn't support multi-socks "
- "in one connection structure.\n");
- exit(1);
- }
-
if (ms_setting.facebook_test && (ms_setting.rep_write_srv > 0))
{
fprintf(stderr, "facebook test couldn't work with replication.\n");
exit(1);
}
- if (ms_setting.reconnect && (ms_setting.sock_per_conn > 1))
- {
- fprintf(stderr, "Reconnection doesn't support multi-socks "
- "in one connection structure.\n");
- exit(1);
- }
-
ms_build_distr();
/* initialize global character block */