diff mbox

[21/33] kvm tools: virtio-net init/exit

Message ID 1346833927-15740-22-git-send-email-levinsasha928@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sasha Levin Sept. 5, 2012, 8:31 a.m. UTC
Make the init/exit of virtio-net self-contained, so the global init code
won't need to check if it was selected or not.

This also moves the bulk of the net-specific initialization code, including
the parser, into virtio-net itself.

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/builtin-run.c            | 122 +++------------------------------
 tools/kvm/include/kvm/virtio-net.h |   6 +-
 tools/kvm/virtio/net.c             | 134 +++++++++++++++++++++++++++++++++++--
 3 files changed, 144 insertions(+), 118 deletions(-)
diff mbox

Patch

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 9a09376..7c6fe80 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -146,97 +146,6 @@  static int virtio_9p_rootdir_parser(const struct option *opt, const char *arg, i
 	return 0;
 }
 
-static inline void str_to_mac(const char *str, char *mac)
-{
-	sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
-		mac, mac+1, mac+2, mac+3, mac+4, mac+5);
-}
-static int set_net_param(struct virtio_net_params *p, const char *param,
-				const char *val)
-{
-	if (strcmp(param, "guest_mac") == 0) {
-		str_to_mac(val, p->guest_mac);
-	} else if (strcmp(param, "mode") == 0) {
-		if (!strncmp(val, "user", 4)) {
-			int i;
-
-			for (i = 0; i < kvm->cfg.num_net_devices; i++)
-				if (kvm->cfg.net_params[i].mode == NET_MODE_USER)
-					die("Only one usermode network device allowed at a time");
-			p->mode = NET_MODE_USER;
-		} else if (!strncmp(val, "tap", 3)) {
-			p->mode = NET_MODE_TAP;
-		} else if (!strncmp(val, "none", 4)) {
-			kvm->cfg.no_net = 1;
-			return -1;
-		} else
-			die("Unknown network mode %s, please use user, tap or none", kvm->cfg.network);
-	} else if (strcmp(param, "script") == 0) {
-		p->script = strdup(val);
-	} else if (strcmp(param, "guest_ip") == 0) {
-		p->guest_ip = strdup(val);
-	} else if (strcmp(param, "host_ip") == 0) {
-		p->host_ip = strdup(val);
-	} else if (strcmp(param, "trans") == 0) {
-		p->trans = strdup(val);
-	} else if (strcmp(param, "vhost") == 0) {
-		p->vhost = atoi(val);
-	} else if (strcmp(param, "fd") == 0) {
-		p->fd = atoi(val);
-	} else
-		die("Unknown network parameter %s", param);
-
-	return 0;
-}
-
-static int netdev_parser(const struct option *opt, const char *arg, int unset)
-{
-	struct virtio_net_params p;
-	char *buf = NULL, *cmd = NULL, *cur = NULL;
-	bool on_cmd = true;
-
-	if (arg) {
-		buf = strdup(arg);
-		if (buf == NULL)
-			die("Failed allocating new net buffer");
-		cur = strtok(buf, ",=");
-	}
-
-	p = (struct virtio_net_params) {
-		.guest_ip	= DEFAULT_GUEST_ADDR,
-		.host_ip	= DEFAULT_HOST_ADDR,
-		.script		= DEFAULT_SCRIPT,
-		.mode		= NET_MODE_TAP,
-	};
-
-	str_to_mac(DEFAULT_GUEST_MAC, p.guest_mac);
-	p.guest_mac[5] += kvm->cfg.num_net_devices;
-
-	while (cur) {
-		if (on_cmd) {
-			cmd = cur;
-		} else {
-			if (set_net_param(&p, cmd, cur) < 0)
-				goto done;
-		}
-		on_cmd = !on_cmd;
-
-		cur = strtok(NULL, ",=");
-	};
-
-	kvm->cfg.num_net_devices++;
-
-	kvm->cfg.net_params = realloc(kvm->cfg.net_params, kvm->cfg.num_net_devices * sizeof(*kvm->cfg.net_params));
-	if (kvm->cfg.net_params == NULL)
-		die("Failed adding new network device");
-
-	kvm->cfg.net_params[kvm->cfg.num_net_devices - 1] = p;
-
-done:
-	free(buf);
-	return 0;
-}
-
 #define BUILD_OPTIONS(name, cfg, kvm)					\
 	struct option name[] = {					\
 	OPT_GROUP("Basic options:"),					\
@@ -287,7 +196,7 @@  done:
 	OPT_GROUP("Networking options:"),				\
 	OPT_CALLBACK_DEFAULT('n', "network", NULL, "network params",	\
 		     "Create a new guest NIC",				\
-		     netdev_parser, NULL, NULL),			\
+		     netdev_parser, NULL, kvm),				\
 	OPT_BOOLEAN('\0', "no-dhcp", &(cfg)->no_dhcp, "Disable kernel DHCP\
 			in rootfs mode"),				\
 									\
