51f89714ac7c407f1039698444c6e2bbf3d23e70
3 * Author: Mingqiang Zhuang
5 * Created on February 10, 2009
7 * (c) Copyright 2009, Schooner Information Technology, Inc.
8 * http://www.schoonerinfotech.com/
15 #include "ms_setting.h"
18 #define MAX_EXEC_NUM 0x4000000000000000 /* 1 << 62 */
19 #define ADDR_ALIGN(addr) ((addr + 15) & ~(16 - 1)) /* 16 bytes aligned */
20 #define RAND_CHAR_SIZE (10 * 1024 * 1024) /* 10M character table */
21 #define RESERVED_RAND_CHAR_SIZE (2 * 1024 * 1024) /* reserved 2M to avoid pointer sloping over */
23 #define DEFAULT_THREADS_NUM 1 /* default start one thread */
24 #define DEFAULT_CONNS_NUM 16 /* default each thread with 16 connections */
25 #define DEFAULT_EXE_NUM 0 /* default execute number is 0 */
26 #define DEFAULT_VERIFY_RATE 0.0 /* default it doesn't do data verification */
27 #define DEFAULT_OVERWRITE_RATE 0.0 /* default it doesn't do overwrite */
28 #define DEFAULT_DIV 1 /* default it runs single get */
29 #define DEFAULT_RUN_TIME 600 /* default run time 10 minutes */
30 #define DEFAULT_WINDOW_SIZE (10 * UNIT_ITEMS_COUNT) /* default window size is 10k */
31 #define DEFAULT_SOCK_PER_CONN 1 /* default socks per connection is 1 */
33 /* Use this for string generation */
34 #define CHAR_COUNT 64 /* number of characters used to generate character table */
35 const char ALPHANUMBERICS
[]=
36 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.-";
38 ms_setting_st ms_setting
; /* store the settings specified by user */
41 /* read setting from configuration file */
42 static void ms_get_serverlist(char *str
);
43 static int ms_get_cpu_count(void);
44 ms_conf_type_t
ms_get_conf_type(char *line
);
45 static int ms_is_line_data(char *line
);
46 static int ms_read_is_data(char *line
, ssize_t nread
);
47 static void ms_no_config_file(void);
48 static void ms_parse_cfg_file(char *cfg_file
);
51 /* initialize setting structure */
52 static void ms_init_random_block(void);
53 static void ms_calc_avg_size(void);
54 static int ms_shuffle_distr(ms_distr_t
*distr
, int length
);
55 static void ms_build_distr(void);
56 static void ms_print_setting(void);
57 static void ms_setting_slapmode_init_pre(void);
58 static void ms_setting_slapmode_init_post(void);
62 * parse the server list string, and build the servers
63 * information structure array. this function is used to parse
64 * the command line options specified by user.
66 * @param str, the string of server list
68 static void ms_get_serverlist(char *str
)
73 char *end_ptr
= str
+ strlen(str
);
74 ms_mcd_server_t
*srvs
= NULL
;
79 * Servers list format is like this. For example:
80 * "localhost:11108, localhost:11109"
82 for (begin_ptr
= str
, string
= index(str
, ',');
84 string
= index(begin_ptr
, ','))
90 memcpy(buffer
, begin_ptr
, (size_t)(string
- begin_ptr
));
91 buffer
[(unsigned int)(string
- begin_ptr
)]= '\0';
92 begin_ptr
= string
+ 1;
96 size_t length
= strlen(begin_ptr
);
97 memcpy(buffer
, begin_ptr
, length
);
102 ptr
= index(buffer
, ':');
108 port
= strtol(ptr
, (char **)NULL
, 10);
111 assert(ms_setting
.srv_cnt
< ms_setting
.total_srv_cnt
);
112 strcpy(ms_setting
.servers
[ms_setting
.srv_cnt
].srv_host_name
, buffer
);
113 ms_setting
.servers
[ms_setting
.srv_cnt
].srv_port
= (int)port
;
114 ms_setting
.servers
[ms_setting
.srv_cnt
].disconn_cnt
= 0;
115 ms_setting
.servers
[ms_setting
.srv_cnt
].reconn_cnt
= 0;
116 ms_setting
.srv_cnt
++;
118 if (ms_setting
.srv_cnt
>= ms_setting
.total_srv_cnt
)
120 srvs
= (ms_mcd_server_t
*)realloc(
122 (uint64_t)ms_setting
.total_srv_cnt
123 * sizeof(ms_mcd_server_t
) * 2);
126 fprintf(stderr
, "Can't reallocate servers structure.\n");
129 ms_setting
.servers
= srvs
;
130 ms_setting
.total_srv_cnt
*= 2;
133 if (isspace(*begin_ptr
))
136 } /* ms_get_serverlist */
140 * used to get the CPU count of the current system
142 * @return return the cpu count if get, else return 1
144 static int ms_get_cpu_count()
146 #ifdef HAVE__SC_NPROCESSORS_ONLN
147 return sysconf(_SC_NPROCESSORS_CONF
);
150 # ifdef HAVE_CPU_SET_T
154 sched_getaffinity(0, sizeof(cpu_set_t
), &cpu_set
);
156 for (int i
= 0; i
< (sizeof(cpu_set_t
) * 8); i
++)
158 if (CPU_ISSET(i
, &cpu_set
))
169 /* the system with one cpu at least */
171 } /* ms_get_cpu_count */
175 * used to get the configure type based on the type string read
176 * from the configuration file.
178 * @param line, string of one line
180 * @return ms_conf_type_t
182 ms_conf_type_t
ms_get_conf_type(char *line
)
184 if (! memcmp(line
, "key", strlen("key")))
188 else if (! memcmp(line
, "value", strlen("value")))
192 else if (! memcmp(line
, "cmd", strlen("cmd")))
200 } /* ms_get_conf_type */
204 * judge whether the line is a line with useful data. used to
205 * parse the configuration file.
207 * @param line, string of one line
209 * @return if success, return 1, else return 0
211 static int ms_is_line_data(char *line
)
213 assert(line
!= NULL
);
215 char *begin_ptr
= line
;
217 while (isspace(*begin_ptr
))
221 if ((begin_ptr
[0] == '\0') || (begin_ptr
[0] == '#'))
225 } /* ms_is_line_data */
229 * function to bypass blank line and comments
231 * @param line, string of one line
232 * @param nread, length of the line
234 * @return if it's EOF or not line data, return 0, else return 1
236 static int ms_read_is_data(char *line
, ssize_t nread
)
238 if ((nread
== EOF
) || ! ms_is_line_data(line
))
242 } /* ms_read_is_data */
246 * if no configuration file, use this function to create the default
247 * configuration file.
249 static void ms_no_config_file()
251 FILE *fd
= fopen("config", "w+");
253 fprintf(fd
, "%s", DEFAULT_CONGIF_STR
);
256 ms_setting
.cfg_file
= strdup("config");
257 } /* ms_no_config_file */
261 * parse the configuration file
263 * @param cfg_file, the configuration file name
265 static void ms_parse_cfg_file(char *cfg_file
)
268 size_t start_len
, end_len
;
275 ms_conf_type_t conf_type
;
277 ms_key_distr_t
*key_distr
= NULL
;
278 ms_value_distr_t
*val_distr
= NULL
;
281 if (cfg_file
== NULL
)
284 cfg_file
= ms_setting
.cfg_file
;
288 /*read key value configure file*/
289 if ((f
= fopen(cfg_file
, "r")) == NULL
)
291 fprintf(stderr
, "Can not open file: '%s'.\n", cfg_file
);
297 if ((((nread
= getline(&line
, &read_len
, f
)) == 1)
298 || ! ms_read_is_data(line
, nread
)) && (nread
!= EOF
)) /* bypass blank line */
302 fprintf(stderr
, "Bad configuration file, no configuration find.\n");
305 conf_type
= ms_get_conf_type(line
);
309 while (! end_of_file
)
316 if ((((nread
= getline(&line
, &read_len
, f
)) == 1)
317 || ! ms_read_is_data(line
, nread
)) && (nread
!= EOF
)) /* bypass blank line */
322 if (sscanf(line
, "%lu %lu %lf ", &start_len
,
323 &end_len
, &proportion
) != 3)
325 conf_type
= ms_get_conf_type(line
);
328 ms_setting
.key_distr
[ms_setting
.key_rng_cnt
].start_len
= start_len
;
329 ms_setting
.key_distr
[ms_setting
.key_rng_cnt
].end_len
= end_len
;
330 ms_setting
.key_distr
[ms_setting
.key_rng_cnt
].key_prop
= proportion
;
331 ms_setting
.key_rng_cnt
++;
333 if (ms_setting
.key_rng_cnt
>= ms_setting
.total_key_rng_cnt
)
335 key_distr
= (ms_key_distr_t
*)realloc(
336 ms_setting
.key_distr
,
337 (uint64_t)ms_setting
.
338 total_key_rng_cnt
* sizeof(ms_key_distr_t
) * 2);
339 if (key_distr
== NULL
)
342 "Can't reallocate key distribution structure.\n");
345 ms_setting
.key_distr
= key_distr
;
346 ms_setting
.total_key_rng_cnt
*= 2;
358 if ((((nread
= getline(&line
, &read_len
, f
)) == 1)
359 || ! ms_read_is_data(line
, nread
)) && (nread
!= EOF
)) /* bypass blank line */
364 if (sscanf(line
, "%lu %lu %lf %lu", &start_len
, &end_len
,
365 &proportion
, &frequence
) != 3)
367 conf_type
= ms_get_conf_type(line
);
370 ms_setting
.value_distr
[ms_setting
.val_rng_cnt
].start_len
=
372 ms_setting
.value_distr
[ms_setting
.val_rng_cnt
].end_len
= end_len
;
373 ms_setting
.value_distr
[ms_setting
.val_rng_cnt
].value_prop
=
375 ms_setting
.val_rng_cnt
++;
377 if (ms_setting
.val_rng_cnt
>= ms_setting
.total_val_rng_cnt
)
379 val_distr
= (ms_value_distr_t
*)realloc(
380 ms_setting
.value_distr
,
381 (uint64_t)ms_setting
.
382 total_val_rng_cnt
* sizeof(ms_value_distr_t
) * 2);
383 if (val_distr
== NULL
)
386 "Can't reallocate key distribution structure.\n");
389 ms_setting
.value_distr
= val_distr
;
390 ms_setting
.total_val_rng_cnt
*= 2;
402 if ((((nread
= getline(&line
, &read_len
, f
)) == 1)
403 || ! ms_read_is_data(line
, nread
)) && (nread
!= EOF
)) /* bypass blank line */
408 if (sscanf(line
, "%d %lf\n", &cmd_type
, &proportion
) != 2)
410 conf_type
= ms_get_conf_type(line
);
413 ms_setting
.cmd_distr
[ms_setting
.cmd_used_count
].cmd_type
=
415 ms_setting
.cmd_distr
[ms_setting
.cmd_used_count
].cmd_prop
=
417 ms_setting
.cmd_used_count
++;
427 if ((((nread
= getline(&line
, &read_len
, f
)) == 1)
428 || ! ms_read_is_data(line
, nread
)) && (nread
!= EOF
)) /* bypass blank line */
433 if ((conf_type
= ms_get_conf_type(line
)) != CONF_NULL
)
454 remove(ms_setting
.cfg_file
);
459 } /* ms_parse_cfg_file */
462 /* calculate the average size of key and value */
463 static void ms_calc_avg_size()
465 double avg_val_size
= 0.0;
466 double avg_key_size
= 0.0;
469 double averge_len
= 0.0;
473 for (int j
= 0; j
< ms_setting
.val_rng_cnt
; j
++)
475 val_pro
= ms_setting
.value_distr
[j
].value_prop
;
476 start_len
= ms_setting
.value_distr
[j
].start_len
;
477 end_len
= ms_setting
.value_distr
[j
].end_len
;
479 averge_len
= val_pro
* ((double)(start_len
+ end_len
)) / 2;
480 avg_val_size
+= averge_len
;
483 for (int j
= 0; j
< ms_setting
.key_rng_cnt
; j
++)
485 key_pro
= ms_setting
.key_distr
[j
].key_prop
;
486 start_len
= ms_setting
.key_distr
[j
].start_len
;
487 end_len
= ms_setting
.key_distr
[j
].end_len
;
489 averge_len
= key_pro
* ((double)(start_len
+ end_len
)) / 2;
490 avg_key_size
+= averge_len
;
493 ms_setting
.avg_val_size
= (size_t)avg_val_size
;
494 ms_setting
.avg_key_size
= (size_t)avg_key_size
;
495 } /* ms_calc_avg_size */
499 * used to shuffle key and value distribution array to ensure
500 * (key, value) pair with different set.
502 * @param distr, pointer of distribution structure array
503 * @param length, length of the array
505 * @return always return 0
507 static int ms_shuffle_distr(ms_distr_t
*distr
, int length
)
514 for (i
= 0; i
< length
; i
++)
517 j
= (int)(rnd
% (length
- i
)) + i
;
522 tmp_size
= distr
[j
].key_size
;
523 distr
[j
].key_size
= distr
[i
].key_size
;
524 distr
[i
].key_size
= tmp_size
;
528 tmp_offset
= distr
[j
].key_offset
;
529 distr
[j
].key_offset
= distr
[i
].key_offset
;
530 distr
[i
].key_offset
= tmp_offset
;
534 tmp_size
= distr
[j
].value_size
;
535 distr
[j
].value_size
= distr
[i
].value_size
;
536 distr
[i
].value_size
= tmp_size
;
545 } /* ms_shuffle_distr */
549 * according to the key and value distribution, to build the
550 * (key, value) pair distribution. the (key, value) pair
551 * distribution array is global, each connection set or get
552 * object keeping this distribution, for the final result, we
553 * can reach the expected key and value distribution.
555 static void ms_build_distr()
561 size_t average_len
= 0;
566 ms_distr_t
*distr
= NULL
;
567 int units
= (int)ms_setting
.win_size
/ UNIT_ITEMS_COUNT
;
569 /* calculate average value size and key size */
572 ms_setting
.char_blk_size
= RAND_CHAR_SIZE
;
574 (int)((ms_setting
.char_blk_size
- RESERVED_RAND_CHAR_SIZE
)
577 ms_setting
.distr
= (ms_distr_t
*)malloc(
578 sizeof(ms_distr_t
) * ms_setting
.win_size
);
579 if (ms_setting
.distr
== NULL
)
581 fprintf(stderr
, "Can't allocate distribution array.");
586 * character block is divided by how many different key
587 * size, each different key size has the same size character
590 for (int m
= 0; m
< units
; m
++)
592 for (int i
= 0; i
< UNIT_ITEMS_COUNT
; i
++)
594 ms_setting
.distr
[m
* UNIT_ITEMS_COUNT
+ i
].key_offset
=
595 ADDR_ALIGN(key_scope_size
* i
);
599 /* initialize key size distribution */
600 for (int m
= 0; m
< units
; m
++)
602 for (int j
= 0; j
< ms_setting
.key_rng_cnt
; j
++)
604 key_cnt
= (int)(UNIT_ITEMS_COUNT
* ms_setting
.key_distr
[j
].key_prop
);
605 start_len
= ms_setting
.key_distr
[j
].start_len
;
606 end_len
= ms_setting
.key_distr
[j
].end_len
;
607 if ((start_len
< MIN_KEY_SIZE
) || (end_len
< MIN_KEY_SIZE
))
609 fprintf(stderr
, "key length must be greater than 16 bytes.\n");
613 if (! ms_setting
.binary_prot
614 && ((start_len
> MAX_KEY_SIZE
) || (end_len
> MAX_KEY_SIZE
)))
616 fprintf(stderr
, "key length must be less than 250 bytes.\n");
620 average_len
= (start_len
+ end_len
) / 2;
621 diff_len
= (end_len
- start_len
) / 2;
622 for (int k
= 0; k
< key_cnt
; k
++)
624 if (offset
>= (m
+ 1) * UNIT_ITEMS_COUNT
)
631 ms_setting
.distr
[offset
].key_size
=
632 (diff_len
== 0) ? average_len
:
633 average_len
+ (size_t)rnd
638 ms_setting
.distr
[offset
].key_size
=
639 (diff_len
== 0) ? average_len
:
640 average_len
- (size_t)rnd
647 if (offset
< (m
+ 1) * UNIT_ITEMS_COUNT
)
649 end
= (m
+ 1) * UNIT_ITEMS_COUNT
- offset
;
650 for (int i
= 0; i
< end
; i
++)
652 ms_setting
.distr
[offset
].key_size
= ms_setting
.avg_key_size
;
659 /* initialize value distribution */
660 if (ms_setting
.fixed_value_size
!= 0)
662 for (int i
= 0; i
< units
* UNIT_ITEMS_COUNT
; i
++)
664 ms_setting
.distr
[i
].value_size
= ms_setting
.fixed_value_size
;
669 for (int m
= 0; m
< units
; m
++)
671 for (int j
= 0; j
< ms_setting
.val_rng_cnt
; j
++)
674 (int)(UNIT_ITEMS_COUNT
* ms_setting
.value_distr
[j
].value_prop
);
675 start_len
= ms_setting
.value_distr
[j
].start_len
;
676 end_len
= ms_setting
.value_distr
[j
].end_len
;
677 if ((start_len
<= 0) || (end_len
<= 0))
679 fprintf(stderr
, "value length must be greater than 0 bytes.\n");
683 if ((start_len
> MAX_VALUE_SIZE
) || (end_len
> MAX_VALUE_SIZE
))
685 fprintf(stderr
, "key length must be less than or equal to 1M.\n");
689 average_len
= (start_len
+ end_len
) / 2;
690 diff_len
= (end_len
- start_len
) / 2;
691 for (int k
= 0; k
< value_cnt
; k
++)
693 if (offset
>= (m
+ 1) * UNIT_ITEMS_COUNT
)
700 ms_setting
.distr
[offset
].value_size
=
701 (diff_len
== 0) ? average_len
:
703 + (size_t)rnd
% diff_len
;
707 ms_setting
.distr
[offset
].value_size
=
708 (diff_len
== 0) ? average_len
:
710 - (size_t)rnd
% diff_len
;
716 if (offset
< (m
+ 1) * UNIT_ITEMS_COUNT
)
718 end
= (m
+ 1) * UNIT_ITEMS_COUNT
- offset
;
719 for (int i
= 0; i
< end
; i
++)
721 ms_setting
.distr
[offset
++].value_size
= ms_setting
.avg_val_size
;
727 /* shuffle distribution */
728 for (int i
= 0; i
< units
; i
++)
730 distr
= &ms_setting
.distr
[i
* UNIT_ITEMS_COUNT
];
731 for (int j
= 0; j
< 4; j
++)
733 ms_shuffle_distr(distr
, UNIT_ITEMS_COUNT
);
736 } /* ms_build_distr */
740 * used to initialize the global character block. The character
741 * block is used to generate the suffix of the key and value. we
742 * only store a pointer in the character block for each key
743 * suffix or value string. It can save much memory to store key
746 static void ms_init_random_block()
750 assert(ms_setting
.char_blk_size
> 0);
752 ms_setting
.char_block
= (char *)malloc(ms_setting
.char_blk_size
);
753 if (ms_setting
.char_block
== NULL
)
755 fprintf(stderr
, "Can't allocate global char block.");
758 ptr
= ms_setting
.char_block
;
760 for (int i
= 0; (size_t)i
< ms_setting
.char_blk_size
; i
++)
762 *(ptr
++)= ALPHANUMBERICS
[random() % CHAR_COUNT
];
764 } /* ms_init_random_block */
768 * after initialization, call this function to output the main
769 * configuration user specified.
771 static void ms_print_setting()
773 fprintf(stdout
, "threads count: %d\n", ms_setting
.nthreads
);
774 fprintf(stdout
, "concurrency: %d\n", ms_setting
.nconns
);
775 if (ms_setting
.run_time
> 0)
777 fprintf(stdout
, "run time: %ds\n", ms_setting
.run_time
);
781 fprintf(stdout
, "execute number: %ld\n", ms_setting
.exec_num
);
783 fprintf(stdout
, "windows size: %ldk\n",
784 (int64_t)(ms_setting
.win_size
/ 1024));
785 fprintf(stdout
, "set proportion: set_prop=%.2f\n",
786 ms_setting
.cmd_distr
[CMD_SET
].cmd_prop
);
787 fprintf(stdout
, "get proportion: get_prop=%.2f\n",
788 ms_setting
.cmd_distr
[CMD_GET
].cmd_prop
);
790 } /* ms_print_setting */
794 * previous part of slap mode initialization of setting structure
796 static void ms_setting_slapmode_init_pre()
798 ms_setting
.exec_num
= DEFAULT_EXE_NUM
;
799 ms_setting
.verify_percent
= DEFAULT_VERIFY_RATE
;
800 ms_setting
.exp_ver_per
= DEFAULT_VERIFY_RATE
;
801 ms_setting
.overwrite_percent
= DEFAULT_OVERWRITE_RATE
;
802 ms_setting
.mult_key_num
= DEFAULT_DIV
;
803 ms_setting
.fixed_value_size
= 0;
804 ms_setting
.win_size
= DEFAULT_WINDOW_SIZE
;
805 ms_setting
.udp
= false;
806 ms_setting
.reconnect
= false;
807 ms_setting
.verbose
= false;
808 ms_setting
.facebook_test
= false;
809 ms_setting
.binary_prot
= false;
810 ms_setting
.stat_freq
= 0;
811 ms_setting
.srv_str
= NULL
;
812 ms_setting
.cfg_file
= NULL
;
813 ms_setting
.sock_per_conn
= DEFAULT_SOCK_PER_CONN
;
814 ms_setting
.expected_tps
= 0;
815 ms_setting
.rep_write_srv
= 0;
816 } /* ms_setting_slapmode_init_pre */
820 * previous part of initialization of setting structure
822 void ms_setting_init_pre()
824 memset(&ms_setting
, 0, sizeof(ms_setting
));
826 /* common initialize */
827 ms_setting
.ncpu
= ms_get_cpu_count();
828 ms_setting
.nthreads
= DEFAULT_THREADS_NUM
;
829 ms_setting
.nconns
= DEFAULT_CONNS_NUM
;
830 ms_setting
.run_time
= DEFAULT_RUN_TIME
;
831 ms_setting
.total_srv_cnt
= MCD_SRVS_NUM_INIT
;
832 ms_setting
.servers
= (ms_mcd_server_t
*)malloc(
833 (uint64_t)ms_setting
.total_srv_cnt
834 * sizeof(ms_mcd_server_t
));
835 if (ms_setting
.servers
== NULL
)
837 fprintf(stderr
, "Can't allocate servers structure.\n");
841 ms_setting_slapmode_init_pre();
842 } /* ms_setting_init_pre */
846 * post part of slap mode initialization of setting structure
848 static void ms_setting_slapmode_init_post()
850 ms_setting
.total_key_rng_cnt
= KEY_RANGE_COUNT_INIT
;
851 ms_setting
.key_distr
= (ms_key_distr_t
*)malloc(
852 (uint64_t)ms_setting
.total_key_rng_cnt
853 * sizeof(ms_key_distr_t
));
854 if (ms_setting
.key_distr
== NULL
)
856 fprintf(stderr
, "Can't allocate key distribution structure.\n");
860 ms_setting
.total_val_rng_cnt
= VALUE_RANGE_COUNT_INIT
;
861 ms_setting
.value_distr
= (ms_value_distr_t
*)malloc(
862 (uint64_t)ms_setting
.total_val_rng_cnt
865 if (ms_setting
.value_distr
== NULL
)
867 fprintf(stderr
, "Can't allocate value distribution structure.\n");
871 ms_parse_cfg_file(ms_setting
.cfg_file
);
874 if ((ms_setting
.exec_num
== 0) && (ms_setting
.run_time
!= 0))
876 ms_setting
.exec_num
= (int64_t)MAX_EXEC_NUM
;
880 /* execute number mode */
881 ms_setting
.run_time
= 0;
884 if (ms_setting
.rep_write_srv
> 0)
886 /* for replication test, need enable reconnect feature */
887 ms_setting
.reconnect
= true;
890 if (ms_setting
.facebook_test
&& (ms_setting
.mult_key_num
< 2))
892 fprintf(stderr
, "facebook test must work with multi-get, "
893 "please specify multi-get key number "
894 "with '--division' option.\n");
898 if (ms_setting
.facebook_test
&& ms_setting
.udp
)
900 fprintf(stderr
, "facebook test couldn't work with UDP.\n");
904 if (ms_setting
.udp
&& (ms_setting
.sock_per_conn
> 1))
906 fprintf(stderr
, "UDP doesn't support multi-socks "
907 "in one connection structure.\n");
912 || ms_setting
.facebook_test
) && ms_setting
.binary_prot
)
914 fprintf(stderr
, "Binary protocol doesn't support UDP now.\n");
918 if ((ms_setting
.rep_write_srv
> 0) && (ms_setting
.srv_cnt
< 2))
920 fprintf(stderr
, "Please specify 2 servers at least for replication\n");
924 if ((ms_setting
.rep_write_srv
> 0)
925 && (ms_setting
.srv_cnt
< ms_setting
.rep_write_srv
))
927 fprintf(stderr
, "Servers to do replication writing "
928 "is larger than the total servers\n");
932 if (ms_setting
.udp
&& (ms_setting
.rep_write_srv
> 0))
934 fprintf(stderr
, "UDP doesn't support replication.\n");
938 if ((ms_setting
.rep_write_srv
> 0) && (ms_setting
.sock_per_conn
> 1))
940 fprintf(stderr
, "Replication doesn't support multi-socks "
941 "in one connection structure.\n");
945 if (ms_setting
.facebook_test
&& (ms_setting
.rep_write_srv
> 0))
947 fprintf(stderr
, "facebook test couldn't work with replication.\n");
951 if (ms_setting
.reconnect
&& (ms_setting
.sock_per_conn
> 1))
953 fprintf(stderr
, "Reconnection doesn't support multi-socks "
954 "in one connection structure.\n");
960 /* initialize global character block */
961 ms_init_random_block();
963 } /* ms_setting_slapmode_init_post */
967 * post part of initialization of setting structure
969 void ms_setting_init_post()
971 ms_get_serverlist(ms_setting
.srv_str
);
972 ms_setting_slapmode_init_post();
977 * clean up the global setting structure
979 void ms_setting_cleanup()
981 if (ms_setting
.distr
!= NULL
)
983 free(ms_setting
.distr
);
986 if (ms_setting
.char_block
!= NULL
)
988 free(ms_setting
.char_block
);
991 if (ms_setting
.srv_str
!= NULL
)
993 free(ms_setting
.srv_str
);
996 if (ms_setting
.cfg_file
!= NULL
)
998 free(ms_setting
.cfg_file
);
1001 if (ms_setting
.servers
!= NULL
)
1003 free(ms_setting
.servers
);
1006 if (ms_setting
.key_distr
!= NULL
)
1008 free(ms_setting
.key_distr
);
1011 if (ms_setting
.value_distr
!= NULL
)
1013 free(ms_setting
.value_distr
);
1015 } /* ms_setting_cleanup */