diff --git a/include/maxscale/router.h b/include/maxscale/router.h index 675de6019..144034f4c 100644 --- a/include/maxscale/router.h +++ b/include/maxscale/router.h @@ -211,6 +211,28 @@ typedef struct mxs_router_object * @param instance Router instance */ void (*destroyInstance)(MXS_ROUTER *instance); + + /** + * @brief Configure router instance at runtime + * + * This function is guaranteed to be called by only one thread at a time. + * The router must declare the RCAP_TYPE_RUNTIME_CONFIG in its capabilities + * in order for this function to be called. + * + * Modifications to the router should be made in an atomic manner so that + * existing sessions do not read a partial configuration. One way to do this + * is to use shared pointers for storing configurations. + * + * @param instance Router instance + * @param params Updated parameters for the service. The parameters are + * validated before this function is called. + * + * @return True if reconfiguration was successful, false if reconfiguration + * failed. If reconfiguration failed, the state of the router + * instance should not be modified. + */ + bool (*configureInstance)(MXS_ROUTER *instance, MXS_CONFIG_PARAMETER* params); + } MXS_ROUTER_OBJECT; /** @@ -218,7 +240,7 @@ typedef struct mxs_router_object * must update these versions numbers in accordance with the rules in * modinfo.h. */ -#define MXS_ROUTER_VERSION { 3, 0, 0 } +#define MXS_ROUTER_VERSION { 3, 1, 0 } /** * Specifies capabilities specific for routers. Common capabilities @@ -231,10 +253,11 @@ typedef struct mxs_router_object */ typedef enum router_capability { - RCAP_TYPE_NO_RSESSION = 0x00010000, /**< Router does not use router sessions */ - RCAP_TYPE_NO_USERS_INIT = 0x00020000, /**< Prevent the loading of authenticator + RCAP_TYPE_NO_RSESSION = 0x00010000, /**< Router does not use router sessions */ + RCAP_TYPE_NO_USERS_INIT = 0x00020000, /**< Prevent the loading of authenticator users when the service is started */ - RCAP_TYPE_NO_AUTH = 0x00040000, /**< No `user` or `password` parameter required */ + RCAP_TYPE_NO_AUTH = 0x00040000, /**< No `user` or `password` parameter required */ + RCAP_TYPE_RUNTIME_CONFIG = 0x00080000, /**< Router supports runtime cofiguration */ } mxs_router_capability_t; typedef enum diff --git a/include/maxscale/router.hh b/include/maxscale/router.hh index 7f6a15d91..0b7507462 100644 --- a/include/maxscale/router.hh +++ b/include/maxscale/router.hh @@ -130,6 +130,13 @@ template class Router : public MXS_ROUTER { public: + + // The default configure entry point, does nothing and always fails + bool configure(MXS_CONFIG_PARAMETER* param) + { + return false; + } + static MXS_ROUTER* createInstance(SERVICE* pService, char** pzOptions) { RouterType* pRouter = NULL; @@ -228,6 +235,14 @@ public: MXS_EXCEPTION_GUARD(delete pRouter); } + static bool configure(MXS_ROUTER* pInstance, MXS_CONFIG_PARAMETER* param) + { + RouterType* pRouter = static_cast(pInstance); + bool rval = false; + MXS_EXCEPTION_GUARD(rval = pRouter->configure(param)); + return rval; + } + static MXS_ROUTER_OBJECT s_object; protected: @@ -254,6 +269,7 @@ MXS_ROUTER_OBJECT Router::s_object = &Router::handleError, &Router::getCapabilities, &Router::destroyInstance, + &Router::configure, }; diff --git a/server/modules/routing/readwritesplit/readwritesplit.cc b/server/modules/routing/readwritesplit/readwritesplit.cc index ed72306ec..c02c70738 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.cc +++ b/server/modules/routing/readwritesplit/readwritesplit.cc @@ -429,7 +429,14 @@ json_t* RWSplit::diagnostics_json() const uint64_t RWSplit::getCapabilities() { return RCAP_TYPE_STMT_INPUT | RCAP_TYPE_TRANSACTION_TRACKING | - RCAP_TYPE_PACKET_OUTPUT | RCAP_TYPE_SESSION_STATE_TRACKING; + RCAP_TYPE_PACKET_OUTPUT | RCAP_TYPE_SESSION_STATE_TRACKING | + RCAP_TYPE_RUNTIME_CONFIG; +} + +bool RWSplit::configure(MXS_CONFIG_PARAMETER* params) +{ + m_config.reset(new Config(params)); + return true; } /** @@ -445,7 +452,8 @@ extern "C" MXS_MODULE *MXS_CREATE_MODULE() "A Read/Write splitting router for enhancement read scalability", "V1.1.0", RCAP_TYPE_STMT_INPUT | RCAP_TYPE_TRANSACTION_TRACKING | - RCAP_TYPE_PACKET_OUTPUT | RCAP_TYPE_SESSION_STATE_TRACKING, + RCAP_TYPE_PACKET_OUTPUT | RCAP_TYPE_SESSION_STATE_TRACKING | + RCAP_TYPE_RUNTIME_CONFIG, &RWSplit::s_object, NULL, /* Process init. */ NULL, /* Process finish. */ diff --git a/server/modules/routing/readwritesplit/readwritesplit.hh b/server/modules/routing/readwritesplit/readwritesplit.hh index 6985d8ee5..a86e78c0d 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.hh +++ b/server/modules/routing/readwritesplit/readwritesplit.hh @@ -298,6 +298,7 @@ public: */ uint64_t getCapabilities(); + bool configure(MXS_CONFIG_PARAMETER* params); private: SERVICE* m_service; /**< Service where the router belongs*/ SConfig m_config;