Beispiel #1
0
/* Execute the server-side duties for remote on-the-wire testing using
 * a real NIC. Basically the server side just needs to send packets
 * over the wire (to the kernel under test) and sniff and verify
 * packets on the wire (from the kernel under test). This is analogous
 * to run_script(), which executes scripts for stand-alone mode,
 * and also executes the client side for remote on-the-wire testing
 * using a real NIC.
 */
static int wire_server_run_script(struct wire_server *wire_server,
				  char **error)
{
	struct state *state = wire_server->state;
	struct event *event = NULL;

	DEBUGP("wire_server_run_script\n");

	state->live_start_time_usecs = now_usecs();
	DEBUGP("live_start_time_usecs is %lld\n",
	       state->live_start_time_usecs);

	while (1) {
		if (get_next_event(state, error))
			return STATUS_ERR;
		event = state->event;
		if (event == NULL)
			break;

		if (wire_server_next_event(wire_server, event))
			return STATUS_ERR;

		/* We adjust relative times after getting notification
		 * that previous client-side events have completed.
		 */
		adjust_relative_event_times(state, event);

		switch (event->type) {
		case PACKET_EVENT:
			if (wire_server_run_packet_event(wire_server, event,
							 event->event.packet,
							 error) == STATUS_ERR)
				return STATUS_ERR;
			break;
		case SYSCALL_EVENT:
			DEBUGP("SYSCALL_EVENT happens on client side...\n");
			break;
		case COMMAND_EVENT:
			DEBUGP("COMMAND_EVENT happens on client side...\n");
			break;
		case CODE_EVENT:
			DEBUGP("CODE_EVENT happens on client side...\n");
			break;
		case INVALID_EVENT:
		case NUM_EVENT_TYPES:
			assert(!"bogus type");
			break;
		/* We omit default case so compiler catches missing values. */
		}
	}

	/* Tell the client about any outstanding packet events it requested. */
	wire_server_next_event(wire_server, NULL);

	DEBUGP("wire_server_run_script: done running\n");

	return STATUS_OK;
}
Beispiel #2
0
void run_script(struct config *config, struct script *script)
{
	char *error = NULL;
	struct state *state = NULL;
	struct netdev *netdev = NULL;
	struct event *event = NULL;

	DEBUGP("run_script: running script\n");

	set_scheduling_priority();
	lock_memory();

	/* This interpreter loop runs for local mode or wire client mode. */
	assert(!config->is_wire_server);

	/* How we use the network is of course a little different in
	 * each of the two cases....
	 */
	if (config->is_wire_client)
		netdev = wire_client_netdev_new(config);
	else
		netdev = local_netdev_new(config);

	state = state_new(config, script, netdev);

	if (config->is_wire_client)
	{
		state->wire_client = wire_client_new();
		wire_client_init(state->wire_client, config, script, state);
	}

	if (script->init_command != NULL)
	{
		if (safe_system(script->init_command->command_line,
		                &error))
		{
			die("%s: error executing init command: %s\n",
			    config->script_path, error);
		}
	}

	signal(SIGPIPE, SIG_IGN);	/* ignore EPIPE */

	state->live_start_time_usecs = schedule_start_time_usecs();
	DEBUGP("live_start_time_usecs is %lld\n",
	       state->live_start_time_usecs);

	if (state->wire_client != NULL)
		wire_client_send_client_starting(state->wire_client);

	while (1)
	{
		if (get_next_event(state, &error))
			die("%s", error);
		event = state->event;
		if (event == NULL)
			break;

		if (state->wire_client != NULL)
			wire_client_next_event(state->wire_client, event);

		/* In wire mode, we adjust relative times after
		 * getting notification that previous packet events
		 * have completed, if any.
		 */
		adjust_relative_event_times(state, event);

		switch (event->type)
		{
		case PACKET_EVENT:
			/* For wire clients, the server handles packets. */
			if (!config->is_wire_client)
			{
				run_local_packet_event(state, event,
				                       event->event.packet);
			}
			break;
		case SYSCALL_EVENT:
			run_system_call_event(state, event,
			                      event->event.syscall);
			break;
		case COMMAND_EVENT:
			run_command_event(state, event,
			                  event->event.command);
			break;
		case CODE_EVENT:
			run_code_event(state, event,
			               event->event.code->text);
			break;
		case INVALID_EVENT:
		case NUM_EVENT_TYPES:
			assert(!"bogus type");
			break;
			/* We omit default case so compiler catches missing values. */
		}
	}

	/* Wait for any outstanding packet events we requested on the server. */
	if (state->wire_client != NULL)
		wire_client_next_event(state->wire_client, NULL);

	if (code_execute(state->code, &error))
	{
		die("%s: error executing code: %s\n",
		    state->config->script_path, error);
		free(error);
	}

	state_free(state);

	DEBUGP("run_script: done running\n");
}