
void session_enable_log(SESSION* ses, logfile_id_t id) and void session_disable_log(SESSION* ses, logfile_id_t id) Which switch specific log type on/off if the log type in question is not generally enabled. Each thread carries a thread-specific struct log_info_t which includes members for current session id and bitfield for enabled log types for the current session. That information is checked before actual log write functions are called. Each file where session-specific logging is used, must include the following exports: /** Defined in log_manager.cc */ extern int lm_enabled_logfiles_bitmask; extern size_t log_ses_count[]; extern __thread log_info_t tls_log_info;
226 lines
5.2 KiB
C
226 lines
5.2 KiB
C
/*
|
|
* This file is distributed as part of the MariaDB Corporation MaxScale. It is free
|
|
* software: you can redistribute it and/or modify it under the terms of the
|
|
* GNU General Public License as published by the Free Software Foundation,
|
|
* version 2.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program; if not, write to the Free Software Foundation, Inc., 51
|
|
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Copyright MariaDB Corporation Ab 2013-2014
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* @file gw_utils.c - A set if utility functions useful within the context
|
|
* of the gateway.
|
|
*
|
|
* @verbatim
|
|
* Revision History
|
|
*
|
|
* Date Who Description
|
|
* 03-06-2013 Massimiliano Pinto gateway utils
|
|
* 12-06-2013 Massimiliano Pinto gw_read_gwbuff
|
|
* with error detection
|
|
* and its handling
|
|
* 01-07-2013 Massimiliano Pinto Removed session->backends
|
|
* from gw_read_gwbuff()
|
|
* 25-09-2013 Massimiliano Pinto setipaddress uses getaddrinfo
|
|
* 06-02-2014 Mark Riddoch Added parse_bindconfig
|
|
* 10-02-2014 Massimiliano Pinto Added return code to setipaddress
|
|
* 02-09-2014 Martin Brampton Replace C++ comment with C comment
|
|
*
|
|
*@endverbatim
|
|
*/
|
|
|
|
#include <gw.h>
|
|
#include <dcb.h>
|
|
#include <session.h>
|
|
|
|
#include <skygw_utils.h>
|
|
#include <log_manager.h>
|
|
|
|
SPINLOCK tmplock = SPINLOCK_INIT;
|
|
|
|
/** Defined in log_manager.cc */
|
|
extern int lm_enabled_logfiles_bitmask;
|
|
extern size_t log_ses_count[];
|
|
extern __thread log_info_t tls_log_info;
|
|
|
|
/*
|
|
* Set IP address in socket structure in_addr
|
|
*
|
|
* @param a Pointer to a struct in_addr into which the address is written
|
|
* @param p The hostname to lookup
|
|
* @return 1 on success, 0 on failure
|
|
*/
|
|
int
|
|
setipaddress(struct in_addr *a, char *p) {
|
|
#ifdef __USE_POSIX
|
|
struct addrinfo *ai = NULL, hint;
|
|
int rc;
|
|
struct sockaddr_in * res_addr;
|
|
memset(&hint, 0, sizeof (hint));
|
|
|
|
hint.ai_socktype = SOCK_STREAM;
|
|
|
|
/*
|
|
* This is for the listening socket, matching INADDR_ANY only for now.
|
|
* For future specific addresses bind, a dedicated routine woulbd be better
|
|
*/
|
|
|
|
if (strcmp(p, "0.0.0.0") == 0) {
|
|
hint.ai_flags = AI_PASSIVE;
|
|
hint.ai_family = AF_UNSPEC;
|
|
if ((rc = getaddrinfo(p, NULL, &hint, &ai)) != 0) {
|
|
LOGIF(LE, (skygw_log_write_flush(
|
|
LOGFILE_ERROR,
|
|
"Error : getaddrinfo failed for [%s] due [%s]",
|
|
p,
|
|
gai_strerror(rc))));
|
|
|
|
return 0;
|
|
}
|
|
} else {
|
|
hint.ai_flags = AI_CANONNAME;
|
|
hint.ai_family = AF_INET;
|
|
|
|
if ((rc = getaddrinfo(p, NULL, &hint, &ai)) != 0) {
|
|
LOGIF(LE, (skygw_log_write_flush(
|
|
LOGFILE_ERROR,
|
|
"Error : getaddrinfo failed for [%s] due [%s]",
|
|
p,
|
|
gai_strerror(rc))));
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/* take the first one */
|
|
if (ai != NULL) {
|
|
res_addr = (struct sockaddr_in *)(ai->ai_addr);
|
|
memcpy(a, &res_addr->sin_addr, sizeof(struct in_addr));
|
|
|
|
freeaddrinfo(ai);
|
|
|
|
return 1;
|
|
}
|
|
#else
|
|
struct hostent *h;
|
|
|
|
spinlock_acquire(&tmplock);
|
|
h = gethostbyname(p);
|
|
spinlock_release(&tmplock);
|
|
|
|
if (h == NULL) {
|
|
if ((a->s_addr = inet_addr(p)) == -1) {
|
|
LOGIF(LE, (skygw_log_write_flush(
|
|
LOGFILE_ERROR,
|
|
"Error : gethostbyname failed for [%s]",
|
|
p)));
|
|
|
|
return 0;
|
|
}
|
|
} else {
|
|
/* take the first one */
|
|
memcpy(a, h->h_addr, h->h_length);
|
|
|
|
return 1;
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Daemonize the process by forking and putting the process into the
|
|
* background.
|
|
*/
|
|
void gw_daemonize(void) {
|
|
pid_t pid;
|
|
|
|
pid = fork();
|
|
|
|
if (pid < 0) {
|
|
fprintf(stderr, "fork() error %s\n", strerror(errno));
|
|
exit(1);
|
|
}
|
|
|
|
if (pid != 0) {
|
|
/* exit from main */
|
|
exit(0);
|
|
}
|
|
|
|
if (setsid() < 0) {
|
|
fprintf(stderr, "setsid() error %s\n", strerror(errno));
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Parse the bind config data. This is passed in a string as address:port.
|
|
*
|
|
* The address may be either a . seperated IP address or a hostname to
|
|
* lookup. The address 0.0.0.0 is the wildcard address for SOCKADR_ANY.
|
|
* The ':' and port may be omitted, in which case the default port is
|
|
* used.
|
|
*
|
|
* @param config The bind address and port seperated by a ':'
|
|
* @param def_port The default port to use
|
|
* @param addr The sockaddr_in in which the data is written
|
|
* @return 0 on failure
|
|
*/
|
|
int
|
|
parse_bindconfig(char *config, unsigned short def_port, struct sockaddr_in *addr)
|
|
{
|
|
char *port, buf[1024 + 1];
|
|
short pnum;
|
|
struct hostent *hp;
|
|
|
|
|
|
strncpy(buf, config, 1024);
|
|
port = strrchr(buf, ':');
|
|
if (port)
|
|
{
|
|
*port = 0;
|
|
port++;
|
|
pnum = atoi(port);
|
|
}
|
|
else
|
|
{
|
|
pnum = def_port;
|
|
}
|
|
|
|
if (!strcmp(buf, "0.0.0.0"))
|
|
{
|
|
addr->sin_addr.s_addr = htonl(INADDR_ANY);
|
|
}
|
|
else
|
|
{
|
|
if (!inet_aton(buf, &addr->sin_addr))
|
|
{
|
|
if ((hp = gethostbyname(buf)) != NULL)
|
|
{
|
|
bcopy(hp->h_addr, &(addr->sin_addr.s_addr), hp->h_length);
|
|
}
|
|
else
|
|
{
|
|
LOGIF(LE, (skygw_log_write_flush(
|
|
LOGFILE_ERROR,
|
|
"Error : Failed to lookup host '%s'. ",
|
|
buf)));
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
addr->sin_family = AF_INET;
|
|
addr->sin_port = htons(pnum);
|
|
return 1;
|
|
}
|