#include #include #include #include "toml.h" #include "log_private.h" #include "stellar_config.h" #define CONFIG_LOG_ERROR(format, ...) STELLAR_LOG_ERROR(__thread_local_logger, "config", format, ##__VA_ARGS__) #define CONFIG_LOG_DEBUG(format, ...) STELLAR_LOG_DEBUG(__thread_local_logger, "config", format, ##__VA_ARGS__) // return 0: success // retuun -1: failed static int parse_snowflake_section(toml_table_t *root, struct snowflake_options *opts) { const char *ptr; toml_table_t *table; table = toml_table_in(root, "snowflake"); if (table == NULL) { CONFIG_LOG_ERROR("config file missing snowflake section"); return -1; } ptr = toml_raw_in(table, "snowflake_base"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing snowflake->snowflake_base"); return -1; } opts->snowflake_base = atoi(ptr); ptr = toml_raw_in(table, "snowflake_offset"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing snowflake->snowflake_offset"); return -1; } opts->snowflake_offset = atoi(ptr); return 0; } // return 0: success // retuun -1: failed static int parse_packet_io_section(toml_table_t *root, struct packet_io_options *opts) { int ret = -1; char *ptr_mode = NULL; char *ptr_dumpfile_path = NULL; char *ptr_app_symbol = NULL; char *ptr_dev_symbol = NULL; const char *ptr; toml_table_t *table; toml_array_t *mask_array; table = toml_table_in(root, "packet_io"); if (table == NULL) { CONFIG_LOG_ERROR("config file missing packet_io section"); goto error_out; } ptr = toml_raw_in(table, "mode"); if (ptr == NULL || toml_rtos(ptr, &ptr_mode) != 0) { CONFIG_LOG_ERROR("config file missing packet_io->mode"); goto error_out; } if (strcmp(ptr_mode, "dumpfile") == 0) { opts->mode = PACKET_IO_DUMPFILE; } else if (strcmp(ptr_mode, "dumpfilelist") == 0) { opts->mode = PACKET_IO_DUMPFILELIST; } else if (strcmp(ptr_mode, "marsio") == 0) { opts->mode = PACKET_IO_MARSIO; } else { CONFIG_LOG_ERROR("config file invalid packet_io->mode %s, only support dumpfile and marsio", ptr); goto error_out; } if (opts->mode == PACKET_IO_DUMPFILE || opts->mode == PACKET_IO_DUMPFILELIST) { ptr = toml_raw_in(table, "dumpfile_path"); if (ptr == NULL || toml_rtos(ptr, &ptr_dumpfile_path) != 0) { CONFIG_LOG_ERROR("config file missing packet_io->dumpfile_path"); goto error_out; } strcpy(opts->dumpfile_path, ptr_dumpfile_path); } else { ptr = toml_raw_in(table, "app_symbol"); if (ptr == NULL || toml_rtos(ptr, &ptr_app_symbol) != 0) { CONFIG_LOG_ERROR("config file missing packet_io->app_symbol"); goto error_out; } strcpy(opts->app_symbol, ptr_app_symbol); ptr = toml_raw_in(table, "dev_symbol"); if (ptr == NULL || toml_rtos(ptr, &ptr_dev_symbol) != 0) { CONFIG_LOG_ERROR("config file missing packet_io->dev_symbol"); goto error_out; } strcpy(opts->dev_symbol, ptr_dev_symbol); } ptr = toml_raw_in(table, "nr_worker_thread"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing packet_io->nr_worker_thread"); goto error_out; } if (atoi(ptr) <= 0 || atoi(ptr) > MAX_THREAD_NUM) { CONFIG_LOG_ERROR("config file invalid packet_io->nr_worker_thread %d, range [1, %d]", atoi(ptr), MAX_THREAD_NUM); goto error_out; } opts->nr_worker_thread = atoi(ptr); mask_array = toml_array_in(table, "cpu_mask"); if (mask_array == NULL) { CONFIG_LOG_ERROR("config file missing packet_io->cpu_mask"); goto error_out; } for (uint16_t i = 0; i < opts->nr_worker_thread; i++) { ptr = toml_raw_at(mask_array, i); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing packet_io->cpu_mask[%d]", i); goto error_out; } opts->cpu_mask[i] = atoi(ptr); } ret = 0; error_out: if (ptr_mode) { free(ptr_mode); } if (ptr_dumpfile_path) { free(ptr_dumpfile_path); } if (ptr_app_symbol) { free(ptr_app_symbol); } if (ptr_dev_symbol) { free(ptr_dev_symbol); } return ret; } // return 0: success // retuun -1: failed static int parse_schedule_options(toml_table_t *root, struct schedule_options *opts) { const char *ptr; toml_table_t *table; table = toml_table_in(root, "schedule"); if (table == NULL) { CONFIG_LOG_ERROR("config file missing schedule section"); return -1; } ptr = toml_raw_in(table, "merge_stat_interval"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing schedule->merge_stat_interval"); return -1; } opts->merge_stat_interval = atoll(ptr); if (opts->merge_stat_interval < 1 || opts->merge_stat_interval > 60000) { CONFIG_LOG_ERROR("config file invalid schedule->merge_stat_interval %ld, range [1, 60000]", opts->merge_stat_interval); return -1; } ptr = toml_raw_in(table, "output_stat_interval"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing schedule->output_stat_interval"); return -1; } opts->output_stat_interval = atoll(ptr); if (opts->output_stat_interval < 1 || opts->output_stat_interval > 60000) { CONFIG_LOG_ERROR("config file invalid schedule->output_stat_interval %ld, range [1, 60000]", opts->output_stat_interval); return -1; } ptr = toml_raw_in(table, "packet_io_yield_interval"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing schedule->packet_io_yield_interval"); return -1; } opts->packet_io_yield_interval = atoll(ptr); if (opts->packet_io_yield_interval < 1 || opts->packet_io_yield_interval > 60000) { CONFIG_LOG_ERROR("config file invalid schedule->packet_io_yield_interval %ld, range [1, 60000]", opts->packet_io_yield_interval); return -1; } return 0; } // return 0: success // retuun -1: failed int stellar_config_load(struct stellar_config *config, const char *file) { int ret = -1; char errbuf[200]; FILE *fp = NULL; toml_table_t *table = NULL; fp = fopen(file, "r"); if (fp == NULL) { CONFIG_LOG_ERROR("open config file %s failed, %s", file, strerror(errno)); goto error_out; } table = toml_parse_file(fp, errbuf, sizeof(errbuf)); if (table == NULL) { CONFIG_LOG_ERROR("parse config file %s failed, %s", file, errbuf); goto error_out; } if (parse_snowflake_section(table, &config->snowflake_opts) != 0) { goto error_out; } if (parse_packet_io_section(table, &config->pkt_io_opts) != 0) { goto error_out; } if (parse_schedule_options(table, &config->sched_opts) != 0) { goto error_out; } ret = 0; error_out: if (table) { toml_free(table); } if (fp) { fclose(fp); } return ret; } void stellar_config_print(const struct stellar_config *config) { if (config == NULL) { return; } const struct packet_io_options *pkt_io_opts = &config->pkt_io_opts; const struct snowflake_options *snowflake_opts = &config->snowflake_opts; // snowflake config CONFIG_LOG_DEBUG("snowflake->snowflake_base : %d", snowflake_opts->snowflake_base); CONFIG_LOG_DEBUG("snowflake->snowflake_offset : %d", snowflake_opts->snowflake_offset); // packet io config CONFIG_LOG_DEBUG("packet_io->mode : %s", pkt_io_opts->mode == PACKET_IO_DUMPFILE ? "dumpfile" : (pkt_io_opts->mode == PACKET_IO_DUMPFILELIST ? "dumpfilelist" : "marsio")); if (pkt_io_opts->mode == PACKET_IO_DUMPFILE || pkt_io_opts->mode == PACKET_IO_DUMPFILELIST) { CONFIG_LOG_DEBUG("packet_io->dumpfile_path : %s", pkt_io_opts->dumpfile_path); } else { CONFIG_LOG_DEBUG("packet_io->app_symbol : %s", pkt_io_opts->app_symbol); CONFIG_LOG_DEBUG("packet_io->dev_symbol : %s", pkt_io_opts->dev_symbol); } CONFIG_LOG_DEBUG("packet_io->nr_worker_thread : %d", pkt_io_opts->nr_worker_thread); for (uint16_t i = 0; i < pkt_io_opts->nr_worker_thread; i++) { CONFIG_LOG_DEBUG("packet_io->cpu_mask[%3d] : %d", i, pkt_io_opts->cpu_mask[i]); } // schedule config CONFIG_LOG_DEBUG("schedule->merge_stat_interval : %ld", config->sched_opts.merge_stat_interval); CONFIG_LOG_DEBUG("schedule->output_stat_interval : %ld", config->sched_opts.output_stat_interval); CONFIG_LOG_DEBUG("schedule->packet_io_yield_interval : %ld", config->sched_opts.packet_io_yield_interval); }