@@ -15804,6 +15804,83 @@ static bool sanitycheck(void)
1580415804 return true;
1580515805}
1580615806
15807+ static int try_load_config_file(const char *path,
15808+ char **username_ptr,
15809+ char **pid_file_ptr,
15810+ const char **engine_ptr,
15811+ bool *lock_memory_ptr,
15812+ bool *do_daemonize_ptr,
15813+ int *maxcore_ptr
15814+ #ifdef ENABLE_ZK_INTEGRATION
15815+ , int *arcus_zk_to_ptr
15816+ #endif
15817+ )
15818+ {
15819+ char *access_mask_str = NULL;
15820+ char *protocol_str = NULL;
15821+
15822+ struct config_item main_config_items[] = {
15823+ { .key = "port", .datatype = DT_UINT32, .value.dt_uint32 = (uint32_t*)&settings.port },
15824+ { .key = "udpport", .datatype = DT_UINT32, .value.dt_uint32 = (uint32_t*)&settings.udpport },
15825+ { .key = "socketpath", .datatype = DT_STRING, .value.dt_string = &settings.socketpath },
15826+ { .key = "access", .datatype = DT_STRING, .value.dt_string = &access_mask_str },
15827+ { .key = "listen", .datatype = DT_STRING, .value.dt_string = &settings.inter },
15828+ { .key = "daemonize", .datatype = DT_BOOL, .value.dt_bool = do_daemonize_ptr },
15829+ { .key = "maxcore", .datatype = DT_BOOL, .value.dt_bool = (bool*)&maxcore_ptr },
15830+ { .key = "username", .datatype = DT_STRING, .value.dt_string = username_ptr },
15831+ { .key = "maxconns", .datatype = DT_UINT32, .value.dt_uint32 = (uint32_t*)&settings.maxconns },
15832+ { .key = "lock_memory", .datatype = DT_BOOL, .value.dt_bool = lock_memory_ptr },
15833+ { .key = "verbosity", .datatype = DT_SIZE, .value.dt_size = (size_t*)&settings.verbose },
15834+ { .key = "pid_file", .datatype = DT_STRING, .value.dt_string = pid_file_ptr },
15835+ { .key = "threads", .datatype = DT_UINT32, .value.dt_uint32 = (uint32_t*)&settings.num_threads },
15836+ { .key = "reqs_per_event", .datatype = DT_UINT32, .value.dt_uint32 = (uint32_t*)&settings.reqs_per_event },
15837+ { .key = "backlog", .datatype = DT_UINT32, .value.dt_uint32 = (uint32_t*)&settings.backlog },
15838+ { .key = "protocol", .datatype = DT_STRING, .value.dt_string = &protocol_str },
15839+ { .key = "engine_path", .datatype = DT_STRING, .value.dt_string = (char**)&engine_ptr },
15840+
15841+ { .key = "memory_limit", .datatype = DT_SIZE, .value.dt_size = &settings.maxbytes },
15842+ { .key = "eviction", .datatype = DT_BOOL, .value.dt_bool = (bool*)&settings.evict_to_free },
15843+ { .key = "sticky_limit", .datatype = DT_SIZE, .value.dt_size = &settings.sticky_limit },
15844+ { .key = "factor", .datatype = DT_FLOAT, .value.dt_float = (float*)&settings.factor },
15845+ { .key = "chunk_size", .datatype = DT_SIZE, .value.dt_size = (size_t*)&settings.chunk_size },
15846+ { .key = "prefix_delimiter", .datatype = DT_CHAR, .value.dt_char = &settings.prefix_delimiter},
15847+ { .key = "use_cas", .datatype = DT_BOOL, .value.dt_bool = &settings.use_cas },
15848+ { .key = "item_size_max", .datatype = DT_SIZE, .value.dt_size = &settings.item_size_max },
15849+
15850+ #ifdef ENABLE_ZK_INTEGRATION
15851+ { .key = "zookeeper", .datatype = DT_STRING, .value.dt_string = (char**)&arcus_zk_cfg },
15852+ { .key = "zk_timeout", .datatype = DT_UINT32, .value.dt_uint32 = (uint32_t*)&arcus_zk_to },
15853+ #endif
15854+ { .key = NULL}
15855+ };
15856+
15857+ if (read_config_file(path, main_config_items, stderr) == -1) {
15858+ fprintf(stderr, "Error parsing config file. Aborting.\n");
15859+ return -1;
15860+ }
15861+
15862+ if (access_mask_str != NULL) {
15863+ settings.access = strtol(access_mask_str, NULL, 8);
15864+ free(access_mask_str);
15865+ }
15866+ if (protocol_str != NULL) {
15867+ if (strcmp(protocol_str, "auto") == 0) {
15868+ settings.binding_protocol = negotiating_prot;
15869+ } else if (strcmp(protocol_str, "binary") == 0) {
15870+ settings.binding_protocol = binary_prot;
15871+ } else if (strcmp(protocol_str, "ascii") == 0) {
15872+ settings.binding_protocol = ascii_prot;
15873+ } else {
15874+ fprintf(stderr, "Invalid value for binding protocol in config file: %s\n", protocol_str);
15875+ free(protocol_str);
15876+ return -1;
15877+ }
15878+ free(protocol_str);
15879+ }
15880+
15881+ return 0;
15882+ }
15883+
1580715884static void settings_reload_engine_config(void)
1580815885{
1580915886 ENGINE_ERROR_CODE ret;
@@ -15898,6 +15975,30 @@ int main (int argc, char **argv)
1589815975 return EX_OSERR;
1589915976 }
1590015977
15978+ /* parse config file */
15979+ if (argc > 1 && argv[1][0] != '-') {
15980+ const char *config_file = argv[1];
15981+
15982+ if (try_load_config_file(config_file,
15983+ &username,
15984+ &pid_file,
15985+ &engine,
15986+ &lock_memory,
15987+ &do_daemonize,
15988+ &maxcore
15989+ #ifdef ENABLE_ZK_INTEGRATION
15990+ , &arcus_zk_to
15991+ #endif
15992+ ) != 0) {
15993+ fprintf(stderr, "Error parsing config file '%s'.", config_file);
15994+ exit(EXIT_FAILURE);
15995+ }
15996+
15997+ optind = 2;
15998+ } else {
15999+ optind = 1;
16000+ }
16001+
1590116002 /* process arguments */
1590216003 while (-1 != (c = getopt(argc, argv,
1590316004 "a:" /* access mask for unix socket */
0 commit comments