예제 #1
0
파일: fail.c 프로젝트: outscale/packetgraph
static int fail_burst(struct pg_brick *brick, enum pg_side from,
                      uint16_t edge_index, struct rte_mbuf **pkts,
                      uint64_t pkts_mask,
                      struct pg_error **errp)
{
    *errp = pg_error_new("Fail brick : %s", brick->name);
    return -1;
}
예제 #2
0
static int packetsgen_init(struct pg_brick *brick,
			   struct pg_brick_config *config,
			   struct pg_error **errp)
{
	struct pg_packetsgen_state *state;
	struct pg_packetsgen_config *packetsgen_config;

	state = pg_brick_get_state(brick, struct pg_packetsgen_state);

	if (!config->brick_config) {
		*errp = pg_error_new("config->brick_config is NULL");
		return -1;
	}

	packetsgen_config = ((struct pg_packetsgen_config *)
			     config->brick_config);

	if (packetsgen_config->packets == NULL) {
		*errp = pg_error_new("packets argument is NULL");
		return -1;
	}

	if (packetsgen_config->packets_nb == 0) {
		*errp = pg_error_new("packet number must be positive");
		return -1;
	}

	state->output = packetsgen_config->output;
	state->packets = packetsgen_config->packets;
	state->packets_nb = packetsgen_config->packets_nb;

	if (pg_error_is_set(errp))
		return -1;

	/* Initialize fast path */
	brick->burst = packetsgen_burst;
	brick->poll = packetsgen_poll;

	return 0;
}
예제 #3
0
int pg_graph_explore(struct pg_graph *graph,
		     const char *brick_name,
		     struct pg_error **error)
{
	struct pg_brick *b = NULL;

	if (brick_name) {
		b = pg_graph_get(graph, brick_name);
		if (!b) {
			*error = pg_error_new("brick %s not found", brick_name);
			return -1;
		}
	}
	return pg_graph_explore_ptr(graph, b, error);
}
예제 #4
0
int pg_spawn_qemu(const char *socket_path_0,
		  const char *socket_path_1,
		  const char *mac_0,
		  const char *mac_1,
		  const char *bzimage_path,
		  const char *cpio_path,
		  const char *hugepages_path,
		  struct pg_error **errp)
{
	GIOChannel *stdout_gio;
	GError *error = NULL;
	gchar *str_stdout;
	/* gchar *str_stderr; */
	int  child_pid;
	gint stdout_fd;
	gchar **argv;
	int readiness = 1;
	struct timeval start, end;
	
	argv     = g_new(gchar *, 33);
	argv[0]  = g_strdup("qemu-system-x86_64");
	argv[1]  = g_strdup("-m");
	argv[2]  = g_strdup("124M");
	argv[3]  = g_strdup("-enable-kvm");
	argv[4]  = g_strdup("-kernel");
	argv[5]  = g_strdup(bzimage_path);
	argv[6]  = g_strdup("-initrd");
	argv[7]  = g_strdup(cpio_path);
	argv[8]  = g_strdup("-append");
	argv[9]  = g_strdup("console=ttyS0 rdinit=/sbin/init noapic");
	argv[10] = g_strdup("-serial");
	argv[11] = g_strdup("stdio");
	argv[12] = g_strdup("-monitor");
	argv[13] = g_strdup("/dev/null");
	argv[14] = g_strdup("-nographic");

	argv[15] = g_strdup("-chardev");
	argv[16] = g_strdup_printf("socket,id=char0,path=%s", socket_path_0);
	argv[17] = g_strdup("-netdev");
	argv[18] =
		g_strdup("type=vhost-user,id=mynet1,chardev=char0,vhostforce");
	argv[19] = g_strdup("-device");
	argv[20] = g_strdup_printf("virtio-net-pci,mac=%s,netdev=mynet1",
				   mac_0);
	argv[21] = g_strdup("-chardev");
	argv[22] = g_strdup_printf("socket,id=char1,path=%s", socket_path_1);
	argv[23] = g_strdup("-netdev");
	argv[24] =
		g_strdup("type=vhost-user,id=mynet2,chardev=char1,vhostforce");
	argv[25] = g_strdup("-device");
	argv[26] = g_strdup_printf("virtio-net-pci,mac=%s,netdev=mynet2",
				   mac_1);
	argv[27] = g_strdup("-object");
	argv[28] =
		g_strdup_printf("memory-backend-file,id=mem,size=124M,mem-path=%s,share=on",
				hugepages_path);
	argv[29] = g_strdup("-numa");
	argv[30] = g_strdup("node,memdev=mem");
	argv[31] = g_strdup("-mem-prealloc");

