Example #1
0
static int
test1()
{
GWBUF   *buffer;
char    *(sql[100]);
int     result, length, residual;

        /* Poll tests */  
        ss_dfprintf(stderr,
                    "testmodutil : Rudimentary tests."); 
        buffer = gwbuf_alloc(100);
        ss_info_dassert(0 == modutil_is_SQL(buffer), "Default buffer should be diagnosed as not SQL");
        /* There would ideally be some straightforward way to create a SQL buffer? */
        ss_dfprintf(stderr, "\t..done\nExtract SQL from buffer");
        ss_info_dassert(0 == modutil_extract_SQL(buffer, sql, &length), "Default buffer should fail");
        ss_dfprintf(stderr, "\t..done\nExtract SQL from buffer different way?");
        ss_info_dassert(0 == modutil_MySQL_Query(buffer, sql, &length, &residual), "Default buffer should fail");
        ss_dfprintf(stderr, "\t..done\nReplace SQL in buffer");
        ss_info_dassert(0 == modutil_replace_SQL(buffer, "select * from some_table;"), "Default buffer should fail");
        ss_dfprintf(stderr, "\t..done\nTidy up.");
        gwbuf_free(buffer);
        ss_dfprintf(stderr, "\t..done\n");
		
	return 0;
        
}
Example #2
0
int
test2()
{
GWBUF   *buffer;
char len = 128;
char query[129];

        buffer = gwbuf_alloc(132);
	ss_info_dassert((buffer != NULL),"Buffer should not be null");

	memset(query,';',128);
    memset(query+128,'\0',1);
	*((unsigned char*)buffer->start) = len;
	*((unsigned char*)buffer->start+1) = 0;
	*((unsigned char*)buffer->start+2) = 0;
	*((unsigned char*)buffer->start+3) = 1;
	*((unsigned char*)buffer->start+4) = 0x03;
	memcpy(buffer->start + 5,query,strlen(query));
	char* result = modutil_get_SQL(buffer);
	ss_dassert(strcmp(result,query) == 0);
	gwbuf_free(buffer);
	free(result);
        ss_dfprintf(stderr, "\t..done\n");
	return 0;

}
Example #3
0
/**
 * test1	Allocate a server and do lots of other things
 *
  */
static int
test1()
{
SERVER   *server;
int     result;
char    *status;

        /* Server tests */
        ss_dfprintf(stderr,
                    "testserver : creating server called MyServer"); 
        server = server_alloc("MyServer", "HTTPD", 9876);
        skygw_log_sync_all();

        //ss_info_dassert(NULL != service, "New server with valid protocol and port must not be null");
        //ss_info_dassert(0 != service_isvalid(service), "Service must be valid after creation");

        ss_dfprintf(stderr, "\t..done\nTest Parameter for Server.");
        ss_info_dassert(NULL == serverGetParameter(server, "name"), "Parameter should be null when not set");
        serverAddParameter(server, "name", "value");
        skygw_log_sync_all();
        ss_info_dassert(0 == strcmp("value", serverGetParameter(server, "name")), "Parameter should be returned correctly");
        ss_dfprintf(stderr, "\t..done\nTesting Unique Name for Server.");
        ss_info_dassert(NULL == server_find_by_unique_name("uniquename"), "Should not find non-existent unique name.");
        server_set_unique_name(server, "uniquename");
        skygw_log_sync_all();
        ss_info_dassert(server == server_find_by_unique_name("uniquename"), "Should find by unique name.");
        ss_dfprintf(stderr, "\t..done\nTesting Status Setting for Server.");
        status = server_status(server);
        skygw_log_sync_all();
        ss_info_dassert(0 == strcmp("Running", status), "Status of Server should be Running by default.");
        if (NULL != status) free(status);
        server_set_status(server, SERVER_MASTER);
        status = server_status(server);
        skygw_log_sync_all();
        ss_info_dassert(0 == strcmp("Master, Running", status), "Should find correct status.");
        server_clear_status(server, SERVER_MASTER);		
		free(status);
        status = server_status(server);
        skygw_log_sync_all();
        ss_info_dassert(0 == strcmp("Running", status), "Status of Server should be Running after master status cleared.");
        if (NULL != status) free(status);
        ss_dfprintf(stderr, "\t..done\nRun Prints for Server and all Servers.");
        printServer(server);
        printAllServers();
        skygw_log_sync_all();
        ss_dfprintf(stderr, "\t..done\nFreeing Server.");
        ss_info_dassert(0 != server_free(server), "Free should succeed");
        ss_dfprintf(stderr, "\t..done\n");
	return 0;
        
}
Example #4
0
/**
 * test1	Allocate a dcb and do lots of other things
 *
  */
