From 20d9a60cbbc51f483d225bddae3c3c318331ce05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 11 Sep 2017 22:52:07 +0300 Subject: [PATCH 1/3] Don't remove util-linux-dev The util-linux-dev package on Alpine Linux provides the libuuid.so library and thus it must not be removed. --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 41d2a1a8d..388710437 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -14,7 +14,7 @@ sqlite-libs tcl-dev util-linux-dev xz xz-dev" # Packages that can be removed after build ARG REM_PKGS="bison bash cmake flex gcc git gnutls-dev g++ jansson-dev \ libedit-dev libgcrypt-dev lua-dev make ncurses-dev openssl-dev perl sqlite-dev \ -tcl-dev util-linux-dev xz-dev" +tcl-dev xz-dev" # MaxScale-specific parameters ARG MS_DIR=/MaxScale_workdir From 16127d893c1157f55ab14730f521dbd7ec1670b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 11 Sep 2017 13:55:46 +0300 Subject: [PATCH 2/3] Fix compilation failures on CentOS 6 Thread-local non-POD types are not supported on CentOS 6 and thus they need to be replaced with pointers to the relevant objects and initialized at runtime. In addition to this, functor objects don't appear to work as expected in CentOS 6 and replacing them with a simple for-loop seems to work. --- server/core/listener.cc | 19 +++-- .../modules/filter/dbfwfilter/dbfwfilter.cc | 73 +++++++++++-------- 2 files changed, 55 insertions(+), 37 deletions(-) diff --git a/server/core/listener.cc b/server/core/listener.cc index 873173196..04f28b0ba 100644 --- a/server/core/listener.cc +++ b/server/core/listener.cc @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -234,23 +235,29 @@ RSA* create_rsa(int bits) #endif } -static thread_local std::string ssl_errbuf; +// thread-local non-POD types are not supported with older versions of GCC +static thread_local std::string* ssl_errbuf; static const char* get_ssl_errors() { + if (ssl_errbuf == NULL) + { + ssl_errbuf = new std::string; + } + char errbuf[200]; // Enough space according to OpenSSL documentation - ssl_errbuf.clear(); + ssl_errbuf->clear(); for (int err = ERR_get_error(); err; err = ERR_get_error()) { - if (!ssl_errbuf.empty()) + if (!ssl_errbuf->empty()) { - ssl_errbuf += ", "; + ssl_errbuf->append(", "); } - ssl_errbuf += ERR_error_string(err, errbuf); + ssl_errbuf->append(ERR_error_string(err, errbuf)); } - return ssl_errbuf.c_str(); + return ssl_errbuf->c_str(); } /** diff --git a/server/modules/filter/dbfwfilter/dbfwfilter.cc b/server/modules/filter/dbfwfilter/dbfwfilter.cc index cef0f4ef9..921c8ba9b 100644 --- a/server/modules/filter/dbfwfilter/dbfwfilter.cc +++ b/server/modules/filter/dbfwfilter/dbfwfilter.cc @@ -93,12 +93,14 @@ int dbfw_yyparse(void*); MXS_END_DECLS /** The rules and users for each thread */ -thread_local struct +struct DbfwThread { int rule_version; RuleList rules; UserMap users; -} this_thread; +}; + +thread_local DbfwThread* this_thread = NULL; bool parse_at_times(const char** tok, char** saveptr, Rule* ruledef); bool parse_limit_queries(Dbfw* instance, Rule* ruledef, const char* rule, char** saveptr); @@ -127,7 +129,7 @@ static json_t* rules_to_json(const RuleList& rules) { json_t* rval = json_array(); - for (RuleList::const_iterator it = this_thread.rules.begin(); it != this_thread.rules.end(); it++) + for (RuleList::const_iterator it = this_thread->rules.begin(); it != this_thread->rules.end(); it++) { const SRule& rule = *it; json_array_append_new(rval, rule_to_json(rule)); @@ -397,7 +399,7 @@ bool dbfw_show_rules(const MODULECMD_ARG *argv, json_t** output) dcb_printf(dcb, "Rule, Type, Times Matched\n"); - if (this_thread.rules.empty() || this_thread.users.empty()) + if (this_thread->rules.empty() || this_thread->users.empty()) { if (!replace_rules(inst)) { @@ -405,7 +407,7 @@ bool dbfw_show_rules(const MODULECMD_ARG *argv, json_t** output) } } - for (RuleList::const_iterator it = this_thread.rules.begin(); it != this_thread.rules.end(); it++) + for (RuleList::const_iterator it = this_thread->rules.begin(); it != this_thread->rules.end(); it++) { const SRule& rule = *it; char buf[rule->name().length() + 200]; // Some extra space @@ -423,7 +425,7 @@ bool dbfw_show_rules_json(const MODULECMD_ARG *argv, json_t** output) json_t* arr = json_array(); - if (this_thread.rules.empty() || this_thread.users.empty()) + if (this_thread->rules.empty() || this_thread->users.empty()) { if (!replace_rules(inst)) { @@ -431,7 +433,7 @@ bool dbfw_show_rules_json(const MODULECMD_ARG *argv, json_t** output) } } - for (RuleList::const_iterator it = this_thread.rules.begin(); it != this_thread.rules.end(); it++) + for (RuleList::const_iterator it = this_thread->rules.begin(); it != this_thread->rules.end(); it++) { const SRule& rule = *it; json_array_append_new(arr, rule_to_json(rule)); @@ -441,6 +443,24 @@ bool dbfw_show_rules_json(const MODULECMD_ARG *argv, json_t** output) return true; } +static int dbfw_thr_init() +{ + int rval = 0; + + if ((this_thread = new (std::nothrow) DbfwThread) == NULL) + { + MXS_OOM(); + rval = -1; + } + + return rval; +} + +static void dbfw_thr_finish() +{ + MXS_EXCEPTION_GUARD(delete this_thread); +} + static const MXS_ENUM_VALUE action_values[] = { {"allow", FW_ACTION_ALLOW}, @@ -501,8 +521,8 @@ MXS_MODULE* MXS_CREATE_MODULE() &Dbfw::s_object, NULL, /* Process init. */ NULL, /* Process finish. */ - NULL, /* Thread init. */ - NULL, /* Thread finish. */ + dbfw_thr_init, /* Thread init. */ + dbfw_thr_finish, /* Thread finish. */ { { "rules", @@ -658,24 +678,15 @@ void dbfw_yyerror(void* scanner, const char* error) */ static SRule find_rule_by_name(const RuleList& rules, std::string name) { - class RuleNameComparator + for (RuleList::const_iterator it = rules.begin(); it != rules.end(); it++) { - public: - RuleNameComparator(std::string name): - m_name(name) - {} - - bool operator()(const SRule& rule) + if ((*it)->name() == name) { - return rule->name() == m_name; + return *it; } + } - private: - std::string m_name; - }; - - RuleList::const_iterator it = std::find_if(rules.begin(), rules.end(), RuleNameComparator(name)); - return it != rules.end() ? *it : SRule(); + return SRule(); } bool set_rule_name(void* scanner, char* name) @@ -1079,11 +1090,11 @@ bool replace_rules(Dbfw* instance) if (process_rule_file(filename, &rules, &users)) { - this_thread.rules.swap(rules); - this_thread.users.swap(users); + this_thread->rules.swap(rules); + this_thread->users.swap(users); rval = true; } - else if (!this_thread.rules.empty() && !this_thread.users.empty()) + else if (!this_thread->rules.empty() && !this_thread->users.empty()) { MXS_ERROR("Failed to parse rules at '%s'. Old rules are still used.", filename.c_str()); @@ -1103,14 +1114,14 @@ static bool update_rules(Dbfw* my_instance) bool rval = true; int rule_version = my_instance->get_rule_version(); - if (this_thread.rule_version < rule_version) + if (this_thread->rule_version < rule_version) { if (!replace_rules(my_instance)) { rval = false; } - this_thread.rule_version = rule_version; + this_thread->rule_version = rule_version; } return rval; @@ -1395,7 +1406,7 @@ int DbfwSession::routeQuery(GWBUF* buffer) ss_dassert(analyzed_queue); } - SUser suser = find_user_data(this_thread.users, user(), remote()); + SUser suser = find_user_data(this_thread->users, user(), remote()); bool query_ok = false; if (command_is_mandatory(buffer)) @@ -1659,7 +1670,7 @@ void Dbfw::diagnostics(DCB *dcb) const dcb_printf(dcb, "Firewall Filter\n"); dcb_printf(dcb, "Rule, Type, Times Matched\n"); - for (RuleList::const_iterator it = this_thread.rules.begin(); it != this_thread.rules.end(); it++) + for (RuleList::const_iterator it = this_thread->rules.begin(); it != this_thread->rules.end(); it++) { const SRule& rule = *it; char buf[rule->name().length() + 200]; @@ -1680,5 +1691,5 @@ void Dbfw::diagnostics(DCB *dcb) const */ json_t* Dbfw::diagnostics_json() const { - return rules_to_json(this_thread.rules); + return rules_to_json(this_thread->rules); } From 3841205704378678d3f10744da97443668920040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 11 Sep 2017 15:16:15 +0300 Subject: [PATCH 3/3] Update mxs729_maxadmin The test expected the old result for the test. --- maxscale-system-test/mxs729_maxadmin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maxscale-system-test/mxs729_maxadmin.cpp b/maxscale-system-test/mxs729_maxadmin.cpp index 07404efd5..2bd4e970e 100644 --- a/maxscale-system-test/mxs729_maxadmin.cpp +++ b/maxscale-system-test/mxs729_maxadmin.cpp @@ -21,7 +21,7 @@ const char * user_added = "The Linux user %s has successfully been enabled.\n"; const char * user_removed = "The Linux user %s has successfully been disabled.\n"; const char * remove_last_admin = "Cannot remove the last admin account"; const char * root_added = "User root has been successfully added.\n"; -const char * user_and_root = "Enabled Linux accounts (secure) : %s\n"; +const char * user_and_root = "Enabled Linux accounts (secure) : root, %s\n"; const char * user_only = "Enabled Linux accounts (secure) : root, %s\n"; void add_remove_maxadmin_user(TestConnections* Test)