Move configuration changes to a common file
The config_runtime.h header contains functions that can be used to manipulate the running configuration. Currently the header contains the function to create, add, remove and destroy servers.
This commit is contained in:
parent
d309444540
commit
8ef99c9066
81
include/maxscale/config_runtime.h
Normal file
81
include/maxscale/config_runtime.h
Normal file
@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file config_runtime.h - Functions for runtime configuration modifications
|
||||
*/
|
||||
|
||||
#include <maxscale/cdefs.h>
|
||||
|
||||
#include <maxscale/filter.h>
|
||||
#include <maxscale/monitor.h>
|
||||
#include <maxscale/server.h>
|
||||
#include <maxscale/service.h>
|
||||
|
||||
/**
|
||||
* @brief Create a new server
|
||||
*
|
||||
* This function creates a new, persistent server by first allocating a new
|
||||
* server and then storing the resulting configuration file on disk. This
|
||||
* function should be used only from administrative interface modules and internal
|
||||
* modules should use server_alloc() instead.
|
||||
*
|
||||
* @param name Server name
|
||||
* @param address Network address
|
||||
* @param port Network port
|
||||
* @param protocol Protocol module name
|
||||
* @param authenticator Authenticator module name
|
||||
* @param options Options for the authenticator module
|
||||
* @return True on success, false if an error occurred
|
||||
*/
|
||||
bool runtime_create_server(const char *name, const char *address,
|
||||
const char *port, const char *protocol,
|
||||
const char *authenticator, const char *options);
|
||||
|
||||
/**
|
||||
* @brief Destroy a server
|
||||
*
|
||||
* This removes any created server configuration files and marks the server removed
|
||||
* If the server is not in use.
|
||||
*
|
||||
* @param server Server to destroy
|
||||
* @return True if server was destroyed
|
||||
*/
|
||||
bool runtime_destroy_server(SERVER *server);
|
||||
|
||||
/**
|
||||
* @brief Link a server to an object
|
||||
*
|
||||
* This function links the server to another object. The target can be either
|
||||
* a monitor or a service.
|
||||
*
|
||||
* @param server Server to link
|
||||
* @param target The monitor or service where the server is added
|
||||
* @return True if the object was found and the server was linked to it, false
|
||||
* if no object matching @c target was found
|
||||
*/
|
||||
bool runtime_link_server(SERVER *server, const char *target);
|
||||
|
||||
/**
|
||||
* @brief Unlink a server from an object
|
||||
*
|
||||
* This function unlinks the server from another object. The target can be either
|
||||
* a monitor or a service.
|
||||
*
|
||||
* @param server Server to unlink
|
||||
* @param target The monitor or service from which the server is removed
|
||||
* @return True if the object was found and the server was unlinked from it, false
|
||||
* if no object matching @c target was found
|
||||
*/
|
||||
bool runtime_unlink_server(SERVER *server, const char *target);
|
@ -203,7 +203,7 @@ struct monitor
|
||||
|
||||
extern MONITOR *monitor_alloc(char *, char *);
|
||||
extern void monitor_free(MONITOR *);
|
||||
extern MONITOR *monitor_find(char *);
|
||||
extern MONITOR *monitor_find(const char *);
|
||||
extern void monitorAddServer(MONITOR *mon, SERVER *server);
|
||||
extern void monitorRemoveServer(MONITOR *mon, SERVER *server);
|
||||
extern void monitorAddUser(MONITOR *, char *, char *);
|
||||
|
@ -227,25 +227,20 @@ extern SERVER* server_alloc(const char *name, const char *address, unsigned shor
|
||||
const char *auth_options);
|
||||
|
||||
/**
|
||||
* @brief Create a new server
|
||||
* @brief Find a server that can be reused
|
||||
*
|
||||
* This function creates a new, persistent server by first allocating a new
|
||||
* server and then storing the resulting configuration file on disk. This
|
||||
* function should be used only from administrative interface modules and internal
|
||||
* modules should use server_alloc() instead.
|
||||
* A server that has been destroyed will not be deleted but only deactivated.
|
||||
*
|
||||
* @param name Server name
|
||||
* @param address Network address
|
||||
* @param port Network port
|
||||
* @param protocol Protocol module name
|
||||
* @param authenticator Authenticator module name
|
||||
* @param options Options for the authenticator module
|
||||
* @return True on success, false if an error occurred
|
||||
* @param name Name of the server
|
||||
* @param protocol Protocol used by the server
|
||||
* @param authenticator The authenticator module of the server
|
||||
* @param auth_options Options for the authenticator
|
||||
* @return Reusable SERVER or NULL if no servers matching the criteria were
|
||||
* found
|
||||
* @see runtime_create_server
|
||||
*/
|
||||
extern bool server_create(const char *name, const char *address, const char *port,
|
||||
const char *protocol, const char *authenticator,
|
||||
const char *options);
|
||||
|
||||
SERVER* server_find_destroyed(const char *name, const char *protocol,
|
||||
const char *authenticator, const char *auth_options);
|
||||
/**
|
||||
* @brief Serialize a server to a file
|
||||
*
|
||||
@ -258,16 +253,6 @@ extern bool server_create(const char *name, const char *address, const char *por
|
||||
*/
|
||||
bool server_serialize(const SERVER *server);
|
||||
|
||||
/**
|
||||
* @brief Destroy a server
|
||||
*
|
||||
* This removes any created server configuration files and marks the server removed
|
||||
* If the server is not in use.
|
||||
* @param server Server to destroy
|
||||
* @return True if server was destroyed
|
||||
*/
|
||||
bool server_destroy(SERVER *server);
|
||||
|
||||
extern int server_free(SERVER *);
|
||||
extern SERVER *server_find_by_unique_name(const char *name);
|
||||
extern SERVER *server_find(char *, unsigned short);
|
||||
|
@ -190,7 +190,7 @@ typedef enum count_spec_t
|
||||
|
||||
extern SERVICE *service_alloc(const char *, const char *);
|
||||
extern int service_free(SERVICE *);
|
||||
extern SERVICE *service_find(char *);
|
||||
extern SERVICE *service_find(const char *);
|
||||
extern int service_isvalid(SERVICE *);
|
||||
extern int serviceAddProtocol(SERVICE *service, char *name, char *protocol,
|
||||
char *address, unsigned short port,
|
||||
|
@ -1,4 +1,4 @@
|
||||
add_library(maxscale-common SHARED adminusers.c alloc.c authenticator.c atomic.c buffer.c config.c dcb.c filter.c externcmd.c gwbitmask.c gwdirs.c hashtable.c hint.c housekeeper.c listmanager.c load_utils.c log_manager.cc maxscale_pcre2.c memlog.c misc.c mlist.c modutil.c monitor.c queuemanager.c query_classifier.c poll.c random_jkiss.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c skygw_utils.cc statistics.c listener.c gw_ssl.c mysql_utils.c mysql_binlog.c modulecmd.c)
|
||||
add_library(maxscale-common SHARED adminusers.c alloc.c authenticator.c atomic.c buffer.c config.c config_runtime.c dcb.c filter.c externcmd.c gwbitmask.c gwdirs.c hashtable.c hint.c housekeeper.c listmanager.c load_utils.c log_manager.cc maxscale_pcre2.c memlog.c misc.c mlist.c modutil.c monitor.c queuemanager.c query_classifier.c poll.c random_jkiss.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c skygw_utils.cc statistics.c listener.c gw_ssl.c mysql_utils.c mysql_binlog.c modulecmd.c )
|
||||
|
||||
target_link_libraries(maxscale-common ${MARIADB_CONNECTOR_LIBRARIES} ${LZMA_LINK_FLAGS} ${PCRE2_LIBRARIES} ${CURL_LIBRARIES} ssl pthread crypt dl crypto inih z rt m stdc++)
|
||||
|
||||
|
190
server/core/config_runtime.c
Normal file
190
server/core/config_runtime.c
Normal file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
#include <maxscale/config_runtime.h>
|
||||
#include <maxscale/gwdirs.h>
|
||||
#include <maxscale/spinlock.h>
|
||||
|
||||
static SPINLOCK crt_lock = SPINLOCK_INIT;
|
||||
|
||||
bool runtime_link_server(SERVER *server, const char *target)
|
||||
{
|
||||
spinlock_acquire(&crt_lock);
|
||||
|
||||
bool rval = false;
|
||||
SERVICE *service = service_find(target);
|
||||
MONITOR *monitor = service ? NULL : monitor_find(target);
|
||||
|
||||
if (service || monitor)
|
||||
{
|
||||
rval = true;
|
||||
|
||||
if (service)
|
||||
{
|
||||
serviceAddBackend(service, server);
|
||||
service_serialize_servers(service);
|
||||
}
|
||||
else if (monitor)
|
||||
{
|
||||
monitorAddServer(monitor, server);
|
||||
monitor_serialize_servers(monitor);
|
||||
}
|
||||
|
||||
const char *type = service ? "service" : "monitor";
|
||||
|
||||
MXS_NOTICE("Added server '%s' to %s '%s'", server->unique_name, type, target);
|
||||
}
|
||||
|
||||
spinlock_release(&crt_lock);
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool runtime_unlink_server(SERVER *server, const char *target)
|
||||
{
|
||||
spinlock_acquire(&crt_lock);
|
||||
|
||||
bool rval = false;
|
||||
SERVICE *service = service_find(target);
|
||||
MONITOR *monitor = service ? NULL : monitor_find(target);
|
||||
|
||||
if (service || monitor)
|
||||
{
|
||||
rval = true;
|
||||
|
||||
if (service)
|
||||
{
|
||||
serviceRemoveBackend(service, server);
|
||||
service_serialize_servers(service);
|
||||
}
|
||||
else if (monitor)
|
||||
{
|
||||
monitorRemoveServer(monitor, server);
|
||||
monitor_serialize_servers(monitor);
|
||||
}
|
||||
|
||||
const char *type = service ? "service" : "monitor";
|
||||
MXS_NOTICE("Removed server '%s' from %s '%s'", server->unique_name, type, target);
|
||||
}
|
||||
|
||||
spinlock_release(&crt_lock);
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
||||
bool runtime_create_server(const char *name, const char *address, const char *port,
|
||||
const char *protocol, const char *authenticator,
|
||||
const char *authenticator_options)
|
||||
{
|
||||
spinlock_acquire(&crt_lock);
|
||||
bool rval = false;
|
||||
|
||||
if (server_find_by_unique_name(name) == NULL)
|
||||
{
|
||||
// TODO: Get default values from the protocol module
|
||||
if (port == NULL)
|
||||
{
|
||||
port = "3306";
|
||||
}
|
||||
if (protocol == NULL)
|
||||
{
|
||||
protocol = "MySQLBackend";
|
||||
}
|
||||
if (authenticator == NULL && (authenticator = get_default_authenticator(protocol)) == NULL)
|
||||
{
|
||||
MXS_ERROR("No authenticator defined for server '%s' and no default "
|
||||
"authenticator for protocol '%s'.", name, protocol);
|
||||
spinlock_release(&crt_lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
/** First check if this service has been created before */
|
||||
SERVER *server = server_find_destroyed(name, protocol, authenticator,
|
||||
authenticator_options);
|
||||
|
||||
if (server)
|
||||
{
|
||||
/** Found old server, replace network details with new ones and
|
||||
* reactivate it */
|
||||
snprintf(server->name, sizeof(server->name), "%s", address);
|
||||
server->port = atoi(port);
|
||||
server->is_active = true;
|
||||
rval = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* server_alloc will add the server to the global list of
|
||||
* servers so we don't need to manually add it.
|
||||
*/
|
||||
server = server_alloc(name, address, atoi(port), protocol,
|
||||
authenticator, authenticator_options);
|
||||
}
|
||||
|
||||
if (server && server_serialize(server))
|
||||
{
|
||||
rval = true;
|
||||
}
|
||||
}
|
||||
|
||||
spinlock_release(&crt_lock);
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool runtime_destroy_server(SERVER *server)
|
||||
{
|
||||
spinlock_acquire(&crt_lock);
|
||||
bool rval = false;
|
||||
|
||||
if (service_server_in_use(server) || monitor_server_in_use(server))
|
||||
{
|
||||
MXS_ERROR("Cannot destroy server '%s' as it is used by at least one "
|
||||
"service or monitor", server->unique_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
char filename[PATH_MAX];
|
||||
snprintf(filename, sizeof(filename), "%s/%s.cnf", get_config_persistdir(),
|
||||
server->unique_name);
|
||||
|
||||
if (unlink(filename) == -1)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
{
|
||||
char err[MXS_STRERROR_BUFLEN];
|
||||
MXS_ERROR("Failed to remove persisted server configuration '%s': %d, %s",
|
||||
filename, errno, strerror_r(errno, err, sizeof(err)));
|
||||
}
|
||||
else
|
||||
{
|
||||
rval = true;
|
||||
MXS_WARNING("Server '%s' was not created at runtime. Remove the "
|
||||
"server manually from the correct configuration file.",
|
||||
server->unique_name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rval = true;
|
||||
}
|
||||
|
||||
if (rval)
|
||||
{
|
||||
MXS_NOTICE("Destroyed server '%s' at %s:%u", server->unique_name,
|
||||
server->name, server->port);
|
||||
server->is_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
spinlock_release(&crt_lock);
|
||||
return rval;
|
||||
}
|
@ -515,7 +515,7 @@ monitorList(DCB *dcb)
|
||||
* @return Pointer to the monitor or NULL
|
||||
*/
|
||||
MONITOR *
|
||||
monitor_find(char *name)
|
||||
monitor_find(const char *name)
|
||||
{
|
||||
MONITOR *ptr;
|
||||
|
||||
|
@ -1228,8 +1228,7 @@ bool server_serialize(const SERVER *server)
|
||||
return rval;
|
||||
}
|
||||
|
||||
/** Try to find a server with a matching name that has been destroyed */
|
||||
static SERVER* find_destroyed_server(const char *name, const char *protocol,
|
||||
SERVER* server_find_destroyed(const char *name, const char *protocol,
|
||||
const char *authenticator, const char *auth_options)
|
||||
{
|
||||
spinlock_acquire(&server_spin);
|
||||
@ -1254,106 +1253,3 @@ static SERVER* find_destroyed_server(const char *name, const char *protocol,
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
bool server_create(const char *name, const char *address, const char *port,
|
||||
const char *protocol, const char *authenticator,
|
||||
const char *authenticator_options)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
if (server_find_by_unique_name(name) == NULL)
|
||||
{
|
||||
// TODO: Get default values from the protocol module
|
||||
if (port == NULL)
|
||||
{
|
||||
port = "3306";
|
||||
}
|
||||
if (protocol == NULL)
|
||||
{
|
||||
protocol = "MySQLBackend";
|
||||
}
|
||||
if (authenticator == NULL && (authenticator = get_default_authenticator(protocol)) == NULL)
|
||||
{
|
||||
MXS_ERROR("No authenticator defined for server '%s' and no default "
|
||||
"authenticator for protocol '%s'.", name, protocol);
|
||||
return false;
|
||||
}
|
||||
|
||||
/** First check if this service has been created before */
|
||||
SERVER *server = find_destroyed_server(name, protocol, authenticator,
|
||||
authenticator_options);
|
||||
|
||||
if (server)
|
||||
{
|
||||
/** Found old server, replace network details with new ones and
|
||||
* reactivate it */
|
||||
snprintf(server->name, sizeof(server->name), "%s", address);
|
||||
server->port = atoi(port);
|
||||
server->is_active = true;
|
||||
rval = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* server_alloc will add the server to the global list of
|
||||
* servers so we don't need to manually add it.
|
||||
*/
|
||||
server = server_alloc(name, address, atoi(port), protocol,
|
||||
authenticator, authenticator_options);
|
||||
}
|
||||
|
||||
if (server && server_serialize(server))
|
||||
{
|
||||
rval = true;
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool server_destroy(SERVER *server)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
if (service_server_in_use(server) || monitor_server_in_use(server))
|
||||
{
|
||||
MXS_ERROR("Cannot destroy server '%s' as it is used by at least one "
|
||||
"service or monitor", server->unique_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
char filename[PATH_MAX];
|
||||
snprintf(filename, sizeof(filename), "%s/%s.cnf", get_config_persistdir(),
|
||||
server->unique_name);
|
||||
|
||||
if (unlink(filename) == -1)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
{
|
||||
char err[MXS_STRERROR_BUFLEN];
|
||||
MXS_ERROR("Failed to remove persisted server configuration '%s': %d, %s",
|
||||
filename, errno, strerror_r(errno, err, sizeof(err)));
|
||||
}
|
||||
else
|
||||
{
|
||||
rval = true;
|
||||
MXS_WARNING("Server '%s' was not created at runtime. Remove the "
|
||||
"server manually from the correct configuration file.",
|
||||
server->unique_name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rval = true;
|
||||
}
|
||||
|
||||
if (rval)
|
||||
{
|
||||
MXS_NOTICE("Destroyed server '%s' at %s:%u", server->unique_name,
|
||||
server->name, server->port);
|
||||
server->is_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
@ -1218,7 +1218,7 @@ serviceSetFilters(SERVICE *service, char *filters)
|
||||
* @return The service or NULL if not found
|
||||
*/
|
||||
SERVICE *
|
||||
service_find(char *servname)
|
||||
service_find(const char *servname)
|
||||
{
|
||||
SERVICE *service;
|
||||
|
||||
|
@ -73,6 +73,7 @@
|
||||
#include <maxscale/housekeeper.h>
|
||||
#include <maxscale/listmanager.h>
|
||||
#include <maxscale/maxscale.h>
|
||||
#include <maxscale/config_runtime.h>
|
||||
|
||||
#include <maxscale/log_manager.h>
|
||||
#include <sys/syslog.h>
|
||||
@ -804,28 +805,9 @@ static void cmd_AddServer(DCB *dcb, SERVER *server, char *v1, char *v2, char *v3
|
||||
|
||||
for (int i = 0; i < items && values[i]; i++)
|
||||
{
|
||||
SERVICE *service = service_find(values[i]);
|
||||
MONITOR *monitor = monitor_find(values[i]);
|
||||
|
||||
if (service || monitor)
|
||||
if (runtime_link_server(server, values[i]))
|
||||
{
|
||||
ss_dassert(service == NULL || monitor == NULL);
|
||||
|
||||
if (service)
|
||||
{
|
||||
serviceAddBackend(service, server);
|
||||
service_serialize_servers(service);
|
||||
}
|
||||
else if (monitor)
|
||||
{
|
||||
monitorAddServer(monitor, server);
|
||||
monitor_serialize_servers(monitor);
|
||||
}
|
||||
|
||||
const char *target = service ? "service" : "monitor";
|
||||
|
||||
MXS_NOTICE("Added server '%s' to %s '%s'", server->unique_name, target, values[i]);
|
||||
dcb_printf(dcb, "Added server '%s' to %s '%s'\n", server->unique_name, target, values[i]);
|
||||
dcb_printf(dcb, "Added server '%s' to '%s'\n", server->unique_name, values[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -872,27 +854,9 @@ static void cmd_RemoveServer(DCB *dcb, SERVER *server, char *v1, char *v2, char
|
||||
|
||||
for (int i = 0; i < items && values[i]; i++)
|
||||
{
|
||||
SERVICE *service = service_find(values[i]);
|
||||
MONITOR *monitor = monitor_find(values[i]);
|
||||
|
||||
if (service || monitor)
|
||||
if (runtime_unlink_server(server, values[i]))
|
||||
{
|
||||
ss_dassert(service == NULL || monitor == NULL);
|
||||
|
||||
if (service)
|
||||
{
|
||||
serviceRemoveBackend(service, server);
|
||||
service_serialize_servers(service);
|
||||
}
|
||||
else if (monitor)
|
||||
{
|
||||
monitorRemoveServer(monitor, server);
|
||||
monitor_serialize_servers(monitor);
|
||||
}
|
||||
|
||||
const char *target = service ? "service" : "monitor";
|
||||
MXS_NOTICE("Removed server '%s' from %s '%s'", server->unique_name, target, values[i]);
|
||||
dcb_printf(dcb, "Removed server '%s' from %s '%s'\n", server->unique_name, target, values[i]);
|
||||
dcb_printf(dcb, "Removed server '%s' from '%s'\n", server->unique_name, values[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1044,7 +1008,7 @@ static void createServer(DCB *dcb, char *name, char *address, char *port,
|
||||
|
||||
if (server_find_by_unique_name(name) == NULL)
|
||||
{
|
||||
if (server_create(name, address, port, protocol, authenticator, authenticator_options))
|
||||
if (runtime_create_server(name, address, port, protocol, authenticator, authenticator_options))
|
||||
{
|
||||
dcb_printf(dcb, "Created server '%s'\n", name);
|
||||
}
|
||||
@ -1093,7 +1057,7 @@ static void destroyServer(DCB *dcb, SERVER *server)
|
||||
char name[strlen(server->unique_name) + 1];
|
||||
strcpy(name, server->unique_name);
|
||||
|
||||
if (server_destroy(server))
|
||||
if (runtime_destroy_server(server))
|
||||
{
|
||||
dcb_printf(dcb, "Destroyed server '%s'\n", name);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user