static int
test1()
{
DCB   *dcb, *extra, *clone;
int     size = 100;
int     bite1 = 35;
int     bite2 = 60;
int     bite3 = 10;
int     buflen;

        /* Single buffer tests */
        ss_dfprintf(stderr,
                    "testdcb : creating buffer with type DCB_ROLE_SERVICE_LISTENER"); 
        dcb = dcb_alloc(DCB_ROLE_SERVICE_LISTENER);
        printDCB(dcb);
        ss_info_dassert(dcb_isvalid(dcb), "New DCB must be valid");
        ss_dfprintf(stderr, "\t..done\nAllocated dcb.");
        clone = dcb_clone(dcb);
        ss_dfprintf(stderr, "\t..done\nCloned dcb");
        printAllDCBs();
        ss_info_dassert(true, "Something is true");
        ss_dfprintf(stderr, "\t..done\n");
        dcb_close(dcb);
        ss_dfprintf(stderr, "Freed original dcb");
        ss_info_dassert(!dcb_isvalid(dcb), "Freed DCB must not be valid");
        ss_dfprintf(stderr, "\t..done\nMake clone DCB a zombie");
        clone->state = DCB_STATE_NOPOLLING;
        dcb_close(clone);
        ss_info_dassert(dcb_get_zombies() == clone, "Clone DCB must be start of zombie list now");
        ss_dfprintf(stderr, "\t..done\nProcess the zombies list");
        dcb_process_zombies(0);
        ss_dfprintf(stderr, "\t..done\nCheck clone no longer valid");
        ss_info_dassert(!dcb_isvalid(clone), "After zombie processing, clone DCB must not be valid");
        ss_dfprintf(stderr, "\t..done\n");
		
	return 0;
}
Example #5
0
/**
 * Link a session to a DCB.
 *
 * @param session       The session to link with the dcb
 * @param dcb           The DCB to be linked
 * @return              True if the session was sucessfully linked to the DCB
 */
bool
session_link_dcb(SESSION *session, DCB *dcb)
{
    spinlock_acquire(&session->ses_lock);
    ss_info_dassert(session->state != SESSION_STATE_FREE,
                    "If session->state is SESSION_STATE_FREE then this attempt to "
                    "access freed memory block.");
    if (session->state == SESSION_STATE_FREE)
    {
        spinlock_release(&session->ses_lock);
        return false;
    }
    atomic_add(&session->refcount, 1);
    dcb->session = session;
    spinlock_release(&session->ses_lock);
    return true;
}
Example #6
0
/**
 * Allocate a new session for a new client of the specified service.
 *
 * Create the link to the router session by calling the newSession
 * entry point of the router using the router instance of the
 * service this session is part of.
 *
 * @param service       The service this connection was established by
 * @param client_dcb    The client side DCB
 * @return              The newly created session or NULL if an error occured
 */
