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.
This commit is contained in:
Markus Mäkelä
2017-09-11 13:55:46 +03:00
parent 20d9a60cbb
commit 16127d893c
2 changed files with 55 additions and 37 deletions

View File

@ -36,6 +36,7 @@
#include <maxscale/listener.h> #include <maxscale/listener.h>
#include <maxscale/paths.h> #include <maxscale/paths.h>
#include <maxscale/ssl.h> #include <maxscale/ssl.h>
#include <maxscale/platform.h>
#include <maxscale/protocol.h> #include <maxscale/protocol.h>
#include <maxscale/log_manager.h> #include <maxscale/log_manager.h>
#include <maxscale/alloc.h> #include <maxscale/alloc.h>
@ -234,23 +235,29 @@ RSA* create_rsa(int bits)
#endif #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() static const char* get_ssl_errors()
{ {
if (ssl_errbuf == NULL)
{
ssl_errbuf = new std::string;
}
char errbuf[200]; // Enough space according to OpenSSL documentation 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()) 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();
} }
/** /**

View File

@ -93,12 +93,14 @@ int dbfw_yyparse(void*);
MXS_END_DECLS MXS_END_DECLS
/** The rules and users for each thread */ /** The rules and users for each thread */
thread_local struct struct DbfwThread
{ {
int rule_version; int rule_version;
RuleList rules; RuleList rules;
UserMap users; UserMap users;
} this_thread; };
thread_local DbfwThread* this_thread = NULL;
bool parse_at_times(const char** tok, char** saveptr, Rule* ruledef); bool parse_at_times(const char** tok, char** saveptr, Rule* ruledef);
bool parse_limit_queries(Dbfw* instance, Rule* ruledef, const char* rule, char** saveptr); 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(); 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; const SRule& rule = *it;
json_array_append_new(rval, rule_to_json(rule)); 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"); 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)) 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; const SRule& rule = *it;
char buf[rule->name().length() + 200]; // Some extra space 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(); 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)) 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; const SRule& rule = *it;
json_array_append_new(arr, rule_to_json(rule)); 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; 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[] = static const MXS_ENUM_VALUE action_values[] =
{ {
{"allow", FW_ACTION_ALLOW}, {"allow", FW_ACTION_ALLOW},
@ -501,8 +521,8 @@ MXS_MODULE* MXS_CREATE_MODULE()
&Dbfw::s_object, &Dbfw::s_object,
NULL, /* Process init. */ NULL, /* Process init. */
NULL, /* Process finish. */ NULL, /* Process finish. */
NULL, /* Thread init. */ dbfw_thr_init, /* Thread init. */
NULL, /* Thread finish. */ dbfw_thr_finish, /* Thread finish. */
{ {
{ {
"rules", "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) 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: if ((*it)->name() == name)
RuleNameComparator(std::string name):
m_name(name)
{}
bool operator()(const SRule& rule)
{ {
return rule->name() == m_name; return *it;
}
} }
private: return SRule();
std::string m_name;
};
RuleList::const_iterator it = std::find_if(rules.begin(), rules.end(), RuleNameComparator(name));
return it != rules.end() ? *it : SRule();
} }
bool set_rule_name(void* scanner, char* name) bool set_rule_name(void* scanner, char* name)
@ -1079,11 +1090,11 @@ bool replace_rules(Dbfw* instance)
if (process_rule_file(filename, &rules, &users)) if (process_rule_file(filename, &rules, &users))
{ {
this_thread.rules.swap(rules); this_thread->rules.swap(rules);
this_thread.users.swap(users); this_thread->users.swap(users);
rval = true; 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.", MXS_ERROR("Failed to parse rules at '%s'. Old rules are still used.",
filename.c_str()); filename.c_str());
@ -1103,14 +1114,14 @@ static bool update_rules(Dbfw* my_instance)
bool rval = true; bool rval = true;
int rule_version = my_instance->get_rule_version(); 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)) if (!replace_rules(my_instance))
{ {
rval = false; rval = false;
} }
this_thread.rule_version = rule_version; this_thread->rule_version = rule_version;
} }
return rval; return rval;
@ -1395,7 +1406,7 @@ int DbfwSession::routeQuery(GWBUF* buffer)
ss_dassert(analyzed_queue); 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; bool query_ok = false;
if (command_is_mandatory(buffer)) if (command_is_mandatory(buffer))
@ -1659,7 +1670,7 @@ void Dbfw::diagnostics(DCB *dcb) const
dcb_printf(dcb, "Firewall Filter\n"); dcb_printf(dcb, "Firewall Filter\n");
dcb_printf(dcb, "Rule, Type, Times Matched\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; const SRule& rule = *it;
char buf[rule->name().length() + 200]; char buf[rule->name().length() + 200];
@ -1680,5 +1691,5 @@ void Dbfw::diagnostics(DCB *dcb) const
*/ */
json_t* Dbfw::diagnostics_json() const json_t* Dbfw::diagnostics_json() const
{ {
return rules_to_json(this_thread.rules); return rules_to_json(this_thread->rules);
} }