void
saftest_daemon_handle_incoming_clm_message(void *data, void *key)
{
    clm_session_t *clm_session = data;
    fd_set *fd_mask = (fd_set *)key;
    SaAisErrorT err;

    if (NULL == data) {
        return;
    }

    if (!FD_ISSET(clm_session->selection_object, fd_mask)) {
        return;
    }

    saftest_log("Incoming request on clm selection fd %d.  "
                 "Calling saClmDispatch\n",
                 clm_session->selection_object);
    saftest_assert(SA_DISPATCH_BLOCKING != clm_session->dispatch_flags,
                   "It will have its own dispatch thread\n");
    err = saClmDispatch(clm_session->clm_handle, clm_session->dispatch_flags);
    if (SA_AIS_OK != err) {
        saftest_log("Error %s performing saClmDispatch\n",
                     get_error_string(err));
        /* !!! We may only want to do this for "short-lived" drivers */
        exit(1);
    }
}
void
saftest_daemon_handle_dispatch_request(
    saftest_map_table_entry_t *map_entry,
    saftest_msg_t *request,
    saftest_msg_t **reply)
{
    clm_session_t *clm_session = NULL;
    SaAisErrorT status;
    SaDispatchFlagsT dispatch_flags;
    clm_driver_thread_t *cdt = get_current_clm_thread_data();

    saftest_log("Received a dispatch request for id %d\n",
                saftest_msg_get_ubit32_value(request, "CLM_SESSION_ID"));
    clm_session = lookup_clm_session_from_request(request);

    dispatch_flags =
        saftest_dispatch_flags_from_string(
                   saftest_msg_get_str_value(request, "DISPATCH_FLAGS"));
    saftest_assert(SAFTEST_DISPATCH_NONE != dispatch_flags,
                   "Can't use SA_DISPATCH_NONE for a dispatch request\n");
    saftest_assert((SA_DISPATCH_BLOCKING != dispatch_flags) ||
                   (FALSE == cdt->main_thread),
                   "You can't call DISPATCH_BLOCKING in the main thread\n");
    status = saClmDispatch(clm_session->clm_handle, dispatch_flags);
    if (SA_DISPATCH_BLOCKING != dispatch_flags) {
        /* 
         * The client is only expecting a reply in non dispatch blocking 
         * cases.  Otherwise the client would hang until we finalized.
         */
        (*reply) = saftest_reply_msg_create(request, 
                                            map_entry->reply_op, status);
    }
}
void saClmClusterTrackStop_01(void)
{
        trackFlags = SA_TRACK_CURRENT;
        nodeId = 131343;
        invocation = 600;
        safassert(saClmInitialize(&clmHandle, &clmCallback11, &clmVersion_1), SA_AIS_OK);
        rc = saClmClusterTrack(clmHandle, trackFlags, NULL);
        rc = saClmClusterTrack(clmHandle, trackFlags, NULL);
	rc = saClmClusterNodeGetAsync(clmHandle, invocation, nodeId);
        rc = saClmClusterTrack(clmHandle, trackFlags, NULL);
	rc = saClmClusterNodeGetAsync(clmHandle, invocation, nodeId);
	rc = saClmClusterNodeGetAsync(clmHandle, invocation, nodeId);
        rc = saClmClusterTrack(clmHandle, trackFlags, NULL);
        safassert(saClmClusterTrackStop(clmHandle), SA_AIS_OK);
        safassert(saClmDispatch(clmHandle,SA_DISPATCH_ALL), SA_AIS_OK);
        rc = saClmClusterTrack(clmHandle, trackFlags, NULL);
        safassert(saClmClusterTrackStop(clmHandle), SA_AIS_OK);
        safassert(saClmFinalize(clmHandle), SA_AIS_OK);
        test_validate(rc, SA_AIS_OK);
}
Example #4
0
int main(int argc, char* argv[])
{
    /* Use syslog for logging (/var/log/messages) */
    openlog(basename(argv[0]), LOG_PID, LOG_USER);
    
    //setenv("CLMSV_TRACE_PATHNAME","/tmp/clma.log",1); //only work if export before run this program

    SaAisErrorT rc;
    SaClmHandleT clmHandle;
    SaClmCallbacksT_4 clmCallbacks = { 0 };
    SaVersionT version = { 'B', 4, 1 };
    clmCallbacks.saClmClusterTrackCallback = clmClusterTrackCallback;
    rc = saClmInitialize_4(&clmHandle, &clmCallbacks, &version);
    if (rc != SA_AIS_OK) {
            syslog(LOG_ERR,"saClmInitialize_4 FAILED %u", rc);
            return 1;
    }
    SaSelectionObjectT clmFd;
    rc = saClmSelectionObjectGet(clmHandle, &clmFd);
    if (rc != SA_AIS_OK) {
        syslog(LOG_ERR,"saClmSelectionObjectGet FAILED %u", rc);
        return 1;
    }
    int clusterSize = 4;
    size_t sizeOfNotificationBuffer = (clusterSize * sizeof(SaClmClusterNotificationT_4));
    SaClmClusterNotificationBufferT_4 clmlusterNotificationBuffer;
    clmlusterNotificationBuffer.viewNumber = 0;
    clmlusterNotificationBuffer.numberOfItems = clusterSize;

    clmlusterNotificationBuffer.notification = (SaClmClusterNotificationT_4*) calloc(1, sizeOfNotificationBuffer);
    if (clmlusterNotificationBuffer.notification == NULL) {
            syslog(LOG_ERR,"FAILED to allocate resources");
            return 1;
    }
    SaUint8T trackFlags = SA_TRACK_CURRENT | SA_TRACK_CHANGES | SA_TRACK_START_STEP; //SA_TRACK_VALIDATE_STEP is supported with PLM only
    rc = saClmClusterTrack_4(clmHandle, trackFlags, &clmlusterNotificationBuffer);
    if (rc != SA_AIS_OK) {
        syslog(LOG_ERR,"saClmClusterTrack_4 FAILED %u", rc);
        if (rc == SA_AIS_ERR_NO_SPACE) {
            syslog(LOG_ERR,"rc = SA_AIS_ERR_NO_SPACE, numberOfItems = %d", clmlusterNotificationBuffer.numberOfItems);
        }
        free(clmlusterNotificationBuffer.notification);
        clmlusterNotificationBuffer.notification = NULL;
        return 1;
    }

    struct pollfd fds;
    fds.fd = clmFd;
    fds.events = POLLIN;
    while(1){
        int res = poll(&fds, 1, -1);
        if (res == -1) {
            if (errno == EINTR)
                continue;
            else {
                syslog(LOG_ERR,"poll FAILED - %s", strerror(errno));
                return 1;
            }
        }
        if (fds.revents & POLLIN) {
            syslog(LOG_INFO,"========= CLM event ===========");
            rc = saClmDispatch(clmHandle, SA_DISPATCH_ONE);
            if (SA_AIS_OK != rc) {
                    syslog(LOG_ERR,"saClmDispatch FAILED %u", rc);
                    return 1;
            }
        }
    }
}
Example #5
0
static void test_clm_during_cpg_test(void)
{
	SaClmHandleT clmHandle = { 0 };
	SaAisErrorT err;
	SaClmCallbacksT callbacks =
		{
			.saClmClusterNodeGetCallback = _clm_nodeget_callback,
			.saClmClusterTrackCallback = _clm_nodetrack_callback,
		};
	SaVersionT version = { .releaseCode = 'B', .majorVersion = 1, .minorVersion = 1 };
	SaClmClusterNodeT node;
	int status = 0;
	pid_t r;

	while ( (err = saClmInitialize(&clmHandle, &callbacks, &version)) == SA_AIS_ERR_TRY_AGAIN );
	if ( err != SA_AIS_OK )
		DIE("saClmInitialize(): %d", err);

	if ( (err = saClmClusterNodeGet(clmHandle, SA_CLM_LOCAL_NODE_ID, 1000000, &node)) != SA_AIS_OK )
		DIE("saClmNodeGet(): %d", err);

	test_data.node_id = node.nodeId;
	DPRINTF("We are '%.*s', ID: %d", node.nodeName.length, node.nodeName.value, node.nodeId);

	if ( (err = saClmClusterTrack(clmHandle, SA_TRACK_CURRENT | SA_TRACK_CHANGES, NULL)) != SA_AIS_OK )
		DIE("saClmClusterTrack(): %d", err);

	r = 0;
	status = 0;
	/* Note: The man pages of FreeBSD says that waitpid() should return 0 if no process has ended
	 * but I get 1 instead. Weird.
	 * TODO(Jflesch): Figure out what I did wrong.
	 */
	while ( test_data.keep_dispatching && (test_data.test_cpg_pid == -1
			|| ( (r = waitpid(test_data.test_cpg_pid, &status, WNOHANG) != -1)
				&& (r == 0 || r == 1 || (!WIFEXITED(status) && !WIFSIGNALED(status))) ) ) )
	{
		if ( (err = saClmDispatch(clmHandle, SA_DISPATCH_ALL)) != SA_AIS_OK )
			DIE("saClmDispatch(): %d", err);

		if ( test_data.nmb_peers == test_data.max_nmb_peers )
		{
			if ( test_data.master_id != test_data.node_id )
			{
				DPRINTF("Synchronized.");
				/* -> we are a slave, the only thing we have to do is run CPG tests again */
				test_data.keep_dispatching = 0;
				test_data.run_cpg_test = 1;
			}
			else if ( test_data.test_cpg_pid == -1 )
			{
				DPRINTF("Synchronized.");
				test_data.nmb_clm_notifications = 0;
				DPRINTF("(master) Running CPG tests ...");
				test_data.test_cpg_pid = start_cpg_tests(); /* // */
				DPRINTF("(master) CPG tests started");
			}
		}

		usleep(10 * 1000); /* 10ms */
	}

	if ( test_data.keep_dispatching ) /* => end of test */
	{
		if ( test_data.test_cpg_pid < 0 )
			DIE("CPG tests not even started");
		if ( r <= -1 )
			DIE("waitpid() failed: %d, %s", errno, strerror(errno));
		if ( WIFSIGNALED(status) )
			DIE("CPG tests died because of signal %d", WTERMSIG(status));
		if ( WEXITSTATUS(status) != 0 )
			DIE("CPG tests died returning the value %d", WEXITSTATUS(status));
	}

#ifdef BE_NICE
	if ( (err = saClmClusterTrackStop(clmHandle)) != SA_AIS_OK )
		DIE("saClmTrackStop(): %d", err);
#endif

	if ( (err = saClmFinalize(clmHandle)) != SA_AIS_OK )
		DIE("saClmFinalize(): %d", err);

	if ( test_data.nmb_clm_notifications <= 0 )
		DIE("Got no CLM notifications");

	if ( test_data.run_cpg_test )
	{
		DPRINTF("(slave) Running CPG tests ...");
		test_cpg_multiplayer(test_data.max_nmb_peers);
		DPRINTF("(slave) CPG test finished");
	}
}

