From 6ea4e50f2cf6731f22a2ce2ea6aff643a6b12352 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 25 Nov 2016 12:15:52 +0200 Subject: [PATCH] Clean up service.h Most of the service header functions now contain the relevant documentation. Cleaned up small parts of it and renamed functions to be more consistent. --- include/maxscale/service.h | 231 ++++++++++++------ server/core/config_runtime.c | 2 +- server/core/gateway.cc | 2 +- server/core/service.c | 113 ++++----- server/modules/routing/debugcli/debugcmd.c | 2 +- server/modules/routing/maxinfo/maxinfo_exec.c | 2 +- 6 files changed, 208 insertions(+), 144 deletions(-) diff --git a/include/maxscale/service.h b/include/maxscale/service.h index fab8f3128..723d1259d 100644 --- a/include/maxscale/service.h +++ b/include/maxscale/service.h @@ -98,10 +98,10 @@ typedef struct typedef struct server_ref_t { struct server_ref_t *next; /**< Next server reference */ - SERVER* server; /**< The actual server */ - int weight; /**< Weight of this server */ - int connections; /**< Number of connections created through this reference */ - bool active; /**< Whether this reference is valid and in use*/ + SERVER* server; /**< The actual server */ + int weight; /**< Weight of this server */ + int connections; /**< Number of connections created through this reference */ + bool active; /**< Whether this reference is valid and in use*/ } SERVER_REF; /** Macro to check whether a SERVER_REF is active */ @@ -119,8 +119,8 @@ typedef struct server_ref_t #define SERVICE_PARAM_UNINIT -1 /* Refresh rate limits for load users from database */ -#define USERS_REFRESH_TIME 30 /* Allowed time interval (in seconds) after last update*/ -#define USERS_REFRESH_MAX_PER_TIME 4 /* Max number of load calls within the time interval */ +#define USERS_REFRESH_TIME 30 /* Allowed time interval (in seconds) after last update*/ +#define USERS_REFRESH_MAX_PER_TIME 4 /* Max number of load calls within the time interval */ /** Default timeout values used by the connections which fetch user authentication data */ #define DEFAULT_AUTH_CONNECT_TIMEOUT 3 @@ -142,25 +142,24 @@ typedef struct service int max_connections; /**< Maximum client connections */ QUEUE_CONFIG *queued_connections; /**< Queued connections, if set */ SERV_LISTENER *ports; /**< Linked list of ports and protocols - * that this service will listen on. - */ + * that this service will listen on */ char *routerModule; /**< Name of router module to use */ char **routerOptions; /**< Router specific option strings */ struct router_object *router; /**< The router we are using */ void *router_instance; /**< The router instance for this service */ - char *version_string; /** version string for this service listeners */ - SERVER_REF *dbref; /** server references */ - int n_dbref; /** Number of server references */ + char *version_string; /**< version string for this service listeners */ + SERVER_REF *dbref; /**< server references */ + int n_dbref; /**< Number of server references */ SERVICE_USER credentials; /**< The cedentials of the service user */ SPINLOCK spin; /**< The service spinlock */ SERVICE_STATS stats; /**< The service statistics */ int enable_root; /**< Allow root user access */ int localhost_match_wildcard_host; /**< Match localhost against wildcard */ - CONFIG_PARAMETER* svc_config_param;/*< list of config params and values */ - int svc_config_version; /*< Version number of configuration */ - bool svc_do_shutdown; /*< tells the service to exit loops etc. */ - bool users_from_all; /*< Load users from one server or all of them */ - bool strip_db_esc; /*< Remove the '\' characters from database names + CONFIG_PARAMETER* svc_config_param;/**< list of config params and values */ + int svc_config_version; /**< Version number of configuration */ + bool svc_do_shutdown; /**< tells the service to exit loops etc. */ + bool users_from_all; /**< Load users from one server or all of them */ + bool strip_db_esc; /**< Remove the '\' characters from database names * when querying them from the server. MySQL Workbench seems * to escape at least the underscore character. */ SPINLOCK users_table_spin; /**< The spinlock for users data refresh */ @@ -168,11 +167,11 @@ typedef struct service FILTER_DEF **filters; /**< Ordered list of filters */ int n_filters; /**< Number of filters */ long conn_idle_timeout; /**< Session timeout in seconds */ - char *weightby; + char *weightby; /**< Service weighting parameter name */ struct service *next; /**< The next service in the linked list */ - bool retry_start; /*< If starting of the service should be retried later */ - bool log_auth_warnings; /*< Log authentication failures and warnings */ - uint64_t capabilities; /*< The capabilities of the service. */ + bool retry_start; /**< If starting of the service should be retried later */ + bool log_auth_warnings; /**< Log authentication failures and warnings */ + uint64_t capabilities; /**< The capabilities of the service. */ } SERVICE; typedef enum count_spec_t @@ -188,60 +187,144 @@ typedef enum count_spec_t #define SERVICE_STATE_FAILED 3 /**< The service failed to start */ #define SERVICE_STATE_STOPPED 4 /**< The service has been stopped */ -extern SERVICE *service_alloc(const char *, const char *); -extern int service_free(SERVICE *); -extern SERVICE *service_find(const char *); -extern int service_isvalid(SERVICE *); -extern SERV_LISTENER* serviceCreateListener(SERVICE *service, const char *name, const char *protocol, - const char *address, unsigned short port, const char *authenticator, - const char *options, SSL_LISTENER *ssl); -extern int serviceHasProtocol(SERVICE *service, const char *protocol, - const char* address, unsigned short port); -extern void serviceAddBackend(SERVICE *, SERVER *); -extern void serviceRemoveBackend(SERVICE *, const SERVER *); -extern bool serviceHasBackend(SERVICE *, SERVER *); -extern void serviceAddRouterOption(SERVICE *, char *); -extern void serviceClearRouterOptions(SERVICE *); -extern int serviceStart(SERVICE *); -extern int serviceStartAll(); -extern bool serviceListen(SERVICE *service, SERV_LISTENER *port); -extern int serviceStop(SERVICE *); -extern int serviceRestart(SERVICE *); -extern int serviceSetUser(SERVICE *, char *, char *); -extern int serviceGetUser(SERVICE *, char **, char **); -extern bool serviceSetFilters(SERVICE *, char *); -extern int serviceSetSSL(SERVICE *service, char* action); -extern int serviceSetSSLVersion(SERVICE *service, char* version); -extern int serviceSetSSLVerifyDepth(SERVICE* service, int depth); -extern void serviceSetCertificates(SERVICE *service, char* cert, char* key, char* ca_cert); -extern int serviceEnableRootUser(SERVICE *, int ); -extern int serviceSetTimeout(SERVICE *, int ); -extern int serviceSetConnectionLimits(SERVICE *, int, int, int); -extern void serviceSetRetryOnFailure(SERVICE *service, char* value); -extern void serviceWeightBy(SERVICE *, char *); -extern char *serviceGetWeightingParameter(SERVICE *); -extern int serviceEnableLocalhostMatchWildcardHost(SERVICE *, int); -extern int serviceStripDbEsc(SERVICE* service, int action); -extern int serviceAuthAllServers(SERVICE *service, int action); -extern void service_update(SERVICE *, char *, char *, char *); -extern int service_refresh_users(SERVICE *); -extern void printService(SERVICE *); -extern void printAllServices(); -extern void dprintAllServices(DCB *); -extern bool service_set_param_value(SERVICE* service, - CONFIG_PARAMETER* param, - char* valstr, - count_spec_t count_spec, - config_param_type_t type); -extern void dprintService(DCB *, SERVICE *); -extern void dListServices(DCB *); -extern void dListListeners(DCB *); -extern char* service_get_name(SERVICE* svc); -extern void service_shutdown(); -extern int serviceSessionCountAll(); -extern RESULTSET *serviceGetList(); -extern RESULTSET *serviceGetListenerList(); -extern bool service_all_services_have_listeners(); +/** + * Service life cycle management + * + * These functions should only be called by the MaxScale core. + */ + +/** + * @brief Allocate a new service + * + * @param name The service name + * @param router The router module this service uses + * + * @return The newly created service or NULL if an error occurred + */ +SERVICE* service_alloc(const char *name, const char *router); + +/** + * @brief Free the specified service + * + * @param service The service to free + */ +void service_free(SERVICE *service); + +/** + * @brief Shut all services down + * + * Stops all services and calls the destroyInstance entry points for all routers + * and filter. This should only be called once by the main shutdown code. + */ +void service_shutdown(void); + +/** + * @brief Launch all services + * + * Initialize and start all services. This should only be called once by the + * main initialization code. + * + * @return Number of successfully started services + */ +int service_launch_all(void); + +/** + * Creating and adding new components to services + */ +SERV_LISTENER* serviceCreateListener(SERVICE *service, const char *name, + const char *protocol, const char *address, + unsigned short port, const char *authenticator, + const char *options, SSL_LISTENER *ssl); +int serviceHasProtocol(SERVICE *service, const char *protocol, + const char* address, unsigned short port); +void serviceAddBackend(SERVICE *service, SERVER *server); +void serviceRemoveBackend(SERVICE *service, const SERVER *server); +bool serviceHasBackend(SERVICE *service, SERVER *server); + +/** + * Starting and stopping services + */ + +/** + * @brief Stop a service + * + * @param service Service to stop + * @return True if service was stopped + */ +bool serviceStop(SERVICE *service); + +/** + * @brief Restart a stopped service + * + * @param service Service to restart + * @return True if service was restarted + */ +bool serviceStart(SERVICE *service); + +/** + * @brief Start a listener for a service + * + * @param service Service where the listener is linked + * @param port Listener to start + * @return True if listener was started + */ +bool serviceStartListener(SERVICE *service, SERV_LISTENER *port); + +/** + * @brief Stop a listener for a service + * + * @param service Service where the listener is linked + * @param name Name of the listener + * @return True if listener was stopped + */ +bool serviceStopListener(SERVICE *service, const char *name); + +/** + * Utility functions + */ +char* service_get_name(SERVICE* service); +bool service_all_services_have_listeners(void); +SERVICE* service_find(const char *name); +int service_isvalid(SERVICE *service); + +/** + * Alteration of the service configuration + */ +void serviceAddRouterOption(SERVICE *service, char *option); +void serviceClearRouterOptions(SERVICE *service); +int serviceSetUser(SERVICE *service, char *user, char *auth); +int serviceGetUser(SERVICE *service, char **user, char **auth); +bool serviceSetFilters(SERVICE *service, char *filters); +int serviceSetSSL(SERVICE *service, char* action); +int serviceSetSSLVersion(SERVICE *service, char* version); +int serviceSetSSLVerifyDepth(SERVICE* service, int depth); +void serviceSetCertificates(SERVICE *service, char* cert, char* key, char* ca_cert); +int serviceEnableRootUser(SERVICE *service, int action); +int serviceSetTimeout(SERVICE *service, int val); +int serviceSetConnectionLimits(SERVICE *service, int max, int queued, int timeout); +void serviceSetRetryOnFailure(SERVICE *service, char* value); +void serviceWeightBy(SERVICE *service, char *weightby); +char* serviceGetWeightingParameter(SERVICE *service); +int serviceEnableLocalhostMatchWildcardHost(SERVICE *service, int action); +int serviceStripDbEsc(SERVICE* service, int action); +int serviceAuthAllServers(SERVICE *service, int action); +void service_update(SERVICE *service, char *router, char *user, char *auth); +int service_refresh_users(SERVICE *service); +bool service_set_param_value(SERVICE* service, CONFIG_PARAMETER* param, char* valstr, + count_spec_t count_spec, config_param_type_t type); + +/** + * Diagnostics + */ +void printService(SERVICE *service); +void printAllServices(void); +void dprintAllServices(DCB *dcb); +void dprintService(DCB *dcb, SERVICE *service); +void dListServices(DCB *dcb); +void dListListeners(DCB *dcb); +int serviceSessionCountAll(void); +RESULTSET* serviceGetList(void); +RESULTSET* serviceGetListenerList(void); /** * Get the capabilities of the servive. diff --git a/server/core/config_runtime.c b/server/core/config_runtime.c index 54c60550d..f7d56628d 100644 --- a/server/core/config_runtime.c +++ b/server/core/config_runtime.c @@ -414,7 +414,7 @@ bool runtime_create_listener(SERVICE *service, const char *name, const char *add SERV_LISTENER *listener = serviceCreateListener(service, name, proto, addr, u_port, auth, auth_opt, ssl); - if (listener && listener_serialize(listener) && serviceListen(service, listener)) + if (listener && listener_serialize(listener) && serviceStartListener(service, listener)) { MXS_NOTICE("Listener '%s' at %s:%s for service '%s' created", name, print_addr, port, service->name); diff --git a/server/core/gateway.cc b/server/core/gateway.cc index 9d6a2e28d..f67f8c36c 100644 --- a/server/core/gateway.cc +++ b/server/core/gateway.cc @@ -1951,7 +1951,7 @@ int main(int argc, char **argv) monitorStartAll(); /** Start the services that were created above */ - n_services = serviceStartAll(); + n_services = service_launch_all(); if (n_services == 0) { diff --git a/server/core/service.c b/server/core/service.c index 66e3da276..128f018f8 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -103,32 +103,21 @@ static void service_internal_restart(void *data); static void service_queue_check(void *data); static void service_calculate_weights(SERVICE *service); -/** - * Allocate a new service for the gateway to support - * - * - * @param servname The service name - * @param router Name of the router module this service uses - * - * @return The newly created service or NULL if an error occurred - */ -SERVICE * -service_alloc(const char *servname, const char *router) +SERVICE* service_alloc(const char *name, const char *router) { - servname = MXS_STRDUP(servname); - router = MXS_STRDUP(router); - + char *my_name = MXS_STRDUP(name); + char *my_router = MXS_STRDUP(router); SERVICE *service = (SERVICE *)MXS_CALLOC(1, sizeof(*service)); - if (!servname || !router || !service) + if (!my_name || !my_router || !service) { - MXS_FREE((void*)servname); - MXS_FREE((void*)router); + MXS_FREE(my_name); + MXS_FREE(my_router); MXS_FREE(service); return NULL; } - if ((service->router = load_module(router, MODULE_ROUTER)) == NULL) + if ((service->router = load_module(my_router, MODULE_ROUTER)) == NULL) { char* home = get_libdir(); char* ldpath = getenv("LD_LIBRARY_PATH"); @@ -138,13 +127,13 @@ service_alloc(const char *servname, const char *router) "following directories :\n\t\t\t " "- %s\n%s%s", MODULE_ROUTER, - router, - router, + my_router, + my_router, home, ldpath ? "\t\t\t - " : "", ldpath ? ldpath : ""); - MXS_FREE((void*)servname); - MXS_FREE((void*)router); + MXS_FREE(my_name); + MXS_FREE(my_router); MXS_FREE(service); return NULL; } @@ -152,8 +141,8 @@ service_alloc(const char *servname, const char *router) service->capabilities = service->router->getCapabilities(); service->client_count = 0; service->n_dbref = 0; - service->name = (char*)servname; - service->routerModule = (char*)router; + service->name = my_name; + service->routerModule = my_router; service->users_from_all = false; service->queued_connections = NULL; service->localhost_match_wildcard_host = SERVICE_PARAM_UNINIT; @@ -478,8 +467,7 @@ static void free_string_array(char** array) * @param service The Service that should be started * @return Returns the number of listeners created */ -int -serviceStart(SERVICE *service) +int serviceInitialize(SERVICE *service) { /** Calculate the server weights */ service_calculate_weights(service); @@ -502,24 +490,36 @@ serviceStart(SERVICE *service) return listeners; } -/** - * Start an individual listener - * - * @param service The service to start the listener for - * @param port The port number - */ -bool serviceListen(SERVICE *service, SERV_LISTENER *port) +bool serviceStartListener(SERVICE *service, SERV_LISTENER *port) { return serviceStartPort(service, port); } -/** - * Start all the services - * - * @return Return the number of services started - */ -int -serviceStartAll() +bool serviceStopListener(SERVICE *service, const char *name) +{ + bool rval = false; + + spinlock_acquire(&service->spin); + + for (SERV_LISTENER *port = service->ports; port; port = port->next) + { + if (strcmp(port->name, name) == 0) + { + if (poll_remove_dcb(port->listener) == 0) + { + port->listener->session->state = SESSION_STATE_LISTENER_STOPPED; + rval = true; + } + break; + } + } + + spinlock_release(&service->spin); + + return rval; +} + +int service_launch_all() { SERVICE *ptr; int n = 0, i; @@ -530,7 +530,7 @@ serviceStartAll() ptr = allServices; while (ptr && !ptr->svc_do_shutdown) { - n += (i = serviceStart(ptr)); + n += (i = serviceInitialize(ptr)); if (i == 0) { @@ -543,16 +543,7 @@ serviceStartAll() return error ? 0 : n; } -/** - * Stop a service - * - * This function stops the listener for the service - * - * @param service The Service that should be stopped - * @return Returns the number of listeners restarted - */ -int -serviceStop(SERVICE *service) +bool serviceStop(SERVICE *service) { SERV_LISTENER *port; int listeners = 0; @@ -572,7 +563,7 @@ serviceStop(SERVICE *service) } service->state = SERVICE_STATE_STOPPED; - return listeners; + return listeners > 0; } /** @@ -583,8 +574,7 @@ serviceStop(SERVICE *service) * @param service The Service that should be restarted * @return Returns the number of listeners restarted */ -int -serviceRestart(SERVICE *service) +bool serviceStart(SERVICE *service) { SERV_LISTENER *port; int listeners = 0; @@ -603,24 +593,16 @@ serviceRestart(SERVICE *service) port = port->next; } service->state = SERVICE_STATE_STARTED; - return listeners; + return listeners > 0; } - -/** - * Deallocate the specified service - * - * @param service The service to deallocate - * @return Returns true if the service was freed - */ -int -service_free(SERVICE *service) +void service_free(SERVICE *service) { SERVICE *ptr; SERVER_REF *srv; if (service->stats.n_current) { - return 0; + return; } /* First of all remove from the linked list */ spinlock_acquire(&service_spin); @@ -661,7 +643,6 @@ service_free(SERVICE *service) serviceClearRouterOptions(service); MXS_FREE(service); - return 1; } /** diff --git a/server/modules/routing/debugcli/debugcmd.c b/server/modules/routing/debugcli/debugcmd.c index a63b81603..34907326c 100644 --- a/server/modules/routing/debugcli/debugcmd.c +++ b/server/modules/routing/debugcli/debugcmd.c @@ -1776,7 +1776,7 @@ shutdown_service(DCB *dcb, SERVICE *service) static void restart_service(DCB *dcb, SERVICE *service) { - serviceRestart(service); + serviceStart(service); } /** diff --git a/server/modules/routing/maxinfo/maxinfo_exec.c b/server/modules/routing/maxinfo/maxinfo_exec.c index d8a990c3d..a82433b1b 100644 --- a/server/modules/routing/maxinfo/maxinfo_exec.c +++ b/server/modules/routing/maxinfo/maxinfo_exec.c @@ -694,7 +694,7 @@ void exec_restart_service(DCB *dcb, MAXINFO_TREE *tree) SERVICE* service = service_find(tree->value); if (service) { - serviceRestart(service); + serviceStart(service); maxinfo_send_ok(dcb); } else