	argv[32] = NULL;

	if (!g_spawn_async_with_pipes(NULL,
				      argv,
				      NULL,
				      (GSpawnFlags) G_SPAWN_SEARCH_PATH |
				      G_SPAWN_DO_NOT_REAP_CHILD,
				      (GSpawnChildSetupFunc) NULL,
				      NULL,
				      &child_pid,
				      NULL,
				      &stdout_fd,
				      NULL,
				      &error))
		g_assert(0);
	g_assert(!error);
	g_strfreev(argv);

	stdout_gio = g_io_channel_unix_new(stdout_fd);
	
	g_io_channel_read_line(stdout_gio,
			       &str_stdout,
			       NULL,
			       NULL,
			       &error);


	g_assert(!error);
	gettimeofday(&start, 0);
	while (!is_ready(str_stdout)) {
		g_free(str_stdout);
		g_io_channel_read_line(stdout_gio,
				       &str_stdout,
				       NULL,
				       NULL,
				       &error);

		g_assert(!error);
		gettimeofday(&end, 0);
		if ((end.tv_sec - start.tv_sec) > 30) {
			readiness = 0;
			break;
		}
	}

	if (!readiness)
		*errp = pg_error_new("qemu spawming timeout");

	g_free(str_stdout);

	g_io_channel_shutdown(stdout_gio, TRUE, &error);
	g_io_channel_unref(stdout_gio);

	return child_pid;
}
예제 #5
0
int pg_util_spawn_qemu(const char *socket_path_0,
		       const char *socket_path_1,
		       const char *mac_0,
		       const char *mac_1,
		       const char *vm_image_path,
		       const char *vm_key_path,
		       const char *hugepages_path,
		       struct pg_error **errp)
{
	int child_pid = 0;
	static uint16_t vm_id;
	gchar **argv = NULL;
	gchar *argv_qemu = NULL;
	gchar *argv_sock_0 = NULL;
	gchar *argv_sock_1 = NULL;
	gchar *ssh_cmd = NULL;
	GError *error = NULL;

	g_assert(g_file_test(socket_path_0, G_FILE_TEST_EXISTS));
	g_assert(g_file_test(socket_path_1, G_FILE_TEST_EXISTS));
	g_assert(g_file_test(vm_image_path, G_FILE_TEST_EXISTS));
	g_assert(g_file_test(vm_key_path, G_FILE_TEST_EXISTS));
	g_assert(g_file_test(hugepages_path, G_FILE_TEST_EXISTS));

	if (socket_path_0) {
		argv_sock_0 = g_strdup_printf("%s%s%s%s%s%s",
		" -chardev socket,id=char0,path=", socket_path_0,
		" -netdev type=vhost-user,id=mynet0,chardev=char0,vhostforce",
		" -device virtio-net-pci,mac=", mac_0, ",netdev=mynet0");
	}

	if (socket_path_1) {
		argv_sock_1 = g_strdup_printf("%s%s%s%s%s%s",
		" -chardev socket,id=char1,path=", socket_path_1,
		" -netdev type=vhost-user,id=mynet1,chardev=char1,vhostforce",
		" -device virtio-net-pci,mac=", mac_1, ",netdev=mynet1");
	}

	argv_qemu = g_strdup_printf(
		"%s%s%u%s%s%s%s%s%s%s%s%u%s%s%s%s",
		"qemu-system-x86_64 -m 512M -enable-kvm",
		" -vnc :", vm_id,
		" -nographic -snapshot -object",
		" memory-backend-file,id=mem,size=512M,mem-path=",
		hugepages_path, ",share=on",
		" -numa node,memdev=mem -mem-prealloc",
		" -drive file=", vm_image_path,
		" -redir tcp:", vm_id + 65000, "::22",
		" -netdev user,id=network0 -device e1000,netdev=network0",
		argv_sock_0, argv_sock_1);

	argv = g_strsplit(argv_qemu, " ", 0);