SESSION *
session_alloc(SERVICE *service, DCB *client_dcb)
{
    SESSION *session;

    session = (SESSION *)calloc(1, sizeof(SESSION));
    ss_info_dassert(session != NULL, "Allocating memory for session failed.");

    if (session == NULL)
    {
        char errbuf[STRERROR_BUFLEN];
        MXS_ERROR("Failed to allocate memory for "
                  "session object due error %d, %s.",
                  errno,
                  strerror_r(errno, errbuf, sizeof(errbuf)));
        return NULL;
    }
#if defined(SS_DEBUG)
    session->ses_chk_top = CHK_NUM_SESSION;
    session->ses_chk_tail = CHK_NUM_SESSION;
#endif
    session->ses_is_child = (bool) DCB_IS_CLONE(client_dcb);
    spinlock_init(&session->ses_lock);
    session->service = service;
    session->client_dcb = client_dcb;
    session->n_filters = 0;
    memset(&session->stats, 0, sizeof(SESSION_STATS));
    session->stats.connect = time(0);
    session->state = SESSION_STATE_ALLOC;
    /*<
     * Associate the session to the client DCB and set the reference count on
     * the session to indicate that there is a single reference to the
     * session. There is no need to protect this or use atomic add as the
     * session has not been made available to the other threads at this
     * point.
     */
    session->refcount = 1;
    /*<
     * This indicates that session is ready to be shared with backend
     * DCBs. Note that this doesn't mean that router is initialized yet!
     */
    session->state = SESSION_STATE_READY;

    /*
     * Only create a router session if we are not the listening
     * DCB or an internal DCB. Creating a router session may create a connection to a
     * backend server, depending upon the router module implementation
     * and should be avoided for the listener session
     *
     * Router session creation may create other DCBs that link to the
     * session, therefore it is important that the session lock is
     * relinquished before the router call.
     */
    if (client_dcb->state != DCB_STATE_LISTENING &&
        client_dcb->dcb_role != DCB_ROLE_INTERNAL)
    {
        session->router_session = service->router->newSession(service->router_instance, session);
        if (session->router_session == NULL)
        {
            session->state = SESSION_STATE_TO_BE_FREED;
            MXS_ERROR("Failed to create new router session for service '%s'. "
                      "See previous errors for more details.", service->name);
        }
        /*
         * Pending filter chain being setup set the head of the chain to
         * be the router. As filters are inserted the current head will
         * be pushed to the filter and the head updated.
         *
         * NB This dictates that filters are created starting at the end
         * of the chain nearest the router working back to the client
         * protocol end of the chain.
         */
        session->head.instance = service->router_instance;
        session->head.session = session->router_session;

        session->head.routeQuery = (void *)(service->router->routeQuery);

        session->tail.instance = session;
        session->tail.session = session;
        session->tail.clientReply = session_reply;

        if (SESSION_STATE_TO_BE_FREED != session->state
            && service->n_filters > 0
            && !session_setup_filters(session))
        {
            session->state = SESSION_STATE_TO_BE_FREED;
            MXS_ERROR("Setting up filters failed. "
                      "Terminating session %s.",
                      service->name);
        }
    }

    if (SESSION_STATE_TO_BE_FREED != session->state)
    {
        session->state = SESSION_STATE_ROUTER_READY;

        if (session->client_dcb->user == NULL)
        {
            MXS_INFO("Started session [%lu] for %s service ",
                     session->ses_id,
                     service->name);
        }
        else
        {
            MXS_INFO("Started %s client session [%lu] for '%s' from %s",
                     service->name,
                     session->ses_id,
                     session->client_dcb->user,
                     session->client_dcb->remote);
        }
    }
    else
    {
        MXS_INFO("Start %s client session [%lu] for '%s' from %s failed, will be "
                 "closed as soon as all related DCBs have been closed.",
                 service->name,
                 session->ses_id,
                 session->client_dcb->user,
                 session->client_dcb->remote);
    }
    spinlock_acquire(&session_spin);
    /** Assign a session id and increase, insert session into list */
    session->ses_id = ++session_id;
    session->next = allSessions;
    allSessions = session;
    spinlock_release(&session_spin);
    atomic_add(&service->stats.n_sessions, 1);
    atomic_add(&service->stats.n_current, 1);
    CHK_SESSION(session);

    client_dcb->session = session;
    return SESSION_STATE_TO_BE_FREED == session->state ? NULL : session;
}
Example #7
0
/**
 * test1	spinlock_acquire_nowait tests
 *
 * Test that spinlock_acquire_nowait returns false if the spinlock
 * is already taken.
 *
 * Test that spinlock_acquire_nowait returns true if the spinlock
 * is not taken.
 *
 * Test that spinlock_acquire_nowait does hold the spinlock.
 */
