diff --git a/include/maxscale/config.h b/include/maxscale/config.h index e96539d92..af6a62a83 100644 --- a/include/maxscale/config.h +++ b/include/maxscale/config.h @@ -126,6 +126,7 @@ extern const char CN_NAME[]; extern const char CN_NON_BLOCKING_POLLS[]; extern const char CN_OPTIONS[]; extern const char CN_PARAMETERS[]; +extern const char CN_PASSIVE[]; extern const char CN_PASSWORD[]; extern const char CN_POLL_SLEEP[]; extern const char CN_PORT[]; @@ -208,6 +209,7 @@ typedef struct unsigned int auth_read_timeout; /**< Read timeout for the user authentication */ unsigned int auth_write_timeout; /**< Write timeout for the user authentication */ bool skip_permission_checks; /**< Skip service and monitor permission checks */ + bool passive; /**< True if MaxScale is in passive mode */ char qc_name[PATH_MAX]; /**< The name of the query classifier to load */ char* qc_args; /**< Arguments for the query classifier */ qc_sql_mode_t qc_sql_mode; /**< The query classifier sql mode */ diff --git a/server/core/config.cc b/server/core/config.cc index 2021e9059..72cf41776 100644 --- a/server/core/config.cc +++ b/server/core/config.cc @@ -104,6 +104,7 @@ const char CN_NAME[] = "name"; const char CN_NON_BLOCKING_POLLS[] = "non_blocking_polls"; const char CN_OPTIONS[] = "options"; const char CN_PARAMETERS[] = "parameters"; +const char CN_PASSIVE[] = "passive"; const char CN_PASSWORD[] = "password"; const char CN_POLL_SLEEP[] = "poll_sleep"; const char CN_PORT[] = "port"; @@ -1566,6 +1567,10 @@ handle_global_item(const char *name, const char *value) { gateway.admin_log_auth_failures = config_truth_value(value); } + else if (strcmp(name, CN_PASSIVE) == 0) + { + gateway.passive = config_truth_value((char*)value); + } else { for (i = 0; lognames[i].name; i++) @@ -1755,6 +1760,7 @@ void config_set_global_defaults() gateway.admin_ssl_key[0] = '\0'; gateway.admin_ssl_cert[0] = '\0'; gateway.admin_ssl_ca_cert[0] = '\0'; + gateway.passive = false; gateway.thread_stack_size = 0; pthread_attr_t attr; @@ -3897,6 +3903,7 @@ json_t* config_maxscale_to_json(const char* host) json_object_set_new(param, CN_ADMIN_SSL_KEY, json_string(cnf->admin_ssl_key)); json_object_set_new(param, CN_ADMIN_SSL_CERT, json_string(cnf->admin_ssl_cert)); json_object_set_new(param, CN_ADMIN_SSL_CA_CERT, json_string(cnf->admin_ssl_ca_cert)); + json_object_set_new(param, CN_PASSIVE, json_boolean(cnf->passive)); json_object_set_new(param, CN_QUERY_CLASSIFIER, json_string(cnf->qc_name)); @@ -3942,6 +3949,7 @@ static bool create_global_config(const char *filename) dprintf(file, "%s=%u\n", CN_AUTH_READ_TIMEOUT, gateway.auth_read_timeout); dprintf(file, "%s=%u\n", CN_AUTH_WRITE_TIMEOUT, gateway.auth_write_timeout); dprintf(file, "%s=%s\n", CN_ADMIN_AUTH, gateway.admin_auth ? "true" : "false"); + dprintf(file, "%s=%u\n", CN_PASSIVE, gateway.passive); close(file); diff --git a/server/core/config_runtime.cc b/server/core/config_runtime.cc index 96836294f..243e7848d 100644 --- a/server/core/config_runtime.cc +++ b/server/core/config_runtime.cc @@ -749,6 +749,23 @@ bool runtime_alter_maxscale(const char* name, const char* value) runtime_error("Invalid boolean value for '%s': %s", CN_ADMIN_LOG_AUTH_FAILURES, value); } } + else if (key == CN_PASSIVE) + { + int boolval = config_truth_value(value); + + if (boolval != -1) + { + MXS_NOTICE("Updated '%s' from '%s' to '%s'", CN_PASSIVE, + cnf.passive ? "true" : "false", + boolval ? "true" : "false"); + cnf.passive = boolval; + rval = true; + } + else + { + runtime_error("Invalid boolean value for '%s': %s", CN_PASSIVE, value); + } + } else { runtime_error("Unknown global parameter: %s=%s", name, value); diff --git a/server/core/gateway.cc b/server/core/gateway.cc index 1f2acd69b..93cef8e0d 100644 --- a/server/core/gateway.cc +++ b/server/core/gateway.cc @@ -129,6 +129,7 @@ static struct option long_options[] = {"version-full", no_argument, 0, 'V'}, {"help", no_argument, 0, '?'}, {"connector_plugindir", required_argument, 0, 'H'}, + {"passive", no_argument, 0, 'p'}, {"debug", required_argument, 0, 'g'}, {0, 0, 0, 0} }; @@ -922,6 +923,7 @@ static void usage(void) " -S, --maxlog=[yes|no] log messages to MaxScale log (default: yes)\n" " -G, --log_augmentation=0|1 augment messages with the name of the function\n" " where the message was logged (default: 0)\n" + " -p, --passive start MaxScale as a passive standby\n" " -g, --debug=arg1,arg2,... enable or disable debug features. Supported arguments:\n", progname); for (int i = 0; debug_arguments[i].action != NULL; i++) @@ -1289,7 +1291,7 @@ int main(int argc, char **argv) file_write_header(stderr); // Option string for getopt - const char accepted_opts[] = "dcf:g:l:vVs:S:?L:D:C:B:U:A:P:G:N:E:F:M:H:"; + const char accepted_opts[] = "dcf:g:l:vVs:S:?L:D:C:B:U:A:P:G:N:E:F:M:H:p"; /*< * Register functions which are called at exit. @@ -1577,6 +1579,10 @@ int main(int argc, char **argv) config_check = true; break; + case 'p': + cnf->passive = true; + break; + case 'g': if (!handle_debug_args(optarg)) {