	g_assert(g_spawn_async(NULL,
			       argv,
			       NULL,
			       (GSpawnFlags) G_SPAWN_SEARCH_PATH |
			       G_SPAWN_DO_NOT_REAP_CHILD,
			       (GSpawnChildSetupFunc) NULL,
			       NULL,
			       &child_pid,
			       &error));
	g_assert(!error);

	ssh_cmd = g_strdup_printf("%s%s%s%u%s%s%s",
				  "ssh root@localhost -q -i ", vm_key_path,
				  " -p ", vm_id + 65000,
				  " -oConnectTimeout=1 ",
				  "-oStrictHostKeyChecking=no ",
				  "ls");
	if (pg_util_cmdloop(ssh_cmd, 10 * 60))
		*errp = pg_error_new("qemu spawn failed");

	vm_id++;
	g_free(argv_qemu);
	g_free(argv_sock_0);
	g_free(argv_sock_1);
	g_free(ssh_cmd);
	g_strfreev(argv);
	return child_pid;
}
예제 #6
0
int pg_bench_run(struct pg_bench *bench, struct pg_bench_stats *result,
		 struct pg_error **error)
{
	uint64_t bit;
	uint64_t it_mask;
	uint64_t i;
	uint16_t cnt;
	uint64_t pkts_burst;
	struct pg_brick_side *side = NULL;
	struct pg_brick *count_brick;
	struct pg_bench bl;

	if (bench == NULL || result == NULL ||
	    bench->pkts == NULL || bench->pkts_nb == 0 ||
	    bench->max_burst_cnt == 0 || bench->pkts_mask == 0) {
		*error = pg_error_new("missing or bad bench parameters");
		return -1;
	}

	/* Link ouput brick to a nop brick to count outcoming packets. */
	if (bench->count_brick == NULL) {
		count_brick = pg_nop_new("nop-bench", error);
		if (*error)
			return -1;
		if (bench->output_side == WEST_SIDE)
			pg_brick_link(count_brick, bench->output_brick, error);
		else
			pg_brick_link(bench->output_brick, count_brick, error);
		if (*error)
			return -1;
	} else {
		count_brick = bench->count_brick;
	}

	/* Set all stats to zero. */
	memset(result, 0, sizeof(struct pg_bench_stats));

	/* Setup callback to get burst count. */
	pkts_burst = 0;
	switch (bench->input_brick->type) {
	case PG_MONOPOLE:
		side = bench->input_brick->sides;
		break;
	case PG_DIPOLE:
	case PG_MULTIPOLE:
		side = &(bench->input_brick->sides
			 [pg_flip_side(bench->input_side)]);
		break;
	default:
		g_assert(0);
		break;
	}
	side->burst_count_cb = pg_bench_burst_cb;
	side->burst_count_private_data = (void *)(&pkts_burst);

	/* Compute average size of packets. */
	it_mask = bench->pkts_mask;
	for (; it_mask;) {
		pg_low_bit_iterate_full(it_mask, bit, i);
		result->pkts_average_size += bench->pkts[i]->data_len;
	}
	result->pkts_average_size /= bench->pkts_nb;

	/* Let's run ! */
	memcpy(&bl, bench, sizeof(struct pg_bench));
	gettimeofday(&result->date_start, NULL);
	for (i = 0; i < bl.max_burst_cnt; i++) {
		/* Burst packets. */
		pg_brick_burst(bl.input_brick,
			       bl.input_side,
			       0,
			       bl.pkts,
			       bl.pkts_mask,
			       error);
		sched_yield();
		if (*error)
			return -1;
		/* Poll back packets if needed. */
		if (bl.output_poll)
			pg_brick_poll(bl.output_brick, &cnt, error);
		if (bl.post_burst_op)
			bl.post_burst_op(bench);
	}
	gettimeofday(&result->date_end, NULL);
	memcpy(bench, &bl, sizeof(struct pg_bench));
	result->pkts_sent = bench->max_burst_cnt * bench->pkts_nb;
	result->burst_cnt = bench->max_burst_cnt;
	result->pkts_burst = pkts_burst;
	result->pkts_received = pg_brick_pkts_count_get(
		count_brick,
		bench->output_side);

	if (bench->count_brick == NULL) {
		pg_brick_unlink(count_brick, error);
		if (*error)
			return -1;
	}
	return 0;
}