static bool do_hashtest(
        int argelems,
        int argsize)
{
        bool       succp = true;
        HASHTABLE* h;
        int        nelems;
        int        i;
        int*       val_arr;
        int        hsize;
        int        longest;
        int*       iter;
        
        ss_dfprintf(stderr,
                    "testhash : creating hash table of size %d, including %d "
                    "elements in total, at time %g.",
                    argsize,
                    argelems,
                    (double)clock()-start); 
        
        val_arr = (int *)malloc(sizeof(void *)*argelems);
        
        h = hashtable_alloc(argsize, hfun, cmpfun);

        ss_dfprintf(stderr, "\t..done\nAdd %d elements to hash table.", argelems);
        
        for (i=0; i<argelems; i++) {
            val_arr[i] = i;
            hashtable_add(h, (void *)&val_arr[i], (void *)&val_arr[i]);
        }
        if (argelems > 1000) ss_dfprintf(stderr, "\t..done\nOperation took %g", (double)clock()-start);
        
        ss_dfprintf(stderr, "\t..done\nRead hash table statistics.");
        
        hashtable_get_stats((void *)h, &hsize, &nelems, &longest);

        ss_dfprintf(stderr, "\t..done\nValidate read values.");
        
        ss_info_dassert(hsize == (argsize > 0 ? argsize: 1), "Invalid hash size");
        ss_info_dassert((nelems == argelems) || (nelems == 0 && argsize == 0),
                        "Invalid element count");
        ss_info_dassert(longest <= nelems, "Too large longest list value");
        if (argelems > 1000) ss_dfprintf(stderr, "\t..done\nOperation took %g", (double)clock()-start);

        ss_dfprintf(stderr, "\t..done\nValidate iterator.");
        
        HASHITERATOR *iterator = hashtable_iterator(h);
        read_lock(h);
        for (i=0; i < (argelems+1); i++) {
            iter = (int *)hashtable_next(iterator);
            if (iter == NULL) break;
            if (argelems < 100) ss_dfprintf(stderr, "\nNext item, iter = %d, i = %d", *iter, i);
        }
        read_unlock(h);
        ss_info_dassert((i == argelems) || (i == 0 && argsize == 0), "\nIncorrect number of elements from iterator");
        hashtable_iterator_free(iterator);
        if (argelems > 1000) ss_dfprintf(stderr, "\t..done\nOperation took %g", (double)clock()-start);

        ss_dfprintf(stderr, "\t\t..done\n\nTest completed successfully.\n\n");
        
        CHK_HASHTABLE(h);
        hashtable_free(h);
        

		free(val_arr);
        return succp;
}
Example #8
0
/**
 * Allocate a new session for a new client of the specified service.
 *
 * Create the link to the router session by calling the newSession
 * entry point of the router using the router instance of the
 * service this session is part of.
 *
 * @param service	The service this connection was established by
 * @param client_dcb	The client side DCB
 * @return		The newly created session or NULL if an error occured
 */
SESSION *
session_alloc(SERVICE *service, DCB *client_dcb)
{
        SESSION 	*session;

        session = (SESSION *)calloc(1, sizeof(SESSION));
        ss_info_dassert(session != NULL,
                        "Allocating memory for session failed.");
        
        if (session == NULL) {
                int eno = errno;
                errno = 0;
                LOGIF(LE, (skygw_log_write_flush(
                        LOGFILE_ERROR,
                        "Error : Failed to allocate memory for "
                        "session object due error %d, %s.",
                        eno,
                        strerror(eno))));
		goto return_session;
        }
#if defined(SS_DEBUG)
        session->ses_chk_top = CHK_NUM_SESSION;
        session->ses_chk_tail = CHK_NUM_SESSION;
#endif
        spinlock_init(&session->ses_lock);
        /*<
         * Prevent backend threads from accessing before session is completely
         * initialized.
         */
        spinlock_acquire(&session->ses_lock);
        session->service = service;
	session->client = client_dcb;
	session->n_filters = 0;
	memset(&session->stats, 0, sizeof(SESSION_STATS));
	session->stats.connect = time(0);
	session->state = SESSION_STATE_ALLOC;
        /*<
	 * Associate the session to the client DCB and set the reference count on
	 * the session to indicate that there is a single reference to the
         * session. There is no need to protect this or use atomic add as the
         * session has not been made available to the other threads at this
         * point.
         */
        session->data = client_dcb->data;
	client_dcb->session = session;
	session->refcount = 1;
        /*<
         * This indicates that session is ready to be shared with backend
         * DCBs. Note that this doesn't mean that router is initialized yet!
         */
        session->state = SESSION_STATE_READY;
        
        /*< Release session lock */
        spinlock_release(&session->ses_lock);

	/*
	 * Only create a router session if we are not the listening 
	 * DCB or an internal DCB. Creating a router session may create a connection to a
	 * backend server, depending upon the router module implementation
	 * and should be avoided for the listener session
	 *
	 * Router session creation may create other DCBs that link to the
	 * session, therefore it is important that the session lock is
         * relinquished beforethe router call.
	 */
	if (client_dcb->state != DCB_STATE_LISTENING && 
                client_dcb->dcb_role != DCB_ROLE_INTERNAL)
	{
		session->router_session =
                    service->router->newSession(service->router_instance,
                                                session);
	
                if (session->router_session == NULL) {
                        /**
                         * Inform other threads that session is closing.
                         */
                        session->state = SESSION_STATE_STOPPING;
                        /*<
                         * Decrease refcount, set dcb's session pointer NULL
                         * and set session pointer to NULL.
                         */
                        session_free(session);
                        client_dcb->session = NULL;
                        session = NULL;
                        LOGIF(LE, (skygw_log_write_flush(
                                LOGFILE_ERROR,
                                "Error : Failed to create %s session.",
                                service->name)));
                        
                        goto return_session;
                }

		/*
		 * Pending filter chain being setup set the head of the chain to
		 * be the router. As filters are inserted the current head will
		 * be pushed to the filter and the head updated.
		 *
		 * NB This dictates that filters are created starting at the end
		 * of the chain nearest the router working back to the client
		 * protocol end of the chain.
		 */
		session->head.instance = service->router_instance;
		session->head.session = session->router_session;

		session->head.routeQuery = (void *)(service->router->routeQuery);

		session->tail.instance = session;
		session->tail.session = session;
		session->tail.clientReply = session_reply;

		if (service->n_filters > 0)
		{
			if (!session_setup_filters(session))
			{
				/**
				 * Inform other threads that session is closing.
				 */
				session->state = SESSION_STATE_STOPPING;
				/*<
				 * Decrease refcount, set dcb's session pointer NULL
				 * and set session pointer to NULL.
				 */
				session_free(session);
				client_dcb->session = NULL;
				session = NULL;
				LOGIF(LE, (skygw_log_write_flush(
					LOGFILE_ERROR,
					"Error : Failed to create %s session.",
					service->name)));
				goto return_session;
			}
		}
        }

	spinlock_acquire(&session_spin);
        
        if (session->state != SESSION_STATE_READY)
        {
                session_free(session);
                client_dcb->session = NULL;
                session = NULL;
                LOGIF(LE, (skygw_log_write_flush(
                        LOGFILE_ERROR,
                        "Error : Failed to create %s session.",
                        service->name)));
                spinlock_release(&session_spin);
        }
        else
        {
                session->state = SESSION_STATE_ROUTER_READY;
                session->next = allSessions;
                allSessions = session;
                spinlock_release(&session_spin);
                atomic_add(&service->stats.n_sessions, 1);
                atomic_add(&service->stats.n_current, 1);
                CHK_SESSION(session);
        }        
return_session:
	return session;
}
Example #9
0
/**
 * Add a DCB to the set of descriptors within the polling
 * environment.
 *
 * @param dcb	The descriptor to add to the poll
 * @return	-1 on error or 0 on success
 */