@@ -739,7 +648,7 @@  static int kvm_cmd_run_init(int argc, const char **argv)
 	static char real_cmdline[2048], default_name[20];
 	struct framebuffer *fb = NULL;
 	unsigned int nr_online_cpus;
-	int i, r;
+	int r;
 
 	kvm = kvm__new();
 	if (IS_ERR(kvm))
@@ -1023,25 +932,10 @@  static int kvm_cmd_run_init(int argc, const char **argv)
 
 	virtio_9p__init(kvm);
 
-	for (i = 0; i < kvm->cfg.num_net_devices; i++) {
-		kvm->cfg.net_params[i].kvm = kvm;
-		virtio_net__init(&kvm->cfg.net_params[i]);
-	}
-
-	if (kvm->cfg.num_net_devices == 0 && kvm->cfg.no_net == 0) {
-		struct virtio_net_params net_params;
-
-		net_params = (struct virtio_net_params) {
-			.guest_ip	= kvm->cfg.guest_ip,
-			.host_ip	= kvm->cfg.host_ip,
-			.kvm		= kvm,
-			.script		= kvm->cfg.script,
-			.mode		= NET_MODE_USER,
-		};
-		str_to_mac(kvm->cfg.guest_mac, net_params.guest_mac);
-		str_to_mac(kvm->cfg.host_mac, net_params.host_mac);
-
-		virtio_net__init(&net_params);
+	r = virtio_net__init(kvm);
+	if (r < 0) {
+		pr_err("virtio_net__init() failed with error %d\n", r);
+		goto fail;
 	}
 
 	kvm__init_ram(kvm);
@@ -1158,6 +1052,10 @@  static void kvm_cmd_run_exit(int guest_ret)
 	if (r < 0)
 		pr_warning("kvm_timer__exit() failed with error %d\n", r);
 
+	r = virtio_net__exit(kvm);
+	if (r < 0)
+		pr_warning("virtio_net__exit() failed with error %d\n", r);
+
 	r = virtio_scsi_exit(kvm);
 	if (r < 0)
 		pr_warning("virtio_scsi_exit() failed with error %d\n", r);
diff --git a/tools/kvm/include/kvm/virtio-net.h b/tools/kvm/include/kvm/virtio-net.h
index 737676eb..db43d98 100644
--- a/tools/kvm/include/kvm/virtio-net.h
+++ b/tools/kvm/include/kvm/virtio-net.h
@@ -1,6 +1,8 @@ 
 #ifndef KVM__VIRTIO_NET_H
 #define KVM__VIRTIO_NET_H
 
+#include "kvm/parse-options.h"
+
 struct kvm;
 
 struct virtio_net_params {
@@ -16,7 +18,9 @@  struct virtio_net_params {
 	int fd;
 };
 
-void virtio_net__init(const struct virtio_net_params *params);
+int virtio_net__init(struct kvm *kvm);
+int virtio_net__exit(struct kvm *kvm);
+int netdev_parser(const struct option *opt, const char *arg, int unset);
 
 enum {
 	NET_MODE_USER,
diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c
index 25bc3a4..4aca581 100644
--- a/tools/kvm/virtio/net.c
+++ b/tools/kvm/virtio/net.c
@@ -490,17 +490,106 @@  static void virtio_net__vhost_init(struct kvm *kvm, struct net_dev *ndev)
 	free(mem);
 }
 
-void virtio_net__init(const struct virtio_net_params *params)
+static inline void str_to_mac(const char *str, char *mac)
+{
+	sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+		mac, mac+1, mac+2, mac+3, mac+4, mac+5);
+}
+static int set_net_param(struct virtio_net_params *p, const char *param,
+				const char *val)
+{
+	if (strcmp(param, "guest_mac") == 0) {
+		str_to_mac(val, p->guest_mac);
+	} else if (strcmp(param, "mode") == 0) {
+		if (!strncmp(val, "user", 4)) {
+			int i;
+
+			for (i = 0; i < kvm->cfg.num_net_devices; i++)
+				if (kvm->cfg.net_params[i].mode == NET_MODE_USER)
+					die("Only one usermode network device allowed at a time");
+			p->mode = NET_MODE_USER;
+		} else if (!strncmp(val, "tap", 3)) {
+			p->mode = NET_MODE_TAP;
+		} else if (!strncmp(val, "none", 4)) {
+			kvm->cfg.no_net = 1;
+			return -1;
+		} else
+			die("Unknown network mode %s, please use user, tap or none", kvm->cfg.network);
+	} else if (strcmp(param, "script") == 0) {
+		p->script = strdup(val);
+	} else if (strcmp(param, "guest_ip") == 0) {
+		p->guest_ip = strdup(val);
+	} else if (strcmp(param, "host_ip") == 0) {
+		p->host_ip = strdup(val);
+	} else if (strcmp(param, "trans") == 0) {
+		p->trans = strdup(val);
+	} else if (strcmp(param, "vhost") == 0) {
+		p->vhost = atoi(val);
+	} else if (strcmp(param, "fd") == 0) {
+		p->fd = atoi(val);
+	} else
+		die("Unknown network parameter %s", param);
+
+	return 0;
+}
+
+int netdev_parser(const struct option *opt, const char *arg, int unset)
+{
+	struct virtio_net_params p;
+	char *buf = NULL, *cmd = NULL, *cur = NULL;
+	bool on_cmd = true;
+	struct kvm *kvm = opt->ptr;
+
+	if (arg) {
+		buf = strdup(arg);
+		if (buf == NULL)
+			die("Failed allocating new net buffer");
+		cur = strtok(buf, ",=");
+	}
+
+	p = (struct virtio_net_params) {
+		.guest_ip	= DEFAULT_GUEST_ADDR,
+		.host_ip	= DEFAULT_HOST_ADDR,
+		.script		= DEFAULT_SCRIPT,
+		.mode		= NET_MODE_TAP,
+	};
+
+	str_to_mac(DEFAULT_GUEST_MAC, p.guest_mac);
+	p.guest_mac[5] += kvm->cfg.num_net_devices;
+
+	while (cur) {
+		if (on_cmd) {
+			cmd = cur;
+		} else {
+			if (set_net_param(&p, cmd, cur) < 0)
+				goto done;
+		}
+		on_cmd = !on_cmd;
+
+		cur = strtok(NULL, ",=");
+	};
+
+	kvm->cfg.num_net_devices++;
+
+	kvm->cfg.net_params = realloc(kvm->cfg.net_params, kvm->cfg.num_net_devices * sizeof(*kvm->cfg.net_params));
+	if (kvm->cfg.net_params == NULL)
+		die("Failed adding new network device");
+
+	kvm->cfg.net_params[kvm->cfg.num_net_devices - 1] = p;
+
+done:
+	free(buf);
+	return 0;
+}
+
+static int virtio_net__init_one(struct virtio_net_params *params)
 {
 	int i;
 	struct net_dev *ndev;
 
-	if (!params)
-		return;
-
 	ndev = calloc(1, sizeof(struct net_dev));
 	if (ndev == NULL)
-		die("Failed allocating ndev");
+		return -ENOMEM;
 
 	list_add_tail(&ndev->list, &ndevs);
 
@@ -543,4 +632,39 @@  void virtio_net__init(const struct virtio_net_params *params)
 
 	if (compat_id == -1)
 		compat_id = virtio_compat_add_message("virtio-net", "CONFIG_VIRTIO_NET");
+
+	return 0;
+}
+
+int virtio_net__init(struct kvm *kvm)
+{
+	int i;
+
+	for (i = 0; i < kvm->cfg.num_net_devices; i++) {
+		kvm->cfg.net_params[i].kvm = kvm;
+		virtio_net__init_one(&kvm->cfg.net_params[i]);
+	}
+
+	if (kvm->cfg.num_net_devices == 0 && kvm->cfg.no_net == 0) {
+		struct virtio_net_params net_params;
+
+		net_params = (struct virtio_net_params) {
+			.guest_ip	= kvm->cfg.guest_ip,
+			.host_ip	= kvm->cfg.host_ip,
+			.kvm		= kvm,
+			.script		= kvm->cfg.script,
+			.mode		= NET_MODE_USER,
+		};
+		str_to_mac(kvm->cfg.guest_mac, net_params.guest_mac);
+		str_to_mac(kvm->cfg.host_mac, net_params.host_mac);
+
+		virtio_net__init_one(&net_params);
+	}
+
+	return 0;
+}
+
+int virtio_net__exit(struct kvm *kvm)
+{
+	return 0;
 }