3 * Author: Mingqiang Zhuang
5 * Created on February 10, 2009
7 * (c) Copyright 2009, Schooner Information Technology, Inc.
8 * http://www.schoonerinfotech.com/
17 #include "ms_setting.h"
20 #define MAX_EXEC_NUM 0x4000000000000000 /* 1 << 62 */
21 #define ADDR_ALIGN(addr) ((addr + 15) & ~(16 - 1)) /* 16 bytes aligned */
22 #define RAND_CHAR_SIZE (10 * 1024 * 1024) /* 10M character table */
23 #define RESERVED_RAND_CHAR_SIZE (2 * 1024 * 1024) /* reserved 2M to avoid pointer sloping over */
25 #define DEFAULT_THREADS_NUM 1 /* default start one thread */
26 #define DEFAULT_CONNS_NUM 16 /* default each thread with 16 connections */
27 #define DEFAULT_EXE_NUM 0 /* default execute number is 0 */
28 #define DEFAULT_VERIFY_RATE 0.0 /* default it doesn't do data verification */
29 #define DEFAULT_OVERWRITE_RATE 0.0 /* default it doesn't do overwrite */
30 #define DEFAULT_DIV 1 /* default it runs single get */
31 #define DEFAULT_RUN_TIME 600 /* default run time 10 minutes */
32 #define DEFAULT_WINDOW_SIZE (10 * UNIT_ITEMS_COUNT) /* default window size is 10k */
33 #define DEFAULT_SOCK_PER_CONN 1 /* default socks per connection is 1 */
35 /* Use this for string generation */
36 #define CHAR_COUNT 64 /* number of characters used to generate character table */
37 const char ALPHANUMBERICS
[]=
38 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.-";
40 ms_setting_st ms_setting
; /* store the settings specified by user */
43 /* read setting from configuration file */
44 static void ms_get_serverlist(char *str
);
45 static int ms_get_cpu_count(void);
46 ms_conf_type_t
ms_get_conf_type(char *line
);
47 static int ms_is_line_data(char *line
);
48 static int ms_read_is_data(char *line
, ssize_t nread
);
49 static void ms_no_config_file(void);
50 static void ms_parse_cfg_file(char *cfg_file
);
53 /* initialize setting structure */
54 static void ms_init_random_block(void);
55 static void ms_calc_avg_size(void);
56 static int ms_shuffle_distr(ms_distr_t
*distr
, int length
);
57 static void ms_build_distr(void);
58 static void ms_print_setting(void);
59 static void ms_setting_slapmode_init_pre(void);
60 static void ms_setting_slapmode_init_post(void);
64 * parse the server list string, and build the servers
65 * information structure array. this function is used to parse
66 * the command line options specified by user.
68 * @param str, the string of server list
70 static void ms_get_serverlist(char *str
)
75 char *end_ptr
= str
+ strlen(str
);
76 ms_mcd_server_t
*srvs
= NULL
;
81 * Servers list format is like this. For example:
82 * "localhost:11108, localhost:11109"
84 for (begin_ptr
= str
, string
= index(str
, ',');
86 string
= index(begin_ptr
, ','))
92 memcpy(buffer
, begin_ptr
, (size_t)(string
- begin_ptr
));
93 buffer
[(unsigned int)(string
- begin_ptr
)]= '\0';
94 begin_ptr
= string
+ 1;
98 size_t length
= strlen(begin_ptr
);
99 memcpy(buffer
, begin_ptr
, length
);
100 buffer
[length
]= '\0';
104 ptr
= index(buffer
, ':');
110 port
= strtol(ptr
, (char **)NULL
, 10);
113 assert(ms_setting
.srv_cnt
< ms_setting
.total_srv_cnt
);
114 strcpy(ms_setting
.servers
[ms_setting
.srv_cnt
].srv_host_name
, buffer
);
115 ms_setting
.servers
[ms_setting
.srv_cnt
].srv_port
= (int)port
;
116 ms_setting
.servers
[ms_setting
.srv_cnt
].disconn_cnt
= 0;
117 ms_setting
.servers
[ms_setting
.srv_cnt
].reconn_cnt
= 0;
118 ms_setting
.srv_cnt
++;
120 if (ms_setting
.srv_cnt
>= ms_setting
.total_srv_cnt
)
122 srvs
= (ms_mcd_server_t
*)realloc(
124 (uint64_t)ms_setting
.total_srv_cnt
125 * sizeof(ms_mcd_server_t
) * 2);
128 fprintf(stderr
, "Can't reallocate servers structure.\n");
131 ms_setting
.servers
= srvs
;
132 ms_setting
.total_srv_cnt
*= 2;
135 if (isspace(*begin_ptr
))
138 } /* ms_get_serverlist */
142 * used to get the CPU count of the current system
144 * @return return the cpu count if get, else return 1
146 static int ms_get_cpu_count()
148 #ifdef HAVE__SC_NPROCESSORS_ONLN
149 return sysconf(_SC_NPROCESSORS_CONF
);
152 # ifdef HAVE_CPU_SET_T
156 sched_getaffinity(0, sizeof(cpu_set_t
), &cpu_set
);
158 for (int i
= 0; i
< (sizeof(cpu_set_t
) * 8); i
++)
160 if (CPU_ISSET(i
, &cpu_set
))
171 /* the system with one cpu at least */
173 } /* ms_get_cpu_count */
177 * used to get the configure type based on the type string read
178 * from the configuration file.
180 * @param line, string of one line
182 * @return ms_conf_type_t
184 ms_conf_type_t
ms_get_conf_type(char *line
)
186 if (! memcmp(line
, "key", strlen("key")))
190 else if (! memcmp(line
, "value", strlen("value")))
194 else if (! memcmp(line
, "cmd", strlen("cmd")))
202 } /* ms_get_conf_type */
206 * judge whether the line is a line with useful data. used to
207 * parse the configuration file.
209 * @param line, string of one line
211 * @return if success, return 1, else return 0
213 static int ms_is_line_data(char *line
)
215 assert(line
!= NULL
);
217 char *begin_ptr
= line
;
219 while (isspace(*begin_ptr
))
223 if ((begin_ptr
[0] == '\0') || (begin_ptr
[0] == '#'))
227 } /* ms_is_line_data */
231 * function to bypass blank line and comments
233 * @param line, string of one line
234 * @param nread, length of the line
236 * @return if it's EOF or not line data, return 0, else return 1
238 static int ms_read_is_data(char *line
, ssize_t nread
)
240 if ((nread
== EOF
) || ! ms_is_line_data(line
))
244 } /* ms_read_is_data */
248 * if no configuration file, use this function to create the default
249 * configuration file.
251 static void ms_no_config_file()
253 FILE *fd
= fopen("config", "w+");
255 fprintf(fd
, "%s", DEFAULT_CONGIF_STR
);
258 ms_setting
.cfg_file
= strdup("config");
259 } /* ms_no_config_file */
263 * parse the configuration file
265 * @param cfg_file, the configuration file name
267 static void ms_parse_cfg_file(char *cfg_file
)
270 size_t start_len
, end_len
;
277 ms_conf_type_t conf_type
;
279 ms_key_distr_t
*key_distr
= NULL
;
280 ms_value_distr_t
*val_distr
= NULL
;
283 if (cfg_file
== NULL
)
286 cfg_file
= ms_setting
.cfg_file
;
290 /*read key value configure file*/
291 if ((f
= fopen(cfg_file
, "r")) == NULL
)
293 fprintf(stderr
, "Can not open file: '%s'.\n", cfg_file
);
299 if ((((nread
= getline(&line
, &read_len
, f
)) == 1)
300 || ! ms_read_is_data(line
, nread
)) && (nread
!= EOF
)) /* bypass blank line */
304 fprintf(stderr
, "Bad configuration file, no configuration find.\n");
307 conf_type
= ms_get_conf_type(line
);
311 while (! end_of_file
)
318 if ((((nread
= getline(&line
, &read_len
, f
)) == 1)
319 || ! ms_read_is_data(line
, nread
)) && (nread
!= EOF
)) /* bypass blank line */
324 if (sscanf(line
, "%lu %lu %lf ", &start_len
,
325 &end_len
, &proportion
) != 3)
327 conf_type
= ms_get_conf_type(line
);
330 ms_setting
.key_distr
[ms_setting
.key_rng_cnt
].start_len
= start_len
;
331 ms_setting
.key_distr
[ms_setting
.key_rng_cnt
].end_len
= end_len
;
332 ms_setting
.key_distr
[ms_setting
.key_rng_cnt
].key_prop
= proportion
;
333 ms_setting
.key_rng_cnt
++;
335 if (ms_setting
.key_rng_cnt
>= ms_setting
.total_key_rng_cnt
)
337 key_distr
= (ms_key_distr_t
*)realloc(
338 ms_setting
.key_distr
,
339 (uint64_t)ms_setting
.
340 total_key_rng_cnt
* sizeof(ms_key_distr_t
) * 2);
341 if (key_distr
== NULL
)
344 "Can't reallocate key distribution structure.\n");
347 ms_setting
.key_distr
= key_distr
;
348 ms_setting
.total_key_rng_cnt
*= 2;
360 if ((((nread
= getline(&line
, &read_len
, f
)) == 1)
361 || ! ms_read_is_data(line
, nread
)) && (nread
!= EOF
)) /* bypass blank line */
366 if (sscanf(line
, "%lu %lu %lf %lu", &start_len
, &end_len
,
367 &proportion
, &frequence
) != 3)
369 conf_type
= ms_get_conf_type(line
);
372 ms_setting
.value_distr
[ms_setting
.val_rng_cnt
].start_len
=
374 ms_setting
.value_distr
[ms_setting
.val_rng_cnt
].end_len
= end_len
;
375 ms_setting
.value_distr
[ms_setting
.val_rng_cnt
].value_prop
=
377 ms_setting
.val_rng_cnt
++;
379 if (ms_setting
.val_rng_cnt
>= ms_setting
.total_val_rng_cnt
)
381 val_distr
= (ms_value_distr_t
*)realloc(
382 ms_setting
.value_distr
,
383 (uint64_t)ms_setting
.
384 total_val_rng_cnt
* sizeof(ms_value_distr_t
) * 2);
385 if (val_distr
== NULL
)
388 "Can't reallocate key distribution structure.\n");
391 ms_setting
.value_distr
= val_distr
;
392 ms_setting
.total_val_rng_cnt
*= 2;
404 if ((((nread
= getline(&line
, &read_len
, f
)) == 1)
405 || ! ms_read_is_data(line
, nread
)) && (nread
!= EOF
)) /* bypass blank line */
410 if (sscanf(line
, "%d %lf\n", &cmd_type
, &proportion
) != 2)
412 conf_type
= ms_get_conf_type(line
);
415 ms_setting
.cmd_distr
[ms_setting
.cmd_used_count
].cmd_type
=
417 ms_setting
.cmd_distr
[ms_setting
.cmd_used_count
].cmd_prop
=
419 ms_setting
.cmd_used_count
++;
429 if ((((nread
= getline(&line
, &read_len
, f
)) == 1)
430 || ! ms_read_is_data(line
, nread
)) && (nread
!= EOF
)) /* bypass blank line */
435 if ((conf_type
= ms_get_conf_type(line
)) != CONF_NULL
)
456 remove(ms_setting
.cfg_file
);
461 } /* ms_parse_cfg_file */
464 /* calculate the average size of key and value */
465 static void ms_calc_avg_size()
467 double avg_val_size
= 0.0;
468 double avg_key_size
= 0.0;
471 double averge_len
= 0.0;
475 for (int j
= 0; j
< ms_setting
.val_rng_cnt
; j
++)
477 val_pro
= ms_setting
.value_distr
[j
].value_prop
;
478 start_len
= ms_setting
.value_distr
[j
].start_len
;
479 end_len
= ms_setting
.value_distr
[j
].end_len
;
481 averge_len
= val_pro
* ((double)(start_len
+ end_len
)) / 2;
482 avg_val_size
+= averge_len
;
485 for (int j
= 0; j
< ms_setting
.key_rng_cnt
; j
++)
487 key_pro
= ms_setting
.key_distr
[j
].key_prop
;
488 start_len
= ms_setting
.key_distr
[j
].start_len
;
489 end_len
= ms_setting
.key_distr
[j
].end_len
;
491 averge_len
= key_pro
* ((double)(start_len
+ end_len
)) / 2;
492 avg_key_size
+= averge_len
;
495 ms_setting
.avg_val_size
= (size_t)avg_val_size
;
496 ms_setting
.avg_key_size
= (size_t)avg_key_size
;
497 } /* ms_calc_avg_size */
501 * used to shuffle key and value distribution array to ensure
502 * (key, value) pair with different set.
504 * @param distr, pointer of distribution structure array
505 * @param length, length of the array
507 * @return always return 0
509 static int ms_shuffle_distr(ms_distr_t
*distr
, int length
)
516 for (i
= 0; i
< length
; i
++)
519 j
= (int)(rnd
% (length
- i
)) + i
;
524 tmp_size
= distr
[j
].key_size
;
525 distr
[j
].key_size
= distr
[i
].key_size
;
526 distr
[i
].key_size
= tmp_size
;
530 tmp_offset
= distr
[j
].key_offset
;
531 distr
[j
].key_offset
= distr
[i
].key_offset
;
532 distr
[i
].key_offset
= tmp_offset
;
536 tmp_size
= distr
[j
].value_size
;
537 distr
[j
].value_size
= distr
[i
].value_size
;
538 distr
[i
].value_size
= tmp_size
;
547 } /* ms_shuffle_distr */
551 * according to the key and value distribution, to build the
552 * (key, value) pair distribution. the (key, value) pair
553 * distribution array is global, each connection set or get
554 * object keeping this distribution, for the final result, we
555 * can reach the expected key and value distribution.
557 static void ms_build_distr()
563 size_t average_len
= 0;
568 ms_distr_t
*distr
= NULL
;
569 int units
= (int)ms_setting
.win_size
/ UNIT_ITEMS_COUNT
;
571 /* calculate average value size and key size */
574 ms_setting
.char_blk_size
= RAND_CHAR_SIZE
;
576 (int)((ms_setting
.char_blk_size
- RESERVED_RAND_CHAR_SIZE
)
579 ms_setting
.distr
= (ms_distr_t
*)malloc(
580 sizeof(ms_distr_t
) * ms_setting
.win_size
);
581 if (ms_setting
.distr
== NULL
)
583 fprintf(stderr
, "Can't allocate distribution array.");
588 * character block is divided by how many different key
589 * size, each different key size has the same size character
592 for (int m
= 0; m
< units
; m
++)
594 for (int i
= 0; i
< UNIT_ITEMS_COUNT
; i
++)
596 ms_setting
.distr
[m
* UNIT_ITEMS_COUNT
+ i
].key_offset
=
597 ADDR_ALIGN(key_scope_size
* i
);
601 /* initialize key size distribution */
602 for (int m
= 0; m
< units
; m
++)
604 for (int j
= 0; j
< ms_setting
.key_rng_cnt
; j
++)
606 key_cnt
= (int)(UNIT_ITEMS_COUNT
* ms_setting
.key_distr
[j
].key_prop
);
607 start_len
= ms_setting
.key_distr
[j
].start_len
;
608 end_len
= ms_setting
.key_distr
[j
].end_len
;
609 if ((start_len
< MIN_KEY_SIZE
) || (end_len
< MIN_KEY_SIZE
))
611 fprintf(stderr
, "key length must be greater than 16 bytes.\n");
615 if (! ms_setting
.binary_prot
616 && ((start_len
> MAX_KEY_SIZE
) || (end_len
> MAX_KEY_SIZE
)))
618 fprintf(stderr
, "key length must be less than 250 bytes.\n");
622 average_len
= (start_len
+ end_len
) / 2;
623 diff_len
= (end_len
- start_len
) / 2;
624 for (int k
= 0; k
< key_cnt
; k
++)
626 if (offset
>= (m
+ 1) * UNIT_ITEMS_COUNT
)
633 ms_setting
.distr
[offset
].key_size
=
634 (diff_len
== 0) ? average_len
:
635 average_len
+ (size_t)rnd
640 ms_setting
.distr
[offset
].key_size
=
641 (diff_len
== 0) ? average_len
:
642 average_len
- (size_t)rnd
649 if (offset
< (m
+ 1) * UNIT_ITEMS_COUNT
)
651 end
= (m
+ 1) * UNIT_ITEMS_COUNT
- offset
;
652 for (int i
= 0; i
< end
; i
++)
654 ms_setting
.distr
[offset
].key_size
= ms_setting
.avg_key_size
;
661 /* initialize value distribution */
662 if (ms_setting
.fixed_value_size
!= 0)
664 for (int i
= 0; i
< units
* UNIT_ITEMS_COUNT
; i
++)
666 ms_setting
.distr
[i
].value_size
= ms_setting
.fixed_value_size
;
671 for (int m
= 0; m
< units
; m
++)
673 for (int j
= 0; j
< ms_setting
.val_rng_cnt
; j
++)
676 (int)(UNIT_ITEMS_COUNT
* ms_setting
.value_distr
[j
].value_prop
);
677 start_len
= ms_setting
.value_distr
[j
].start_len
;
678 end_len
= ms_setting
.value_distr
[j
].end_len
;
679 if ((start_len
<= 0) || (end_len
<= 0))
681 fprintf(stderr
, "value length must be greater than 0 bytes.\n");
685 if ((start_len
> MAX_VALUE_SIZE
) || (end_len
> MAX_VALUE_SIZE
))
687 fprintf(stderr
, "key length must be less than or equal to 1M.\n");
691 average_len
= (start_len
+ end_len
) / 2;
692 diff_len
= (end_len
- start_len
) / 2;
693 for (int k
= 0; k
< value_cnt
; k
++)
695 if (offset
>= (m
+ 1) * UNIT_ITEMS_COUNT
)
702 ms_setting
.distr
[offset
].value_size
=
703 (diff_len
== 0) ? average_len
:
705 + (size_t)rnd
% diff_len
;
709 ms_setting
.distr
[offset
].value_size
=
710 (diff_len
== 0) ? average_len
:
712 - (size_t)rnd
% diff_len
;
718 if (offset
< (m
+ 1) * UNIT_ITEMS_COUNT
)
720 end
= (m
+ 1) * UNIT_ITEMS_COUNT
- offset
;
721 for (int i
= 0; i
< end
; i
++)
723 ms_setting
.distr
[offset
++].value_size
= ms_setting
.avg_val_size
;
729 /* shuffle distribution */
730 for (int i
= 0; i
< units
; i
++)
732 distr
= &ms_setting
.distr
[i
* UNIT_ITEMS_COUNT
];
733 for (int j
= 0; j
< 4; j
++)
735 ms_shuffle_distr(distr
, UNIT_ITEMS_COUNT
);
738 } /* ms_build_distr */
742 * used to initialize the global character block. The character
743 * block is used to generate the suffix of the key and value. we
744 * only store a pointer in the character block for each key
745 * suffix or value string. It can save much memory to store key
748 static void ms_init_random_block()
752 assert(ms_setting
.char_blk_size
> 0);
754 ms_setting
.char_block
= (char *)malloc(ms_setting
.char_blk_size
);
755 if (ms_setting
.char_block
== NULL
)
757 fprintf(stderr
, "Can't allocate global char block.");
760 ptr
= ms_setting
.char_block
;
762 for (int i
= 0; (size_t)i
< ms_setting
.char_blk_size
; i
++)
764 *(ptr
++)= ALPHANUMBERICS
[random() % CHAR_COUNT
];
766 } /* ms_init_random_block */
770 * after initialization, call this function to output the main
771 * configuration user specified.
773 static void ms_print_setting()
775 fprintf(stdout
, "threads count: %d\n", ms_setting
.nthreads
);
776 fprintf(stdout
, "concurrency: %d\n", ms_setting
.nconns
);
777 if (ms_setting
.run_time
> 0)
779 fprintf(stdout
, "run time: %ds\n", ms_setting
.run_time
);
783 fprintf(stdout
, "execute number: %ld\n", ms_setting
.exec_num
);
785 fprintf(stdout
, "windows size: %ldk\n",
786 (int64_t)(ms_setting
.win_size
/ 1024));
787 fprintf(stdout
, "set proportion: set_prop=%.2f\n",
788 ms_setting
.cmd_distr
[CMD_SET
].cmd_prop
);
789 fprintf(stdout
, "get proportion: get_prop=%.2f\n",
790 ms_setting
.cmd_distr
[CMD_GET
].cmd_prop
);
792 } /* ms_print_setting */
796 * previous part of slap mode initialization of setting structure
798 static void ms_setting_slapmode_init_pre()
800 ms_setting
.exec_num
= DEFAULT_EXE_NUM
;
801 ms_setting
.verify_percent
= DEFAULT_VERIFY_RATE
;
802 ms_setting
.exp_ver_per
= DEFAULT_VERIFY_RATE
;
803 ms_setting
.overwrite_percent
= DEFAULT_OVERWRITE_RATE
;
804 ms_setting
.mult_key_num
= DEFAULT_DIV
;
805 ms_setting
.fixed_value_size
= 0;
806 ms_setting
.win_size
= DEFAULT_WINDOW_SIZE
;
807 ms_setting
.udp
= false;
808 ms_setting
.reconnect
= false;
809 ms_setting
.verbose
= false;
810 ms_setting
.facebook_test
= false;
811 ms_setting
.binary_prot
= false;
812 ms_setting
.stat_freq
= 0;
813 ms_setting
.srv_str
= NULL
;
814 ms_setting
.cfg_file
= NULL
;
815 ms_setting
.sock_per_conn
= DEFAULT_SOCK_PER_CONN
;
816 ms_setting
.expected_tps
= 0;
817 ms_setting
.rep_write_srv
= 0;
818 } /* ms_setting_slapmode_init_pre */
822 * previous part of initialization of setting structure
824 void ms_setting_init_pre()
826 memset(&ms_setting
, 0, sizeof(ms_setting
));
828 /* common initialize */
829 ms_setting
.ncpu
= ms_get_cpu_count();
830 ms_setting
.nthreads
= DEFAULT_THREADS_NUM
;
831 ms_setting
.nconns
= DEFAULT_CONNS_NUM
;
832 ms_setting
.run_time
= DEFAULT_RUN_TIME
;
833 ms_setting
.total_srv_cnt
= MCD_SRVS_NUM_INIT
;
834 ms_setting
.servers
= (ms_mcd_server_t
*)malloc(
835 (uint64_t)ms_setting
.total_srv_cnt
836 * sizeof(ms_mcd_server_t
));
837 if (ms_setting
.servers
== NULL
)
839 fprintf(stderr
, "Can't allocate servers structure.\n");
843 ms_setting_slapmode_init_pre();
844 } /* ms_setting_init_pre */
848 * post part of slap mode initialization of setting structure
850 static void ms_setting_slapmode_init_post()
852 ms_setting
.total_key_rng_cnt
= KEY_RANGE_COUNT_INIT
;
853 ms_setting
.key_distr
= (ms_key_distr_t
*)malloc(
854 (uint64_t)ms_setting
.total_key_rng_cnt
855 * sizeof(ms_key_distr_t
));
856 if (ms_setting
.key_distr
== NULL
)
858 fprintf(stderr
, "Can't allocate key distribution structure.\n");
862 ms_setting
.total_val_rng_cnt
= VALUE_RANGE_COUNT_INIT
;
863 ms_setting
.value_distr
= (ms_value_distr_t
*)malloc(
864 (uint64_t)ms_setting
.total_val_rng_cnt
867 if (ms_setting
.value_distr
== NULL
)
869 fprintf(stderr
, "Can't allocate value distribution structure.\n");
873 ms_parse_cfg_file(ms_setting
.cfg_file
);
876 if ((ms_setting
.exec_num
== 0) && (ms_setting
.run_time
!= 0))
878 ms_setting
.exec_num
= (int64_t)MAX_EXEC_NUM
;
882 /* execute number mode */
883 ms_setting
.run_time
= 0;
886 if (ms_setting
.rep_write_srv
> 0)
888 /* for replication test, need enable reconnect feature */
889 ms_setting
.reconnect
= true;
892 if (ms_setting
.facebook_test
&& (ms_setting
.mult_key_num
< 2))
894 fprintf(stderr
, "facebook test must work with multi-get, "
895 "please specify multi-get key number "
896 "with '--division' option.\n");
900 if (ms_setting
.facebook_test
&& ms_setting
.udp
)
902 fprintf(stderr
, "facebook test couldn't work with UDP.\n");
906 if (ms_setting
.udp
&& (ms_setting
.sock_per_conn
> 1))
908 fprintf(stderr
, "UDP doesn't support multi-socks "
909 "in one connection structure.\n");
914 || ms_setting
.facebook_test
) && ms_setting
.binary_prot
)
916 fprintf(stderr
, "Binary protocol doesn't support UDP now.\n");
920 if ((ms_setting
.rep_write_srv
> 0) && (ms_setting
.srv_cnt
< 2))
922 fprintf(stderr
, "Please specify 2 servers at least for replication\n");
926 if ((ms_setting
.rep_write_srv
> 0)
927 && (ms_setting
.srv_cnt
< ms_setting
.rep_write_srv
))
929 fprintf(stderr
, "Servers to do replication writing "
930 "is larger than the total servers\n");
934 if (ms_setting
.udp
&& (ms_setting
.rep_write_srv
> 0))
936 fprintf(stderr
, "UDP doesn't support replication.\n");
940 if ((ms_setting
.rep_write_srv
> 0) && (ms_setting
.sock_per_conn
> 1))
942 fprintf(stderr
, "Replication doesn't support multi-socks "
943 "in one connection structure.\n");
947 if (ms_setting
.facebook_test
&& (ms_setting
.rep_write_srv
> 0))
949 fprintf(stderr
, "facebook test couldn't work with replication.\n");
953 if (ms_setting
.reconnect
&& (ms_setting
.sock_per_conn
> 1))
955 fprintf(stderr
, "Reconnection doesn't support multi-socks "
956 "in one connection structure.\n");
962 /* initialize global character block */
963 ms_init_random_block();
965 } /* ms_setting_slapmode_init_post */
969 * post part of initialization of setting structure
971 void ms_setting_init_post()
973 ms_get_serverlist(ms_setting
.srv_str
);
974 ms_setting_slapmode_init_post();
979 * clean up the global setting structure
981 void ms_setting_cleanup()
983 if (ms_setting
.distr
!= NULL
)
985 free(ms_setting
.distr
);
988 if (ms_setting
.char_block
!= NULL
)
990 free(ms_setting
.char_block
);
993 if (ms_setting
.srv_str
!= NULL
)
995 free(ms_setting
.srv_str
);
998 if (ms_setting
.cfg_file
!= NULL
)
1000 free(ms_setting
.cfg_file
);
1003 if (ms_setting
.servers
!= NULL
)
1005 free(ms_setting
.servers
);
1008 if (ms_setting
.key_distr
!= NULL
)
1010 free(ms_setting
.key_distr
);
1013 if (ms_setting
.value_distr
!= NULL
)
1015 free(ms_setting
.value_distr
);
1017 } /* ms_setting_cleanup */