int
poll_add_dcb(DCB *dcb)
{
        int         rc = -1;
        dcb_state_t old_state = DCB_STATE_UNDEFINED;
        dcb_state_t new_state;
        struct	epoll_event	ev;

        CHK_DCB(dcb);

#ifdef EPOLLRDHUP
	ev.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLHUP | EPOLLET;
#else
	ev.events = EPOLLIN | EPOLLOUT | EPOLLHUP | EPOLLET;
#endif
	ev.data.ptr = dcb;

        /*<
         * Choose new state according to the role of dcb.
         */
        if (dcb->dcb_role == DCB_ROLE_REQUEST_HANDLER) {
                new_state = DCB_STATE_POLLING;
        } else {
                ss_dassert(dcb->dcb_role == DCB_ROLE_SERVICE_LISTENER);
                new_state = DCB_STATE_LISTENING;
        }
        /*<
         * If dcb is in unexpected state, state change fails indicating that dcb
         * is not polling anymore.
         */
        if (dcb_set_state(dcb, new_state, &old_state)) {
                rc = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, dcb->fd, &ev);

                if (rc != 0) {
                        int eno = errno;
                        errno = 0;
                        LOGIF(LE, (skygw_log_write_flush(
                                LOGFILE_ERROR,
                                "Error : Adding dcb %p in state %s "
                                "to poll set failed. epoll_ctl failed due "
                                "%d, %s.",
                                dcb,
                                STRDCBSTATE(dcb->state),
                                eno,
                                strerror(eno))));
                } else {
                        LOGIF(LD, (skygw_log_write(
                                LOGFILE_DEBUG,
                                "%lu [poll_add_dcb] Added dcb %p in state %s to "
                                "poll set.",
                                pthread_self(),
                                dcb,
                                STRDCBSTATE(dcb->state))));
                }
                ss_info_dassert(rc == 0, "Unable to add poll"); /*< trap in debug */
        } else {
                LOGIF(LE, (skygw_log_write_flush(
                        LOGFILE_ERROR,
                        "Error : Unable to set new state for dcb %p "
                        "in state %s. Adding to poll set failed.",
                        dcb,
                        STRDCBSTATE(dcb->state))));
        }
        
	return rc; 
}