From 853a8fc4dc2ec23b8e6981a91dc58f91054bbac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Fri, 13 Mar 2015 21:26:43 +0000 Subject: [PATCH] Improving processing of command line options. Drafting implementation of command line options --initial and --reload (issues #230 and #231) Removing command line option --admin-pathdb Cleaning ProxySQL_GlobalVariables::process_opts_pre() and ProxySQL_GlobalVariables::process_opts_post() Standard_ProxySQL_Admin::init() now opens file GloVars.admindb instead of "proxysql.db" Improving command line processing in main() ProxySQL_ConfigFile::OpenFile() exits in case of parsing error Adding docs file on command line options --- .gitignore | 2 ++ doc/internal/command_line_options.txt | 19 ++++++++++ include/proxysql_glovars.hpp | 7 +++- lib/ProxySQL_GloVars.cpp | 52 ++++++++++++++++++--------- lib/Standard_ProxySQL_Admin.cpp | 2 +- lib/configfile.cpp | 1 + src/main.cpp | 52 +++++++++++++++++++++++++-- src/proxysql.cfg | 9 +++-- 8 files changed, 120 insertions(+), 24 deletions(-) create mode 100644 doc/internal/command_line_options.txt diff --git a/.gitignore b/.gitignore index 0be524937..e9ae4970d 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,8 @@ core #config proxysql.cnf* +proxysql.cfg* +proxysql.db* jeprof*heap perf.data* diff --git a/doc/internal/command_line_options.txt b/doc/internal/command_line_options.txt new file mode 100644 index 000000000..24a7da480 --- /dev/null +++ b/doc/internal/command_line_options.txt @@ -0,0 +1,19 @@ +Command Line Options + +Configuration of proxysql is performed through the processing of a config file, or a database file, or a combination of both. + +Config file is a read only file that proxysql does not modify. +Database file is a read write file that proxysql can modify. +The path of the config file can be passed to proxysql through the --config option. +The path to the database file cannot be passed to proxysql directly, instead it is possible to pass its directory (called datadir) through the --datadir option. +The database file is named proxysql.db inside the datadir. +Both config file and datadir have default values if not specified in the command line. + +If a datadir is not provided in the command line, the config file is read to parse a possible datadir. + +If a database file is present in the datadir, its configuration is used by proxysql. + +If the option --initial is present, the database file is deleted. +If a database file does not exist (or deleted because of --initial), the config file is parsed and a new database file is created based on its content. + +If the option --reload is specified, the config file is parsed and an attempt to merge its content with the database file is performed. diff --git a/include/proxysql_glovars.hpp b/include/proxysql_glovars.hpp index 3672f4d89..3e0a3833c 100644 --- a/include/proxysql_glovars.hpp +++ b/include/proxysql_glovars.hpp @@ -15,15 +15,20 @@ class ProxySQL_GlobalVariables { ez::ezOptionParser *opt; //ezOptionParser *opt; ProxySQL_ConfigFile *confFile; + bool configfile_open; char *__cmd_proxysql_config_file; char *__cmd_proxysql_datadir; - char *__cmd_proxysql_admin_pathdb; + //char *__cmd_proxysql_admin_pathdb; // bool __cmd_proxysql_print_version=false; int __cmd_proxysql_nostart; int __cmd_proxysql_foreground; int __cmd_proxysql_gdbg; + bool __cmd_proxysql_initial; + bool __cmd_proxysql_reload; char *__cmd_proxysql_admin_socket; char *config_file; + char *datadir; + char *admindb; struct { bool gdbg; bool nostart; diff --git a/lib/ProxySQL_GloVars.cpp b/lib/ProxySQL_GloVars.cpp index b9b3704b5..c80b69440 100644 --- a/lib/ProxySQL_GloVars.cpp +++ b/lib/ProxySQL_GloVars.cpp @@ -30,7 +30,14 @@ ProxySQL_GlobalVariables::ProxySQL_GlobalVariables() { confFile=NULL; __cmd_proxysql_config_file=NULL; __cmd_proxysql_datadir=NULL; - __cmd_proxysql_admin_pathdb=NULL; +// __cmd_proxysql_admin_pathdb=NULL; + + config_file=NULL; + datadir=NULL; + configfile_open=false; + + __cmd_proxysql_initial=false; + __cmd_proxysql_reload=false; global.gdbg=false; global.nostart=false; @@ -68,7 +75,9 @@ opt.add( opt->add((const char *)"~/proxysql.cnf",0,1,0,(const char *)"Configuraton file",(const char *)"-c",(const char *)"--config"); opt->add((const char *)"",0,1,0,(const char *)"Disable custom memory allocator",(const char *)"-m",(const char *)"--no-memory"); opt->add((const char *)"",0,1,0,(const char *)"Datadir",(const char *)"-D",(const char *)"--datadir"); - opt->add((const char *)"",0,1,0,(const char *)"Configuration DB path",(const char *)"-a",(const char *)"--admin-pathdb"); + opt->add((const char *)"",0,1,0,(const char *)"Rename/empty database file",(const char *)"--initial"); + opt->add((const char *)"",0,1,0,(const char *)"Merge config file into database file",(const char *)"--reload"); +// opt->add((const char *)"",0,1,0,(const char *)"Configuration DB path",(const char *)"-a",(const char *)"--admin-pathdb"); opt->add((const char *)"",0,1,0,(const char *)"Administration Unix Socket",(const char *)"-S",(const char *)"--admin-socket"); // opt.add("",0,0,0,"","-d","--debug"); // opt.add("",0,0,0,"","-d","--debug"); @@ -122,6 +131,24 @@ void ProxySQL_GlobalVariables::process_opts_pre() { global.use_proxysql_mem=true; } + if (opt->isSet("--initial")) { + __cmd_proxysql_initial=true; + } + + if (opt->isSet("--reload")) { + __cmd_proxysql_reload=true; + } + + + config_file=GloVars.__cmd_proxysql_config_file; + + if (config_file==NULL) { + config_file=(char *)"proxysql.cnf"; + //if (!g_file_test(config_file,(GFileTest)(G_FILE_TEST_EXISTS|G_FILE_TEST_IS_REGULAR))) { + if (Proxy_file_regular(config_file)==false) { + config_file=(char *)"/etc/proxysql.cnf"; + } + } #ifdef DEBUG init_debug_struct(); #endif @@ -139,7 +166,7 @@ void ProxySQL_GlobalVariables::process_opts_post() { if (opt->isSet("-f")) { global.foreground=true; } - +/* if (opt->isSet("-D")) { std::string datadir; opt->get("-D")->getString(datadir); @@ -153,7 +180,7 @@ void ProxySQL_GlobalVariables::process_opts_post() { if (GloVars.__cmd_proxysql_admin_pathdb) free(GloVars.__cmd_proxysql_admin_pathdb); GloVars.__cmd_proxysql_admin_pathdb=strdup(admindb_path.c_str()); } - +*/ if (opt->isSet("-S")) { std::string admin_socket; opt->get("-S")->getString(admin_socket); @@ -164,15 +191,6 @@ void ProxySQL_GlobalVariables::process_opts_post() { proxy_debug(PROXY_DEBUG_GENERIC, 4, "processing opts\n"); //gchar *config_file=*config_file_ptr; - config_file=GloVars.__cmd_proxysql_config_file; - - if (config_file==NULL) { - config_file=(char *)"proxysql.cnf"; - //if (!g_file_test(config_file,(GFileTest)(G_FILE_TEST_EXISTS|G_FILE_TEST_IS_REGULAR))) { - if (Proxy_file_regular(config_file)==false) { - config_file=(char *)"/etc/proxysql.cnf"; - } - } // rc=config_file_is_readable(config_file); // if (rc==0) { @@ -195,10 +213,10 @@ void ProxySQL_GlobalVariables::process_opts_post() { free(glovars.proxy_datadir); glovars.proxy_datadir=strdup(GloVars.__cmd_proxysql_datadir); } - if (GloVars.__cmd_proxysql_admin_pathdb) { - free(glovars.proxy_admin_pathdb); - glovars.proxy_admin_pathdb=strdup(GloVars.__cmd_proxysql_admin_pathdb); - } +// if (GloVars.__cmd_proxysql_admin_pathdb) { +// free(glovars.proxy_admin_pathdb); +// glovars.proxy_admin_pathdb=strdup(GloVars.__cmd_proxysql_admin_pathdb); +// } if (GloVars.__cmd_proxysql_admin_socket) { free(glovars.proxy_admin_socket); glovars.proxy_admin_socket=strdup(GloVars.__cmd_proxysql_admin_socket); diff --git a/lib/Standard_ProxySQL_Admin.cpp b/lib/Standard_ProxySQL_Admin.cpp index 59dda53e7..61987dd45 100644 --- a/lib/Standard_ProxySQL_Admin.cpp +++ b/lib/Standard_ProxySQL_Admin.cpp @@ -1420,7 +1420,7 @@ bool Standard_ProxySQL_Admin::init() { statsdb=new SQLite3DB(); statsdb->open((char *)"file:mem_statsdb?mode=memory&cache=shared", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX); configdb=new SQLite3DB(); - configdb->open((char *)"proxysql.db", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX); + configdb->open((char *)GloVars.admindb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX); tables_defs_admin=new std::vector; diff --git a/lib/configfile.cpp b/lib/configfile.cpp index 228d4ca8d..7d7adf1c6 100644 --- a/lib/configfile.cpp +++ b/lib/configfile.cpp @@ -63,6 +63,7 @@ bool ProxySQL_ConfigFile::OpenFile(const char *__filename) { { std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine() << " - " << pex.getError() << std::endl; + exit(EXIT_FAILURE); return false; } return true; diff --git a/src/main.cpp b/src/main.cpp index 47f7b8f55..4f089680b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -240,8 +240,56 @@ int main(int argc, const char * argv[]) { GloVars.parse(argc,argv); GloVars.process_opts_pre(); + + // alwasy try to open a config file + if (GloVars.confFile->OpenFile(GloVars.config_file) == true) { + GloVars.configfile_open=true; + } + + if (GloVars.__cmd_proxysql_datadir==NULL) { + // datadir was not specified , try to read config file + if (GloVars.configfile_open==true) { + const Setting& root = GloVars.confFile->cfg.getRoot(); + if (root.exists("datadir")==true) { + // reading datadir from config file + std::string datadir; + bool rc; + rc=root.lookupValue("datadir", datadir); + if (rc==true) { + GloVars.datadir=strdup(datadir.c_str()); + } else { + GloVars.datadir=(char *)"/var/run/proxysql"; + } + } else { + // datadir was not specified in config file + GloVars.datadir=(char *)"/var/run/proxysql"; + } + } else { + // config file not readable + GloVars.datadir=(char *)"/var/run/proxysql"; + std::cerr << "[Warning]: Cannot open config file " << GloVars.config_file << ". Using default datadir " << GloVars.datadir << endl; + } + } else { + GloVars.datadir=GloVars.__cmd_proxysql_datadir; + } + + GloVars.admindb=(char *)malloc(strlen(GloVars.datadir)+strlen((char *)"proxysql.db")+2); + sprintf(GloVars.admindb,"%s/%s",GloVars.datadir, (char *)"proxysql.db"); + + if (GloVars.__cmd_proxysql_initial==true) { + std::cerr << "Renaming database file " << GloVars.admindb << endl; + char *newpath=(char *)malloc(strlen(GloVars.admindb)+8); + sprintf(newpath,"%s.bak",GloVars.admindb); + rename(GloVars.admindb,newpath); // FIXME: should we check return value, or ignore whatever it successed or not? + } + + GloVars.confFile->ReadGlobals(); + + + GloVars.process_opts_post(); +/* //if (GloVars.confFile->OpenFile("proxysql.cnf2") == true) { if (GloVars.confFile->OpenFile(GloVars.config_file) == true) { // open config file @@ -249,11 +297,11 @@ int main(int argc, const char * argv[]) { std::cerr << "[Warning]: Cannot open config file " << GloVars.config_file << endl; //exit(EXIT_FAILURE); } - GloVars.confFile->ReadGlobals(); +*/ - bool rc; + //bool rc; dlerror(); char* dlsym_error = NULL; diff --git a/src/proxysql.cfg b/src/proxysql.cfg index ee9d50025..dfb15ca25 100644 --- a/src/proxysql.cfg +++ b/src/proxysql.cfg @@ -5,6 +5,9 @@ # Grammar is also copied at the end of this file + +datadir="/tmp" + # defines all the MySQL servers mysql_servers = ( @@ -26,7 +29,7 @@ mysql_servers = port=3306 hostgroup=0 }, - { address="127.0.0.1" , port=3306 , hostgroup=1 } + { address="127.0.0.1" , port=3306 , hostgroup=1 }, { address="127.0.0.2" , port=3306 , hostgroup=1 }, { address="127.0.0.3" , port=3306 , hostgroup=1 }, { address="127.0.0.4" , port=3306 , hostgroup=1 }, @@ -49,8 +52,8 @@ mysql_users: default_hostgroup = 0 # active = 1 }, - { username = "user1" , password = "password" , default_hostgroup = 0 , active = 0 }, -) + { username = "user1" , password = "password" , default_hostgroup = 0 , active = 0 } +,) # http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-File-Grammar