Removed the passing of epoll fd and isolated epoll functionality to

a signle file

Addition of show epoll debug CLI command
This commit is contained in:
Mark Riddoch
2013-06-19 16:29:52 +02:00
parent c2b24884fd
commit 0fc2f9dda3
20 changed files with 412 additions and 280 deletions

View File

@ -30,10 +30,10 @@
static char *version_str = "V1.0.0";
int gw_read_backend_event(DCB* dcb, int epfd);
int gw_write_backend_event(DCB *dcb, int epfd);
int gw_read_backend_event(DCB* dcb);
int gw_write_backend_event(DCB *dcb);
int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue);
int gw_error_backend_event(DCB *dcb, int epfd, int event);
int gw_error_backend_event(DCB *dcb);
static GWPROTOCOL MyObject = {
gw_read_backend_event, /* Read - EPOLLIN handler */
@ -86,7 +86,7 @@ GetModuleObject()
//////////////////////////////////////////
//backend read event triggered by EPOLLIN
//////////////////////////////////////////
int gw_read_backend_event(DCB *dcb, int epfd) {
int gw_read_backend_event(DCB *dcb) {
int n;
MySQLProtocol *client_protocol = NULL;
@ -99,7 +99,6 @@ int gw_read_backend_event(DCB *dcb, int epfd) {
#endif
if ((client_protocol->state == MYSQL_WAITING_RESULT) || (client_protocol->state == MYSQL_IDLE)) {
struct epoll_event new_event;
int w;
int b = -1;
int tot_b = -1;
@ -150,7 +149,7 @@ int gw_read_backend_event(DCB *dcb, int epfd) {
//////////////////////////////////////////
//backend write event triggered by EPOLLOUT
//////////////////////////////////////////
int gw_write_backend_event(DCB *dcb, int epfd) {
int gw_write_backend_event(DCB *dcb) {
//fprintf(stderr, ">>> gw_write_backend_event for %i\n", dcb->fd);
return 0;
}
@ -229,8 +228,7 @@ int w, saved_errno = 0;
return 0;
}
int gw_error_backend_event(DCB *dcb, int epfd, int event) {
struct epoll_event ed;
int gw_error_backend_event(DCB *dcb) {
MySQLProtocol *protocol = DCB_PROTOCOL(dcb, MySQLProtocol);
fprintf(stderr, "#### Handle Backend error function for %i\n", dcb->fd);
@ -250,8 +248,8 @@ int gw_error_backend_event(DCB *dcb, int epfd, int event) {
#endif
if (dcb->state != DCB_STATE_LISTENING) {
if (epoll_ctl(epfd, EPOLL_CTL_DEL, dcb->fd, &ed) == -1) {
fprintf(stderr, "Backend epoll_ctl_del: from events check failed to delete %i, [%i]:[%s]\n", dcb->fd, errno, strerror(errno));
if (poll_remove_dcb(dcb) == -1) {
fprintf(stderr, "Backend poll_remove_dcb: from events check failed to delete %i, [%i]:[%s]\n", dcb->fd, errno, strerror(errno));
}
#ifdef GW_EVENT_DEBUG

View File

@ -29,15 +29,16 @@
*/
#include "mysql_client_server_protocol.h"
#include "poll.h"
static char *version_str = "V1.0.0";
static int gw_MySQLAccept(DCB *listener, int efd);
static int gw_MySQLListener(DCB *listener, int epfd, char *config_bind);
static int gw_read_client_event(DCB* dcb, int epfd);
static int gw_write_client_event(DCB *dcb, int epfd);
static int gw_MySQLAccept(DCB *listener);
static int gw_MySQLListener(DCB *listener, char *config_bind);
static int gw_read_client_event(DCB* dcb);
static int gw_write_client_event(DCB *dcb);
static int gw_MySQLWrite_client(DCB *dcb, GWBUF *queue);
static int gw_error_client_event(DCB *dcb, int epfd, int event);
static int gw_error_client_event(DCB *dcb);
static int gw_check_mysql_scramble_data(uint8_t *token, unsigned int token_len, uint8_t *scramble, unsigned int scramble_len, char *username, uint8_t *stage1_hash);
static int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, void *repository);
@ -659,10 +660,9 @@ int w, saved_errno = 0;
* Client read event triggered by EPOLLIN
*
* @param dcb Descriptor control block
* @param epfd Epoll descriptor
* @return TRUE on error
*/
int gw_read_client_event(DCB* dcb, int epfd) {
int gw_read_client_event(DCB* dcb) {
MySQLProtocol *protocol = NULL;
uint8_t buffer[MAX_BUFFER_SIZE] = "";
int n = 0;
@ -769,9 +769,9 @@ int gw_read_client_event(DCB* dcb, int epfd) {
fprintf(stderr, "COM_QUIT received\n");
if (dcb->session->backends) {
dcb->session->backends->func.write(dcb, queue);
(dcb->session->backends->func).error(dcb->session->backends, epfd);
(dcb->session->backends->func).error(dcb->session->backends);
}
(dcb->func).error(dcb, epfd);
(dcb->func).error(dcb);
return 1;
}
@ -799,10 +799,9 @@ int gw_read_client_event(DCB* dcb, int epfd) {
///////////////////////////////////////////////
// client write event to Client triggered by EPOLLOUT
//////////////////////////////////////////////
int gw_write_client_event(DCB *dcb, int epfd) {
int gw_write_client_event(DCB *dcb) {
MySQLProtocol *protocol = NULL;
int n;
struct epoll_event new_event;
if (dcb == NULL) {
fprintf(stderr, "DCB is NULL, return\n");
@ -839,7 +838,7 @@ int gw_write_client_event(DCB *dcb, int epfd) {
// create one backend connection
// This is not working now, as the backend dcb functions are in the mysql_protocol.c
// and it will loaded separately
//gw_create_backend_connection(dcb, epfd);
//gw_create_backend_connection(dcb);
protocol->state = MYSQL_IDLE;
@ -850,9 +849,9 @@ int gw_write_client_event(DCB *dcb, int epfd) {
// still to implement
mysql_send_auth_error(dcb, 2, 0, "Authorization failed");
dcb->func.error(dcb, epfd);
dcb->func.error(dcb);
if (dcb->session->backends)
dcb->session->backends->func.error(dcb->session->backends, epfd);
dcb->session->backends->func.error(dcb->session->backends);
return 0;
}
@ -904,7 +903,7 @@ int gw_write_client_event(DCB *dcb, int epfd) {
///
// set listener for mysql protocol
///
int gw_MySQLListener(DCB *listener, int epfd, char *config_bind) {
int gw_MySQLListener(DCB *listener, char *config_bind) {
int l_so;
int fl;
struct sockaddr_in serv_addr;
@ -915,7 +914,6 @@ int gw_MySQLListener(DCB *listener, int epfd, char *config_bind) {
char address[1024]="";
int port=0;
int one;
struct epoll_event ev;
// this gateway, as default, will bind on port 4404 for localhost only
(config_bind != NULL) ? (bind_address_and_port = config_bind) : (bind_address_and_port = "127.0.0.1:4406");
@ -973,15 +971,9 @@ int gw_MySQLListener(DCB *listener, int epfd, char *config_bind) {
// assign l_so to dcb
listener->fd = l_so;
// register events, don't add EPOLLET for now
ev.events = EPOLLIN;
// set user data to dcb struct
ev.data.ptr = listener;
// add listening socket to epoll structure
if (epoll_ctl(epfd, EPOLL_CTL_ADD, l_so, &ev) == -1) {
fprintf(stderr, ">>> epoll_ctl: can't add the listen_sock! Errno %i, %s\n", errno, strerror(errno));
// add listening socket to poll structure
if (poll_add_dcb(listener) == -1) {
fprintf(stderr, ">>> poll_add_dcb: can't add the listen_sock! Errno %i, %s\n", errno, strerror(errno));
return 1;
}
@ -993,7 +985,7 @@ int gw_MySQLListener(DCB *listener, int epfd, char *config_bind) {
}
int gw_MySQLAccept(DCB *listener, int efd) {
int gw_MySQLAccept(DCB *listener) {
fprintf(stderr, "MySQL Listener socket is: %i\n", listener->fd);
@ -1002,7 +994,6 @@ int gw_MySQLAccept(DCB *listener, int efd) {
struct sockaddr_in local;
socklen_t addrlen;
addrlen = sizeof(local);
struct epoll_event ee;
DCB *client;
SESSION *session;
MySQLProtocol *protocol;
@ -1052,18 +1043,14 @@ int gw_MySQLAccept(DCB *listener, int efd) {
// assign function poiters to "func" field
memcpy(&client->func, &MyObject, sizeof(GWPROTOCOL));
// edge triggering flag added
ee.events = EPOLLIN | EPOLLOUT | EPOLLET;
ee.data.ptr = client;
client->state = DCB_STATE_IDLE;
// event install
if (epoll_ctl(efd, EPOLL_CTL_ADD, c_sock, &ee) == -1) {
perror("epoll_ctl: conn_sock");
if (poll_add_dcb(client) == -1) {
perror("poll_add_dcb: conn_sock");
exit(EXIT_FAILURE);
} else {
//fprintf(stderr, "Added fd %i to epoll, protocol state [%i]\n", c_sock , client->state);
//fprintf(stderr, "Added fd %i to poll, protocol state [%i]\n", c_sock , client->state);
client->state = DCB_STATE_POLLING;
}
@ -1081,8 +1068,7 @@ int gw_MySQLAccept(DCB *listener, int efd) {
/*
*/
static int gw_error_client_event(DCB *dcb, int epfd, int event) {
struct epoll_event ed;
static int gw_error_client_event(DCB *dcb) {
MySQLProtocol *protocol = DCB_PROTOCOL(dcb, MySQLProtocol);
@ -1107,8 +1093,8 @@ static int gw_error_client_event(DCB *dcb, int epfd, int event) {
#endif
if (dcb->state != DCB_STATE_LISTENING) {
if (epoll_ctl(epfd, EPOLL_CTL_DEL, dcb->fd, &ed) == -1) {
fprintf(stderr, "***** epoll_ctl_del: from events check failed to delete %i, [%i]:[%s]\n", dcb->fd, errno, strerror(errno));
if (poll_remove_dcb(dcb) == -1) {
fprintf(stderr, "***** poll_remove_dcb: from events check failed to delete %i, [%i]:[%s]\n", dcb->fd, errno, strerror(errno));
}
#ifdef GW_EVENT_DEBUG

View File

@ -32,10 +32,10 @@ static char *version_str = "V1.0.0";
static MySQLProtocol *gw_mysql_init(MySQLProtocol *data);
static void gw_mysql_close(MySQLProtocol **ptr);
extern gw_read_backend_event(DCB* dcb, int epfd);
extern gw_write_backend_event(DCB *dcb, int epfd);
extern gw_read_backend_event(DCB* dcb);
extern gw_write_backend_event(DCB *dcb);
extern int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue);
extern int gw_error_backend_event(DCB *dcb, int epfd, int event);
extern int gw_error_backend_event(DCB *dcb);
///////////////////////////////
// Initialize mysql protocol struct
@ -101,14 +101,13 @@ void gw_mysql_close(MySQLProtocol **ptr) {
* Create a new MySQL backend connection.
*
* This routine performs the MySQL connection to the backend and fills the session->backends of the callier dcb
* with the new allocatetd dcb and adds the new socket to the epoll set
* with the new allocatetd dcb and adds the new socket to the poll set
*
* - backend dcb allocation
* - MySQL session data fetch
* - backend connection using data in MySQL session
*
* @param client_dcb The client DCB struct
* @param epfd The epoll set to add the new connection
* @return 0 on Success or 1 on Failure.
*/
@ -116,8 +115,7 @@ void gw_mysql_close(MySQLProtocol **ptr) {
* This function cannot work as it will be called from mysql_client.c but it needs function pointers from mysql_backend.c
* They are modules loaded separately!!
*
int gw_create_backend_connection(DCB *client_dcb, int efd) {
struct epoll_event ee;
int gw_create_backend_connection(DCB *client_dcb) {
DCB *backend = NULL;
MySQLProtocol *ptr_proto = NULL;
MySQLProtocol *client_protocol = NULL;

View File

@ -21,13 +21,13 @@
#include <buffer.h>
#include <service.h>
#include <session.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <router.h>
#include <poll.h>
/**
* @file telnetd.c - telnet daemon protocol module
@ -52,14 +52,14 @@
static char *version_str = "V1.0.0";
static int telnetd_read_event(DCB* dcb, int epfd);
static int telnetd_write_event(DCB *dcb, int epfd);
static int telnetd_read_event(DCB* dcb);
static int telnetd_write_event(DCB *dcb);
static int telnetd_write(DCB *dcb, GWBUF *queue);
static int telnetd_error(DCB *dcb, int event);
static int telnetd_hangup(DCB *dcb, int event);
static int telnetd_accept(DCB *dcb, int event);
static int telnetd_close(DCB *dcb, int event);
static int telnetd_listen(DCB *dcb, int efd, char *config);
static int telnetd_error(DCB *dcb);
static int telnetd_hangup(DCB *dcb);
static int telnetd_accept(DCB *dcb);
static int telnetd_close(DCB *dcb);
static int telnetd_listen(DCB *dcb, char *config);
/**
* The "module object" for the telnetd protocol module.
@ -76,6 +76,9 @@ static GWPROTOCOL MyObject = {
telnetd_listen /**< Create a listener */
};
static void
telnetd_command(DCB *, char *cmd);
/**
* Implementation of the mandatory version entry point
*
@ -115,11 +118,10 @@ GetModuleObject()
* Read event for EPOLLIN on the telnetd protocol module.
*
* @param dcb The descriptor control block
* @param epfd The epoll descriptor
* @return
*/
static int
telnetd_read_event(DCB* dcb, int epfd)
telnetd_read_event(DCB* dcb)
{
int n;
GWBUF *head = NULL;
@ -130,17 +132,20 @@ void *rsession = session->router_session;
if ((n = dcb_read(dcb, &head)) != -1)
{
dcb->state = DCB_STATE_PROCESSING;
if (head)
{
char *ptr = GWBUF_DATA(head);
ptr = GWBUF_DATA(head);
if (*ptr == TELNET_IAC)
{
telnetd_command(dcb, ptr + 1);
GWBUF_CONSUME(head, 2);
}
router->routeQuery(router_instance, rsession, head);
}
}
dcb->state = DCB_STATE_POLLING;
return n;
}
@ -149,11 +154,10 @@ void *rsession = session->router_session;
* EPOLLOUT handler for the telnetd protocol module.
*
* @param dcb The descriptor control block
* @param epfd The epoll descriptor
* @return
*/
static int
telnetd_write_event(DCB *dcb, int epfd)
telnetd_write_event(DCB *dcb)
{
return dcb_drain_writeq(dcb);
}
@ -177,10 +181,9 @@ telnetd_write(DCB *dcb, GWBUF *queue)
* Handler for the EPOLLERR event.
*
* @param dcb The descriptor control block
* @param event The epoll descriptor
*/
static int
telnetd_error(DCB *dcb, int event)
telnetd_error(DCB *dcb)
{
}
@ -188,10 +191,9 @@ telnetd_error(DCB *dcb, int event)
* Handler for the EPOLLHUP event.
*
* @param dcb The descriptor control block
* @param event The epoll descriptor
*/
static int
telnetd_hangup(DCB *dcb, int event)
telnetd_hangup(DCB *dcb)
{
}
@ -200,10 +202,9 @@ telnetd_hangup(DCB *dcb, int event)
* socket for the protocol.
*
* @param dcb The descriptor control block
* @param efd The epoll descriptor
*/
static int
telnetd_accept(DCB *dcb, int efd)
telnetd_accept(DCB *dcb)
{
int n_connect = 0;
@ -213,7 +214,6 @@ int n_connect = 0;
struct sockaddr_in addr;
socklen_t addrlen;
DCB *client;
struct epoll_event ee;
if ((so = accept(dcb->fd, (struct sockaddr *)&addr, &addrlen)) == -1)
return n_connect;
@ -225,17 +225,16 @@ int n_connect = 0;
memcpy(&client->func, &MyObject, sizeof(GWPROTOCOL));
client->session = session_alloc(dcb->session->service, client);
ee.events = EPOLLIN | EPOLLOUT | EPOLLET;
ee.data.ptr = client;
client->state = DCB_STATE_IDLE;
if (epoll_ctl(efd, EPOLL_CTL_ADD, so, &ee) == -1)
if (poll_add_dcb(client) == -1)
{
return n_connect;
}
n_connect++;
dcb_printf(client, "Gateway> ");
client->state = DCB_STATE_POLLING;
}
}
return n_connect;
@ -246,27 +245,25 @@ int n_connect = 0;
* explicitly close a connection.
*
* @param dcb The descriptor control block
* @param efd The epoll descriptor
*/
static int
telnetd_close(DCB *dcb, int efd)
telnetd_close(DCB *dcb)
{
dcb_close(dcb, efd);
dcb_close(dcb);
}
/**
* Telnet daemon listener entry point
*
* @param efd epoll File descriptor
* @param listener The Listener DCB
* @param config Configuration (ip:port)
*/
static int
telnetd_listen(DCB *listener, int efd, char *config)
telnetd_listen(DCB *listener, char *config)
{
struct sockaddr_in addr;
char *port;
struct epoll_event ev;
int one = 1;
short pnum;
@ -301,11 +298,24 @@ short pnum;
listener->state = DCB_STATE_LISTENING;
listen(listener->fd, SOMAXCONN);
ev.events = EPOLLIN;
ev.data.ptr = listener;
if (epoll_ctl(efd, EPOLL_CTL_ADD, listener->fd, &ev) == -1)
if (poll_add_dcb(listener) == -1)
{
return 0;
}
return 1;
}
/**
* Telnet command implementation
*
* Called for each command in the telnet stream.
*
* Currently we do no command execution
*
* @param dcb The client DCB
* @param cmd The command stream
*/
static void
telnetd_command(DCB *dcb, char *cmd)
{
}