void test_clm(int nmb_peers)
{
	if ( nmb_peers <= 1 )
		DIE("Not enought peers");

	test_data = TEST_DATA_START_VALUE;
	test_data.max_nmb_peers = nmb_peers;

	DPRINTF("   - Rerun of the CPG multiplayer test, keeping an eye on CLM behavior");
	test_clm_during_cpg_test();
	/* 	DPRINTF("   - Misuse of the API"); ? */
}
Example #6
0
int main(void)
{
	SaSelectionObjectT st;
	SaErrorT ret;
	SaClmNodeIdT nid;

	SaClmCallbacksT my_callbacks = {
		.saClmClusterTrackCallback
		=	(SaClmClusterTrackCallbackT)track_callback,
		.saClmClusterNodeGetCallback
		=	(SaClmClusterNodeGetCallbackT)getnode_callback
	};

	if ((ret = saClmInitialize(&hd, &my_callbacks, NULL)) != SA_OK) {
		fprintf(stderr, "saClmInitialize error, errno [%d]\n",ret);
		return 1;
	}
	if ((ret = saClmSelectionObjectGet(&hd, &st)) != SA_OK) {
		fprintf(stderr, "saClmSelectionObjectGet error, errno [%d]\n"
		,	ret);
		return 1;
	}

	nid = 0;

	/* Synchronously get nodeId information */
	printf("-------------------------------------------------\n");
	printf("Get nodeId [%lu] info by SaClmClusterNodeGet\n", nid);
	if ((ret = saClmClusterNodeGet(nid, 10, &cn)) != SA_OK) {
		if (ret == SA_ERR_INVALID_PARAM) {
			fprintf(stderr, "NodeId [%lu] record not found!\n",nid);
		} else {
			fprintf(stderr
			,	"saClmClusterNodeGet error, errno [%d]\n"
			,	ret);
			return 1;
		}
	} else {
		dump_nodeinfo(&cn);
	}

	/* Asynchronously get my nodeId information */
	nid = 1;
	printf("-------------------------------------------------\n");
	printf("Get nodeId [%lu] info by SaClmClusterNodeGetAsync\n", nid);
	if ((ret = saClmClusterNodeGetAsync(&hd, 1234, nid, &cn)) != SA_OK) {
		if (ret == SA_ERR_INVALID_PARAM) {
			fprintf(stderr, "NodeId [%lu] record not found!\n",nid);
		} else {
			fprintf(stderr
			,	"saClmClusterNodeGet error, errno [%d]\n"
			,	ret);
			return 1;
		}
	}

	/* Start to track cluster membership changes events */
	track_start(SIGUSR1);
	signal(SIGUSR2, &track_stop);

	for (;;) {
		fd_set rset;

		FD_ZERO(&rset);
		FD_SET(st, &rset);

		if (select(st + 1, &rset, NULL, NULL, NULL) == -1) {
			/* TODO should we use pselect here? */
			if (errno == EINTR)
				continue;
			else {
				perror("select");
				return 1;
			}
		}
		if ((ret = saClmDispatch(&hd, SA_DISPATCH_ALL)) != SA_OK) {
			if (ret == SA_ERR_LIBRARY) {
				fprintf(stderr, "I am evicted!\n");
				return 1;
			}
			fprintf(stderr, "saClmDispatch error, errno [%d]\n"
			,	ret);
			return 1;
		}
	}

	return 0;
}
Example #7
0
/****************************************************************************
 * Name          : eds_main_process
 *
 * Description   : This is the function which is given as a input to the 
 *                 EDS task.
 *                 This function will be select of both the FD's (AMF FD and
 *                 Mail Box FD), depending on which FD has been selected, it
 *                 will call the corresponding routines.
 *
 * Arguments     : mbx  - This is the mail box pointer on which EDS is 
 *                        going to block.  
 *
 * Return Values : None.
 *
 * Notes         : None.
 *****************************************************************************/
void eds_main_process(SYSF_MBX *mbx)
{

	NCS_SEL_OBJ mbx_fd;
	SaAisErrorT error = SA_AIS_OK;
	EDS_CB *eds_cb = NULL;
	int term_fd;
	TRACE_ENTER();

	if (NULL == (eds_cb = (EDS_CB *)ncshm_take_hdl(NCS_SERVICE_ID_EDS, gl_eds_hdl))) {
		LOG_ER("Global take handle failed");
		return;
	}

	mbx_fd = m_NCS_IPC_GET_SEL_OBJ(&eds_cb->mbx);

	/* Give back the handle */
	ncshm_give_hdl(gl_eds_hdl);

	/* Initialize with IMM */
	if (eds_imm_init(eds_cb) != SA_AIS_OK) {
		LOG_ER("Imm Init Failed. Exiting");
		exit(EXIT_FAILURE);
	}

	daemon_sigterm_install(&term_fd);

	/* Set up all file descriptors to listen to */
	fds[FD_TERM].fd = term_fd;
	fds[FD_TERM].events = POLLIN;
	fds[FD_AMF].fd = eds_cb->amfSelectionObject;
	fds[FD_AMF].events = POLLIN;
	fds[FD_CLM].fd = eds_cb->clm_sel_obj;
	fds[FD_CLM].events = POLLIN;
	fds[FD_MBCSV].fd = eds_cb->mbcsv_sel_obj;
	fds[FD_MBCSV].events = POLLIN;
	fds[FD_MBX].fd = mbx_fd.rmv_obj;
	fds[FD_MBX].events = POLLIN;
	fds[FD_IMM].fd = eds_cb->imm_sel_obj;
	fds[FD_IMM].events = POLLIN;

	TRACE("Entering the forever loop");

	while (1) {

		if ((eds_cb->immOiHandle != 0) && (eds_cb->is_impl_set == true)){
			fds[FD_IMM].fd = eds_cb->imm_sel_obj;
			fds[FD_IMM].events = POLLIN;
			nfds = NUM_FD;
		} else {
			nfds = NUM_FD - 1;
		}
		
		int ret = poll(fds, nfds, -1);

		if (ret == -1) {
			if (errno == EINTR)
				continue;

			TRACE("poll failed - %s", strerror(errno));
			break;
		}

		/* process the sigterm */
		if (fds[FD_TERM].revents & POLLIN) {
			daemon_exit();
		}

		/* process all the AMF messages */
		if (fds[FD_AMF].revents & POLLIN) {
			/* dispatch all the AMF pending callbacks */
			error = saAmfDispatch(eds_cb->amf_hdl, SA_DISPATCH_ALL);
			if (error != SA_AIS_OK)
				LOG_ER("AMF Dispatch failed with rc = %d",error);
		}

		/* process all mbcsv messages */
		if (fds[FD_MBCSV].revents & POLLIN) {
			error = eds_mbcsv_dispatch(eds_cb->mbcsv_hdl);
			if (NCSCC_RC_SUCCESS != error)
				LOG_ER("MBCSv Dispatch failed with rc = %d",error);
		}

		/* Process the EDS Mail box, if eds is ACTIVE. */
		if (fds[FD_MBX].revents & POLLIN) {
			/* now got the IPC mail box event */
			eds_process_mbx(mbx);
		}

		/* process the CLM messages */
		if (fds[FD_CLM].revents & POLLIN) {
			/* dispatch all the AMF pending callbacks */
			error = saClmDispatch(eds_cb->clm_hdl, SA_DISPATCH_ALL);
			if (error != SA_AIS_OK)
				LOG_ER("CLM Dispatch failed with rc = %d",error);
		}

		/* process the IMM messages */
		if (eds_cb->immOiHandle && fds[FD_IMM].revents & POLLIN) {

			/* dispatch the IMM event */
			error = saImmOiDispatch(eds_cb->immOiHandle, SA_DISPATCH_ONE);

			/*
			 ** BAD_HANDLE is interpreted as an IMM service restart. Try 
			 ** reinitialize the IMM OI API in a background thread and let 
			 ** this thread do business as usual especially handling write 
			 ** requests.
			 **
			 ** All other errors are treated as non-recoverable (fatal) and will
			 ** cause an exit of the process.
			 */

			if (error == SA_AIS_ERR_BAD_HANDLE) {
				TRACE("saImmOiDispatch returned BAD_HANDLE");

				/* Invalidate the IMM OI handle. */
				saImmOiFinalize(eds_cb->immOiHandle);
				eds_cb->immOiHandle = 0;
				eds_cb->is_impl_set = false;
				eds_imm_reinit_bg(eds_cb);
				
			} else if (error != SA_AIS_OK) {
				LOG_ER("saImmOiDispatch FAILED with rc = %d", error);
				break;
			}

		}
	}

	TRACE_LEAVE();
	return;
}	/* End eds_main_process() */