[Qemu-devel] [PATCH 1/2] slirp: remove duplicate definition

2012-02-15 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 slirp/if.c |2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/slirp/if.c b/slirp/if.c
index 2852396..8e0cac2 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -8,8 +8,6 @@
 #include 
 #include "qemu-timer.h"
 
-#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
-
 static void
 ifs_insque(struct mbuf *ifm, struct mbuf *ifmhead)
 {
-- 
1.7.6




[Qemu-devel] [PATCH 2/2] slirp: fix packet requeue issue in batchq

2012-02-15 Thread zwu . kernel
From: Zhi Yong Wu 

This patch fixes the slirp crash in current QEMU upstream.

Signed-off-by: Zhi Yong Wu 
---
 slirp/if.c   |   37 ++---
 slirp/mbuf.c |3 +--
 2 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/slirp/if.c b/slirp/if.c
index 8e0cac2..f7f8577 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -20,8 +20,15 @@ ifs_insque(struct mbuf *ifm, struct mbuf *ifmhead)
 static void
 ifs_remque(struct mbuf *ifm)
 {
-   ifm->ifs_prev->ifs_next = ifm->ifs_next;
-   ifm->ifs_next->ifs_prev = ifm->ifs_prev;
+if (ifm->ifs_next->ifs_next == ifm
+&& ifm->ifs_next->ifs_prev == ifm) {
+ifs_init(ifm->ifs_next);
+} else {
+ifm->ifs_prev->ifs_next = ifm->ifs_next;
+ifm->ifs_next->ifs_prev = ifm->ifs_prev;
+}
+
+ifs_init(ifm);
 }
 
 void
@@ -154,14 +161,18 @@ if_start(Slirp *slirp)
 {
 uint64_t now = qemu_get_clock_ns(rt_clock);
 int requeued = 0;
-   struct mbuf *ifm, *ifqt;
+struct mbuf *ifm, *ifqt, *ifm_next;
 
-   DEBUG_CALL("if_start");
+DEBUG_CALL("if_start");
 
-   if (slirp->if_queued == 0)
-  return; /* Nothing to do */
+if (slirp->if_queued == 0)
+return; /* Nothing to do */
+
+slirp->next_m = &slirp->if_batchq;
 
  again:
+ifm_next = NULL;
+
 /* check if we can really output */
 if (!slirp_can_output(slirp->opaque))
 return;
@@ -190,6 +201,7 @@ if_start(Slirp *slirp)
/* If there are more packets for this session, re-queue them */
if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) {
insque(ifm->ifs_next, ifqt);
+ifm_next = ifm->ifs_next;
ifs_remque(ifm);
}
 
@@ -209,7 +221,18 @@ if_start(Slirp *slirp)
 m_free(ifm);
 } else {
 /* re-queue */
-insque(ifm, ifqt);
+if (ifm_next) {
+/*restore the original state of bachq*/
+remque(ifm_next);
+insque(ifm, ifqt);
+ifm_next->ifs_prev->ifs_next = ifm;
+ifm->ifs_prev = ifm_next->ifs_prev;
+ifm->ifs_next = ifm_next;
+ifm_next->ifs_prev = ifm;
+} else {
+insque(ifm, ifqt);
+}
+
 requeued++;
 }
 }
diff --git a/slirp/mbuf.c b/slirp/mbuf.c
index c699c75..f429c0a 100644
--- a/slirp/mbuf.c
+++ b/slirp/mbuf.c
@@ -68,8 +68,7 @@ m_get(Slirp *slirp)
m->m_size = SLIRP_MSIZE - offsetof(struct mbuf, m_dat);
m->m_data = m->m_dat;
m->m_len = 0;
-m->m_nextpkt = NULL;
-m->m_prevpkt = NULL;
+ifs_init(m);
 m->arp_requested = false;
 m->expiration_date = (uint64_t)-1;
 end_error:
-- 
1.7.6




[Qemu-devel] [PATCH v2] slirp: fix packet requeue issue in batchq

2012-02-16 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 slirp/if.c   |   19 +--
 slirp/mbuf.c |3 +--
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/slirp/if.c b/slirp/if.c
index 8e0cac2..57350d5 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -22,6 +22,7 @@ ifs_remque(struct mbuf *ifm)
 {
ifm->ifs_prev->ifs_next = ifm->ifs_next;
ifm->ifs_next->ifs_prev = ifm->ifs_prev;
+ifs_init(ifm);
 }
 
 void
@@ -154,7 +155,7 @@ if_start(Slirp *slirp)
 {
 uint64_t now = qemu_get_clock_ns(rt_clock);
 int requeued = 0;
-   struct mbuf *ifm, *ifqt;
+struct mbuf *ifm, *ifqt, *ifm_next;
 
DEBUG_CALL("if_start");
 
@@ -162,6 +163,8 @@ if_start(Slirp *slirp)
   return; /* Nothing to do */
 
  again:
+ifm_next = NULL;
+
 /* check if we can really output */
 if (!slirp_can_output(slirp->opaque))
 return;
@@ -190,6 +193,7 @@ if_start(Slirp *slirp)
/* If there are more packets for this session, re-queue them */
if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) {
insque(ifm->ifs_next, ifqt);
+ifm_next = ifm->ifs_next;
ifs_remque(ifm);
}
 
@@ -209,7 +213,18 @@ if_start(Slirp *slirp)
 m_free(ifm);
 } else {
 /* re-queue */
-insque(ifm, ifqt);
+if (ifm_next) {
+/*restore the original state of batchq*/
+remque(ifm_next);
+insque(ifm, ifqt);
+ifm_next->ifs_prev->ifs_next = ifm;
+ifm->ifs_prev = ifm_next->ifs_prev;
+ifm->ifs_next = ifm_next;
+ifm_next->ifs_prev = ifm;
+} else {
+insque(ifm, ifqt);
+}
+
 requeued++;
 }
 }
diff --git a/slirp/mbuf.c b/slirp/mbuf.c
index c699c75..f429c0a 100644
--- a/slirp/mbuf.c
+++ b/slirp/mbuf.c
@@ -68,8 +68,7 @@ m_get(Slirp *slirp)
m->m_size = SLIRP_MSIZE - offsetof(struct mbuf, m_dat);
m->m_data = m->m_dat;
m->m_len = 0;
-m->m_nextpkt = NULL;
-m->m_prevpkt = NULL;
+ifs_init(m);
 m->arp_requested = false;
 m->expiration_date = (uint64_t)-1;
 end_error:
-- 
1.7.6




[Qemu-devel] [PATCH] socket: add the support for -netdev socket, listen

2012-02-16 Thread zwu . kernel
From: Zhi Yong Wu 

As you have known, QEMU upstream currently doesn't support for -netdev 
socket,listen; This patch makes it work now.

Signed-off-by: Zhi Yong Wu 
---
 net/socket.c |   17 +
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index d4c2002..f82e69d 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -43,6 +43,7 @@ typedef struct NetSocketState {
 } NetSocketState;
 
 typedef struct NetSocketListenState {
+VLANClientState *nc;
 VLANState *vlan;
 char *model;
 char *name;
@@ -389,6 +390,11 @@ static void net_socket_accept(void *opaque)
 break;
 }
 }
+
+if (s->nc) {
+qemu_del_vlan_client(s->nc);
+}
+
 s1 = net_socket_fd_init(s->vlan, s->model, s->name, fd, 1);
 if (s1) {
 snprintf(s1->nc.info_str, sizeof(s1->nc.info_str),
@@ -397,6 +403,13 @@ static void net_socket_accept(void *opaque)
 }
 }
 
+static NetClientInfo net_listen_info = {
+.type = NET_CLIENT_TYPE_NONE,
+.size = sizeof(VLANClientState),
+.receive = NULL,
+.cleanup = NULL,
+};
+
 static int net_socket_listen_init(VLANState *vlan,
   const char *model,
   const char *name,
@@ -441,6 +454,10 @@ static int net_socket_listen_init(VLANState *vlan,
 s->model = g_strdup(model);
 s->name = name ? g_strdup(name) : NULL;
 s->fd = fd;
+
+s->nc = qemu_new_net_client(&net_listen_info, NULL, NULL, model, name);
+s->nc->link_down = true;
+
 qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
 return 0;
 }
-- 
1.7.6




[Qemu-devel] [PATCH v2] net: roll back qdev_prop_vlan

2012-06-18 Thread zwu . kernel
From: Zhi Yong Wu 

We're trying to preserve backward compatibility.  This
command-line break:

x86_64-softmmu/qemu-system-x86_64 -net user,vlan=1 -device virtio-net-pci,vlan=1

Instead of dropping the qdev_prop_vlan completely the
hw/qdev-properties.c code needs to call net/hub.h external functions
to implement equivalent functionality.

The change from v1:
  1.) %d -> %u [stefanha]
  2.) the error handling when net_hub_id_for_client fails [stefanha]

Signed-off-by: Zhi Yong Wu 
---
 hw/qdev-properties.c |   77 ++
 hw/qdev.h|3 ++
 net.h|1 +
 net/hub.c|   25 
 net/hub.h|1 +
 5 files changed, 107 insertions(+), 0 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 1c13bda..e553386 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -2,6 +2,7 @@
 #include "qdev.h"
 #include "qerror.h"
 #include "blockdev.h"
+#include "net/hub.h"
 
 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
 {
@@ -623,6 +624,82 @@ PropertyInfo qdev_prop_netdev = {
 .set   = set_netdev,
 };
 
+/* --- vlan --- */
+
+static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
+
+if (*ptr) {
+unsigned int id;
+if (!net_hub_id_for_client(*ptr, &id)) {
+return snprintf(dest, len, "%u", id);
+}
+}
+
+return snprintf(dest, len, "");
+}
+
+static void get_vlan(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
+NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
+int64_t id = -1;
+
+if (*ptr) {
+unsigned int hub_id;
+if(!net_hub_id_for_client(*ptr, &hub_id)) {
+   id = (int64_t)hub_id;
+}
+}
+
+visit_type_int(v, &id, name, errp);
+}
+
+static void set_vlan(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
+NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
+Error *local_err = NULL;
+int64_t id;
+NetClientState *hubport;
+
+if (dev->state != DEV_STATE_CREATED) {
+error_set(errp, QERR_PERMISSION_DENIED);
+return;
+}
+
+visit_type_int(v, &id, name, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
+if (id == -1) {
+*ptr = NULL;
+return;
+}
+
+hubport = net_hub_port_find(id);
+if (!hubport) {
+error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+  name, prop->info->name);
+return;
+}
+*ptr = hubport;
+}
+
+PropertyInfo qdev_prop_vlan = {
+.name  = "vlan",
+.print = print_vlan,
+.get   = get_vlan,
+.set   = set_vlan,
+};
+
 /* --- pointer --- */
 
 /* Not a proper property, just for dirty hacks.  TODO Remove it!  */
diff --git a/hw/qdev.h b/hw/qdev.h
index edbf8fa..f4aea27 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -222,6 +222,7 @@ extern PropertyInfo qdev_prop_macaddr;
 extern PropertyInfo qdev_prop_losttickpolicy;
 extern PropertyInfo qdev_prop_drive;
 extern PropertyInfo qdev_prop_netdev;
+extern PropertyInfo qdev_prop_vlan;
 extern PropertyInfo qdev_prop_pci_devfn;
 extern PropertyInfo qdev_prop_blocksize;
 
@@ -276,6 +277,8 @@ extern PropertyInfo qdev_prop_blocksize;
 DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
 #define DEFINE_PROP_NETDEV(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, NetClientState*)
+#define DEFINE_PROP_VLAN(_n, _s, _f) \
+DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, NetClientState*)
 #define DEFINE_PROP_DRIVE(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *)
 #define DEFINE_PROP_MACADDR(_n, _s, _f) \
diff --git a/net.h b/net.h
index 08306a4..c4e56cc 100644
--- a/net.h
+++ b/net.h
@@ -22,6 +22,7 @@ typedef struct NICConf {
 
 #define DEFINE_NIC_PROPERTIES(_state, _conf)\
 DEFINE_PROP_MACADDR("mac",   _state, _conf.macaddr),\
+DEFINE_PROP_VLAN("vlan", _state, _conf.peer),   \
 DEFINE_PROP_NETDEV("netdev", _state, _conf.peer),   \
 DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1)
 
diff --git a/net/hub.c b/net/hub.c
index efd90b5..001f818 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -205,6 +205,31 @@ NetClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
 }
 
 /**
+ * Find a available port on a hub; otherwise create one new port
+ */
+NetClientState *net_hub_port_find(unsigned int hub_id)
+{
+NetHub *hub;
+NetHubPort *port;
+NetClientState *nc;
+
+QLIST_FOREACH(hub, &hubs, next) {
+if (hub->id == hub_id) {
+QLIST_FOREACH(port, &hub->ports, next) 

[Qemu-devel] [PATCH v5 00/17] hub-based networking patches

2012-06-18 Thread zwu . kernel
From: Zhi Yong Wu 

All comments have been addressed and stefan has completed one more reviewing.

Changelog from v4:
 1.) roll back qdev_prop_vlan [stefanha]

v4:
 1.) refactor hub own flow control [paolo]
 2.) refactor the output for monitor command "info network" [jan kiszka]

v3:
 1.) add the support for hub own flow control [paolo]
 2.) make the monitor output more reasonable hub info [jan kiszka]

v2:
 1.) cleanup some obsolete vlan info
 2.) cleanup deliver/deliver_iov func pointers [paolo]
 3.) support more flexible flow control [paolo]

Stefan Hajnoczi (12):
  net: Add a hub net client
  net: Use hubs for the vlan feature
  net: Look up 'vlan' net clients using hubs
  hub: Check that hubs are configured correctly
  net: Drop vlan argument to qemu_new_net_client()
  net: Remove vlan qdev property
  net: Remove vlan code from net.c
  net: Remove VLANState
  net: Rename non_vlan_clients to net_clients
  net: Rename VLANClientState to NetClientState
  net: Rename vc local variables to nc
  net: Rename qemu_del_vlan_client() to qemu_del_net_client()

Zhi Yong Wu (5):
  net: Make "info network" output more readable info
  net: cleanup deliver/deliver_iov func pointers
  net: determine if packets can be sent before net queue deliver
packets
  hub: add the support for hub own flow control
  net: roll back qdev_prop_vlan

 hw/cadence_gem.c|8 +-
 hw/dp8393x.c|6 +-
 hw/e1000.c  |   10 +-
 hw/eepro100.c   |8 +-
 hw/etraxfs_eth.c|8 +-
 hw/lan9118.c|8 +-
 hw/lance.c  |2 +-
 hw/mcf_fec.c|6 +-
 hw/milkymist-minimac2.c |6 +-
 hw/mipsnet.c|6 +-
 hw/musicpal.c   |6 +-
 hw/ne2000-isa.c |2 +-
 hw/ne2000.c |8 +-
 hw/ne2000.h |4 +-
 hw/opencores_eth.c  |8 +-
 hw/pcnet-pci.c  |4 +-
 hw/pcnet.c  |6 +-
 hw/pcnet.h  |6 +-
 hw/qdev-properties.c|   53 +++--
 hw/qdev.c   |2 -
 hw/qdev.h   |7 +-
 hw/rtl8139.c|   10 +-
 hw/smc91c111.c  |6 +-
 hw/spapr_llan.c |4 +-
 hw/stellaris_enet.c |6 +-
 hw/usb/dev-network.c|8 +-
 hw/vhost_net.c  |   24 +-
 hw/vhost_net.h  |2 +-
 hw/virtio-net.c |   12 +-
 hw/xen_nic.c|7 +-
 hw/xgmac.c  |6 +-
 hw/xilinx_axienet.c |6 +-
 hw/xilinx_ethlite.c |6 +-
 net.c   |  593 ++-
 net.h   |   87 
 net/Makefile.objs   |2 +-
 net/dump.c  |   27 ++-
 net/dump.h  |2 +-
 net/hub.c   |  335 ++
 net/hub.h   |   29 +++
 net/queue.c |   37 ++--
 net/queue.h |   25 +--
 net/slirp.c |   32 +--
 net/slirp.h |2 +-
 net/socket.c|   66 +++---
 net/socket.h|2 +-
 net/tap-win32.c |   26 +-
 net/tap.c   |   44 ++--
 net/tap.h   |   20 +-
 net/vde.c   |   16 +-
 net/vde.h   |2 +-
 qemu-common.h   |3 +-
 slirp/if.c  |5 -
 slirp/libslirp.h|1 -
 54 files changed, 860 insertions(+), 767 deletions(-)
 create mode 100644 net/hub.c
 create mode 100644 net/hub.h

-- 
1.7.6




[Qemu-devel] [PATCH v5 01/17] net: Add a hub net client

2012-06-18 Thread zwu . kernel
From: Stefan Hajnoczi 

The vlan feature can be implemented in terms of hubs.  By introducing a
hub net client it becomes possible to remove the special case vlan code
from net.c and push the vlan feature out of generic networking code.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.h |1 +
 net/Makefile.objs |2 +-
 net/hub.c |  201 +
 net/hub.h |   24 ++
 4 files changed, 227 insertions(+), 1 deletions(-)
 create mode 100644 net/hub.c
 create mode 100644 net/hub.h

diff --git a/net.h b/net.h
index bdc2a06..c1198b6 100644
--- a/net.h
+++ b/net.h
@@ -38,6 +38,7 @@ typedef enum {
 NET_CLIENT_TYPE_VDE,
 NET_CLIENT_TYPE_DUMP,
 NET_CLIENT_TYPE_BRIDGE,
+NET_CLIENT_TYPE_HUB,
 
 NET_CLIENT_TYPE_MAX
 } net_client_type;
diff --git a/net/Makefile.objs b/net/Makefile.objs
index 72f50bc..cf04187 100644
--- a/net/Makefile.objs
+++ b/net/Makefile.objs
@@ -1,4 +1,4 @@
-common-obj-y = queue.o checksum.o util.o
+common-obj-y = queue.o checksum.o util.o hub.o
 common-obj-y += socket.o
 common-obj-y += dump.o
 common-obj-$(CONFIG_POSIX) += tap.o
diff --git a/net/hub.c b/net/hub.c
new file mode 100644
index 000..28ff45c
--- /dev/null
+++ b/net/hub.c
@@ -0,0 +1,201 @@
+/*
+ * Hub net client
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Stefan Hajnoczi   
+ *  Zhi Yong Wu   
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "monitor.h"
+#include "net.h"
+#include "hub.h"
+
+/*
+ * A hub broadcasts incoming packets to all its ports except the source port.
+ * Hubs can be used to provide independent network segments, also confusingly
+ * named the QEMU 'vlan' feature.
+ */
+
+typedef struct NetHub NetHub;
+
+typedef struct NetHubPort {
+VLANClientState nc;
+QLIST_ENTRY(NetHubPort) next;
+NetHub *hub;
+unsigned int id;
+} NetHubPort;
+
+struct NetHub {
+unsigned int id;
+QLIST_ENTRY(NetHub) next;
+unsigned int num_ports;
+QLIST_HEAD(, NetHubPort) ports;
+};
+
+static QLIST_HEAD(, NetHub) hubs = QLIST_HEAD_INITIALIZER(&hubs);
+
+static ssize_t net_hub_receive(NetHub *hub, NetHubPort *source_port,
+   const uint8_t *buf, size_t len)
+{
+NetHubPort *port;
+
+QLIST_FOREACH(port, &hub->ports, next) {
+if (port == source_port) {
+continue;
+}
+
+qemu_send_packet(&port->nc, buf, len);
+}
+return len;
+}
+
+static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port,
+   const struct iovec *iov, int iovcnt)
+{
+NetHubPort *port;
+ssize_t ret = 0;
+
+QLIST_FOREACH(port, &hub->ports, next) {
+if (port == source_port) {
+continue;
+}
+
+ret = qemu_sendv_packet(&port->nc, iov, iovcnt);
+}
+return ret;
+}
+
+static NetHub *net_hub_new(unsigned int id)
+{
+NetHub *hub;
+
+hub = g_malloc(sizeof(*hub));
+hub->id = id;
+hub->num_ports = 0;
+QLIST_INIT(&hub->ports);
+
+QLIST_INSERT_HEAD(&hubs, hub, next);
+
+return hub;
+}
+
+static ssize_t net_hub_port_receive(VLANClientState *nc,
+const uint8_t *buf, size_t len)
+{
+NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
+
+return net_hub_receive(port->hub, port, buf, len);
+}
+
+static ssize_t net_hub_port_receive_iov(VLANClientState *nc,
+const struct iovec *iov, int iovcnt)
+{
+NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
+
+return net_hub_receive_iov(port->hub, port, iov, iovcnt);
+}
+
+static void net_hub_port_cleanup(VLANClientState *nc)
+{
+NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
+
+QLIST_REMOVE(port, next);
+}
+
+static NetClientInfo net_hub_port_info = {
+.type = NET_CLIENT_TYPE_HUB,
+.size = sizeof(NetHubPort),
+.receive = net_hub_port_receive,
+.receive_iov = net_hub_port_receive_iov,
+.cleanup = net_hub_port_cleanup,
+};
+
+static NetHubPort *net_hub_port_new(NetHub *hub)
+{
+VLANClientState *nc;
+NetHubPort *port;
+unsigned int id = hub->num_ports++;
+char name[128];
+
+snprintf(name, sizeof name, "hub%uport%u", hub->id, id);
+
+nc = qemu_new_net_client(&net_hub_port_info, NULL, NULL, "hub", name);
+port = DO_UPCAST(NetHubPort, nc, nc);
+port->id = id;
+port->hub = hub;
+
+QLIST_INSERT_HEAD(&hub->ports, port, next);
+
+return port;
+}
+
+/**
+ * Create a port on a given hub
+ *
+ * If there is no existing hub with the given id then a new hub is created.
+ */
+VLANClientState *net_hub_add_port(unsigned int hub_id)
+{
+NetHub *hub;
+NetHubPort *port;
+
+QLIST_FOREACH(hub, &hubs, next) {
+if (hub->id == hub_id) {
+break;
+}
+}
+
+if (!hub) {
+hub = net_hub_new(hub_id);

[Qemu-devel] [PATCH v5 03/17] net: Look up 'vlan' net clients using hubs

2012-06-18 Thread zwu . kernel
From: Stefan Hajnoczi 

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c   |   28 +---
 net/hub.c   |   24 
 net/hub.h   |2 ++
 net/slirp.c |5 +++--
 4 files changed, 30 insertions(+), 29 deletions(-)

diff --git a/net.c b/net.c
index 9a63d22..f80a0c0 100644
--- a/net.c
+++ b/net.c
@@ -312,32 +312,6 @@ void qemu_del_vlan_client(VLANClientState *vc)
 qemu_free_vlan_client(vc);
 }
 
-VLANClientState *
-qemu_find_vlan_client_by_name(Monitor *mon, int vlan_id,
-  const char *client_str)
-{
-VLANState *vlan;
-VLANClientState *vc;
-
-vlan = qemu_find_vlan(vlan_id, 0);
-if (!vlan) {
-monitor_printf(mon, "unknown VLAN %d\n", vlan_id);
-return NULL;
-}
-
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-if (!strcmp(vc->name, client_str)) {
-break;
-}
-}
-if (!vc) {
-monitor_printf(mon, "can't find device %s on VLAN %d\n",
-   client_str, vlan_id);
-}
-
-return vc;
-}
-
 void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
 {
 VLANClientState *nc;
@@ -1226,7 +1200,7 @@ void net_host_device_remove(Monitor *mon, const QDict 
*qdict)
 int vlan_id = qdict_get_int(qdict, "vlan_id");
 const char *device = qdict_get_str(qdict, "device");
 
-vc = qemu_find_vlan_client_by_name(mon, vlan_id, device);
+vc = net_hub_find_client_by_name(vlan_id, device);
 if (!vc) {
 return;
 }
diff --git a/net/hub.c b/net/hub.c
index 28ff45c..56efc2c 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -160,6 +160,30 @@ VLANClientState *net_hub_add_port(unsigned int hub_id)
 }
 
 /**
+ * Find a specific client on a hub
+ */
+VLANClientState *net_hub_find_client_by_name(unsigned int hub_id,
+ const char *name)
+{
+NetHub *hub;
+NetHubPort *port;
+VLANClientState *peer;
+
+QLIST_FOREACH(hub, &hubs, next) {
+if (hub->id == hub_id) {
+QLIST_FOREACH(port, &hub->ports, next) {
+peer = port->nc.peer;
+
+if (peer && strcmp(peer->name, name) == 0) {
+return peer;
+}
+}
+}
+}
+return NULL;
+}
+
+/**
  * Print hub configuration
  */
 void net_hub_info(Monitor *mon)
diff --git a/net/hub.h b/net/hub.h
index bf8798b..e149e04 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -18,6 +18,8 @@
 #include "qemu-common.h"
 
 VLANClientState *net_hub_add_port(unsigned int hub_id);
+VLANClientState *net_hub_find_client_by_name(unsigned int hub_id,
+ const char *name);
 void net_hub_info(Monitor *mon);
 int net_hub_id_for_client(VLANClientState *nc, unsigned int *id);
 
diff --git a/net/slirp.c b/net/slirp.c
index 70e7c94..c8c557a 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -29,6 +29,7 @@
 #include 
 #endif
 #include "net.h"
+#include "net/hub.h"
 #include "monitor.h"
 #include "qemu_socket.h"
 #include "slirp/libslirp.h"
@@ -283,7 +284,7 @@ static SlirpState *slirp_lookup(Monitor *mon, const char 
*vlan,
 
 if (vlan) {
 VLANClientState *nc;
-nc = qemu_find_vlan_client_by_name(mon, strtol(vlan, NULL, 0), stack);
+nc = net_hub_find_client_by_name(strtol(vlan, NULL, 0), stack);
 if (!nc) {
 return NULL;
 }
@@ -648,7 +649,7 @@ void do_info_usernet(Monitor *mon)
 
 QTAILQ_FOREACH(s, &slirp_stacks, entry) {
 monitor_printf(mon, "VLAN %d (%s):\n",
-   s->nc.vlan ? s->nc.vlan->id : -1,
+   -1, /* TODO */
s->nc.name);
 slirp_connection_info(s->slirp, mon);
 }
-- 
1.7.6




[Qemu-devel] [PATCH v5 07/17] net: Remove vlan code from net.c

2012-06-18 Thread zwu . kernel
From: Stefan Hajnoczi 

The vlan implementation in net.c has been replaced by hubs so we can
remove the code.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 hw/xen_nic.c |1 -
 net.c|  108 --
 net.h|1 -
 3 files changed, 0 insertions(+), 110 deletions(-)

diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index 9a59bda..85526fe 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -328,7 +328,6 @@ static int net_init(struct XenDevice *xendev)
 return -1;
 }
 
-netdev->conf.vlan = qemu_find_vlan(netdev->xendev.dev, 1);
 netdev->conf.peer = NULL;
 
 netdev->nic = qemu_new_nic(&net_xen_info, &netdev->conf,
diff --git a/net.c b/net.c
index 553f032..812589a 100644
--- a/net.c
+++ b/net.c
@@ -388,50 +388,6 @@ static ssize_t qemu_deliver_packet(VLANClientState *sender,
 return ret;
 }
 
-static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
-unsigned flags,
-const uint8_t *buf,
-size_t size,
-void *opaque)
-{
-VLANState *vlan = opaque;
-VLANClientState *vc;
-ssize_t ret = -1;
-
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-ssize_t len;
-
-if (vc == sender) {
-continue;
-}
-
-if (vc->link_down) {
-ret = size;
-continue;
-}
-
-if (vc->receive_disabled) {
-ret = 0;
-continue;
-}
-
-if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->info->receive_raw) {
-len = vc->info->receive_raw(vc, buf, size);
-} else {
-len = vc->info->receive(vc, buf, size);
-}
-
-if (len == 0) {
-vc->receive_disabled = 1;
-}
-
-ret = (ret >= 0) ? ret : len;
-
-}
-
-return ret;
-}
-
 void qemu_purge_queued_packets(VLANClientState *vc)
 {
 NetQueue *queue;
@@ -538,42 +494,6 @@ static ssize_t qemu_deliver_packet_iov(VLANClientState 
*sender,
 }
 }
 
-static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState *sender,
-unsigned flags,
-const struct iovec *iov,
-int iovcnt,
-void *opaque)
-{
-VLANState *vlan = opaque;
-VLANClientState *vc;
-ssize_t ret = -1;
-
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-ssize_t len;
-
-if (vc == sender) {
-continue;
-}
-
-if (vc->link_down) {
-ret = iov_size(iov, iovcnt);
-continue;
-}
-
-assert(!(flags & QEMU_NET_PACKET_FLAG_RAW));
-
-if (vc->info->receive_iov) {
-len = vc->info->receive_iov(vc, iov, iovcnt);
-} else {
-len = vc_sendv_compat(vc, iov, iovcnt);
-}
-
-ret = (ret >= 0) ? ret : len;
-}
-
-return ret;
-}
-
 ssize_t qemu_sendv_packet_async(VLANClientState *sender,
 const struct iovec *iov, int iovcnt,
 NetPacketSent *sent_cb)
@@ -601,34 +521,6 @@ qemu_sendv_packet(VLANClientState *vc, const struct iovec 
*iov, int iovcnt)
 return qemu_sendv_packet_async(vc, iov, iovcnt, NULL);
 }
 
-/* find or alloc a new VLAN */
-VLANState *qemu_find_vlan(int id, int allocate)
-{
-VLANState *vlan;
-
-QTAILQ_FOREACH(vlan, &vlans, next) {
-if (vlan->id == id) {
-return vlan;
-}
-}
-
-if (!allocate) {
-return NULL;
-}
-
-vlan = g_malloc0(sizeof(VLANState));
-vlan->id = id;
-QTAILQ_INIT(&vlan->clients);
-
-vlan->send_queue = qemu_new_net_queue(qemu_vlan_deliver_packet,
-  qemu_vlan_deliver_packet_iov,
-  vlan);
-
-QTAILQ_INSERT_TAIL(&vlans, vlan, next);
-
-return vlan;
-}
-
 VLANClientState *qemu_find_netdev(const char *id)
 {
 VLANClientState *vc;
diff --git a/net.h b/net.h
index 42fbc49..791ca4f 100644
--- a/net.h
+++ b/net.h
@@ -87,7 +87,6 @@ struct VLANState {
 NetQueue *send_queue;
 };
 
-VLANState *qemu_find_vlan(int id, int allocate);
 VLANClientState *qemu_find_netdev(const char *id);
 VLANClientState *qemu_new_net_client(NetClientInfo *info,
  VLANClientState *peer,
-- 
1.7.6




[Qemu-devel] [PATCH v5 08/17] net: Remove VLANState

2012-06-18 Thread zwu . kernel
From: Stefan Hajnoczi 

VLANState is no longer used and can be removed.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c |  127 ++---
 net.h |8 
 net/socket.c  |6 +-
 net/tap.c |6 +-
 net/tap.h |2 +-
 qemu-common.h |1 -
 6 files changed, 29 insertions(+), 121 deletions(-)

diff --git a/net.c b/net.c
index 812589a..73325b0 100644
--- a/net.c
+++ b/net.c
@@ -44,7 +44,6 @@
 # define CONFIG_NET_BRIDGE
 #endif
 
-static QTAILQ_HEAD(, VLANState) vlans;
 static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
 
 int default_net = 1;
@@ -249,11 +248,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
 
 static void qemu_cleanup_vlan_client(VLANClientState *vc)
 {
-if (vc->vlan) {
-QTAILQ_REMOVE(&vc->vlan->clients, vc, next);
-} else {
-QTAILQ_REMOVE(&non_vlan_clients, vc, next);
-}
+QTAILQ_REMOVE(&non_vlan_clients, vc, next);
 
 if (vc->info->cleanup) {
 vc->info->cleanup(vc);
@@ -262,13 +257,11 @@ static void qemu_cleanup_vlan_client(VLANClientState *vc)
 
 static void qemu_free_vlan_client(VLANClientState *vc)
 {
-if (!vc->vlan) {
-if (vc->send_queue) {
-qemu_del_net_queue(vc->send_queue);
-}
-if (vc->peer) {
-vc->peer->peer = NULL;
-}
+if (vc->send_queue) {
+qemu_del_net_queue(vc->send_queue);
+}
+if (vc->peer) {
+vc->peer->peer = NULL;
 }
 g_free(vc->name);
 g_free(vc->model);
@@ -278,7 +271,7 @@ static void qemu_free_vlan_client(VLANClientState *vc)
 void qemu_del_vlan_client(VLANClientState *vc)
 {
 /* If there is a peer NIC, delete and cleanup client, but do not free. */
-if (!vc->vlan && vc->peer && vc->peer->info->type == NET_CLIENT_TYPE_NIC) {
+if (vc->peer && vc->peer->info->type == NET_CLIENT_TYPE_NIC) {
 NICState *nic = DO_UPCAST(NICState, nc, vc->peer);
 if (nic->peer_deleted) {
 return;
@@ -294,7 +287,7 @@ void qemu_del_vlan_client(VLANClientState *vc)
 }
 
 /* If this is a peer NIC and peer has already been deleted, free it now. */
-if (!vc->vlan && vc->peer && vc->info->type == NET_CLIENT_TYPE_NIC) {
+if (vc->peer && vc->info->type == NET_CLIENT_TYPE_NIC) {
 NICState *nic = DO_UPCAST(NICState, nc, vc);
 if (nic->peer_deleted) {
 qemu_free_vlan_client(vc->peer);
@@ -308,52 +301,25 @@ void qemu_del_vlan_client(VLANClientState *vc)
 void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
 {
 VLANClientState *nc;
-VLANState *vlan;
 
 QTAILQ_FOREACH(nc, &non_vlan_clients, next) {
 if (nc->info->type == NET_CLIENT_TYPE_NIC) {
 func(DO_UPCAST(NICState, nc, nc), opaque);
 }
 }
-
-QTAILQ_FOREACH(vlan, &vlans, next) {
-QTAILQ_FOREACH(nc, &vlan->clients, next) {
-if (nc->info->type == NET_CLIENT_TYPE_NIC) {
-func(DO_UPCAST(NICState, nc, nc), opaque);
-}
-}
-}
 }
 
 int qemu_can_send_packet(VLANClientState *sender)
 {
-VLANState *vlan = sender->vlan;
-VLANClientState *vc;
-
-if (sender->peer) {
-if (sender->peer->receive_disabled) {
-return 0;
-} else if (sender->peer->info->can_receive &&
-   !sender->peer->info->can_receive(sender->peer)) {
-return 0;
-} else {
-return 1;
-}
-}
-
-if (!sender->vlan) {
+if (!sender->peer) {
 return 1;
 }
 
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-if (vc == sender) {
-continue;
-}
-
-/* no can_receive() handler, they can always receive */
-if (vc->info->can_receive && !vc->info->can_receive(vc)) {
-return 0;
-}
+if (sender->peer->receive_disabled) {
+return 0;
+} else if (sender->peer->info->can_receive &&
+   !sender->peer->info->can_receive(sender->peer)) {
+return 0;
 }
 return 1;
 }
@@ -390,34 +356,18 @@ static ssize_t qemu_deliver_packet(VLANClientState 
*sender,
 
 void qemu_purge_queued_packets(VLANClientState *vc)
 {
-NetQueue *queue;
-
-if (!vc->peer && !vc->vlan) {
+if (!vc->peer) {
 return;
 }
 
-if (vc->peer) {
-queue = vc->peer->send_queue;
-} else {
-queue = vc->vlan->send_queue;
-}
-
-qemu_net_queue_purge(queue, vc);
+qemu_net_queue_purge(vc->peer->send_queue, vc);
 }
 
 void qemu_flush_queued_packets(VLANClientState *vc)
 {
-NetQueue *queue;
-
 vc->receive_disabled = 0;
 
-if (vc->vlan) {
-queue = vc->vlan->send_queue;
-} else {
-queue = vc->send_queue;
-}
-
-qemu_net_queue_flush(queue);
+qemu_net_queue_flush(vc->send_queue);
 }
 
 static ssize_t qemu_send_packet_async_with_flags(VLANClientState *sender,
@@ -432,15 +382,11 @@ static ssize_t 
qemu_send_packet_async_with_flags(V

[Qemu-devel] [PATCH v5 12/17] net: Rename qemu_del_vlan_client() to qemu_del_net_client()

2012-06-18 Thread zwu . kernel
From: Stefan Hajnoczi 

Another step in moving the vlan feature out of net core.  Users only
deal with NetClientState and therefore qemu_del_vlan_client() should be
named qemu_del_net_client().

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 hw/e1000.c   |2 +-
 hw/eepro100.c|2 +-
 hw/ne2000.c  |2 +-
 hw/pcnet-pci.c   |2 +-
 hw/rtl8139.c |2 +-
 hw/usb/dev-network.c |2 +-
 hw/virtio-net.c  |2 +-
 hw/xen_nic.c |2 +-
 net.c|   20 ++--
 net.h|2 +-
 net/slirp.c  |2 +-
 11 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/hw/e1000.c b/hw/e1000.c
index 8c7fd3b..cf1e124 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1201,7 +1201,7 @@ pci_e1000_uninit(PCIDevice *dev)
 qemu_free_timer(d->autoneg_timer);
 memory_region_destroy(&d->mmio);
 memory_region_destroy(&d->io);
-qemu_del_vlan_client(&d->nic->nc);
+qemu_del_net_client(&d->nic->nc);
 return 0;
 }
 
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 5725ccf..0217795 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1840,7 +1840,7 @@ static int pci_nic_uninit(PCIDevice *pci_dev)
 memory_region_destroy(&s->flash_bar);
 vmstate_unregister(&pci_dev->qdev, s->vmstate, s);
 eeprom93xx_free(&pci_dev->qdev, s->eeprom);
-qemu_del_vlan_client(&s->nic->nc);
+qemu_del_net_client(&s->nic->nc);
 return 0;
 }
 
diff --git a/hw/ne2000.c b/hw/ne2000.c
index 2339725..e8b1d68 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -750,7 +750,7 @@ static int pci_ne2000_exit(PCIDevice *pci_dev)
 NE2000State *s = &d->ne2000;
 
 memory_region_destroy(&s->io);
-qemu_del_vlan_client(&s->nic->nc);
+qemu_del_net_client(&s->nic->nc);
 return 0;
 }
 
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 8c82667..8bbad47 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -279,7 +279,7 @@ static int pci_pcnet_uninit(PCIDevice *dev)
 memory_region_destroy(&d->io_bar);
 qemu_del_timer(d->state.poll_timer);
 qemu_free_timer(d->state.poll_timer);
-qemu_del_vlan_client(&d->state.nic->nc);
+qemu_del_net_client(&d->state.nic->nc);
 return 0;
 }
 
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 1e4f4eb..3642fcb 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3448,7 +3448,7 @@ static int pci_rtl8139_uninit(PCIDevice *dev)
 }
 qemu_del_timer(s->timer);
 qemu_free_timer(s->timer);
-qemu_del_vlan_client(&s->nic->nc);
+qemu_del_net_client(&s->nic->nc);
 return 0;
 }
 
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index a1d3495..2d03639 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -1309,7 +1309,7 @@ static void usb_net_handle_destroy(USBDevice *dev)
 
 /* TODO: remove the nd_table[] entry */
 rndis_clear_responsequeue(s);
-qemu_del_vlan_client(&s->nic->nc);
+qemu_del_net_client(&s->nic->nc);
 }
 
 static NetClientInfo net_usbnet_info = {
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index a73c523..d5527d4 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -1077,6 +1077,6 @@ void virtio_net_exit(VirtIODevice *vdev)
 qemu_bh_delete(n->tx_bh);
 }
 
-qemu_del_vlan_client(&n->nic->nc);
+qemu_del_net_client(&n->nic->nc);
 virtio_cleanup(&n->vdev);
 }
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index 6391a04..ba4a45c 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -409,7 +409,7 @@ static void net_disconnect(struct XenDevice *xendev)
 netdev->rxs = NULL;
 }
 if (netdev->nic) {
-qemu_del_vlan_client(&netdev->nic->nc);
+qemu_del_net_client(&netdev->nic->nc);
 netdev->nic = NULL;
 }
 }
diff --git a/net.c b/net.c
index 7fd0fde..e7d49b3 100644
--- a/net.c
+++ b/net.c
@@ -246,7 +246,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
 return nic;
 }
 
-static void qemu_cleanup_vlan_client(NetClientState *nc)
+static void qemu_cleanup_net_client(NetClientState *nc)
 {
 QTAILQ_REMOVE(&net_clients, nc, next);
 
@@ -255,7 +255,7 @@ static void qemu_cleanup_vlan_client(NetClientState *nc)
 }
 }
 
-static void qemu_free_vlan_client(NetClientState *nc)
+static void qemu_free_net_client(NetClientState *nc)
 {
 if (nc->send_queue) {
 qemu_del_net_queue(nc->send_queue);
@@ -268,7 +268,7 @@ static void qemu_free_vlan_client(NetClientState *nc)
 g_free(nc);
 }
 
-void qemu_del_vlan_client(NetClientState *nc)
+void qemu_del_net_client(NetClientState *nc)
 {
 /* If there is a peer NIC, delete and cleanup client, but do not free. */
 if (nc->peer && nc->peer->info->type == NET_CLIENT_TYPE_NIC) {
@@ -282,7 +282,7 @@ void qemu_del_vlan_client(NetClientState *nc)
 if (nc->peer->info->link_status_changed) {
 nc->peer->info->link_status_changed(nc->peer);
 }
-qemu_cleanup_vlan_client(nc);
+qemu_cleanup_net_client(nc);
 return;
 }
 
@@ -290,12 +290,12 @@ void qemu_del_v

[Qemu-devel] [PATCH v5 04/17] hub: Check that hubs are configured correctly

2012-06-18 Thread zwu . kernel
From: Stefan Hajnoczi 

Checks can be performed to make sure that hubs have at least one NIC and
one host device, warning the user if this is not the case.
Configurations which do not meet this rule tend to be broken but just
emit a warning.  This patch preserves compatibility with the checks
performed by net core on vlans.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c |   25 +
 net/hub.c |   45 +
 net/hub.h |1 +
 3 files changed, 47 insertions(+), 24 deletions(-)

diff --git a/net.c b/net.c
index f80a0c0..d6bb480 100644
--- a/net.c
+++ b/net.c
@@ -1356,7 +1356,6 @@ void net_cleanup(void)
 
 void net_check_clients(void)
 {
-VLANState *vlan;
 VLANClientState *vc;
 int i;
 
@@ -1372,30 +1371,8 @@ void net_check_clients(void)
 return;
 }
 
-QTAILQ_FOREACH(vlan, &vlans, next) {
-int has_nic = 0, has_host_dev = 0;
+net_hub_check_clients();
 
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-switch (vc->info->type) {
-case NET_CLIENT_TYPE_NIC:
-has_nic = 1;
-break;
-case NET_CLIENT_TYPE_USER:
-case NET_CLIENT_TYPE_TAP:
-case NET_CLIENT_TYPE_SOCKET:
-case NET_CLIENT_TYPE_VDE:
-has_host_dev = 1;
-break;
-default: ;
-}
-}
-if (has_host_dev && !has_nic)
-fprintf(stderr, "Warning: vlan %d with no nics\n", vlan->id);
-if (has_nic && !has_host_dev)
-fprintf(stderr,
-"Warning: vlan %d is not connected to host network\n",
-vlan->id);
-}
 QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
 if (!vc->peer) {
 fprintf(stderr, "Warning: %s %s has no peer\n",
diff --git a/net/hub.c b/net/hub.c
index 56efc2c..e4a3980 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -223,3 +223,48 @@ int net_hub_id_for_client(VLANClientState *nc, unsigned 
int *id)
 }
 return -ENOENT;
 }
+
+/**
+ * Warn if hub configurations are likely wrong
+ */
+void net_hub_check_clients(void)
+{
+NetHub *hub;
+NetHubPort *port;
+VLANClientState *peer;
+
+QLIST_FOREACH(hub, &hubs, next) {
+int has_nic = 0, has_host_dev = 0;
+
+QLIST_FOREACH(port, &hub->ports, next) {
+peer = port->nc.peer;
+if (!peer) {
+fprintf(stderr, "Warning: hub port %s has no peer\n",
+port->nc.name);
+continue;
+}
+
+switch (peer->info->type) {
+case NET_CLIENT_TYPE_NIC:
+has_nic = 1;
+break;
+case NET_CLIENT_TYPE_USER:
+case NET_CLIENT_TYPE_TAP:
+case NET_CLIENT_TYPE_SOCKET:
+case NET_CLIENT_TYPE_VDE:
+has_host_dev = 1;
+break;
+default:
+break;
+}
+}
+if (has_host_dev && !has_nic) {
+fprintf(stderr, "Warning: vlan %u with no nics\n", hub->id);
+}
+if (has_nic && !has_host_dev) {
+fprintf(stderr,
+"Warning: vlan %u is not connected to host network\n",
+hub->id);
+}
+}
+}
diff --git a/net/hub.h b/net/hub.h
index e149e04..10bf036 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -22,5 +22,6 @@ VLANClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
  const char *name);
 void net_hub_info(Monitor *mon);
 int net_hub_id_for_client(VLANClientState *nc, unsigned int *id);
+void net_hub_check_clients(void);
 
 #endif /* NET_HUB_H */
-- 
1.7.6




[Qemu-devel] [PATCH v5 11/17] net: Rename vc local variables to nc

2012-06-18 Thread zwu . kernel
From: Stefan Hajnoczi 

Now that VLANClientState has been renamed to NetClientState all 'vc'
local variables should be 'nc'.  Much of the code already used 'nc' but
there are places where 'vc' needs to be renamed.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 hw/ne2000.h |4 +-
 hw/vhost_net.c  |   18 +++---
 net.c   |  206 +++---
 net.h   |   20 +++---
 net/tap-win32.c |8 +-
 net/tap.h   |   16 ++--
 6 files changed, 136 insertions(+), 136 deletions(-)

diff --git a/hw/ne2000.h b/hw/ne2000.h
index 6c196a2..1e7ab07 100644
--- a/hw/ne2000.h
+++ b/hw/ne2000.h
@@ -31,5 +31,5 @@ typedef struct NE2000State {
 void ne2000_setup_io(NE2000State *s, unsigned size);
 extern const VMStateDescription vmstate_ne2000;
 void ne2000_reset(NE2000State *s);
-int ne2000_can_receive(NetClientState *vc);
-ssize_t ne2000_receive(NetClientState *vc, const uint8_t *buf, size_t size_);
+int ne2000_can_receive(NetClientState *nc);
+ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_);
diff --git a/hw/vhost_net.c b/hw/vhost_net.c
index c3e6546..c2d90df 100644
--- a/hw/vhost_net.c
+++ b/hw/vhost_net.c
@@ -42,7 +42,7 @@ struct vhost_net {
 struct vhost_dev dev;
 struct vhost_virtqueue vqs[2];
 int backend;
-NetClientState *vc;
+NetClientState *nc;
 };
 
 unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
@@ -104,7 +104,7 @@ struct vhost_net *vhost_net_init(NetClientState *backend, 
int devfd,
 if (r < 0) {
 goto fail;
 }
-net->vc = backend;
+net->nc = backend;
 net->dev.backend_features = tap_has_vnet_hdr(backend) ? 0 :
 (1 << VHOST_NET_F_VIRTIO_NET_HDR);
 net->backend = r;
@@ -151,7 +151,7 @@ int vhost_net_start(struct vhost_net *net,
 goto fail_notifiers;
 }
 if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
-tap_set_vnet_hdr_len(net->vc,
+tap_set_vnet_hdr_len(net->nc,
  sizeof(struct virtio_net_hdr_mrg_rxbuf));
 }
 
@@ -160,7 +160,7 @@ int vhost_net_start(struct vhost_net *net,
 goto fail_start;
 }
 
-net->vc->info->poll(net->vc, false);
+net->nc->info->poll(net->nc, false);
 qemu_set_fd_handler(net->backend, NULL, NULL, NULL);
 file.fd = net->backend;
 for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
@@ -177,10 +177,10 @@ fail:
 int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
 assert(r >= 0);
 }
-net->vc->info->poll(net->vc, true);
+net->nc->info->poll(net->nc, true);
 vhost_dev_stop(&net->dev, dev);
 if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
-tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
+tap_set_vnet_hdr_len(net->nc, sizeof(struct virtio_net_hdr));
 }
 fail_start:
 vhost_dev_disable_notifiers(&net->dev, dev);
@@ -197,10 +197,10 @@ void vhost_net_stop(struct vhost_net *net,
 int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
 assert(r >= 0);
 }
-net->vc->info->poll(net->vc, true);
+net->nc->info->poll(net->nc, true);
 vhost_dev_stop(&net->dev, dev);
 if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
-tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
+tap_set_vnet_hdr_len(net->nc, sizeof(struct virtio_net_hdr));
 }
 vhost_dev_disable_notifiers(&net->dev, dev);
 }
@@ -209,7 +209,7 @@ void vhost_net_cleanup(struct vhost_net *net)
 {
 vhost_dev_cleanup(&net->dev);
 if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
-tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
+tap_set_vnet_hdr_len(net->nc, sizeof(struct virtio_net_hdr));
 }
 g_free(net);
 }
diff --git a/net.c b/net.c
index b35339a..7fd0fde 100644
--- a/net.c
+++ b/net.c
@@ -129,11 +129,11 @@ int parse_host_port(struct sockaddr_in *saddr, const char 
*str)
 return 0;
 }
 
-void qemu_format_nic_info_str(NetClientState *vc, uint8_t macaddr[6])
+void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6])
 {
-snprintf(vc->info_str, sizeof(vc->info_str),
+snprintf(nc->info_str, sizeof(nc->info_str),
  "model=%s,macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
- vc->model,
+ nc->model,
  macaddr[0], macaddr[1], macaddr[2],
  macaddr[3], macaddr[4], macaddr[5]);
 }
@@ -159,19 +159,19 @@ void qemu_macaddr_default_if_unset(MACAddr *macaddr)
  * Only net clients created with the legacy -net option need this.  Naming is
  * mandatory for net clients created with -netdev.
  */
-static char *assign_name(NetClientState *vc1, const char *model)
+static char *assign_name(NetClientState *nc1, const char *model)
 {
-NetClientState *vc;
+NetClientState *nc;
 char buf[256];
 int id = 0;
 
-QTAILQ_FOREACH(vc, &net_clients, 

[Qemu-devel] [PATCH v5 13/17] net: Make "info network" output more readable info

2012-06-18 Thread zwu . kernel
From: Zhi Yong Wu 

Reviewed-by:   Jan Kiszka  
Signed-off-by: Zhi Yong Wu 
---
 net.c |   14 +-
 net.h |1 +
 net/hub.c |   23 +--
 net/hub.h |1 +
 4 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/net.c b/net.c
index e7d49b3..d0be471 100644
--- a/net.c
+++ b/net.c
@@ -1087,7 +1087,7 @@ void qmp_netdev_del(const char *id, Error **errp)
 qemu_opts_del(qemu_opts_find(qemu_find_opts_err("netdev", errp), id));
 }
 
-static void print_net_client(Monitor *mon, NetClientState *vc)
+void print_net_client(Monitor *mon, NetClientState *vc)
 {
 monitor_printf(mon, "%s: type=%s,%s\n", vc->name,
net_client_types[vc->info->type].type, vc->info_str);
@@ -1098,20 +1098,24 @@ void do_info_network(Monitor *mon)
 NetClientState *nc, *peer;
 net_client_type type;
 
-monitor_printf(mon, "Devices not on any VLAN:\n");
+net_hub_info(mon);
+
 QTAILQ_FOREACH(nc, &net_clients, next) {
 peer = nc->peer;
 type = nc->info->type;
+
+if (net_hub_port_peer_nc(nc)) {
+continue;
+}
+
 if (!peer || type == NET_CLIENT_TYPE_NIC) {
-monitor_printf(mon, "  ");
 print_net_client(mon, nc);
 } /* else it's a netdev connected to a NIC, printed with the NIC */
 if (peer && type == NET_CLIENT_TYPE_NIC) {
-monitor_printf(mon, "   \\ ");
+monitor_printf(mon, " \\ ");
 print_net_client(mon, peer);
 }
 }
-net_hub_info(mon);
 }
 
 void qmp_set_link(const char *name, bool up, Error **errp)
diff --git a/net.h b/net.h
index 20fcc94..e1509f9 100644
--- a/net.h
+++ b/net.h
@@ -112,6 +112,7 @@ void qemu_check_nic_model(NICInfo *nd, const char *model);
 int qemu_find_nic_model(NICInfo *nd, const char * const *models,
 const char *default_model);
 
+void print_net_client(Monitor *mon, NetClientState *vc);
 void do_info_network(Monitor *mon);
 
 /* NIC info */
diff --git a/net/hub.c b/net/hub.c
index 122de69..230d86a 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -184,6 +184,25 @@ NetClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
 }
 
 /**
+ * Determine if one nc peers with one hub port
+ */
+bool net_hub_port_peer_nc(NetClientState *nc)
+{
+NetHub *hub;
+NetHubPort *port;
+
+QLIST_FOREACH(hub, &hubs, next) {
+QLIST_FOREACH(port, &hub->ports, next) {
+if (nc == port->nc.peer) {
+return true;
+}
+}
+}
+
+return false;
+}
+
+/**
  * Print hub configuration
  */
 void net_hub_info(Monitor *mon)
@@ -194,8 +213,8 @@ void net_hub_info(Monitor *mon)
 QLIST_FOREACH(hub, &hubs, next) {
 monitor_printf(mon, "hub %u\n", hub->id);
 QLIST_FOREACH(port, &hub->ports, next) {
-monitor_printf(mon, "port %u peer %s\n", port->id,
-   port->nc.peer ? port->nc.peer->name : "");
+monitor_printf(mon, " \\ ");
+print_net_client(mon, port->nc.peer);
 }
 }
 }
diff --git a/net/hub.h b/net/hub.h
index ff5024a..550189b 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -23,5 +23,6 @@ NetClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
 void net_hub_info(Monitor *mon);
 int net_hub_id_for_client(NetClientState *nc, unsigned int *id);
 void net_hub_check_clients(void);
+bool net_hub_port_peer_nc(NetClientState *nc);
 
 #endif /* NET_HUB_H */
-- 
1.7.6




[Qemu-devel] [PATCH v5 16/17] hub: add the support for hub own flow control

2012-06-18 Thread zwu . kernel
From: Zhi Yong Wu 

Only when all other hub port's *peer* .can_receive() all return 1,
the source hub port .can_receive() return 1.

Reviewed-off-by: Paolo Bonzini 
Signed-off-by: Zhi Yong Wu 
---
 net/hub.c |   27 ---
 1 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/net/hub.c b/net/hub.c
index 230d86a..efd90b5 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -15,6 +15,7 @@
 #include "monitor.h"
 #include "net.h"
 #include "hub.h"
+#include "iov.h"
 
 /*
  * A hub broadcasts incoming packets to all its ports except the source port.
@@ -59,16 +60,16 @@ static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort 
*source_port,
const struct iovec *iov, int iovcnt)
 {
 NetHubPort *port;
-ssize_t ret = 0;
+ssize_t len = iov_size(iov, iovcnt);
 
 QLIST_FOREACH(port, &hub->ports, next) {
 if (port == source_port) {
 continue;
 }
 
-ret = qemu_sendv_packet(&port->nc, iov, iovcnt);
+qemu_sendv_packet(&port->nc, iov, iovcnt);
 }
-return ret;
+return len;
 }
 
 static NetHub *net_hub_new(unsigned int id)
@@ -85,6 +86,25 @@ static NetHub *net_hub_new(unsigned int id)
 return hub;
 }
 
+static int net_hub_port_can_receive(NetClientState *nc)
+{
+NetHubPort *port;
+NetHubPort *src_port = DO_UPCAST(NetHubPort, nc, nc);
+NetHub *hub = src_port->hub;
+
+QLIST_FOREACH(port, &hub->ports, next) {
+if (port == src_port) {
+continue;
+}
+
+if (!qemu_can_send_packet(&port->nc)) {
+return 0;
+}
+}
+
+return 1;
+}
+
 static ssize_t net_hub_port_receive(NetClientState *nc,
 const uint8_t *buf, size_t len)
 {
@@ -111,6 +131,7 @@ static void net_hub_port_cleanup(NetClientState *nc)
 static NetClientInfo net_hub_port_info = {
 .type = NET_CLIENT_TYPE_HUB,
 .size = sizeof(NetHubPort),
+.can_receive = net_hub_port_can_receive,
 .receive = net_hub_port_receive,
 .receive_iov = net_hub_port_receive_iov,
 .cleanup = net_hub_port_cleanup,
-- 
1.7.6




[Qemu-devel] [PATCH 2/3] net: add the support for -netdev socket, listen

2012-06-18 Thread zwu . kernel
From: Zhi Yong Wu 

The -net socket,listen option does not work with the newer -netdev
syntax:
 http://lists.gnu.org/archive/html/qemu-devel/2011-11/msg01508.html

This patch makes it work now.

For the case where one vlan has multiple listenning sockets,
the patch will also provide the support.

Supported syntax:
 1.) -net socket,listen=127.0.0.1:1234,vlan=0
 2.) -net socket,listen=127.0.0.1:1234,vlan=0 -net 
socket,listen=127.0.0.1:1235,vlan=0
 3.) -netdev socket,listen=127.0.0.1:1234,id=socket0

 Drop the NetSocketListenState struct and add a listen_fd field
to NetSocketState.  When a -netdev socket,listen= instance is created
there will be a NetSocketState with fd=-1 and a valid listen_fd.  The
net_socket_accept() handler waits for listen_fd to become readable and
then accepts the connection.  When this state transition happens, we no
longer monitor listen_fd for incoming connections...until the client
disconnects again.

Suggested-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net/socket.c |   60 +
 1 files changed, 31 insertions(+), 29 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index ba8583f..408d00e 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -35,6 +35,7 @@
 
 typedef struct NetSocketState {
 NetClientState nc;
+int listen_fd;
 int fd;
 int state; /* 0 = getting length, 1 = getting data */
 unsigned int index;
@@ -43,12 +44,7 @@ typedef struct NetSocketState {
 struct sockaddr_in dgram_dst; /* contains inet host and port destination 
iff connectionless (SOCK_DGRAM) */
 } NetSocketState;
 
-typedef struct NetSocketListenState {
-NetClientState *peer;
-char *model;
-char *name;
-int fd;
-} NetSocketListenState;
+static void net_socket_accept(void *opaque);
 
 /* XXX: we consider we can send the whole packet without blocking */
 static ssize_t net_socket_receive(NetClientState *nc, const uint8_t *buf, 
size_t size)
@@ -86,7 +82,16 @@ static void net_socket_send(void *opaque)
 /* end of connection */
 eoc:
 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
+qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
 closesocket(s->fd);
+
+s->fd = -1;
+s->state = 0;
+s->index = 0;
+s->packet_len = 0;
+memset(s->buf, 0, sizeof(s->buf));
+memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
+
 return;
 }
 buf = buf1;
@@ -377,29 +382,28 @@ static NetSocketState *net_socket_fd_init(NetClientState 
*peer,
 
 static void net_socket_accept(void *opaque)
 {
-NetSocketListenState *s = opaque;
-NetSocketState *s1;
+NetSocketState *s = opaque;
 struct sockaddr_in saddr;
 socklen_t len;
 int fd;
 
 for(;;) {
 len = sizeof(saddr);
-fd = qemu_accept(s->fd, (struct sockaddr *)&saddr, &len);
+fd = qemu_accept(s->listen_fd, (struct sockaddr *)&saddr, &len);
 if (fd < 0 && errno != EINTR) {
 return;
 } else if (fd >= 0) {
+qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
 break;
 }
 }
-s1 = net_socket_fd_init(s->peer, s->model, s->name, fd, 1);
-if (!s1) {
-closesocket(fd);
-} else {
-snprintf(s1->nc.info_str, sizeof(s1->nc.info_str),
- "socket: connection from %s:%d",
- inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
-}
+
+s->fd = fd;
+s->nc.link_down = false;
+net_socket_connect(s);
+snprintf(s->nc.info_str, sizeof(s->nc.info_str),
+ "socket: connection from %s:%d",
+ inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
 }
 
 static int net_socket_listen_init(NetClientState *peer,
@@ -407,19 +411,17 @@ static int net_socket_listen_init(NetClientState *peer,
   const char *name,
   const char *host_str)
 {
-NetSocketListenState *s;
-int fd, val, ret;
+VLANClientState *nc;
+NetSocketState *s;
 struct sockaddr_in saddr;
+int fd, val, ret;
 
 if (parse_host_port(&saddr, host_str) < 0)
 return -1;
 
-s = g_malloc0(sizeof(NetSocketListenState));
-
 fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
 if (fd < 0) {
 perror("socket");
-g_free(s);
 return -1;
 }
 socket_set_nonblock(fd);
@@ -431,22 +433,22 @@ static int net_socket_listen_init(NetClientState *peer,
 ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
 if (ret < 0) {
 perror("bind");
-g_free(s);
 closesocket(fd);
 return -1;
 }
 ret = listen(fd, 0);
 if (ret < 0) {
 perror("listen");
-g_free(s);
 closesocket(fd);
 return -1;
 }
-s->peer = peer;
-s->model = g_strdup(model);
-s->name = name ? g_strdup(name) : NULL;
-s->fd = fd;
-qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
+
+

[Qemu-devel] [PATCH 1/3] net: fix the coding style

2012-06-18 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 net/socket.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index dc5ba40..ba8583f 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -301,7 +301,9 @@ static NetSocketState 
*net_socket_fd_init_dgram(NetClientState *peer,
 qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
 
 /* mcast: save bound address as dst */
-if (is_connected) s->dgram_dst=saddr;
+if (is_connected) {
+s->dgram_dst = saddr;
+}
 
 return s;
 
-- 
1.7.6




[Qemu-devel] [PATCH 0/3] Some socket fix patches

2012-06-18 Thread zwu . kernel
From: Zhi Yong Wu 

The patchset is on top of hub-based networking patchset.

Zhi Yong Wu (3):
  net: fix the coding style
  net: add the support for -netdev socket, listen
  net: complete NetSocketState lifecycle handling

 net/socket.c |   82 +++--
 1 files changed, 50 insertions(+), 32 deletions(-)

-- 
1.7.6




[Qemu-devel] [PATCH 3/3] net: complete NetSocketS?tate lifecycle handling

2012-06-18 Thread zwu . kernel
From: Zhi Yong Wu 

The NetSocketState struct contains two file descriptors: an active
connection and a listen socket for new connections.  It's important that
we clean up after ourselves so these file descriptors are initialized to
-1 when unused.  This allows makes it possible to call cleanup functions
only when the file descriptors are valid (not -1).

The specific issue solved by this patch is that we avoid calling
close(-1), close(0), and qemu_set_fd_handler(-1, net_socket_accept,
NULL, s).  All of these are either problematic or unclean (e.g. reported
as warnings by Valgrind).

Also stay consistent by bringing the link down when the active
connection is closed.

Signed-off-by: Stefan Hajnoczi 
---
 net/socket.c |   24 +++-
 1 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index 408d00e..9b15479 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -82,13 +82,16 @@ static void net_socket_send(void *opaque)
 /* end of connection */
 eoc:
 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
-qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
+if (s->listen_fd != -1) {
+qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
+}
 closesocket(s->fd);
 
 s->fd = -1;
 s->state = 0;
 s->index = 0;
 s->packet_len = 0;
+s->nc.link_down = true;
 memset(s->buf, 0, sizeof(s->buf));
 memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
 
@@ -239,8 +242,16 @@ fail:
 static void net_socket_cleanup(NetClientState *nc)
 {
 NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
-qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
-close(s->fd);
+if (s->fd != -1) {
+qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
+close(s->fd);
+s->fd = -1;
+}
+if (s->listen_fd != -1) {
+qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
+closesocket(s->listen_fd);
+s->listen_fd = -1;
+}
 }
 
 static NetClientInfo net_dgram_socket_info = {
@@ -302,6 +313,7 @@ static NetSocketState 
*net_socket_fd_init_dgram(NetClientState *peer,
 s = DO_UPCAST(NetSocketState, nc, nc);
 
 s->fd = fd;
+s->listen_fd = -1;
 
 qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
 
@@ -345,6 +357,7 @@ static NetSocketState 
*net_socket_fd_init_stream(NetClientState *peer,
 s = DO_UPCAST(NetSocketState, nc, nc);
 
 s->fd = fd;
+s->listen_fd = -1;
 
 if (is_connected) {
 net_socket_connect(s);
@@ -411,7 +424,7 @@ static int net_socket_listen_init(NetClientState *peer,
   const char *name,
   const char *host_str)
 {
-VLANClientState *nc;
+NetClientState *nc;
 NetSocketState *s;
 struct sockaddr_in saddr;
 int fd, val, ret;
@@ -443,8 +456,9 @@ static int net_socket_listen_init(NetClientState *peer,
 return -1;
 }
 
-nc = qemu_new_net_client(&net_socket_info, vlan, NULL, model, name);
+nc = qemu_new_net_client(&net_socket_info, peer, model, name);
 s = DO_UPCAST(NetSocketState, nc, nc);
+s->fd = -1;
 s->listen_fd = fd;
 s->nc.link_down = true;
 
-- 
1.7.6




[Qemu-devel] [PATCH 3/3] net: complete NetSocketState lifecycle handling

2012-06-18 Thread zwu . kernel
From: Zhi Yong Wu 

The NetSocketState struct contains two file descriptors: an active
connection and a listen socket for new connections.  It's important that
we clean up after ourselves so these file descriptors are initialized to
-1 when unused.  This allows makes it possible to call cleanup functions
only when the file descriptors are valid (not -1).

The specific issue solved by this patch is that we avoid calling
close(-1), close(0), and qemu_set_fd_handler(-1, net_socket_accept,
NULL, s).  All of these are either problematic or unclean (e.g. reported
as warnings by Valgrind).

Also stay consistent by bringing the link down when the active
connection is closed.

Signed-off-by: Stefan Hajnoczi 
---
 net/socket.c |   24 +++-
 1 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index 408d00e..9b15479 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -82,13 +82,16 @@ static void net_socket_send(void *opaque)
 /* end of connection */
 eoc:
 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
-qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
+if (s->listen_fd != -1) {
+qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
+}
 closesocket(s->fd);
 
 s->fd = -1;
 s->state = 0;
 s->index = 0;
 s->packet_len = 0;
+s->nc.link_down = true;
 memset(s->buf, 0, sizeof(s->buf));
 memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
 
@@ -239,8 +242,16 @@ fail:
 static void net_socket_cleanup(NetClientState *nc)
 {
 NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
-qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
-close(s->fd);
+if (s->fd != -1) {
+qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
+close(s->fd);
+s->fd = -1;
+}
+if (s->listen_fd != -1) {
+qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
+closesocket(s->listen_fd);
+s->listen_fd = -1;
+}
 }
 
 static NetClientInfo net_dgram_socket_info = {
@@ -302,6 +313,7 @@ static NetSocketState 
*net_socket_fd_init_dgram(NetClientState *peer,
 s = DO_UPCAST(NetSocketState, nc, nc);
 
 s->fd = fd;
+s->listen_fd = -1;
 
 qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
 
@@ -345,6 +357,7 @@ static NetSocketState 
*net_socket_fd_init_stream(NetClientState *peer,
 s = DO_UPCAST(NetSocketState, nc, nc);
 
 s->fd = fd;
+s->listen_fd = -1;
 
 if (is_connected) {
 net_socket_connect(s);
@@ -411,7 +424,7 @@ static int net_socket_listen_init(NetClientState *peer,
   const char *name,
   const char *host_str)
 {
-VLANClientState *nc;
+NetClientState *nc;
 NetSocketState *s;
 struct sockaddr_in saddr;
 int fd, val, ret;
@@ -443,8 +456,9 @@ static int net_socket_listen_init(NetClientState *peer,
 return -1;
 }
 
-nc = qemu_new_net_client(&net_socket_info, vlan, NULL, model, name);
+nc = qemu_new_net_client(&net_socket_info, peer, model, name);
 s = DO_UPCAST(NetSocketState, nc, nc);
+s->fd = -1;
 s->listen_fd = fd;
 s->nc.link_down = true;
 
-- 
1.7.6




[Qemu-devel] [PATCH v5 09/17] net: Rename non_vlan_clients to net_clients

2012-06-18 Thread zwu . kernel
From: Stefan Hajnoczi 

There is no longer a distinction between vlan clients and non-vlan
clients in the net core.  The net core only knows about point-to-point
clients which are connected to a peer.  It's time to rename the global
list of net clients since it no longer refers to vlans at all.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c |   20 ++--
 1 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/net.c b/net.c
index 73325b0..d3a685e 100644
--- a/net.c
+++ b/net.c
@@ -44,7 +44,7 @@
 # define CONFIG_NET_BRIDGE
 #endif
 
-static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
+static QTAILQ_HEAD(, VLANClientState) net_clients;
 
 int default_net = 1;
 
@@ -165,7 +165,7 @@ static char *assign_name(VLANClientState *vc1, const char 
*model)
 char buf[256];
 int id = 0;
 
-QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
+QTAILQ_FOREACH(vc, &net_clients, next) {
 if (vc == vc1) {
 continue;
 }
@@ -216,7 +216,7 @@ VLANClientState *qemu_new_net_client(NetClientInfo *info,
 vc->peer = peer;
 peer->peer = vc;
 }
-QTAILQ_INSERT_TAIL(&non_vlan_clients, vc, next);
+QTAILQ_INSERT_TAIL(&net_clients, vc, next);
 
 vc->send_queue = qemu_new_net_queue(qemu_deliver_packet,
 qemu_deliver_packet_iov,
@@ -248,7 +248,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
 
 static void qemu_cleanup_vlan_client(VLANClientState *vc)
 {
-QTAILQ_REMOVE(&non_vlan_clients, vc, next);
+QTAILQ_REMOVE(&net_clients, vc, next);
 
 if (vc->info->cleanup) {
 vc->info->cleanup(vc);
@@ -302,7 +302,7 @@ void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
 {
 VLANClientState *nc;
 
-QTAILQ_FOREACH(nc, &non_vlan_clients, next) {
+QTAILQ_FOREACH(nc, &net_clients, next) {
 if (nc->info->type == NET_CLIENT_TYPE_NIC) {
 func(DO_UPCAST(NICState, nc, nc), opaque);
 }
@@ -467,7 +467,7 @@ VLANClientState *qemu_find_netdev(const char *id)
 {
 VLANClientState *vc;
 
-QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
+QTAILQ_FOREACH(vc, &net_clients, next) {
 if (vc->info->type == NET_CLIENT_TYPE_NIC)
 continue;
 if (!strcmp(vc->name, id)) {
@@ -1099,7 +1099,7 @@ void do_info_network(Monitor *mon)
 net_client_type type;
 
 monitor_printf(mon, "Devices not on any VLAN:\n");
-QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
+QTAILQ_FOREACH(vc, &net_clients, next) {
 peer = vc->peer;
 type = vc->info->type;
 if (!peer || type == NET_CLIENT_TYPE_NIC) {
@@ -1152,7 +1152,7 @@ void net_cleanup(void)
 {
 VLANClientState *vc, *next_vc;
 
-QTAILQ_FOREACH_SAFE(vc, &non_vlan_clients, next, next_vc) {
+QTAILQ_FOREACH_SAFE(vc, &net_clients, next, next_vc) {
 qemu_del_vlan_client(vc);
 }
 }
@@ -1176,7 +1176,7 @@ void net_check_clients(void)
 
 net_hub_check_clients();
 
-QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
+QTAILQ_FOREACH(vc, &net_clients, next) {
 if (!vc->peer) {
 fprintf(stderr, "Warning: %s %s has no peer\n",
 vc->info->type == NET_CLIENT_TYPE_NIC ? "nic" : "netdev",
@@ -1240,7 +1240,7 @@ int net_init_clients(void)
 #endif
 }
 
-QTAILQ_INIT(&non_vlan_clients);
+QTAILQ_INIT(&net_clients);
 
 if (qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, 1) 
== -1)
 return -1;
-- 
1.7.6




[Qemu-devel] [PATCH v5 05/17] net: Drop vlan argument to qemu_new_net_client()

2012-06-18 Thread zwu . kernel
From: Stefan Hajnoczi 

Since hubs are now used to implement the 'vlan' feature and the vlan
argument is always NULL, remove the argument entirely and update all net
clients that use qemu_new_net_client().

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c   |   27 ++-
 net.h   |1 -
 net/dump.c  |2 +-
 net/hub.c   |2 +-
 net/slirp.c |2 +-
 net/socket.c|4 ++--
 net/tap-win32.c |2 +-
 net/tap.c   |2 +-
 net/vde.c   |2 +-
 9 files changed, 18 insertions(+), 26 deletions(-)

diff --git a/net.c b/net.c
index d6bb480..553f032 100644
--- a/net.c
+++ b/net.c
@@ -194,7 +194,6 @@ static ssize_t qemu_deliver_packet_iov(VLANClientState 
*sender,
void *opaque);
 
 VLANClientState *qemu_new_net_client(NetClientInfo *info,
- VLANState *vlan,
  VLANClientState *peer,
  const char *model,
  const char *name)
@@ -213,22 +212,16 @@ VLANClientState *qemu_new_net_client(NetClientInfo *info,
 vc->name = assign_name(vc, model);
 }
 
-if (vlan) {
-assert(!peer);
-vc->vlan = vlan;
-QTAILQ_INSERT_TAIL(&vc->vlan->clients, vc, next);
-} else {
-if (peer) {
-assert(!peer->peer);
-vc->peer = peer;
-peer->peer = vc;
-}
-QTAILQ_INSERT_TAIL(&non_vlan_clients, vc, next);
-
-vc->send_queue = qemu_new_net_queue(qemu_deliver_packet,
-qemu_deliver_packet_iov,
-vc);
+if (peer) {
+assert(!peer->peer);
+vc->peer = peer;
+peer->peer = vc;
 }
+QTAILQ_INSERT_TAIL(&non_vlan_clients, vc, next);
+
+vc->send_queue = qemu_new_net_queue(qemu_deliver_packet,
+qemu_deliver_packet_iov,
+vc);
 
 return vc;
 }
@@ -245,7 +238,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
 assert(info->type == NET_CLIENT_TYPE_NIC);
 assert(info->size >= sizeof(NICState));
 
-nc = qemu_new_net_client(info, conf->vlan, conf->peer, model, name);
+nc = qemu_new_net_client(info, conf->peer, model, name);
 
 nic = DO_UPCAST(NICState, nc, nc);
 nic->conf = conf;
diff --git a/net.h b/net.h
index c1198b6..a96ae20 100644
--- a/net.h
+++ b/net.h
@@ -92,7 +92,6 @@ struct VLANState {
 VLANState *qemu_find_vlan(int id, int allocate);
 VLANClientState *qemu_find_netdev(const char *id);
 VLANClientState *qemu_new_net_client(NetClientInfo *info,
- VLANState *vlan,
  VLANClientState *peer,
  const char *model,
  const char *name);
diff --git a/net/dump.c b/net/dump.c
index a59133a..0349210 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -129,7 +129,7 @@ static int net_dump_init(VLANClientState *peer, const char 
*device,
 return -1;
 }
 
-nc = qemu_new_net_client(&net_dump_info, NULL, peer, device, name);
+nc = qemu_new_net_client(&net_dump_info, peer, device, name);
 
 snprintf(nc->info_str, sizeof(nc->info_str),
  "dump to %s (len=%d)", filename, len);
diff --git a/net/hub.c b/net/hub.c
index e4a3980..fe78a72 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -125,7 +125,7 @@ static NetHubPort *net_hub_port_new(NetHub *hub)
 
 snprintf(name, sizeof name, "hub%uport%u", hub->id, id);
 
-nc = qemu_new_net_client(&net_hub_port_info, NULL, NULL, "hub", name);
+nc = qemu_new_net_client(&net_hub_port_info, NULL, "hub", name);
 port = DO_UPCAST(NetHubPort, nc, nc);
 port->id = id;
 port->hub = hub;
diff --git a/net/slirp.c b/net/slirp.c
index c8c557a..1145412 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -238,7 +238,7 @@ static int net_slirp_init(VLANClientState *peer, const char 
*model,
 }
 #endif
 
-nc = qemu_new_net_client(&net_slirp_info, NULL, peer, model, name);
+nc = qemu_new_net_client(&net_slirp_info, peer, model, name);
 
 snprintf(nc->info_str, sizeof(nc->info_str),
  "net=%s,restrict=%s", inet_ntoa(net),
diff --git a/net/socket.c b/net/socket.c
index f231f7b..d4f7a7b 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -287,7 +287,7 @@ static NetSocketState 
*net_socket_fd_init_dgram(VLANClientState *peer,
 }
 }
 
-nc = qemu_new_net_client(&net_dgram_socket_info, NULL, peer, model, name);
+nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name);
 
 snprintf(nc->info_str, sizeof(nc->info_str),
 "socket: fd=%d (%s mcast=%s:%d)",
@@ -331,7 +331,7 @@ static NetSocketState 
*net_socket_fd_init_stream(VLANClientState *peer,
 VLANClientState *nc;
 NetSocketState *s;
 
-nc = qemu_new_net_

[Qemu-devel] [PATCH v5 14/17] net: cleanup deliver/deliver_iov func pointers

2012-06-18 Thread zwu . kernel
From: Zhi Yong Wu 

Reviewed-by:   Paolo Bonzini 
Signed-off-by: Zhi Yong Wu 
---
 net.c   |   35 +++
 net.h   |   11 +++
 net/queue.c |   13 -
 net/queue.h |   17 ++---
 4 files changed, 28 insertions(+), 48 deletions(-)

diff --git a/net.c b/net.c
index d0be471..6bbc9fc 100644
--- a/net.c
+++ b/net.c
@@ -181,17 +181,6 @@ static char *assign_name(NetClientState *nc1, const char 
*model)
 return g_strdup(buf);
 }
 
-static ssize_t qemu_deliver_packet(NetClientState *sender,
-   unsigned flags,
-   const uint8_t *data,
-   size_t size,
-   void *opaque);
-static ssize_t qemu_deliver_packet_iov(NetClientState *sender,
-   unsigned flags,
-   const struct iovec *iov,
-   int iovcnt,
-   void *opaque);
-
 NetClientState *qemu_new_net_client(NetClientInfo *info,
 NetClientState *peer,
 const char *model,
@@ -218,9 +207,7 @@ NetClientState *qemu_new_net_client(NetClientInfo *info,
 }
 QTAILQ_INSERT_TAIL(&net_clients, nc, next);
 
-nc->send_queue = qemu_new_net_queue(qemu_deliver_packet,
-qemu_deliver_packet_iov,
-nc);
+nc->send_queue = qemu_new_net_queue(nc);
 
 return nc;
 }
@@ -324,11 +311,11 @@ int qemu_can_send_packet(NetClientState *sender)
 return 1;
 }
 
-static ssize_t qemu_deliver_packet(NetClientState *sender,
-   unsigned flags,
-   const uint8_t *data,
-   size_t size,
-   void *opaque)
+ssize_t qemu_deliver_packet(NetClientState *sender,
+unsigned flags,
+const uint8_t *data,
+size_t size,
+void *opaque)
 {
 NetClientState *nc = opaque;
 ssize_t ret;
@@ -421,11 +408,11 @@ static ssize_t nc_sendv_compat(NetClientState *nc, const 
struct iovec *iov,
 return nc->info->receive(nc, buffer, offset);
 }
 
-static ssize_t qemu_deliver_packet_iov(NetClientState *sender,
-   unsigned flags,
-   const struct iovec *iov,
-   int iovcnt,
-   void *opaque)
+ssize_t qemu_deliver_packet_iov(NetClientState *sender,
+unsigned flags,
+const struct iovec *iov,
+int iovcnt,
+void *opaque)
 {
 NetClientState *nc = opaque;
 
diff --git a/net.h b/net.h
index e1509f9..99b43f4 100644
--- a/net.h
+++ b/net.h
@@ -112,6 +112,17 @@ void qemu_check_nic_model(NICInfo *nd, const char *model);
 int qemu_find_nic_model(NICInfo *nd, const char * const *models,
 const char *default_model);
 
+ssize_t qemu_deliver_packet(NetClientState *sender,
+unsigned flags,
+const uint8_t *data,
+size_t size,
+void *opaque);
+ssize_t qemu_deliver_packet_iov(NetClientState *sender,
+unsigned flags,
+const struct iovec *iov,
+int iovcnt,
+void *opaque);
+
 void print_net_client(Monitor *mon, NetClientState *vc);
 void do_info_network(Monitor *mon);
 
diff --git a/net/queue.c b/net/queue.c
index 35c3463..0afd783 100644
--- a/net/queue.c
+++ b/net/queue.c
@@ -23,6 +23,7 @@
 
 #include "net/queue.h"
 #include "qemu-queue.h"
+#include "net.h"
 
 /* The delivery handler may only return zero if it will call
  * qemu_net_queue_flush() when it determines that it is once again able
@@ -48,8 +49,6 @@ struct NetPacket {
 };
 
 struct NetQueue {
-NetPacketDeliver *deliver;
-NetPacketDeliverIOV *deliver_iov;
 void *opaque;
 
 QTAILQ_HEAD(packets, NetPacket) packets;
@@ -57,16 +56,12 @@ struct NetQueue {
 unsigned delivering : 1;
 };
 
-NetQueue *qemu_new_net_queue(NetPacketDeliver *deliver,
- NetPacketDeliverIOV *deliver_iov,
- void *opaque)
+NetQueue *qemu_new_net_queue(void *opaque)
 {
 NetQueue *queue;
 
 queue = g_malloc0(sizeof(NetQueue));
 
-queue->deliver = deliver;
-queue->deliver_iov = deliver_iov;
 queue->opaque = opaque;
 
 QTAILQ_INIT(&queue->packets);
@@ -151,7 +146,7 @@ static ssize_t qemu_net_queue_deliver(NetQueue *queue,
 ssize_t ret = -1;
 
 queue->delivering = 1;
-

[Qemu-devel] [PATCH v5 17/17] net: roll back qdev_prop_vlan

2012-06-18 Thread zwu . kernel
From: Zhi Yong Wu 

We're trying to preserve backward compatibility.  This
command-line break:

x86_64-softmmu/qemu-system-x86_64 -net user,vlan=1 -device virtio-net-pci,vlan=1

Instead of dropping the qdev_prop_vlan completely the
hw/qdev-properties.c code needs to call net/hub.h external functions
to implement equivalent functionality.

Signed-off-by: Zhi Yong Wu 
---
 hw/qdev-properties.c |   77 ++
 hw/qdev.h|3 ++
 net.h|1 +
 net/hub.c|   25 
 net/hub.h|1 +
 5 files changed, 107 insertions(+), 0 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 6fd3163..92960db 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -2,6 +2,7 @@
 #include "qdev.h"
 #include "qerror.h"
 #include "blockdev.h"
+#include "net/hub.h"
 
 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
 {
@@ -591,6 +592,82 @@ PropertyInfo qdev_prop_netdev = {
 .set   = set_netdev,
 };
 
+/* --- vlan --- */
+
+static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
+
+if (*ptr) {
+unsigned int id;
+if (!net_hub_id_for_client(*ptr, &id)) {
+return snprintf(dest, len, "%u", id);
+}
+}
+
+return snprintf(dest, len, "");
+}
+
+static void get_vlan(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
+NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
+int64_t id = -1;
+
+if (*ptr) {
+unsigned int hub_id;
+if(!net_hub_id_for_client(*ptr, &hub_id)) {
+   id = (int64_t)hub_id;
+}
+}
+
+visit_type_int(v, &id, name, errp);
+}
+
+static void set_vlan(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
+NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
+Error *local_err = NULL;
+int64_t id;
+NetClientState *hubport;
+
+if (dev->state != DEV_STATE_CREATED) {
+error_set(errp, QERR_PERMISSION_DENIED);
+return;
+}
+
+visit_type_int(v, &id, name, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
+if (id == -1) {
+*ptr = NULL;
+return;
+}
+
+hubport = net_hub_port_find(id);
+if (!hubport) {
+error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+  name, prop->info->name);
+return;
+}
+*ptr = hubport;
+}
+
+PropertyInfo qdev_prop_vlan = {
+.name  = "vlan",
+.print = print_vlan,
+.get   = get_vlan,
+.set   = set_vlan,
+};
+
 /* --- pointer --- */
 
 /* Not a proper property, just for dirty hacks.  TODO Remove it!  */
diff --git a/hw/qdev.h b/hw/qdev.h
index 33d4f6e..6966b5b 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -220,6 +220,7 @@ extern PropertyInfo qdev_prop_macaddr;
 extern PropertyInfo qdev_prop_losttickpolicy;
 extern PropertyInfo qdev_prop_drive;
 extern PropertyInfo qdev_prop_netdev;
+extern PropertyInfo qdev_prop_vlan;
 extern PropertyInfo qdev_prop_pci_devfn;
 extern PropertyInfo qdev_prop_blocksize;
 
@@ -274,6 +275,8 @@ extern PropertyInfo qdev_prop_blocksize;
 DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
 #define DEFINE_PROP_NETDEV(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, NetClientState*)
+#define DEFINE_PROP_VLAN(_n, _s, _f) \
+DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, NetClientState*)
 #define DEFINE_PROP_DRIVE(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *)
 #define DEFINE_PROP_MACADDR(_n, _s, _f) \
diff --git a/net.h b/net.h
index 99b43f4..0256ff9 100644
--- a/net.h
+++ b/net.h
@@ -22,6 +22,7 @@ typedef struct NICConf {
 
 #define DEFINE_NIC_PROPERTIES(_state, _conf)\
 DEFINE_PROP_MACADDR("mac",   _state, _conf.macaddr),\
+DEFINE_PROP_VLAN("vlan", _state, _conf.peer),   \
 DEFINE_PROP_NETDEV("netdev", _state, _conf.peer),   \
 DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1)
 
diff --git a/net/hub.c b/net/hub.c
index efd90b5..001f818 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -205,6 +205,31 @@ NetClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
 }
 
 /**
+ * Find a available port on a hub; otherwise create one new port
+ */
+NetClientState *net_hub_port_find(unsigned int hub_id)
+{
+NetHub *hub;
+NetHubPort *port;
+NetClientState *nc;
+
+QLIST_FOREACH(hub, &hubs, next) {
+if (hub->id == hub_id) {
+QLIST_FOREACH(port, &hub->ports, next) {
+nc = port->nc.peer;
+if (!nc) {
+return &(port->nc);
+   

[Qemu-devel] [PATCH v5 02/17] net: Use hubs for the vlan feature

2012-06-18 Thread zwu . kernel
From: Stefan Hajnoczi 

Stop using the special-case vlan code in net.c.  Instead use the hub net
client to implement the vlan feature.  The next patch will remove vlan
code from net.c completely.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c   |   38 +-
 net/dump.c  |   19 +--
 net/dump.h  |2 +-
 net/slirp.c |8 
 net/slirp.h |2 +-
 net/socket.c|   48 ++--
 net/socket.h|2 +-
 net/tap-win32.c |8 
 net/tap.c   |6 +++---
 net/tap.h   |2 +-
 net/vde.c   |8 
 net/vde.h   |2 +-
 12 files changed, 80 insertions(+), 65 deletions(-)

diff --git a/net.c b/net.c
index 4aa416c..9a63d22 100644
--- a/net.c
+++ b/net.c
@@ -25,6 +25,7 @@
 
 #include "config-host.h"
 
+#include "net/hub.h"
 #include "net/tap.h"
 #include "net/socket.h"
 #include "net/dump.h"
@@ -153,23 +154,25 @@ void qemu_macaddr_default_if_unset(MACAddr *macaddr)
 macaddr->a[5] = 0x56 + index++;
 }
 
+/**
+ * Generate a name for net client
+ *
+ * Only net clients created with the legacy -net option need this.  Naming is
+ * mandatory for net clients created with -netdev.
+ */
 static char *assign_name(VLANClientState *vc1, const char *model)
 {
-VLANState *vlan;
 VLANClientState *vc;
 char buf[256];
 int id = 0;
 
-QTAILQ_FOREACH(vlan, &vlans, next) {
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-if (vc != vc1 && strcmp(vc->model, model) == 0) {
-id++;
-}
-}
-}
-
 QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
-if (vc != vc1 && strcmp(vc->model, model) == 0) {
+if (vc == vc1) {
+continue;
+}
+/* For compatibility only bump id for net clients on a vlan */
+if (strcmp(vc->model, model) == 0 &&
+net_hub_id_for_client(vc, NULL) == 0) {
 id++;
 }
 }
@@ -745,7 +748,7 @@ int net_handle_fd_param(Monitor *mon, const char *param)
 return fd;
 }
 
-static int net_init_nic(QemuOpts *opts, const char *name, VLANState *vlan)
+static int net_init_nic(QemuOpts *opts, const char *name, VLANClientState 
*peer)
 {
 int idx;
 NICInfo *nd;
@@ -768,8 +771,8 @@ static int net_init_nic(QemuOpts *opts, const char *name, 
VLANState *vlan)
 return -1;
 }
 } else {
-assert(vlan);
-nd->vlan = vlan;
+assert(peer);
+nd->netdev = peer;
 }
 if (name) {
 nd->name = g_strdup(name);
@@ -819,7 +822,7 @@ static int net_init_nic(QemuOpts *opts, const char *name, 
VLANState *vlan)
 
 typedef int (*net_client_init_func)(QemuOpts *opts,
 const char *name,
-VLANState *vlan);
+VLANClientState *peer);
 
 /* magic number, but compiler will warn if too small */
 #define NET_MAX_DESC 20
@@ -1133,7 +1136,7 @@ int net_client_init(QemuOpts *opts, int is_netdev, Error 
**errp)
 if (net_client_types[i].type != NULL &&
 !strcmp(net_client_types[i].type, type)) {
 Error *local_err = NULL;
-VLANState *vlan = NULL;
+VLANClientState *peer = NULL;
 int ret;
 
 qemu_opts_validate(opts, &net_client_types[i].desc[0], &local_err);
@@ -1146,12 +1149,12 @@ int net_client_init(QemuOpts *opts, int is_netdev, 
Error **errp)
  * netdev= parameter. */
 if (!(is_netdev ||
   (strcmp(type, "nic") == 0 && qemu_opt_get(opts, "netdev" 
{
-vlan = qemu_find_vlan(qemu_opt_get_number(opts, "vlan", 0), 1);
+peer = net_hub_add_port(qemu_opt_get_number(opts, "vlan", 0));
 }
 
 ret = 0;
 if (net_client_types[i].init) {
-ret = net_client_types[i].init(opts, name, vlan);
+ret = net_client_types[i].init(opts, name, peer);
 if (ret < 0) {
 /* TODO push error reporting into init() methods */
 error_set(errp, QERR_DEVICE_INIT_FAILED, type);
@@ -1316,6 +1319,7 @@ void do_info_network(Monitor *mon)
 print_net_client(mon, peer);
 }
 }
+net_hub_info(mon);
 }
 
 void qmp_set_link(const char *name, bool up, Error **errp)
diff --git a/net/dump.c b/net/dump.c
index f835c51..a59133a 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -27,6 +27,7 @@
 #include "qemu-error.h"
 #include "qemu-log.h"
 #include "qemu-timer.h"
+#include "hub.h"
 
 typedef struct DumpState {
 VLANClientState nc;
@@ -99,7 +100,7 @@ static NetClientInfo net_dump_info = {
 .cleanup = dump_cleanup,
 };
 
-static int net_dump_init(VLANState *vlan, const char *device,
+static int net_dump_init(VLANClientState *peer, const char *device,
  const char *name, const char *fil

[Qemu-devel] [PATCH v5 15/17] net: determine if packets can be sent before net queue deliver packets

2012-06-18 Thread zwu . kernel
From: Zhi Yong Wu 

Reviewed-by:   Paolo Bonzini 
Signed-off-by: Zhi Yong Wu 
---
 net/queue.c  |8 
 net/slirp.c  |7 ---
 slirp/if.c   |5 -
 slirp/libslirp.h |1 -
 4 files changed, 4 insertions(+), 17 deletions(-)

diff --git a/net/queue.c b/net/queue.c
index 0afd783..7484d2a 100644
--- a/net/queue.c
+++ b/net/queue.c
@@ -176,8 +176,8 @@ ssize_t qemu_net_queue_send(NetQueue *queue,
 {
 ssize_t ret;
 
-if (queue->delivering) {
-return qemu_net_queue_append(queue, sender, flags, data, size, NULL);
+if (queue->delivering || !qemu_can_send_packet(sender)) {
+return qemu_net_queue_append(queue, sender, flags, data, size, 
sent_cb);
 }
 
 ret = qemu_net_queue_deliver(queue, sender, flags, data, size);
@@ -200,8 +200,8 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue,
 {
 ssize_t ret;
 
-if (queue->delivering) {
-return qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt, 
NULL);
+if (queue->delivering || !qemu_can_send_packet(sender)) {
+return qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt, 
sent_cb);
 }
 
 ret = qemu_net_queue_deliver_iov(queue, sender, flags, iov, iovcnt);
diff --git a/net/slirp.c b/net/slirp.c
index 2df50a8..1e5cabb 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -96,13 +96,6 @@ static void slirp_smb_cleanup(SlirpState *s);
 static inline void slirp_smb_cleanup(SlirpState *s) { }
 #endif
 
-int slirp_can_output(void *opaque)
-{
-SlirpState *s = opaque;
-
-return qemu_can_send_packet(&s->nc);
-}
-
 void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
 {
 SlirpState *s = opaque;
diff --git a/slirp/if.c b/slirp/if.c
index 096cf6f..533295d 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -177,11 +177,6 @@ void if_start(Slirp *slirp)
 }
 
 while (ifm_next) {
-/* check if we can really output */
-if (!slirp_can_output(slirp->opaque)) {
-break;
-}
-
 ifm = ifm_next;
 from_batchq = next_from_batchq;
 
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 77527ad..9b471b5 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -25,7 +25,6 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, 
fd_set *xfds,
 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
 
 /* you must provide the following functions: */
-int slirp_can_output(void *opaque);
 void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len);
 
 int slirp_add_hostfwd(Slirp *slirp, int is_udp,
-- 
1.7.6




[Qemu-devel] [PATCH v5 06/17] net: Remove vlan qdev property

2012-06-18 Thread zwu . kernel
From: Stefan Hajnoczi 

The vlan feature is implemented using hubs and no longer uses
special-purpose VLANState structs that are accessible as qdev
properties.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 hw/qdev-properties.c |   72 --
 hw/qdev.c|2 -
 hw/qdev.h|4 ---
 net.h|3 --
 4 files changed, 0 insertions(+), 81 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 9ae3187..6624dd5 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -591,71 +591,6 @@ PropertyInfo qdev_prop_netdev = {
 .set   = set_netdev,
 };
 
-/* --- vlan --- */
-
-static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
-VLANState **ptr = qdev_get_prop_ptr(dev, prop);
-
-if (*ptr) {
-return snprintf(dest, len, "%d", (*ptr)->id);
-} else {
-return snprintf(dest, len, "");
-}
-}
-
-static void get_vlan(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
-{
-DeviceState *dev = DEVICE(obj);
-Property *prop = opaque;
-VLANState **ptr = qdev_get_prop_ptr(dev, prop);
-int64_t id;
-
-id = *ptr ? (*ptr)->id : -1;
-visit_type_int64(v, &id, name, errp);
-}
-
-static void set_vlan(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
-{
-DeviceState *dev = DEVICE(obj);
-Property *prop = opaque;
-VLANState **ptr = qdev_get_prop_ptr(dev, prop);
-Error *local_err = NULL;
-int64_t id;
-VLANState *vlan;
-
-if (dev->state != DEV_STATE_CREATED) {
-error_set(errp, QERR_PERMISSION_DENIED);
-return;
-}
-
-visit_type_int64(v, &id, name, &local_err);
-if (local_err) {
-error_propagate(errp, local_err);
-return;
-}
-if (id == -1) {
-*ptr = NULL;
-return;
-}
-vlan = qemu_find_vlan(id, 1);
-if (!vlan) {
-error_set(errp, QERR_INVALID_PARAMETER_VALUE,
-  name, prop->info->name);
-return;
-}
-*ptr = vlan;
-}
-
-PropertyInfo qdev_prop_vlan = {
-.name  = "vlan",
-.print = print_vlan,
-.get   = get_vlan,
-.set   = set_vlan,
-};
-
 /* --- pointer --- */
 
 /* Not a proper property, just for dirty hacks.  TODO Remove it!  */
@@ -1065,13 +1000,6 @@ void qdev_prop_set_netdev(DeviceState *dev, const char 
*name, VLANClientState *v
 assert_no_error(errp);
 }
 
-void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
-{
-Error *errp = NULL;
-object_property_set_int(OBJECT(dev), value ? value->id : -1, name, &errp);
-assert_no_error(errp);
-}
-
 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
 {
 Error *errp = NULL;
diff --git a/hw/qdev.c b/hw/qdev.c
index 6a8f6bd..49dd303 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -316,8 +316,6 @@ void qdev_connect_gpio_out(DeviceState * dev, int n, 
qemu_irq pin)
 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
 {
 qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
-if (nd->vlan)
-qdev_prop_set_vlan(dev, "vlan", nd->vlan);
 if (nd->netdev)
 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
diff --git a/hw/qdev.h b/hw/qdev.h
index 5386b16..0510eb7 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -220,7 +220,6 @@ extern PropertyInfo qdev_prop_macaddr;
 extern PropertyInfo qdev_prop_losttickpolicy;
 extern PropertyInfo qdev_prop_drive;
 extern PropertyInfo qdev_prop_netdev;
-extern PropertyInfo qdev_prop_vlan;
 extern PropertyInfo qdev_prop_pci_devfn;
 extern PropertyInfo qdev_prop_blocksize;
 
@@ -275,8 +274,6 @@ extern PropertyInfo qdev_prop_blocksize;
 DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
 #define DEFINE_PROP_NETDEV(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, VLANClientState*)
-#define DEFINE_PROP_VLAN(_n, _s, _f) \
-DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, VLANState*)
 #define DEFINE_PROP_DRIVE(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *)
 #define DEFINE_PROP_MACADDR(_n, _s, _f) \
@@ -303,7 +300,6 @@ void qdev_prop_set_uint64(DeviceState *dev, const char 
*name, uint64_t value);
 void qdev_prop_set_string(DeviceState *dev, const char *name, char *value);
 void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState 
*value);
 void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState 
*value);
-void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value);
 int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState 
*value) QEMU_WARN_UNUSED_RESULT;
 void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, 
BlockDriverState *value);
 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
diff --git a/net.h

[Qemu-devel] [PATCH 08/17] net: Remove VLANState

2012-06-19 Thread zwu . kernel
From: Stefan Hajnoczi 

VLANState is no longer used and can be removed.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 hw/dp8393x.c|1 -
 hw/exynos4_boards.c |2 +-
 hw/highbank.c   |2 +-
 hw/integratorcp.c   |2 +-
 hw/mcf5208.c|2 +-
 hw/mcf_fec.c|1 -
 hw/mips_mipssim.c   |2 +-
 hw/mips_r4k.c   |2 +-
 hw/vexpress.c   |2 +-
 hw/xtensa_lx60.c|2 +-
 net.c   |  127 +--
 net.h   |8 ---
 net/socket.c|6 +-
 net/tap.c   |6 +-
 net/tap.h   |2 +-
 qemu-common.h   |1 -
 16 files changed, 37 insertions(+), 131 deletions(-)

diff --git a/hw/dp8393x.c b/hw/dp8393x.c
index 017d074..3fd7677 100644
--- a/hw/dp8393x.c
+++ b/hw/dp8393x.c
@@ -899,7 +899,6 @@ void dp83932_init(NICInfo *nd, target_phys_addr_t base, int 
it_shift,
 s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
 
 s->conf.macaddr = nd->macaddr;
-s->conf.vlan = nd->vlan;
 s->conf.peer = nd->netdev;
 
 s->nic = qemu_new_nic(&net_dp83932_info, &s->conf, nd->model, nd->name, s);
diff --git a/hw/exynos4_boards.c b/hw/exynos4_boards.c
index e5c2a5f..4bb0a60 100644
--- a/hw/exynos4_boards.c
+++ b/hw/exynos4_boards.c
@@ -81,7 +81,7 @@ static void lan9215_init(uint32_t base, qemu_irq irq)
 SysBusDevice *s;
 
 /* This should be a 9215 but the 9118 is close enough */
-if (nd_table[0].vlan) {
+if (nd_table[0].used) {
 qemu_check_nic_model(&nd_table[0], "lan9118");
 dev = qdev_create(NULL, "lan9118");
 qdev_set_nic_properties(dev, &nd_table[0]);
diff --git a/hw/highbank.c b/hw/highbank.c
index 4bdea5d..11aa131 100644
--- a/hw/highbank.c
+++ b/hw/highbank.c
@@ -284,7 +284,7 @@ static void highbank_init(ram_addr_t ram_size,
 
 sysbus_create_simple("sysbus-ahci", 0xffe08000, pic[83]);
 
-if (nd_table[0].vlan) {
+if (nd_table[0].used) {
 qemu_check_nic_model(&nd_table[0], "xgmac");
 dev = qdev_create(NULL, "xgmac");
 qdev_set_nic_properties(dev, &nd_table[0]);
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index deacbf4..d0e2e90 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -493,7 +493,7 @@ static void integratorcp_init(ram_addr_t ram_size,
 sysbus_create_simple("pl050_keyboard", 0x1800, pic[3]);
 sysbus_create_simple("pl050_mouse", 0x1900, pic[4]);
 sysbus_create_varargs("pl181", 0x1c00, pic[23], pic[24], NULL);
-if (nd_table[0].vlan)
+if (nd_table[0].used)
 smc91c111_init(&nd_table[0], 0xc800, pic[27]);
 
 sysbus_create_simple("pl110", 0xc000, pic[22]);
diff --git a/hw/mcf5208.c b/hw/mcf5208.c
index d3ebe8d..ee25b1b 100644
--- a/hw/mcf5208.c
+++ b/hw/mcf5208.c
@@ -236,7 +236,7 @@ static void mcf5208evb_init(ram_addr_t ram_size,
 fprintf(stderr, "Too many NICs\n");
 exit(1);
 }
-if (nd_table[0].vlan)
+if (nd_table[0].used)
 mcf_fec_init(address_space_mem, &nd_table[0],
  0xfc03, pic + 36);
 
diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c
index ae37bef..739b349 100644
--- a/hw/mcf_fec.c
+++ b/hw/mcf_fec.c
@@ -472,7 +472,6 @@ void mcf_fec_init(MemoryRegion *sysmem, NICInfo *nd,
 memory_region_add_subregion(sysmem, base, &s->iomem);
 
 s->conf.macaddr = nd->macaddr;
-s->conf.vlan = nd->vlan;
 s->conf.peer = nd->netdev;
 
 s->nic = qemu_new_nic(&net_mcf_fec_info, &s->conf, nd->model, nd->name, s);
diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c
index eb03047..830f635 100644
--- a/hw/mips_mipssim.c
+++ b/hw/mips_mipssim.c
@@ -217,7 +217,7 @@ mips_mipssim_init (ram_addr_t ram_size,
 if (serial_hds[0])
 serial_init(0x3f8, env->irq[4], 115200, serial_hds[0]);
 
-if (nd_table[0].vlan)
+if (nd_table[0].used)
 /* MIPSnet uses the MIPS CPU INT0, which is interrupt 2. */
 mipsnet_init(0x4200, env->irq[2], &nd_table[0]);
 }
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index d685999..967a76e 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -283,7 +283,7 @@ void mips_r4k_init (ram_addr_t ram_size,
 
 isa_vga_init(isa_bus);
 
-if (nd_table[0].vlan)
+if (nd_table[0].used)
 isa_ne2000_init(isa_bus, 0x300, 9, &nd_table[0]);
 
 ide_drive_get(hd, MAX_IDE_BUS);
diff --git a/hw/vexpress.c b/hw/vexpress.c
index 8072c5a..12aa2d5 100644
--- a/hw/vexpress.c
+++ b/hw/vexpress.c
@@ -420,7 +420,7 @@ static void vexpress_common_init(const VEDBoardInfo 
*daughterboard,
 memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram);
 
 /* 0x4e00 LAN9118 Ethernet */
-if (nd_table[0].vlan) {
+if (nd_table[0].used) {
 lan9118_init(&nd_table[0], map[VE_ETHERNET], pic[15]);
 }
 
diff --git a/hw/xtensa_lx60.c b/hw/xtensa_lx60.c
index 152eed9..c4f616f 100644
--- a/hw/xtensa_lx60.c
+++ b/hw/xtensa_lx60.c
@@ -201,7 +201,7 @@ static void lx_init(const LxBoardDesc 

[Qemu-devel] [PATCH v2 1/3] net: fix the coding style

2012-06-20 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 net/socket.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index dc5ba40..ba8583f 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -301,7 +301,9 @@ static NetSocketState 
*net_socket_fd_init_dgram(NetClientState *peer,
 qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
 
 /* mcast: save bound address as dst */
-if (is_connected) s->dgram_dst=saddr;
+if (is_connected) {
+s->dgram_dst = saddr;
+}
 
 return s;
 
-- 
1.7.6




[Qemu-devel] [PATCH v2 2/3] net: add the support for -netdev socket, listen

2012-06-20 Thread zwu . kernel
From: Zhi Yong Wu 

The -net socket,listen option does not work with the newer -netdev
syntax:
 http://lists.gnu.org/archive/html/qemu-devel/2011-11/msg01508.html

This patch makes it work now.

For the case where one vlan has multiple listenning sockets,
the patch will also provide the support.

Supported syntax:
 1.) -net socket,listen=127.0.0.1:1234,vlan=0
 2.) -net socket,listen=127.0.0.1:1234,vlan=0 -net 
socket,listen=127.0.0.1:1235,vlan=0
 3.) -netdev socket,listen=127.0.0.1:1234,id=socket0

 Drop the NetSocketListenState struct and add a listen_fd field
to NetSocketState.  When a -netdev socket,listen= instance is created
there will be a NetSocketState with fd=-1 and a valid listen_fd.  The
net_socket_accept() handler waits for listen_fd to become readable and
then accepts the connection.  When this state transition happens, we no
longer monitor listen_fd for incoming connections...until the client
disconnects again.

Suggested-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net/socket.c |   60 +
 1 files changed, 31 insertions(+), 29 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index ba8583f..e61e346 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -35,6 +35,7 @@
 
 typedef struct NetSocketState {
 NetClientState nc;
+int listen_fd;
 int fd;
 int state; /* 0 = getting length, 1 = getting data */
 unsigned int index;
@@ -43,12 +44,7 @@ typedef struct NetSocketState {
 struct sockaddr_in dgram_dst; /* contains inet host and port destination 
iff connectionless (SOCK_DGRAM) */
 } NetSocketState;
 
-typedef struct NetSocketListenState {
-NetClientState *peer;
-char *model;
-char *name;
-int fd;
-} NetSocketListenState;
+static void net_socket_accept(void *opaque);
 
 /* XXX: we consider we can send the whole packet without blocking */
 static ssize_t net_socket_receive(NetClientState *nc, const uint8_t *buf, 
size_t size)
@@ -86,7 +82,16 @@ static void net_socket_send(void *opaque)
 /* end of connection */
 eoc:
 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
+qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
 closesocket(s->fd);
+
+s->fd = -1;
+s->state = 0;
+s->index = 0;
+s->packet_len = 0;
+memset(s->buf, 0, sizeof(s->buf));
+memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
+
 return;
 }
 buf = buf1;
@@ -377,29 +382,28 @@ static NetSocketState *net_socket_fd_init(NetClientState 
*peer,
 
 static void net_socket_accept(void *opaque)
 {
-NetSocketListenState *s = opaque;
-NetSocketState *s1;
+NetSocketState *s = opaque;
 struct sockaddr_in saddr;
 socklen_t len;
 int fd;
 
 for(;;) {
 len = sizeof(saddr);
-fd = qemu_accept(s->fd, (struct sockaddr *)&saddr, &len);
+fd = qemu_accept(s->listen_fd, (struct sockaddr *)&saddr, &len);
 if (fd < 0 && errno != EINTR) {
 return;
 } else if (fd >= 0) {
+qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
 break;
 }
 }
-s1 = net_socket_fd_init(s->peer, s->model, s->name, fd, 1);
-if (!s1) {
-closesocket(fd);
-} else {
-snprintf(s1->nc.info_str, sizeof(s1->nc.info_str),
- "socket: connection from %s:%d",
- inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
-}
+
+s->fd = fd;
+s->nc.link_down = false;
+net_socket_connect(s);
+snprintf(s->nc.info_str, sizeof(s->nc.info_str),
+ "socket: connection from %s:%d",
+ inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
 }
 
 static int net_socket_listen_init(NetClientState *peer,
@@ -407,19 +411,17 @@ static int net_socket_listen_init(NetClientState *peer,
   const char *name,
   const char *host_str)
 {
-NetSocketListenState *s;
-int fd, val, ret;
+NetClientState *nc;
+NetSocketState *s;
 struct sockaddr_in saddr;
+int fd, val, ret;
 
 if (parse_host_port(&saddr, host_str) < 0)
 return -1;
 
-s = g_malloc0(sizeof(NetSocketListenState));
-
 fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
 if (fd < 0) {
 perror("socket");
-g_free(s);
 return -1;
 }
 socket_set_nonblock(fd);
@@ -431,22 +433,22 @@ static int net_socket_listen_init(NetClientState *peer,
 ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
 if (ret < 0) {
 perror("bind");
-g_free(s);
 closesocket(fd);
 return -1;
 }
 ret = listen(fd, 0);
 if (ret < 0) {
 perror("listen");
-g_free(s);
 closesocket(fd);
 return -1;
 }
-s->peer = peer;
-s->model = g_strdup(model);
-s->name = name ? g_strdup(name) : NULL;
-s->fd = fd;
-qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
+
+n

[Qemu-devel] [PATCH v2 0/3] Some socket fix patches

2012-06-20 Thread zwu . kernel
From: Zhi Yong Wu 

The patchset is on top of hub-based networking patchset.

For this patchset, my git repo:

g...@github.com:wuzhy/qemu.git for-anthony

Zhi Yong Wu (3):
  net: fix the coding style
  net: add the support for -netdev socket, listen
  net: complete NetSocketState lifecycle handling

 net/socket.c |   82 +++--
 1 files changed, 50 insertions(+), 32 deletions(-)

-- 
1.7.6




[Qemu-devel] [PATCH v2 3/3] net: complete NetSocketState lifecycle handling

2012-06-20 Thread zwu . kernel
From: Zhi Yong Wu 

The NetSocketState struct contains two file descriptors: an active
connection and a listen socket for new connections.  It's important that
we clean up after ourselves so these file descriptors are initialized to
-1 when unused.  This allows makes it possible to call cleanup functions
only when the file descriptors are valid (not -1).

The specific issue solved by this patch is that we avoid calling
close(-1), close(0), and qemu_set_fd_handler(-1, net_socket_accept,
NULL, s).  All of these are either problematic or unclean (e.g. reported
as warnings by Valgrind).

Also stay consistent by bringing the link down when the active
connection is closed.

Signed-off-by: Stefan Hajnoczi 
---
 net/socket.c |   20 +---
 1 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index e61e346..9b15479 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -82,13 +82,16 @@ static void net_socket_send(void *opaque)
 /* end of connection */
 eoc:
 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
-qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
+if (s->listen_fd != -1) {
+qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
+}
 closesocket(s->fd);
 
 s->fd = -1;
 s->state = 0;
 s->index = 0;
 s->packet_len = 0;
+s->nc.link_down = true;
 memset(s->buf, 0, sizeof(s->buf));
 memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
 
@@ -239,8 +242,16 @@ fail:
 static void net_socket_cleanup(NetClientState *nc)
 {
 NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
-qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
-close(s->fd);
+if (s->fd != -1) {
+qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
+close(s->fd);
+s->fd = -1;
+}
+if (s->listen_fd != -1) {
+qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
+closesocket(s->listen_fd);
+s->listen_fd = -1;
+}
 }
 
 static NetClientInfo net_dgram_socket_info = {
@@ -302,6 +313,7 @@ static NetSocketState 
*net_socket_fd_init_dgram(NetClientState *peer,
 s = DO_UPCAST(NetSocketState, nc, nc);
 
 s->fd = fd;
+s->listen_fd = -1;
 
 qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
 
@@ -345,6 +357,7 @@ static NetSocketState 
*net_socket_fd_init_stream(NetClientState *peer,
 s = DO_UPCAST(NetSocketState, nc, nc);
 
 s->fd = fd;
+s->listen_fd = -1;
 
 if (is_connected) {
 net_socket_connect(s);
@@ -445,6 +458,7 @@ static int net_socket_listen_init(NetClientState *peer,
 
 nc = qemu_new_net_client(&net_socket_info, peer, model, name);
 s = DO_UPCAST(NetSocketState, nc, nc);
+s->fd = -1;
 s->listen_fd = fd;
 s->nc.link_down = true;
 
-- 
1.7.6




[Qemu-devel] [PATCH v6 08/17] net: Remove VLANState

2012-06-20 Thread zwu . kernel
From: Stefan Hajnoczi 

VLANState is no longer used and can be removed.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 hw/dp8393x.c|1 -
 hw/exynos4_boards.c |2 +-
 hw/highbank.c   |2 +-
 hw/integratorcp.c   |2 +-
 hw/mcf5208.c|2 +-
 hw/mcf_fec.c|1 -
 hw/mips_mipssim.c   |2 +-
 hw/mips_r4k.c   |2 +-
 hw/vexpress.c   |2 +-
 hw/xtensa_lx60.c|2 +-
 net.c   |  127 +--
 net.h   |8 ---
 net/socket.c|6 +-
 net/tap.c   |6 +-
 net/tap.h   |2 +-
 qemu-common.h   |1 -
 16 files changed, 37 insertions(+), 131 deletions(-)

diff --git a/hw/dp8393x.c b/hw/dp8393x.c
index 017d074..3fd7677 100644
--- a/hw/dp8393x.c
+++ b/hw/dp8393x.c
@@ -899,7 +899,6 @@ void dp83932_init(NICInfo *nd, target_phys_addr_t base, int 
it_shift,
 s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
 
 s->conf.macaddr = nd->macaddr;
-s->conf.vlan = nd->vlan;
 s->conf.peer = nd->netdev;
 
 s->nic = qemu_new_nic(&net_dp83932_info, &s->conf, nd->model, nd->name, s);
diff --git a/hw/exynos4_boards.c b/hw/exynos4_boards.c
index e5c2a5f..4bb0a60 100644
--- a/hw/exynos4_boards.c
+++ b/hw/exynos4_boards.c
@@ -81,7 +81,7 @@ static void lan9215_init(uint32_t base, qemu_irq irq)
 SysBusDevice *s;
 
 /* This should be a 9215 but the 9118 is close enough */
-if (nd_table[0].vlan) {
+if (nd_table[0].used) {
 qemu_check_nic_model(&nd_table[0], "lan9118");
 dev = qdev_create(NULL, "lan9118");
 qdev_set_nic_properties(dev, &nd_table[0]);
diff --git a/hw/highbank.c b/hw/highbank.c
index 4bdea5d..11aa131 100644
--- a/hw/highbank.c
+++ b/hw/highbank.c
@@ -284,7 +284,7 @@ static void highbank_init(ram_addr_t ram_size,
 
 sysbus_create_simple("sysbus-ahci", 0xffe08000, pic[83]);
 
-if (nd_table[0].vlan) {
+if (nd_table[0].used) {
 qemu_check_nic_model(&nd_table[0], "xgmac");
 dev = qdev_create(NULL, "xgmac");
 qdev_set_nic_properties(dev, &nd_table[0]);
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index deacbf4..d0e2e90 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -493,7 +493,7 @@ static void integratorcp_init(ram_addr_t ram_size,
 sysbus_create_simple("pl050_keyboard", 0x1800, pic[3]);
 sysbus_create_simple("pl050_mouse", 0x1900, pic[4]);
 sysbus_create_varargs("pl181", 0x1c00, pic[23], pic[24], NULL);
-if (nd_table[0].vlan)
+if (nd_table[0].used)
 smc91c111_init(&nd_table[0], 0xc800, pic[27]);
 
 sysbus_create_simple("pl110", 0xc000, pic[22]);
diff --git a/hw/mcf5208.c b/hw/mcf5208.c
index d3ebe8d..ee25b1b 100644
--- a/hw/mcf5208.c
+++ b/hw/mcf5208.c
@@ -236,7 +236,7 @@ static void mcf5208evb_init(ram_addr_t ram_size,
 fprintf(stderr, "Too many NICs\n");
 exit(1);
 }
-if (nd_table[0].vlan)
+if (nd_table[0].used)
 mcf_fec_init(address_space_mem, &nd_table[0],
  0xfc03, pic + 36);
 
diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c
index ae37bef..739b349 100644
--- a/hw/mcf_fec.c
+++ b/hw/mcf_fec.c
@@ -472,7 +472,6 @@ void mcf_fec_init(MemoryRegion *sysmem, NICInfo *nd,
 memory_region_add_subregion(sysmem, base, &s->iomem);
 
 s->conf.macaddr = nd->macaddr;
-s->conf.vlan = nd->vlan;
 s->conf.peer = nd->netdev;
 
 s->nic = qemu_new_nic(&net_mcf_fec_info, &s->conf, nd->model, nd->name, s);
diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c
index eb03047..830f635 100644
--- a/hw/mips_mipssim.c
+++ b/hw/mips_mipssim.c
@@ -217,7 +217,7 @@ mips_mipssim_init (ram_addr_t ram_size,
 if (serial_hds[0])
 serial_init(0x3f8, env->irq[4], 115200, serial_hds[0]);
 
-if (nd_table[0].vlan)
+if (nd_table[0].used)
 /* MIPSnet uses the MIPS CPU INT0, which is interrupt 2. */
 mipsnet_init(0x4200, env->irq[2], &nd_table[0]);
 }
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index d685999..967a76e 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -283,7 +283,7 @@ void mips_r4k_init (ram_addr_t ram_size,
 
 isa_vga_init(isa_bus);
 
-if (nd_table[0].vlan)
+if (nd_table[0].used)
 isa_ne2000_init(isa_bus, 0x300, 9, &nd_table[0]);
 
 ide_drive_get(hd, MAX_IDE_BUS);
diff --git a/hw/vexpress.c b/hw/vexpress.c
index 8072c5a..12aa2d5 100644
--- a/hw/vexpress.c
+++ b/hw/vexpress.c
@@ -420,7 +420,7 @@ static void vexpress_common_init(const VEDBoardInfo 
*daughterboard,
 memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram);
 
 /* 0x4e00 LAN9118 Ethernet */
-if (nd_table[0].vlan) {
+if (nd_table[0].used) {
 lan9118_init(&nd_table[0], map[VE_ETHERNET], pic[15]);
 }
 
diff --git a/hw/xtensa_lx60.c b/hw/xtensa_lx60.c
index 152eed9..c4f616f 100644
--- a/hw/xtensa_lx60.c
+++ b/hw/xtensa_lx60.c
@@ -201,7 +201,7 @@ static void lx_init(const LxBoardDesc 

[Qemu-devel] [PATCH v6 11/17] net: Rename vc local variables to nc

2012-06-20 Thread zwu . kernel
From: Stefan Hajnoczi 

Now that VLANClientState has been renamed to NetClientState all 'vc'
local variables should be 'nc'.  Much of the code already used 'nc' but
there are places where 'vc' needs to be renamed.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 hw/ne2000.h |4 +-
 hw/vhost_net.c  |   18 +++---
 net.c   |  206 +++---
 net.h   |   20 +++---
 net/tap-win32.c |8 +-
 net/tap.h   |   16 ++--
 6 files changed, 136 insertions(+), 136 deletions(-)

diff --git a/hw/ne2000.h b/hw/ne2000.h
index 6c196a2..1e7ab07 100644
--- a/hw/ne2000.h
+++ b/hw/ne2000.h
@@ -31,5 +31,5 @@ typedef struct NE2000State {
 void ne2000_setup_io(NE2000State *s, unsigned size);
 extern const VMStateDescription vmstate_ne2000;
 void ne2000_reset(NE2000State *s);
-int ne2000_can_receive(NetClientState *vc);
-ssize_t ne2000_receive(NetClientState *vc, const uint8_t *buf, size_t size_);
+int ne2000_can_receive(NetClientState *nc);
+ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_);
diff --git a/hw/vhost_net.c b/hw/vhost_net.c
index c3e6546..c2d90df 100644
--- a/hw/vhost_net.c
+++ b/hw/vhost_net.c
@@ -42,7 +42,7 @@ struct vhost_net {
 struct vhost_dev dev;
 struct vhost_virtqueue vqs[2];
 int backend;
-NetClientState *vc;
+NetClientState *nc;
 };
 
 unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
@@ -104,7 +104,7 @@ struct vhost_net *vhost_net_init(NetClientState *backend, 
int devfd,
 if (r < 0) {
 goto fail;
 }
-net->vc = backend;
+net->nc = backend;
 net->dev.backend_features = tap_has_vnet_hdr(backend) ? 0 :
 (1 << VHOST_NET_F_VIRTIO_NET_HDR);
 net->backend = r;
@@ -151,7 +151,7 @@ int vhost_net_start(struct vhost_net *net,
 goto fail_notifiers;
 }
 if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
-tap_set_vnet_hdr_len(net->vc,
+tap_set_vnet_hdr_len(net->nc,
  sizeof(struct virtio_net_hdr_mrg_rxbuf));
 }
 
@@ -160,7 +160,7 @@ int vhost_net_start(struct vhost_net *net,
 goto fail_start;
 }
 
-net->vc->info->poll(net->vc, false);
+net->nc->info->poll(net->nc, false);
 qemu_set_fd_handler(net->backend, NULL, NULL, NULL);
 file.fd = net->backend;
 for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
@@ -177,10 +177,10 @@ fail:
 int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
 assert(r >= 0);
 }
-net->vc->info->poll(net->vc, true);
+net->nc->info->poll(net->nc, true);
 vhost_dev_stop(&net->dev, dev);
 if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
-tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
+tap_set_vnet_hdr_len(net->nc, sizeof(struct virtio_net_hdr));
 }
 fail_start:
 vhost_dev_disable_notifiers(&net->dev, dev);
@@ -197,10 +197,10 @@ void vhost_net_stop(struct vhost_net *net,
 int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
 assert(r >= 0);
 }
-net->vc->info->poll(net->vc, true);
+net->nc->info->poll(net->nc, true);
 vhost_dev_stop(&net->dev, dev);
 if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
-tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
+tap_set_vnet_hdr_len(net->nc, sizeof(struct virtio_net_hdr));
 }
 vhost_dev_disable_notifiers(&net->dev, dev);
 }
@@ -209,7 +209,7 @@ void vhost_net_cleanup(struct vhost_net *net)
 {
 vhost_dev_cleanup(&net->dev);
 if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
-tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
+tap_set_vnet_hdr_len(net->nc, sizeof(struct virtio_net_hdr));
 }
 g_free(net);
 }
diff --git a/net.c b/net.c
index b35339a..7fd0fde 100644
--- a/net.c
+++ b/net.c
@@ -129,11 +129,11 @@ int parse_host_port(struct sockaddr_in *saddr, const char 
*str)
 return 0;
 }
 
-void qemu_format_nic_info_str(NetClientState *vc, uint8_t macaddr[6])
+void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6])
 {
-snprintf(vc->info_str, sizeof(vc->info_str),
+snprintf(nc->info_str, sizeof(nc->info_str),
  "model=%s,macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
- vc->model,
+ nc->model,
  macaddr[0], macaddr[1], macaddr[2],
  macaddr[3], macaddr[4], macaddr[5]);
 }
@@ -159,19 +159,19 @@ void qemu_macaddr_default_if_unset(MACAddr *macaddr)
  * Only net clients created with the legacy -net option need this.  Naming is
  * mandatory for net clients created with -netdev.
  */
-static char *assign_name(NetClientState *vc1, const char *model)
+static char *assign_name(NetClientState *nc1, const char *model)
 {
-NetClientState *vc;
+NetClientState *nc;
 char buf[256];
 int id = 0;
 
-QTAILQ_FOREACH(vc, &net_clients, 

[Qemu-devel] [PATCH v6 04/17] hub: Check that hubs are configured correctly

2012-06-20 Thread zwu . kernel
From: Stefan Hajnoczi 

Checks can be performed to make sure that hubs have at least one NIC and
one host device, warning the user if this is not the case.
Configurations which do not meet this rule tend to be broken but just
emit a warning.  This patch preserves compatibility with the checks
performed by net core on vlans.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c |   25 +
 net/hub.c |   45 +
 net/hub.h |1 +
 3 files changed, 47 insertions(+), 24 deletions(-)

diff --git a/net.c b/net.c
index f80a0c0..d6bb480 100644
--- a/net.c
+++ b/net.c
@@ -1356,7 +1356,6 @@ void net_cleanup(void)
 
 void net_check_clients(void)
 {
-VLANState *vlan;
 VLANClientState *vc;
 int i;
 
@@ -1372,30 +1371,8 @@ void net_check_clients(void)
 return;
 }
 
-QTAILQ_FOREACH(vlan, &vlans, next) {
-int has_nic = 0, has_host_dev = 0;
+net_hub_check_clients();
 
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-switch (vc->info->type) {
-case NET_CLIENT_TYPE_NIC:
-has_nic = 1;
-break;
-case NET_CLIENT_TYPE_USER:
-case NET_CLIENT_TYPE_TAP:
-case NET_CLIENT_TYPE_SOCKET:
-case NET_CLIENT_TYPE_VDE:
-has_host_dev = 1;
-break;
-default: ;
-}
-}
-if (has_host_dev && !has_nic)
-fprintf(stderr, "Warning: vlan %d with no nics\n", vlan->id);
-if (has_nic && !has_host_dev)
-fprintf(stderr,
-"Warning: vlan %d is not connected to host network\n",
-vlan->id);
-}
 QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
 if (!vc->peer) {
 fprintf(stderr, "Warning: %s %s has no peer\n",
diff --git a/net/hub.c b/net/hub.c
index 56efc2c..e4a3980 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -223,3 +223,48 @@ int net_hub_id_for_client(VLANClientState *nc, unsigned 
int *id)
 }
 return -ENOENT;
 }
+
+/**
+ * Warn if hub configurations are likely wrong
+ */
+void net_hub_check_clients(void)
+{
+NetHub *hub;
+NetHubPort *port;
+VLANClientState *peer;
+
+QLIST_FOREACH(hub, &hubs, next) {
+int has_nic = 0, has_host_dev = 0;
+
+QLIST_FOREACH(port, &hub->ports, next) {
+peer = port->nc.peer;
+if (!peer) {
+fprintf(stderr, "Warning: hub port %s has no peer\n",
+port->nc.name);
+continue;
+}
+
+switch (peer->info->type) {
+case NET_CLIENT_TYPE_NIC:
+has_nic = 1;
+break;
+case NET_CLIENT_TYPE_USER:
+case NET_CLIENT_TYPE_TAP:
+case NET_CLIENT_TYPE_SOCKET:
+case NET_CLIENT_TYPE_VDE:
+has_host_dev = 1;
+break;
+default:
+break;
+}
+}
+if (has_host_dev && !has_nic) {
+fprintf(stderr, "Warning: vlan %u with no nics\n", hub->id);
+}
+if (has_nic && !has_host_dev) {
+fprintf(stderr,
+"Warning: vlan %u is not connected to host network\n",
+hub->id);
+}
+}
+}
diff --git a/net/hub.h b/net/hub.h
index e149e04..10bf036 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -22,5 +22,6 @@ VLANClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
  const char *name);
 void net_hub_info(Monitor *mon);
 int net_hub_id_for_client(VLANClientState *nc, unsigned int *id);
+void net_hub_check_clients(void);
 
 #endif /* NET_HUB_H */
-- 
1.7.6




[Qemu-devel] [PATCH v6 16/17] hub: add the support for hub own flow control

2012-06-20 Thread zwu . kernel
From: Zhi Yong Wu 

Only when all other hub port's *peer* .can_receive() all return 1,
the source hub port .can_receive() return 1.

Reviewed-off-by: Paolo Bonzini 
Signed-off-by: Zhi Yong Wu 
---
 net/hub.c |   27 ---
 1 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/net/hub.c b/net/hub.c
index 230d86a..efd90b5 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -15,6 +15,7 @@
 #include "monitor.h"
 #include "net.h"
 #include "hub.h"
+#include "iov.h"
 
 /*
  * A hub broadcasts incoming packets to all its ports except the source port.
@@ -59,16 +60,16 @@ static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort 
*source_port,
const struct iovec *iov, int iovcnt)
 {
 NetHubPort *port;
-ssize_t ret = 0;
+ssize_t len = iov_size(iov, iovcnt);
 
 QLIST_FOREACH(port, &hub->ports, next) {
 if (port == source_port) {
 continue;
 }
 
-ret = qemu_sendv_packet(&port->nc, iov, iovcnt);
+qemu_sendv_packet(&port->nc, iov, iovcnt);
 }
-return ret;
+return len;
 }
 
 static NetHub *net_hub_new(unsigned int id)
@@ -85,6 +86,25 @@ static NetHub *net_hub_new(unsigned int id)
 return hub;
 }
 
+static int net_hub_port_can_receive(NetClientState *nc)
+{
+NetHubPort *port;
+NetHubPort *src_port = DO_UPCAST(NetHubPort, nc, nc);
+NetHub *hub = src_port->hub;
+
+QLIST_FOREACH(port, &hub->ports, next) {
+if (port == src_port) {
+continue;
+}
+
+if (!qemu_can_send_packet(&port->nc)) {
+return 0;
+}
+}
+
+return 1;
+}
+
 static ssize_t net_hub_port_receive(NetClientState *nc,
 const uint8_t *buf, size_t len)
 {
@@ -111,6 +131,7 @@ static void net_hub_port_cleanup(NetClientState *nc)
 static NetClientInfo net_hub_port_info = {
 .type = NET_CLIENT_TYPE_HUB,
 .size = sizeof(NetHubPort),
+.can_receive = net_hub_port_can_receive,
 .receive = net_hub_port_receive,
 .receive_iov = net_hub_port_receive_iov,
 .cleanup = net_hub_port_cleanup,
-- 
1.7.6




[Qemu-devel] [PATCH v6 03/17] net: Look up 'vlan' net clients using hubs

2012-06-20 Thread zwu . kernel
From: Stefan Hajnoczi 

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c   |   28 +---
 net/hub.c   |   24 
 net/hub.h   |2 ++
 net/slirp.c |5 +++--
 4 files changed, 30 insertions(+), 29 deletions(-)

diff --git a/net.c b/net.c
index 9a63d22..f80a0c0 100644
--- a/net.c
+++ b/net.c
@@ -312,32 +312,6 @@ void qemu_del_vlan_client(VLANClientState *vc)
 qemu_free_vlan_client(vc);
 }
 
-VLANClientState *
-qemu_find_vlan_client_by_name(Monitor *mon, int vlan_id,
-  const char *client_str)
-{
-VLANState *vlan;
-VLANClientState *vc;
-
-vlan = qemu_find_vlan(vlan_id, 0);
-if (!vlan) {
-monitor_printf(mon, "unknown VLAN %d\n", vlan_id);
-return NULL;
-}
-
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-if (!strcmp(vc->name, client_str)) {
-break;
-}
-}
-if (!vc) {
-monitor_printf(mon, "can't find device %s on VLAN %d\n",
-   client_str, vlan_id);
-}
-
-return vc;
-}
-
 void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
 {
 VLANClientState *nc;
@@ -1226,7 +1200,7 @@ void net_host_device_remove(Monitor *mon, const QDict 
*qdict)
 int vlan_id = qdict_get_int(qdict, "vlan_id");
 const char *device = qdict_get_str(qdict, "device");
 
-vc = qemu_find_vlan_client_by_name(mon, vlan_id, device);
+vc = net_hub_find_client_by_name(vlan_id, device);
 if (!vc) {
 return;
 }
diff --git a/net/hub.c b/net/hub.c
index 28ff45c..56efc2c 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -160,6 +160,30 @@ VLANClientState *net_hub_add_port(unsigned int hub_id)
 }
 
 /**
+ * Find a specific client on a hub
+ */
+VLANClientState *net_hub_find_client_by_name(unsigned int hub_id,
+ const char *name)
+{
+NetHub *hub;
+NetHubPort *port;
+VLANClientState *peer;
+
+QLIST_FOREACH(hub, &hubs, next) {
+if (hub->id == hub_id) {
+QLIST_FOREACH(port, &hub->ports, next) {
+peer = port->nc.peer;
+
+if (peer && strcmp(peer->name, name) == 0) {
+return peer;
+}
+}
+}
+}
+return NULL;
+}
+
+/**
  * Print hub configuration
  */
 void net_hub_info(Monitor *mon)
diff --git a/net/hub.h b/net/hub.h
index bf8798b..e149e04 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -18,6 +18,8 @@
 #include "qemu-common.h"
 
 VLANClientState *net_hub_add_port(unsigned int hub_id);
+VLANClientState *net_hub_find_client_by_name(unsigned int hub_id,
+ const char *name);
 void net_hub_info(Monitor *mon);
 int net_hub_id_for_client(VLANClientState *nc, unsigned int *id);
 
diff --git a/net/slirp.c b/net/slirp.c
index 70e7c94..c8c557a 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -29,6 +29,7 @@
 #include 
 #endif
 #include "net.h"
+#include "net/hub.h"
 #include "monitor.h"
 #include "qemu_socket.h"
 #include "slirp/libslirp.h"
@@ -283,7 +284,7 @@ static SlirpState *slirp_lookup(Monitor *mon, const char 
*vlan,
 
 if (vlan) {
 VLANClientState *nc;
-nc = qemu_find_vlan_client_by_name(mon, strtol(vlan, NULL, 0), stack);
+nc = net_hub_find_client_by_name(strtol(vlan, NULL, 0), stack);
 if (!nc) {
 return NULL;
 }
@@ -648,7 +649,7 @@ void do_info_usernet(Monitor *mon)
 
 QTAILQ_FOREACH(s, &slirp_stacks, entry) {
 monitor_printf(mon, "VLAN %d (%s):\n",
-   s->nc.vlan ? s->nc.vlan->id : -1,
+   -1, /* TODO */
s->nc.name);
 slirp_connection_info(s->slirp, mon);
 }
-- 
1.7.6




[Qemu-devel] [PATCH v6 14/17] net: cleanup deliver/deliver_iov func pointers

2012-06-20 Thread zwu . kernel
From: Zhi Yong Wu 

Reviewed-by:   Paolo Bonzini 
Signed-off-by: Zhi Yong Wu 
---
 net.c   |   35 +++
 net.h   |   11 +++
 net/queue.c |   13 -
 net/queue.h |   17 ++---
 4 files changed, 28 insertions(+), 48 deletions(-)

diff --git a/net.c b/net.c
index d0be471..6bbc9fc 100644
--- a/net.c
+++ b/net.c
@@ -181,17 +181,6 @@ static char *assign_name(NetClientState *nc1, const char 
*model)
 return g_strdup(buf);
 }
 
-static ssize_t qemu_deliver_packet(NetClientState *sender,
-   unsigned flags,
-   const uint8_t *data,
-   size_t size,
-   void *opaque);
-static ssize_t qemu_deliver_packet_iov(NetClientState *sender,
-   unsigned flags,
-   const struct iovec *iov,
-   int iovcnt,
-   void *opaque);
-
 NetClientState *qemu_new_net_client(NetClientInfo *info,
 NetClientState *peer,
 const char *model,
@@ -218,9 +207,7 @@ NetClientState *qemu_new_net_client(NetClientInfo *info,
 }
 QTAILQ_INSERT_TAIL(&net_clients, nc, next);
 
-nc->send_queue = qemu_new_net_queue(qemu_deliver_packet,
-qemu_deliver_packet_iov,
-nc);
+nc->send_queue = qemu_new_net_queue(nc);
 
 return nc;
 }
@@ -324,11 +311,11 @@ int qemu_can_send_packet(NetClientState *sender)
 return 1;
 }
 
-static ssize_t qemu_deliver_packet(NetClientState *sender,
-   unsigned flags,
-   const uint8_t *data,
-   size_t size,
-   void *opaque)
+ssize_t qemu_deliver_packet(NetClientState *sender,
+unsigned flags,
+const uint8_t *data,
+size_t size,
+void *opaque)
 {
 NetClientState *nc = opaque;
 ssize_t ret;
@@ -421,11 +408,11 @@ static ssize_t nc_sendv_compat(NetClientState *nc, const 
struct iovec *iov,
 return nc->info->receive(nc, buffer, offset);
 }
 
-static ssize_t qemu_deliver_packet_iov(NetClientState *sender,
-   unsigned flags,
-   const struct iovec *iov,
-   int iovcnt,
-   void *opaque)
+ssize_t qemu_deliver_packet_iov(NetClientState *sender,
+unsigned flags,
+const struct iovec *iov,
+int iovcnt,
+void *opaque)
 {
 NetClientState *nc = opaque;
 
diff --git a/net.h b/net.h
index e1509f9..99b43f4 100644
--- a/net.h
+++ b/net.h
@@ -112,6 +112,17 @@ void qemu_check_nic_model(NICInfo *nd, const char *model);
 int qemu_find_nic_model(NICInfo *nd, const char * const *models,
 const char *default_model);
 
+ssize_t qemu_deliver_packet(NetClientState *sender,
+unsigned flags,
+const uint8_t *data,
+size_t size,
+void *opaque);
+ssize_t qemu_deliver_packet_iov(NetClientState *sender,
+unsigned flags,
+const struct iovec *iov,
+int iovcnt,
+void *opaque);
+
 void print_net_client(Monitor *mon, NetClientState *vc);
 void do_info_network(Monitor *mon);
 
diff --git a/net/queue.c b/net/queue.c
index 35c3463..0afd783 100644
--- a/net/queue.c
+++ b/net/queue.c
@@ -23,6 +23,7 @@
 
 #include "net/queue.h"
 #include "qemu-queue.h"
+#include "net.h"
 
 /* The delivery handler may only return zero if it will call
  * qemu_net_queue_flush() when it determines that it is once again able
@@ -48,8 +49,6 @@ struct NetPacket {
 };
 
 struct NetQueue {
-NetPacketDeliver *deliver;
-NetPacketDeliverIOV *deliver_iov;
 void *opaque;
 
 QTAILQ_HEAD(packets, NetPacket) packets;
@@ -57,16 +56,12 @@ struct NetQueue {
 unsigned delivering : 1;
 };
 
-NetQueue *qemu_new_net_queue(NetPacketDeliver *deliver,
- NetPacketDeliverIOV *deliver_iov,
- void *opaque)
+NetQueue *qemu_new_net_queue(void *opaque)
 {
 NetQueue *queue;
 
 queue = g_malloc0(sizeof(NetQueue));
 
-queue->deliver = deliver;
-queue->deliver_iov = deliver_iov;
 queue->opaque = opaque;
 
 QTAILQ_INIT(&queue->packets);
@@ -151,7 +146,7 @@ static ssize_t qemu_net_queue_deliver(NetQueue *queue,
 ssize_t ret = -1;
 
 queue->delivering = 1;
-

[Qemu-devel] [PATCH v6 02/17] net: Use hubs for the vlan feature

2012-06-20 Thread zwu . kernel
From: Stefan Hajnoczi 

Stop using the special-case vlan code in net.c.  Instead use the hub net
client to implement the vlan feature.  The next patch will remove vlan
code from net.c completely.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c   |   38 +-
 net/dump.c  |   19 +--
 net/dump.h  |2 +-
 net/slirp.c |8 
 net/slirp.h |2 +-
 net/socket.c|   48 ++--
 net/socket.h|2 +-
 net/tap-win32.c |8 
 net/tap.c   |6 +++---
 net/tap.h   |2 +-
 net/vde.c   |8 
 net/vde.h   |2 +-
 12 files changed, 80 insertions(+), 65 deletions(-)

diff --git a/net.c b/net.c
index 4aa416c..9a63d22 100644
--- a/net.c
+++ b/net.c
@@ -25,6 +25,7 @@
 
 #include "config-host.h"
 
+#include "net/hub.h"
 #include "net/tap.h"
 #include "net/socket.h"
 #include "net/dump.h"
@@ -153,23 +154,25 @@ void qemu_macaddr_default_if_unset(MACAddr *macaddr)
 macaddr->a[5] = 0x56 + index++;
 }
 
+/**
+ * Generate a name for net client
+ *
+ * Only net clients created with the legacy -net option need this.  Naming is
+ * mandatory for net clients created with -netdev.
+ */
 static char *assign_name(VLANClientState *vc1, const char *model)
 {
-VLANState *vlan;
 VLANClientState *vc;
 char buf[256];
 int id = 0;
 
-QTAILQ_FOREACH(vlan, &vlans, next) {
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-if (vc != vc1 && strcmp(vc->model, model) == 0) {
-id++;
-}
-}
-}
-
 QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
-if (vc != vc1 && strcmp(vc->model, model) == 0) {
+if (vc == vc1) {
+continue;
+}
+/* For compatibility only bump id for net clients on a vlan */
+if (strcmp(vc->model, model) == 0 &&
+net_hub_id_for_client(vc, NULL) == 0) {
 id++;
 }
 }
@@ -745,7 +748,7 @@ int net_handle_fd_param(Monitor *mon, const char *param)
 return fd;
 }
 
-static int net_init_nic(QemuOpts *opts, const char *name, VLANState *vlan)
+static int net_init_nic(QemuOpts *opts, const char *name, VLANClientState 
*peer)
 {
 int idx;
 NICInfo *nd;
@@ -768,8 +771,8 @@ static int net_init_nic(QemuOpts *opts, const char *name, 
VLANState *vlan)
 return -1;
 }
 } else {
-assert(vlan);
-nd->vlan = vlan;
+assert(peer);
+nd->netdev = peer;
 }
 if (name) {
 nd->name = g_strdup(name);
@@ -819,7 +822,7 @@ static int net_init_nic(QemuOpts *opts, const char *name, 
VLANState *vlan)
 
 typedef int (*net_client_init_func)(QemuOpts *opts,
 const char *name,
-VLANState *vlan);
+VLANClientState *peer);
 
 /* magic number, but compiler will warn if too small */
 #define NET_MAX_DESC 20
@@ -1133,7 +1136,7 @@ int net_client_init(QemuOpts *opts, int is_netdev, Error 
**errp)
 if (net_client_types[i].type != NULL &&
 !strcmp(net_client_types[i].type, type)) {
 Error *local_err = NULL;
-VLANState *vlan = NULL;
+VLANClientState *peer = NULL;
 int ret;
 
 qemu_opts_validate(opts, &net_client_types[i].desc[0], &local_err);
@@ -1146,12 +1149,12 @@ int net_client_init(QemuOpts *opts, int is_netdev, 
Error **errp)
  * netdev= parameter. */
 if (!(is_netdev ||
   (strcmp(type, "nic") == 0 && qemu_opt_get(opts, "netdev" 
{
-vlan = qemu_find_vlan(qemu_opt_get_number(opts, "vlan", 0), 1);
+peer = net_hub_add_port(qemu_opt_get_number(opts, "vlan", 0));
 }
 
 ret = 0;
 if (net_client_types[i].init) {
-ret = net_client_types[i].init(opts, name, vlan);
+ret = net_client_types[i].init(opts, name, peer);
 if (ret < 0) {
 /* TODO push error reporting into init() methods */
 error_set(errp, QERR_DEVICE_INIT_FAILED, type);
@@ -1316,6 +1319,7 @@ void do_info_network(Monitor *mon)
 print_net_client(mon, peer);
 }
 }
+net_hub_info(mon);
 }
 
 void qmp_set_link(const char *name, bool up, Error **errp)
diff --git a/net/dump.c b/net/dump.c
index f835c51..a59133a 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -27,6 +27,7 @@
 #include "qemu-error.h"
 #include "qemu-log.h"
 #include "qemu-timer.h"
+#include "hub.h"
 
 typedef struct DumpState {
 VLANClientState nc;
@@ -99,7 +100,7 @@ static NetClientInfo net_dump_info = {
 .cleanup = dump_cleanup,
 };
 
-static int net_dump_init(VLANState *vlan, const char *device,
+static int net_dump_init(VLANClientState *peer, const char *device,
  const char *name, const char *fil

[Qemu-devel] [PATCH v6 12/17] net: Rename qemu_del_vlan_client() to qemu_del_net_client()

2012-06-20 Thread zwu . kernel
From: Stefan Hajnoczi 

Another step in moving the vlan feature out of net core.  Users only
deal with NetClientState and therefore qemu_del_vlan_client() should be
named qemu_del_net_client().

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 hw/e1000.c   |2 +-
 hw/eepro100.c|2 +-
 hw/ne2000.c  |2 +-
 hw/pcnet-pci.c   |2 +-
 hw/rtl8139.c |2 +-
 hw/usb/dev-network.c |2 +-
 hw/virtio-net.c  |2 +-
 hw/xen_nic.c |2 +-
 net.c|   20 ++--
 net.h|2 +-
 net/slirp.c  |2 +-
 11 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/hw/e1000.c b/hw/e1000.c
index 8c7fd3b..cf1e124 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1201,7 +1201,7 @@ pci_e1000_uninit(PCIDevice *dev)
 qemu_free_timer(d->autoneg_timer);
 memory_region_destroy(&d->mmio);
 memory_region_destroy(&d->io);
-qemu_del_vlan_client(&d->nic->nc);
+qemu_del_net_client(&d->nic->nc);
 return 0;
 }
 
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 5725ccf..0217795 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1840,7 +1840,7 @@ static int pci_nic_uninit(PCIDevice *pci_dev)
 memory_region_destroy(&s->flash_bar);
 vmstate_unregister(&pci_dev->qdev, s->vmstate, s);
 eeprom93xx_free(&pci_dev->qdev, s->eeprom);
-qemu_del_vlan_client(&s->nic->nc);
+qemu_del_net_client(&s->nic->nc);
 return 0;
 }
 
diff --git a/hw/ne2000.c b/hw/ne2000.c
index 2339725..e8b1d68 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -750,7 +750,7 @@ static int pci_ne2000_exit(PCIDevice *pci_dev)
 NE2000State *s = &d->ne2000;
 
 memory_region_destroy(&s->io);
-qemu_del_vlan_client(&s->nic->nc);
+qemu_del_net_client(&s->nic->nc);
 return 0;
 }
 
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 8c82667..8bbad47 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -279,7 +279,7 @@ static int pci_pcnet_uninit(PCIDevice *dev)
 memory_region_destroy(&d->io_bar);
 qemu_del_timer(d->state.poll_timer);
 qemu_free_timer(d->state.poll_timer);
-qemu_del_vlan_client(&d->state.nic->nc);
+qemu_del_net_client(&d->state.nic->nc);
 return 0;
 }
 
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 0b33cda..b31a649 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3448,7 +3448,7 @@ static int pci_rtl8139_uninit(PCIDevice *dev)
 }
 qemu_del_timer(s->timer);
 qemu_free_timer(s->timer);
-qemu_del_vlan_client(&s->nic->nc);
+qemu_del_net_client(&s->nic->nc);
 return 0;
 }
 
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index a1d3495..2d03639 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -1309,7 +1309,7 @@ static void usb_net_handle_destroy(USBDevice *dev)
 
 /* TODO: remove the nd_table[] entry */
 rndis_clear_responsequeue(s);
-qemu_del_vlan_client(&s->nic->nc);
+qemu_del_net_client(&s->nic->nc);
 }
 
 static NetClientInfo net_usbnet_info = {
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index a73c523..d5527d4 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -1077,6 +1077,6 @@ void virtio_net_exit(VirtIODevice *vdev)
 qemu_bh_delete(n->tx_bh);
 }
 
-qemu_del_vlan_client(&n->nic->nc);
+qemu_del_net_client(&n->nic->nc);
 virtio_cleanup(&n->vdev);
 }
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index 6391a04..ba4a45c 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -409,7 +409,7 @@ static void net_disconnect(struct XenDevice *xendev)
 netdev->rxs = NULL;
 }
 if (netdev->nic) {
-qemu_del_vlan_client(&netdev->nic->nc);
+qemu_del_net_client(&netdev->nic->nc);
 netdev->nic = NULL;
 }
 }
diff --git a/net.c b/net.c
index 7fd0fde..e7d49b3 100644
--- a/net.c
+++ b/net.c
@@ -246,7 +246,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
 return nic;
 }
 
-static void qemu_cleanup_vlan_client(NetClientState *nc)
+static void qemu_cleanup_net_client(NetClientState *nc)
 {
 QTAILQ_REMOVE(&net_clients, nc, next);
 
@@ -255,7 +255,7 @@ static void qemu_cleanup_vlan_client(NetClientState *nc)
 }
 }
 
-static void qemu_free_vlan_client(NetClientState *nc)
+static void qemu_free_net_client(NetClientState *nc)
 {
 if (nc->send_queue) {
 qemu_del_net_queue(nc->send_queue);
@@ -268,7 +268,7 @@ static void qemu_free_vlan_client(NetClientState *nc)
 g_free(nc);
 }
 
-void qemu_del_vlan_client(NetClientState *nc)
+void qemu_del_net_client(NetClientState *nc)
 {
 /* If there is a peer NIC, delete and cleanup client, but do not free. */
 if (nc->peer && nc->peer->info->type == NET_CLIENT_TYPE_NIC) {
@@ -282,7 +282,7 @@ void qemu_del_vlan_client(NetClientState *nc)
 if (nc->peer->info->link_status_changed) {
 nc->peer->info->link_status_changed(nc->peer);
 }
-qemu_cleanup_vlan_client(nc);
+qemu_cleanup_net_client(nc);
 return;
 }
 
@@ -290,12 +290,12 @@ void qemu_del_v

[Qemu-devel] [PATCH v6 07/17] net: Remove vlan code from net.c

2012-06-20 Thread zwu . kernel
From: Stefan Hajnoczi 

The vlan implementation in net.c has been replaced by hubs so we can
remove the code.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 hw/xen_nic.c |1 -
 net.c|  108 --
 net.h|1 -
 3 files changed, 0 insertions(+), 110 deletions(-)

diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index 9a59bda..85526fe 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -328,7 +328,6 @@ static int net_init(struct XenDevice *xendev)
 return -1;
 }
 
-netdev->conf.vlan = qemu_find_vlan(netdev->xendev.dev, 1);
 netdev->conf.peer = NULL;
 
 netdev->nic = qemu_new_nic(&net_xen_info, &netdev->conf,
diff --git a/net.c b/net.c
index 553f032..812589a 100644
--- a/net.c
+++ b/net.c
@@ -388,50 +388,6 @@ static ssize_t qemu_deliver_packet(VLANClientState *sender,
 return ret;
 }
 
-static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
-unsigned flags,
-const uint8_t *buf,
-size_t size,
-void *opaque)
-{
-VLANState *vlan = opaque;
-VLANClientState *vc;
-ssize_t ret = -1;
-
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-ssize_t len;
-
-if (vc == sender) {
-continue;
-}
-
-if (vc->link_down) {
-ret = size;
-continue;
-}
-
-if (vc->receive_disabled) {
-ret = 0;
-continue;
-}
-
-if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->info->receive_raw) {
-len = vc->info->receive_raw(vc, buf, size);
-} else {
-len = vc->info->receive(vc, buf, size);
-}
-
-if (len == 0) {
-vc->receive_disabled = 1;
-}
-
-ret = (ret >= 0) ? ret : len;
-
-}
-
-return ret;
-}
-
 void qemu_purge_queued_packets(VLANClientState *vc)
 {
 NetQueue *queue;
@@ -538,42 +494,6 @@ static ssize_t qemu_deliver_packet_iov(VLANClientState 
*sender,
 }
 }
 
-static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState *sender,
-unsigned flags,
-const struct iovec *iov,
-int iovcnt,
-void *opaque)
-{
-VLANState *vlan = opaque;
-VLANClientState *vc;
-ssize_t ret = -1;
-
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-ssize_t len;
-
-if (vc == sender) {
-continue;
-}
-
-if (vc->link_down) {
-ret = iov_size(iov, iovcnt);
-continue;
-}
-
-assert(!(flags & QEMU_NET_PACKET_FLAG_RAW));
-
-if (vc->info->receive_iov) {
-len = vc->info->receive_iov(vc, iov, iovcnt);
-} else {
-len = vc_sendv_compat(vc, iov, iovcnt);
-}
-
-ret = (ret >= 0) ? ret : len;
-}
-
-return ret;
-}
-
 ssize_t qemu_sendv_packet_async(VLANClientState *sender,
 const struct iovec *iov, int iovcnt,
 NetPacketSent *sent_cb)
@@ -601,34 +521,6 @@ qemu_sendv_packet(VLANClientState *vc, const struct iovec 
*iov, int iovcnt)
 return qemu_sendv_packet_async(vc, iov, iovcnt, NULL);
 }
 
-/* find or alloc a new VLAN */
-VLANState *qemu_find_vlan(int id, int allocate)
-{
-VLANState *vlan;
-
-QTAILQ_FOREACH(vlan, &vlans, next) {
-if (vlan->id == id) {
-return vlan;
-}
-}
-
-if (!allocate) {
-return NULL;
-}
-
-vlan = g_malloc0(sizeof(VLANState));
-vlan->id = id;
-QTAILQ_INIT(&vlan->clients);
-
-vlan->send_queue = qemu_new_net_queue(qemu_vlan_deliver_packet,
-  qemu_vlan_deliver_packet_iov,
-  vlan);
-
-QTAILQ_INSERT_TAIL(&vlans, vlan, next);
-
-return vlan;
-}
-
 VLANClientState *qemu_find_netdev(const char *id)
 {
 VLANClientState *vc;
diff --git a/net.h b/net.h
index 42fbc49..791ca4f 100644
--- a/net.h
+++ b/net.h
@@ -87,7 +87,6 @@ struct VLANState {
 NetQueue *send_queue;
 };
 
-VLANState *qemu_find_vlan(int id, int allocate);
 VLANClientState *qemu_find_netdev(const char *id);
 VLANClientState *qemu_new_net_client(NetClientInfo *info,
  VLANClientState *peer,
-- 
1.7.6




[Qemu-devel] [PATCH v6 00/17] hub-based networking patchset

2012-06-20 Thread zwu . kernel
From: Zhi Yong Wu 

All comments have been addressed and stefan has completed one more reviewing.

For this patchset, my git repo:

g...@github.com:wuzhy/qemu.git for-anthony

Changelog from v5:
 1.) cleanup VLANState in other targets files [anthony]

v5:
 1.) roll back qdev_prop_vlan [stefanha]

v4:
 1.) refactor hub own flow control [paolo]
 2.) refactor the output for monitor command "info network" [jan kiszka]

v3:
 1.) add the support for hub own flow control [paolo]
 2.) make the monitor output more reasonable hub info [jan kiszka]

v2:
 1.) cleanup some obsolete vlan info
 2.) cleanup deliver/deliver_iov func pointers [paolo]
 3.) support more flexible flow control [paolo]

Stefan Hajnoczi (12):
  net: Add a hub net client
  net: Use hubs for the vlan feature
  net: Look up 'vlan' net clients using hubs
  hub: Check that hubs are configured correctly
  net: Drop vlan argument to qemu_new_net_client()
  net: Remove vlan qdev property
  net: Remove vlan code from net.c
  net: Remove VLANState
  net: Rename non_vlan_clients to net_clients
  net: Rename VLANClientState to NetClientState
  net: Rename vc local variables to nc
  net: Rename qemu_del_vlan_client() to qemu_del_net_client()

Zhi Yong Wu (5):
  net: Make "info network" output more readable info
  net: cleanup deliver/deliver_iov func pointers
  net: determine if packets can be sent before net queue deliver
packets
  hub: add the support for hub own flow control
  net: roll back qdev_prop_vlan

 hw/cadence_gem.c|8 +-
 hw/dp8393x.c|7 +-
 hw/e1000.c  |   10 +-
 hw/eepro100.c   |8 +-
 hw/etraxfs_eth.c|8 +-
 hw/exynos4_boards.c |2 +-
 hw/highbank.c   |2 +-
 hw/integratorcp.c   |2 +-
 hw/lan9118.c|8 +-
 hw/lance.c  |2 +-
 hw/mcf5208.c|2 +-
 hw/mcf_fec.c|7 +-
 hw/milkymist-minimac2.c |6 +-
 hw/mips_mipssim.c   |2 +-
 hw/mips_r4k.c   |2 +-
 hw/mipsnet.c|6 +-
 hw/musicpal.c   |6 +-
 hw/ne2000-isa.c |2 +-
 hw/ne2000.c |8 +-
 hw/ne2000.h |4 +-
 hw/opencores_eth.c  |8 +-
 hw/pcnet-pci.c  |4 +-
 hw/pcnet.c  |6 +-
 hw/pcnet.h  |6 +-
 hw/qdev-properties.c|   53 +++--
 hw/qdev.c   |2 -
 hw/qdev.h   |7 +-
 hw/rtl8139.c|   10 +-
 hw/smc91c111.c  |6 +-
 hw/spapr_llan.c |4 +-
 hw/stellaris_enet.c |6 +-
 hw/usb/dev-network.c|8 +-
 hw/vexpress.c   |2 +-
 hw/vhost_net.c  |   24 +-
 hw/vhost_net.h  |2 +-
 hw/virtio-net.c |   12 +-
 hw/xen_nic.c|7 +-
 hw/xgmac.c  |6 +-
 hw/xilinx_axienet.c |6 +-
 hw/xilinx_ethlite.c |6 +-
 hw/xtensa_lx60.c|2 +-
 net.c   |  593 ++-
 net.h   |   87 
 net/Makefile.objs   |2 +-
 net/dump.c  |   27 ++-
 net/dump.h  |2 +-
 net/hub.c   |  335 ++
 net/hub.h   |   29 +++
 net/queue.c |   37 ++--
 net/queue.h |   25 +--
 net/slirp.c |   32 +--
 net/slirp.h |2 +-
 net/socket.c|   66 +++---
 net/socket.h|2 +-
 net/tap-win32.c |   26 +-
 net/tap.c   |   44 ++--
 net/tap.h   |   20 +-
 net/vde.c   |   16 +-
 net/vde.h   |2 +-
 qemu-common.h   |3 +-
 slirp/if.c  |5 -
 slirp/libslirp.h|1 -
 62 files changed, 868 insertions(+), 777 deletions(-)
 create mode 100644 net/hub.c
 create mode 100644 net/hub.h

-- 
1.7.6




[Qemu-devel] [PATCH v6 13/17] net: Make "info network" output more readable info

2012-06-20 Thread zwu . kernel
From: Zhi Yong Wu 

Reviewed-by:   Jan Kiszka  
Signed-off-by: Zhi Yong Wu 
---
 net.c |   14 +-
 net.h |1 +
 net/hub.c |   23 +--
 net/hub.h |1 +
 4 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/net.c b/net.c
index e7d49b3..d0be471 100644
--- a/net.c
+++ b/net.c
@@ -1087,7 +1087,7 @@ void qmp_netdev_del(const char *id, Error **errp)
 qemu_opts_del(qemu_opts_find(qemu_find_opts_err("netdev", errp), id));
 }
 
-static void print_net_client(Monitor *mon, NetClientState *vc)
+void print_net_client(Monitor *mon, NetClientState *vc)
 {
 monitor_printf(mon, "%s: type=%s,%s\n", vc->name,
net_client_types[vc->info->type].type, vc->info_str);
@@ -1098,20 +1098,24 @@ void do_info_network(Monitor *mon)
 NetClientState *nc, *peer;
 net_client_type type;
 
-monitor_printf(mon, "Devices not on any VLAN:\n");
+net_hub_info(mon);
+
 QTAILQ_FOREACH(nc, &net_clients, next) {
 peer = nc->peer;
 type = nc->info->type;
+
+if (net_hub_port_peer_nc(nc)) {
+continue;
+}
+
 if (!peer || type == NET_CLIENT_TYPE_NIC) {
-monitor_printf(mon, "  ");
 print_net_client(mon, nc);
 } /* else it's a netdev connected to a NIC, printed with the NIC */
 if (peer && type == NET_CLIENT_TYPE_NIC) {
-monitor_printf(mon, "   \\ ");
+monitor_printf(mon, " \\ ");
 print_net_client(mon, peer);
 }
 }
-net_hub_info(mon);
 }
 
 void qmp_set_link(const char *name, bool up, Error **errp)
diff --git a/net.h b/net.h
index 20fcc94..e1509f9 100644
--- a/net.h
+++ b/net.h
@@ -112,6 +112,7 @@ void qemu_check_nic_model(NICInfo *nd, const char *model);
 int qemu_find_nic_model(NICInfo *nd, const char * const *models,
 const char *default_model);
 
+void print_net_client(Monitor *mon, NetClientState *vc);
 void do_info_network(Monitor *mon);
 
 /* NIC info */
diff --git a/net/hub.c b/net/hub.c
index 122de69..230d86a 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -184,6 +184,25 @@ NetClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
 }
 
 /**
+ * Determine if one nc peers with one hub port
+ */
+bool net_hub_port_peer_nc(NetClientState *nc)
+{
+NetHub *hub;
+NetHubPort *port;
+
+QLIST_FOREACH(hub, &hubs, next) {
+QLIST_FOREACH(port, &hub->ports, next) {
+if (nc == port->nc.peer) {
+return true;
+}
+}
+}
+
+return false;
+}
+
+/**
  * Print hub configuration
  */
 void net_hub_info(Monitor *mon)
@@ -194,8 +213,8 @@ void net_hub_info(Monitor *mon)
 QLIST_FOREACH(hub, &hubs, next) {
 monitor_printf(mon, "hub %u\n", hub->id);
 QLIST_FOREACH(port, &hub->ports, next) {
-monitor_printf(mon, "port %u peer %s\n", port->id,
-   port->nc.peer ? port->nc.peer->name : "");
+monitor_printf(mon, " \\ ");
+print_net_client(mon, port->nc.peer);
 }
 }
 }
diff --git a/net/hub.h b/net/hub.h
index ff5024a..550189b 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -23,5 +23,6 @@ NetClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
 void net_hub_info(Monitor *mon);
 int net_hub_id_for_client(NetClientState *nc, unsigned int *id);
 void net_hub_check_clients(void);
+bool net_hub_port_peer_nc(NetClientState *nc);
 
 #endif /* NET_HUB_H */
-- 
1.7.6




[Qemu-devel] [PATCH v6 17/17] net: roll back qdev_prop_vlan

2012-06-20 Thread zwu . kernel
From: Zhi Yong Wu 

We're trying to preserve backward compatibility.  This
command-line break:

x86_64-softmmu/qemu-system-x86_64 -net user,vlan=1 -device virtio-net-pci,vlan=1

Instead of dropping the qdev_prop_vlan completely the
hw/qdev-properties.c code needs to call net/hub.h external functions
to implement equivalent functionality.

Signed-off-by: Zhi Yong Wu 
---
 hw/qdev-properties.c |   77 ++
 hw/qdev.h|3 ++
 net.h|1 +
 net/hub.c|   25 
 net/hub.h|1 +
 5 files changed, 107 insertions(+), 0 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 5fc7483..fcec09e 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -2,6 +2,7 @@
 #include "qdev.h"
 #include "qerror.h"
 #include "blockdev.h"
+#include "net/hub.h"
 
 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
 {
@@ -591,6 +592,82 @@ PropertyInfo qdev_prop_netdev = {
 .set   = set_netdev,
 };
 
+/* --- vlan --- */
+
+static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
+
+if (*ptr) {
+unsigned int id;
+if (!net_hub_id_for_client(*ptr, &id)) {
+return snprintf(dest, len, "%u", id);
+}
+}
+
+return snprintf(dest, len, "");
+}
+
+static void get_vlan(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
+NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
+int64_t id = -1;
+
+if (*ptr) {
+unsigned int hub_id;
+if(!net_hub_id_for_client(*ptr, &hub_id)) {
+   id = (int64_t)hub_id;
+}
+}
+
+visit_type_int(v, &id, name, errp);
+}
+
+static void set_vlan(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
+NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
+Error *local_err = NULL;
+int64_t id;
+NetClientState *hubport;
+
+if (dev->state != DEV_STATE_CREATED) {
+error_set(errp, QERR_PERMISSION_DENIED);
+return;
+}
+
+visit_type_int(v, &id, name, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
+if (id == -1) {
+*ptr = NULL;
+return;
+}
+
+hubport = net_hub_port_find(id);
+if (!hubport) {
+error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+  name, prop->info->name);
+return;
+}
+*ptr = hubport;
+}
+
+PropertyInfo qdev_prop_vlan = {
+.name  = "vlan",
+.print = print_vlan,
+.get   = get_vlan,
+.set   = set_vlan,
+};
+
 /* --- pointer --- */
 
 /* Not a proper property, just for dirty hacks.  TODO Remove it!  */
diff --git a/hw/qdev.h b/hw/qdev.h
index 2645d0c..1b32b3a 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -234,6 +234,7 @@ extern PropertyInfo qdev_prop_macaddr;
 extern PropertyInfo qdev_prop_losttickpolicy;
 extern PropertyInfo qdev_prop_drive;
 extern PropertyInfo qdev_prop_netdev;
+extern PropertyInfo qdev_prop_vlan;
 extern PropertyInfo qdev_prop_pci_devfn;
 extern PropertyInfo qdev_prop_blocksize;
 
@@ -288,6 +289,8 @@ extern PropertyInfo qdev_prop_blocksize;
 DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
 #define DEFINE_PROP_NETDEV(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, NetClientState*)
+#define DEFINE_PROP_VLAN(_n, _s, _f) \
+DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, NetClientState*)
 #define DEFINE_PROP_DRIVE(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *)
 #define DEFINE_PROP_MACADDR(_n, _s, _f) \
diff --git a/net.h b/net.h
index 99b43f4..0256ff9 100644
--- a/net.h
+++ b/net.h
@@ -22,6 +22,7 @@ typedef struct NICConf {
 
 #define DEFINE_NIC_PROPERTIES(_state, _conf)\
 DEFINE_PROP_MACADDR("mac",   _state, _conf.macaddr),\
+DEFINE_PROP_VLAN("vlan", _state, _conf.peer),   \
 DEFINE_PROP_NETDEV("netdev", _state, _conf.peer),   \
 DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1)
 
diff --git a/net/hub.c b/net/hub.c
index efd90b5..001f818 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -205,6 +205,31 @@ NetClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
 }
 
 /**
+ * Find a available port on a hub; otherwise create one new port
+ */
+NetClientState *net_hub_port_find(unsigned int hub_id)
+{
+NetHub *hub;
+NetHubPort *port;
+NetClientState *nc;
+
+QLIST_FOREACH(hub, &hubs, next) {
+if (hub->id == hub_id) {
+QLIST_FOREACH(port, &hub->ports, next) {
+nc = port->nc.peer;
+if (!nc) {
+return &(port->nc);
+   

[Qemu-devel] [PATCH v6 01/17] net: Add a hub net client

2012-06-20 Thread zwu . kernel
From: Stefan Hajnoczi 

The vlan feature can be implemented in terms of hubs.  By introducing a
hub net client it becomes possible to remove the special case vlan code
from net.c and push the vlan feature out of generic networking code.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.h |1 +
 net/Makefile.objs |2 +-
 net/hub.c |  201 +
 net/hub.h |   24 ++
 4 files changed, 227 insertions(+), 1 deletions(-)
 create mode 100644 net/hub.c
 create mode 100644 net/hub.h

diff --git a/net.h b/net.h
index bdc2a06..c1198b6 100644
--- a/net.h
+++ b/net.h
@@ -38,6 +38,7 @@ typedef enum {
 NET_CLIENT_TYPE_VDE,
 NET_CLIENT_TYPE_DUMP,
 NET_CLIENT_TYPE_BRIDGE,
+NET_CLIENT_TYPE_HUB,
 
 NET_CLIENT_TYPE_MAX
 } net_client_type;
diff --git a/net/Makefile.objs b/net/Makefile.objs
index 72f50bc..cf04187 100644
--- a/net/Makefile.objs
+++ b/net/Makefile.objs
@@ -1,4 +1,4 @@
-common-obj-y = queue.o checksum.o util.o
+common-obj-y = queue.o checksum.o util.o hub.o
 common-obj-y += socket.o
 common-obj-y += dump.o
 common-obj-$(CONFIG_POSIX) += tap.o
diff --git a/net/hub.c b/net/hub.c
new file mode 100644
index 000..28ff45c
--- /dev/null
+++ b/net/hub.c
@@ -0,0 +1,201 @@
+/*
+ * Hub net client
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Stefan Hajnoczi   
+ *  Zhi Yong Wu   
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "monitor.h"
+#include "net.h"
+#include "hub.h"
+
+/*
+ * A hub broadcasts incoming packets to all its ports except the source port.
+ * Hubs can be used to provide independent network segments, also confusingly
+ * named the QEMU 'vlan' feature.
+ */
+
+typedef struct NetHub NetHub;
+
+typedef struct NetHubPort {
+VLANClientState nc;
+QLIST_ENTRY(NetHubPort) next;
+NetHub *hub;
+unsigned int id;
+} NetHubPort;
+
+struct NetHub {
+unsigned int id;
+QLIST_ENTRY(NetHub) next;
+unsigned int num_ports;
+QLIST_HEAD(, NetHubPort) ports;
+};
+
+static QLIST_HEAD(, NetHub) hubs = QLIST_HEAD_INITIALIZER(&hubs);
+
+static ssize_t net_hub_receive(NetHub *hub, NetHubPort *source_port,
+   const uint8_t *buf, size_t len)
+{
+NetHubPort *port;
+
+QLIST_FOREACH(port, &hub->ports, next) {
+if (port == source_port) {
+continue;
+}
+
+qemu_send_packet(&port->nc, buf, len);
+}
+return len;
+}
+
+static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port,
+   const struct iovec *iov, int iovcnt)
+{
+NetHubPort *port;
+ssize_t ret = 0;
+
+QLIST_FOREACH(port, &hub->ports, next) {
+if (port == source_port) {
+continue;
+}
+
+ret = qemu_sendv_packet(&port->nc, iov, iovcnt);
+}
+return ret;
+}
+
+static NetHub *net_hub_new(unsigned int id)
+{
+NetHub *hub;
+
+hub = g_malloc(sizeof(*hub));
+hub->id = id;
+hub->num_ports = 0;
+QLIST_INIT(&hub->ports);
+
+QLIST_INSERT_HEAD(&hubs, hub, next);
+
+return hub;
+}
+
+static ssize_t net_hub_port_receive(VLANClientState *nc,
+const uint8_t *buf, size_t len)
+{
+NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
+
+return net_hub_receive(port->hub, port, buf, len);
+}
+
+static ssize_t net_hub_port_receive_iov(VLANClientState *nc,
+const struct iovec *iov, int iovcnt)
+{
+NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
+
+return net_hub_receive_iov(port->hub, port, iov, iovcnt);
+}
+
+static void net_hub_port_cleanup(VLANClientState *nc)
+{
+NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
+
+QLIST_REMOVE(port, next);
+}
+
+static NetClientInfo net_hub_port_info = {
+.type = NET_CLIENT_TYPE_HUB,
+.size = sizeof(NetHubPort),
+.receive = net_hub_port_receive,
+.receive_iov = net_hub_port_receive_iov,
+.cleanup = net_hub_port_cleanup,
+};
+
+static NetHubPort *net_hub_port_new(NetHub *hub)
+{
+VLANClientState *nc;
+NetHubPort *port;
+unsigned int id = hub->num_ports++;
+char name[128];
+
+snprintf(name, sizeof name, "hub%uport%u", hub->id, id);
+
+nc = qemu_new_net_client(&net_hub_port_info, NULL, NULL, "hub", name);
+port = DO_UPCAST(NetHubPort, nc, nc);
+port->id = id;
+port->hub = hub;
+
+QLIST_INSERT_HEAD(&hub->ports, port, next);
+
+return port;
+}
+
+/**
+ * Create a port on a given hub
+ *
+ * If there is no existing hub with the given id then a new hub is created.
+ */
+VLANClientState *net_hub_add_port(unsigned int hub_id)
+{
+NetHub *hub;
+NetHubPort *port;
+
+QLIST_FOREACH(hub, &hubs, next) {
+if (hub->id == hub_id) {
+break;
+}
+}
+
+if (!hub) {
+hub = net_hub_new(hub_id);

[Qemu-devel] [PATCH v6 05/17] net: Drop vlan argument to qemu_new_net_client()

2012-06-20 Thread zwu . kernel
From: Stefan Hajnoczi 

Since hubs are now used to implement the 'vlan' feature and the vlan
argument is always NULL, remove the argument entirely and update all net
clients that use qemu_new_net_client().

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c   |   27 ++-
 net.h   |1 -
 net/dump.c  |2 +-
 net/hub.c   |2 +-
 net/slirp.c |2 +-
 net/socket.c|4 ++--
 net/tap-win32.c |2 +-
 net/tap.c   |2 +-
 net/vde.c   |2 +-
 9 files changed, 18 insertions(+), 26 deletions(-)

diff --git a/net.c b/net.c
index d6bb480..553f032 100644
--- a/net.c
+++ b/net.c
@@ -194,7 +194,6 @@ static ssize_t qemu_deliver_packet_iov(VLANClientState 
*sender,
void *opaque);
 
 VLANClientState *qemu_new_net_client(NetClientInfo *info,
- VLANState *vlan,
  VLANClientState *peer,
  const char *model,
  const char *name)
@@ -213,22 +212,16 @@ VLANClientState *qemu_new_net_client(NetClientInfo *info,
 vc->name = assign_name(vc, model);
 }
 
-if (vlan) {
-assert(!peer);
-vc->vlan = vlan;
-QTAILQ_INSERT_TAIL(&vc->vlan->clients, vc, next);
-} else {
-if (peer) {
-assert(!peer->peer);
-vc->peer = peer;
-peer->peer = vc;
-}
-QTAILQ_INSERT_TAIL(&non_vlan_clients, vc, next);
-
-vc->send_queue = qemu_new_net_queue(qemu_deliver_packet,
-qemu_deliver_packet_iov,
-vc);
+if (peer) {
+assert(!peer->peer);
+vc->peer = peer;
+peer->peer = vc;
 }
+QTAILQ_INSERT_TAIL(&non_vlan_clients, vc, next);
+
+vc->send_queue = qemu_new_net_queue(qemu_deliver_packet,
+qemu_deliver_packet_iov,
+vc);
 
 return vc;
 }
@@ -245,7 +238,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
 assert(info->type == NET_CLIENT_TYPE_NIC);
 assert(info->size >= sizeof(NICState));
 
-nc = qemu_new_net_client(info, conf->vlan, conf->peer, model, name);
+nc = qemu_new_net_client(info, conf->peer, model, name);
 
 nic = DO_UPCAST(NICState, nc, nc);
 nic->conf = conf;
diff --git a/net.h b/net.h
index c1198b6..a96ae20 100644
--- a/net.h
+++ b/net.h
@@ -92,7 +92,6 @@ struct VLANState {
 VLANState *qemu_find_vlan(int id, int allocate);
 VLANClientState *qemu_find_netdev(const char *id);
 VLANClientState *qemu_new_net_client(NetClientInfo *info,
- VLANState *vlan,
  VLANClientState *peer,
  const char *model,
  const char *name);
diff --git a/net/dump.c b/net/dump.c
index a59133a..0349210 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -129,7 +129,7 @@ static int net_dump_init(VLANClientState *peer, const char 
*device,
 return -1;
 }
 
-nc = qemu_new_net_client(&net_dump_info, NULL, peer, device, name);
+nc = qemu_new_net_client(&net_dump_info, peer, device, name);
 
 snprintf(nc->info_str, sizeof(nc->info_str),
  "dump to %s (len=%d)", filename, len);
diff --git a/net/hub.c b/net/hub.c
index e4a3980..fe78a72 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -125,7 +125,7 @@ static NetHubPort *net_hub_port_new(NetHub *hub)
 
 snprintf(name, sizeof name, "hub%uport%u", hub->id, id);
 
-nc = qemu_new_net_client(&net_hub_port_info, NULL, NULL, "hub", name);
+nc = qemu_new_net_client(&net_hub_port_info, NULL, "hub", name);
 port = DO_UPCAST(NetHubPort, nc, nc);
 port->id = id;
 port->hub = hub;
diff --git a/net/slirp.c b/net/slirp.c
index c8c557a..1145412 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -238,7 +238,7 @@ static int net_slirp_init(VLANClientState *peer, const char 
*model,
 }
 #endif
 
-nc = qemu_new_net_client(&net_slirp_info, NULL, peer, model, name);
+nc = qemu_new_net_client(&net_slirp_info, peer, model, name);
 
 snprintf(nc->info_str, sizeof(nc->info_str),
  "net=%s,restrict=%s", inet_ntoa(net),
diff --git a/net/socket.c b/net/socket.c
index f231f7b..d4f7a7b 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -287,7 +287,7 @@ static NetSocketState 
*net_socket_fd_init_dgram(VLANClientState *peer,
 }
 }
 
-nc = qemu_new_net_client(&net_dgram_socket_info, NULL, peer, model, name);
+nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name);
 
 snprintf(nc->info_str, sizeof(nc->info_str),
 "socket: fd=%d (%s mcast=%s:%d)",
@@ -331,7 +331,7 @@ static NetSocketState 
*net_socket_fd_init_stream(VLANClientState *peer,
 VLANClientState *nc;
 NetSocketState *s;
 
-nc = qemu_new_net_

[Qemu-devel] [PATCH v6 09/17] net: Rename non_vlan_clients to net_clients

2012-06-20 Thread zwu . kernel
From: Stefan Hajnoczi 

There is no longer a distinction between vlan clients and non-vlan
clients in the net core.  The net core only knows about point-to-point
clients which are connected to a peer.  It's time to rename the global
list of net clients since it no longer refers to vlans at all.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c |   20 ++--
 1 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/net.c b/net.c
index 73325b0..d3a685e 100644
--- a/net.c
+++ b/net.c
@@ -44,7 +44,7 @@
 # define CONFIG_NET_BRIDGE
 #endif
 
-static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
+static QTAILQ_HEAD(, VLANClientState) net_clients;
 
 int default_net = 1;
 
@@ -165,7 +165,7 @@ static char *assign_name(VLANClientState *vc1, const char 
*model)
 char buf[256];
 int id = 0;
 
-QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
+QTAILQ_FOREACH(vc, &net_clients, next) {
 if (vc == vc1) {
 continue;
 }
@@ -216,7 +216,7 @@ VLANClientState *qemu_new_net_client(NetClientInfo *info,
 vc->peer = peer;
 peer->peer = vc;
 }
-QTAILQ_INSERT_TAIL(&non_vlan_clients, vc, next);
+QTAILQ_INSERT_TAIL(&net_clients, vc, next);
 
 vc->send_queue = qemu_new_net_queue(qemu_deliver_packet,
 qemu_deliver_packet_iov,
@@ -248,7 +248,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
 
 static void qemu_cleanup_vlan_client(VLANClientState *vc)
 {
-QTAILQ_REMOVE(&non_vlan_clients, vc, next);
+QTAILQ_REMOVE(&net_clients, vc, next);
 
 if (vc->info->cleanup) {
 vc->info->cleanup(vc);
@@ -302,7 +302,7 @@ void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
 {
 VLANClientState *nc;
 
-QTAILQ_FOREACH(nc, &non_vlan_clients, next) {
+QTAILQ_FOREACH(nc, &net_clients, next) {
 if (nc->info->type == NET_CLIENT_TYPE_NIC) {
 func(DO_UPCAST(NICState, nc, nc), opaque);
 }
@@ -467,7 +467,7 @@ VLANClientState *qemu_find_netdev(const char *id)
 {
 VLANClientState *vc;
 
-QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
+QTAILQ_FOREACH(vc, &net_clients, next) {
 if (vc->info->type == NET_CLIENT_TYPE_NIC)
 continue;
 if (!strcmp(vc->name, id)) {
@@ -1099,7 +1099,7 @@ void do_info_network(Monitor *mon)
 net_client_type type;
 
 monitor_printf(mon, "Devices not on any VLAN:\n");
-QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
+QTAILQ_FOREACH(vc, &net_clients, next) {
 peer = vc->peer;
 type = vc->info->type;
 if (!peer || type == NET_CLIENT_TYPE_NIC) {
@@ -1152,7 +1152,7 @@ void net_cleanup(void)
 {
 VLANClientState *vc, *next_vc;
 
-QTAILQ_FOREACH_SAFE(vc, &non_vlan_clients, next, next_vc) {
+QTAILQ_FOREACH_SAFE(vc, &net_clients, next, next_vc) {
 qemu_del_vlan_client(vc);
 }
 }
@@ -1176,7 +1176,7 @@ void net_check_clients(void)
 
 net_hub_check_clients();
 
-QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
+QTAILQ_FOREACH(vc, &net_clients, next) {
 if (!vc->peer) {
 fprintf(stderr, "Warning: %s %s has no peer\n",
 vc->info->type == NET_CLIENT_TYPE_NIC ? "nic" : "netdev",
@@ -1240,7 +1240,7 @@ int net_init_clients(void)
 #endif
 }
 
-QTAILQ_INIT(&non_vlan_clients);
+QTAILQ_INIT(&net_clients);
 
 if (qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, 1) 
== -1)
 return -1;
-- 
1.7.6




[Qemu-devel] [PATCH v6 15/17] net: determine if packets can be sent before net queue deliver packets

2012-06-20 Thread zwu . kernel
From: Zhi Yong Wu 

Reviewed-by:   Paolo Bonzini 
Signed-off-by: Zhi Yong Wu 
---
 net/queue.c  |8 
 net/slirp.c  |7 ---
 slirp/if.c   |5 -
 slirp/libslirp.h |1 -
 4 files changed, 4 insertions(+), 17 deletions(-)

diff --git a/net/queue.c b/net/queue.c
index 0afd783..7484d2a 100644
--- a/net/queue.c
+++ b/net/queue.c
@@ -176,8 +176,8 @@ ssize_t qemu_net_queue_send(NetQueue *queue,
 {
 ssize_t ret;
 
-if (queue->delivering) {
-return qemu_net_queue_append(queue, sender, flags, data, size, NULL);
+if (queue->delivering || !qemu_can_send_packet(sender)) {
+return qemu_net_queue_append(queue, sender, flags, data, size, 
sent_cb);
 }
 
 ret = qemu_net_queue_deliver(queue, sender, flags, data, size);
@@ -200,8 +200,8 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue,
 {
 ssize_t ret;
 
-if (queue->delivering) {
-return qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt, 
NULL);
+if (queue->delivering || !qemu_can_send_packet(sender)) {
+return qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt, 
sent_cb);
 }
 
 ret = qemu_net_queue_deliver_iov(queue, sender, flags, iov, iovcnt);
diff --git a/net/slirp.c b/net/slirp.c
index 2df50a8..1e5cabb 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -96,13 +96,6 @@ static void slirp_smb_cleanup(SlirpState *s);
 static inline void slirp_smb_cleanup(SlirpState *s) { }
 #endif
 
-int slirp_can_output(void *opaque)
-{
-SlirpState *s = opaque;
-
-return qemu_can_send_packet(&s->nc);
-}
-
 void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
 {
 SlirpState *s = opaque;
diff --git a/slirp/if.c b/slirp/if.c
index 096cf6f..533295d 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -177,11 +177,6 @@ void if_start(Slirp *slirp)
 }
 
 while (ifm_next) {
-/* check if we can really output */
-if (!slirp_can_output(slirp->opaque)) {
-break;
-}
-
 ifm = ifm_next;
 from_batchq = next_from_batchq;
 
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 77527ad..9b471b5 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -25,7 +25,6 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, 
fd_set *xfds,
 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
 
 /* you must provide the following functions: */
-int slirp_can_output(void *opaque);
 void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len);
 
 int slirp_add_hostfwd(Slirp *slirp, int is_udp,
-- 
1.7.6




[Qemu-devel] [PATCH v6 06/17] net: Remove vlan qdev property

2012-06-20 Thread zwu . kernel
From: Stefan Hajnoczi 

The vlan feature is implemented using hubs and no longer uses
special-purpose VLANState structs that are accessible as qdev
properties.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 hw/qdev-properties.c |   72 --
 hw/qdev.c|2 -
 hw/qdev.h|4 ---
 net.h|3 --
 4 files changed, 0 insertions(+), 81 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 099a7aa..e0bdee2 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -591,71 +591,6 @@ PropertyInfo qdev_prop_netdev = {
 .set   = set_netdev,
 };
 
-/* --- vlan --- */
-
-static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
-VLANState **ptr = qdev_get_prop_ptr(dev, prop);
-
-if (*ptr) {
-return snprintf(dest, len, "%d", (*ptr)->id);
-} else {
-return snprintf(dest, len, "");
-}
-}
-
-static void get_vlan(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
-{
-DeviceState *dev = DEVICE(obj);
-Property *prop = opaque;
-VLANState **ptr = qdev_get_prop_ptr(dev, prop);
-int64_t id;
-
-id = *ptr ? (*ptr)->id : -1;
-visit_type_int64(v, &id, name, errp);
-}
-
-static void set_vlan(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
-{
-DeviceState *dev = DEVICE(obj);
-Property *prop = opaque;
-VLANState **ptr = qdev_get_prop_ptr(dev, prop);
-Error *local_err = NULL;
-int64_t id;
-VLANState *vlan;
-
-if (dev->state != DEV_STATE_CREATED) {
-error_set(errp, QERR_PERMISSION_DENIED);
-return;
-}
-
-visit_type_int64(v, &id, name, &local_err);
-if (local_err) {
-error_propagate(errp, local_err);
-return;
-}
-if (id == -1) {
-*ptr = NULL;
-return;
-}
-vlan = qemu_find_vlan(id, 1);
-if (!vlan) {
-error_set(errp, QERR_INVALID_PARAMETER_VALUE,
-  name, prop->info->name);
-return;
-}
-*ptr = vlan;
-}
-
-PropertyInfo qdev_prop_vlan = {
-.name  = "vlan",
-.print = print_vlan,
-.get   = get_vlan,
-.set   = set_vlan,
-};
-
 /* --- pointer --- */
 
 /* Not a proper property, just for dirty hacks.  TODO Remove it!  */
@@ -1061,13 +996,6 @@ void qdev_prop_set_netdev(DeviceState *dev, const char 
*name, VLANClientState *v
 assert_no_error(errp);
 }
 
-void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
-{
-Error *errp = NULL;
-object_property_set_int(OBJECT(dev), value ? value->id : -1, name, &errp);
-assert_no_error(errp);
-}
-
 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
 {
 Error *errp = NULL;
diff --git a/hw/qdev.c b/hw/qdev.c
index a6c4c02..f787d83 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -319,8 +319,6 @@ void qdev_connect_gpio_out(DeviceState * dev, int n, 
qemu_irq pin)
 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
 {
 qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
-if (nd->vlan)
-qdev_prop_set_vlan(dev, "vlan", nd->vlan);
 if (nd->netdev)
 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
diff --git a/hw/qdev.h b/hw/qdev.h
index ae1d281..68e0980 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -234,7 +234,6 @@ extern PropertyInfo qdev_prop_macaddr;
 extern PropertyInfo qdev_prop_losttickpolicy;
 extern PropertyInfo qdev_prop_drive;
 extern PropertyInfo qdev_prop_netdev;
-extern PropertyInfo qdev_prop_vlan;
 extern PropertyInfo qdev_prop_pci_devfn;
 extern PropertyInfo qdev_prop_blocksize;
 
@@ -289,8 +288,6 @@ extern PropertyInfo qdev_prop_blocksize;
 DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
 #define DEFINE_PROP_NETDEV(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, VLANClientState*)
-#define DEFINE_PROP_VLAN(_n, _s, _f) \
-DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, VLANState*)
 #define DEFINE_PROP_DRIVE(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *)
 #define DEFINE_PROP_MACADDR(_n, _s, _f) \
@@ -316,7 +313,6 @@ void qdev_prop_set_uint64(DeviceState *dev, const char 
*name, uint64_t value);
 void qdev_prop_set_string(DeviceState *dev, const char *name, char *value);
 void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState 
*value);
 void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState 
*value);
-void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value);
 int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState 
*value) QEMU_WARN_UNUSED_RESULT;
 void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, 
BlockDriverState *value);
 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
diff --git a/net.h 

[Qemu-devel] [PATCH] net, hub: fix the indent in the comments

2012-12-06 Thread zwu . kernel
From: Zhi Yong Wu 

  Remove some redundant blanks in the comments of
net_hub_id_for_client().

Signed-off-by: Zhi Yong Wu 
---
 net/hub.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/hub.c b/net/hub.c
index be41301..3b2d1ff 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -256,7 +256,7 @@ void net_hub_info(Monitor *mon)
 /**
  * Get the hub id that a client is connected to
  *
- * @id  Pointer for hub id output, may be NULL
+ * @id: Pointer for hub id output, may be NULL
  */
 int net_hub_id_for_client(NetClientState *nc, int *id)
 {
-- 
1.7.6.5




[Qemu-devel] [PATCH] libcacard: fix compile error on glib2-2.12.3-4.el5

2014-09-26 Thread zwu . kernel
From: Zhi Yong Wu 

lt LINK libcacard.la
  CClibcacard/vscclient.o
lt LINK vscclient
/usr/bin/ld: -f may not be used without -shared
collect2: ld returned 1 exit status
make: *** [vscclient] Error 1

Signed-off-by: Zhi Yong Wu 
---
 libcacard/Makefile |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/libcacard/Makefile b/libcacard/Makefile
index 0e7903f..40f7a28 100644
--- a/libcacard/Makefile
+++ b/libcacard/Makefile
@@ -1,5 +1,6 @@
 libcacard_includedir=$(includedir)/cacard
-
+CFLAGS += -fPIC
+LDFLAGS += $(LDFLAGS_SHARED)
 TOOLS += vscclient$(EXESUF)
 
 # objects linked into a shared library, built with libtool with -fPIC if 
required
-- 
1.5.5.6




[Qemu-devel] [PATCH] block: add the support to drain throttled requests

2012-03-12 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
[ Iterate until all block devices have processed all requests,
 add comments. - Paolo ]
Signed-off-by: Paolo Bonzini 
---
 block.c |   24 ++--
 1 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/block.c b/block.c
index 52ffe14..52dabd0 100644
--- a/block.c
+++ b/block.c
@@ -858,12 +858,32 @@ void bdrv_close_all(void)
  *
  * This function does not flush data to disk, use bdrv_flush_all() for that
  * after calling this function.
- */
+ *
+ * Note that completion of an asynchronous I/O operation can trigger any
+ * number of other I/O operations on other devices---for example a coroutine
+ * can be arbitrarily complex and a constant flow of I/O to multiple devices
+ * can come until the coroutine is complete.  Because of this, it is not
+ * possible to drain a single device's I/O queue.
+*/
 void bdrv_drain_all(void)
 {
 BlockDriverState *bs;
+bool busy;
 
-qemu_aio_flush();
+do {
+busy = false;
+qemu_aio_flush();
+
+/* FIXME: We do not have timer support here, so this is effectively
+ * a busy wait.
+ */
+QTAILQ_FOREACH(bs, &bdrv_states, list) {
+if (!qemu_co_queue_empty(&bs->throttled_reqs)) {
+qemu_co_queue_restart_all(&bs->throttled_reqs);
+busy = true;
+}
+}
+} while (busy);
 
 /* If requests are still pending there is a bug somewhere */
 QTAILQ_FOREACH(bs, &bdrv_states, list) {
-- 
1.7.6




[Qemu-devel] [RFC 0/9] QOM: qomify -netdev

2012-03-25 Thread zwu . kernel
From: Zhi Yong Wu 

Sending the patchset is mainly intended to get some comments and void the wrong 
development direction.

The patchset is used to qomify -netdev, but it introduce one infrastructure for 
host devices based on raw Class and Object, not qdev. So they are not related 
with DeviceClass and DeviceState.

patch #1 introduce one new class and object for host devices.

patch #2 introduce one net host device class and object.

Note: the code changes still have some issues, but it doesn't affect that we 
talk with its infrastructure.


Zhi Yong Wu (9):
  hostdev: introduce the infrastructure for host device model
  net: introduce one net host device class
  net: adjust net common part for qomify -netdev
  net: adjust nic init API
  net: adjust dump init API
  net: qomify -netdev user
  net: qomify -netdev socket
  net: qomify -netdev vde
  net: qomify -netdev tap & -netdev bridge

 include/qemu/hostdev.h |  128 ++
 net.c  |  153 +--
 net.h  |   28 
 net/dump.c |8 +-
 net/dump.h |3 +-
 net/slirp.c|   42 ++-
 net/slirp.h|7 +-
 net/socket.c   |   38 +-
 net/socket.h   |4 +-
 net/tap.c  |   64 +-
 net/tap.h  |8 +-
 net/vde.c  |   34 +-
 net/vde.h  |4 +-
 qom/Makefile   |2 +-
 qom/hostdev.c  |  333 
 vl.c   |   12 +-
 16 files changed, 821 insertions(+), 47 deletions(-)
 create mode 100644 include/qemu/hostdev.h
 create mode 100644 qom/hostdev.c

-- 
1.7.6




[Qemu-devel] [RFC 1/9] hostdev: introduce the infrastructure for host device model

2012-03-25 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 include/qemu/hostdev.h |  128 ++
 qom/Makefile   |2 +-
 qom/hostdev.c  |  333 
 3 files changed, 462 insertions(+), 1 deletions(-)
 create mode 100644 include/qemu/hostdev.h
 create mode 100644 qom/hostdev.c

diff --git a/include/qemu/hostdev.h b/include/qemu/hostdev.h
new file mode 100644
index 000..a291761
--- /dev/null
+++ b/include/qemu/hostdev.h
@@ -0,0 +1,128 @@
+/*
+ * QEMU host device model
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Zhi Yong Wu   
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_HOSTDEV_H
+#define QEMU_HOSTDEV_H
+
+#include "qemu-queue.h"
+#include "qemu-char.h"
+#include "qemu-option.h"
+#include "qapi/qapi-visit-core.h"
+#include "qemu/object.h"
+
+typedef struct hostdevProperty hostdevProperty;
+typedef struct hostdevPropertyInfo hostdevPropertyInfo;
+
+/**
+ * SECTION: hostdev
+ * @section_id: QEMU-hostdev
+ * @title: hostdev Class
+ * @short_description: Base class for all host devices
+ */
+
+typedef struct HOSTDevice HOSTDevice;
+
+#define TYPE_HOSTDEV "host-dev"
+#define HOST_DEVICE(obj) \
+ OBJECT_CHECK(HOSTDevice, (obj), TYPE_HOSTDEV)
+#define HOSTDEV_CLASS(klass) \
+ OBJECT_CLASS_CHECK(HOSTDeviceClass, (klass), TYPE_HOSTDEV)
+#define HOSTDEV_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(HOSTDeviceClass, (obj), TYPE_HOSTDEV)
+
+/**
+ * HOSTDeviceClass:
+ *
+ * Represents a host device model.
+ */
+typedef struct HOSTDeviceClass {
+ObjectClass parent_class;
+hostdevProperty *props;
+
+int (*init)(HOSTDevice *host_dv);
+} HOSTDeviceClass;
+
+/**
+ * HOSTDevice:
+ *
+ * State of one host device.
+ */
+struct HOSTDevice {
+/*< private >*/
+Object parent_obj;
+
+/*< public >*/
+};
+
+struct hostdevProperty {
+const char   *name;
+hostdevPropertyInfo *info;
+int  offset;
+uint8_t  bitnr;
+uint8_t  qtype;
+int64_t  defval;
+};
+
+struct hostdevPropertyInfo {
+const char *name;
+const char *legacy_name;
+const char **enum_table;
+int64_t min;
+int64_t max;
+int (*parse)(HOSTDevice *dev,
+ hostdevProperty *prop,
+ const char *str);
+int (*print)(HOSTDevice *dev,
+ hostdevProperty *prop,
+ char *dest,
+ size_t len);
+ObjectPropertyAccessor *get;
+ObjectPropertyAccessor *set;
+ObjectPropertyRelease *release;
+};
+
+extern hostdevPropertyInfo hostdev_prop_int32;
+extern hostdevPropertyInfo hostdev_prop_string;
+extern hostdevPropertyInfo hostdev_prop_netdev;
+
+#define DEFINE_HOSTDEV_PROP(_name, _state, _field, _prop, _type) { \
+.name  = (_name),\
+.info  = &(_prop),   \
+.offset= offsetof(_state, _field)\
++ type_check(_type,typeof_field(_state, _field)),\
+}
+#define DEFINE_HOSTDEV_PROP_DEFAULT(_name, _state, _field, _defval, _prop, 
_type) { \
+.name  = (_name),   \
+.info  = &(_prop),  \
+.offset= offsetof(_state, _field)   \
++ type_check(_type,typeof_field(_state, _field)),   \
+.qtype = QTYPE_QINT,\
+.defval= (_type)_defval,\
+}
+#define DEFINE_HOSTDEV_PROP_END_OF_LIST()   \
+{}
+#define DEFINE_HOSTDEV_PROP_INT32(_n, _s, _f, _d)  \
+DEFINE_HOSTDEV_PROP_DEFAULT(_n, _s, _f, _d, hostdev_prop_int32, int32_t)
+#define DEFINE_HOSTDEV_PROP_PEER(_n, _s, _f) \
+DEFINE_HOSTDEV_PROP(_n, _s, _f, hostdev_prop_netdev, NetClientState*)
+#define DEFINE_HOSTDEV_PROP_STRING(_n, _s, _f) \
+DEFINE_HOSTDEV_PROP(_n, _s, _f, hostdev_prop_string, char*)
+
+HOSTDevice *hostdev_device_create(const char *type);
+int hostdev_device_init(HOSTDevice *dev, const char *type, const char *id);
+void hostdev_prop_set_string(HOSTDevice *dev,
+ const char *name, char *value);
+void hostdev_prop_set_peer(HOSTDevice *dev,
+   const char *name, NetClientState *value);
+
+#endif
diff --git a/qom/Makefile b/qom/Makefile
index 34c6de5..4731fb9 100644
--- a/qom/Makefile
+++ b/qom/Makefile
@@ -1,2 +1,2 @@
 qom-y = object.o container.o qom-qobject.o
-qom-twice-y = cpu.o
+qom-twice-y = cpu.o hostdev.o
diff --git a/qom/hostdev.c b/qom/hostdev.c
new file mode 100644
index 000..867e869
--- /dev/null
+++ b/qom/hostdev.c
@@ -0,0 +1,333 @@
+/*
+ * QEMU host device model
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Zhi Yong Wu   
+ *
+ * Thi

[Qemu-devel] [PATCH] net: qomify -netdev

2012-03-25 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 net.c|   54 +-
 net.h|2 ++
 net/slirp.c  |   33 +
 net/slirp.h  |1 +
 net/socket.c |   33 +
 net/socket.h |7 +--
 net/tap.c|   46 ++
 net/tap.h|1 +
 qom/Makefile |2 +-
 vl.c |   12 ++--
 10 files changed, 177 insertions(+), 14 deletions(-)

diff --git a/net.c b/net.c
index dd67d16..ee8737c 100644
--- a/net.c
+++ b/net.c
@@ -972,6 +972,58 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int 
is_netdev)
 return -1;
 }
 
+static int net_client_netdev_init(Monitor *mon, QemuOpts *opts, int is_netdev)
+{
+const char *name;
+const char *type;
+
+type = qemu_opt_get(opts, "type");
+if (!type) {
+qerror_report(QERR_MISSING_PARAMETER, "type");
+return -1;
+}
+
+if (is_netdev) {
+if (strcmp(type, "tap") != 0 &&
+#ifdef CONFIG_NET_BRIDGE
+strcmp(type, "bridge") != 0 &&
+#endif
+#ifdef CONFIG_SLIRP
+strcmp(type, "user") != 0 &&
+#endif
+#ifdef CONFIG_VDE
+strcmp(type, "vde") != 0 &&
+#endif
+strcmp(type, "socket") != 0) {
+qerror_report(QERR_INVALID_PARAMETER_VALUE, "type",
+  "a netdev backend type");
+return -1;
+}
+
+if (qemu_opt_get(opts, "vlan")) {
+qerror_report(QERR_INVALID_PARAMETER, "vlan");
+return -1;
+}
+if (qemu_opt_get(opts, "name")) {
+qerror_report(QERR_INVALID_PARAMETER, "name");
+return -1;
+}
+if (!qemu_opts_id(opts)) {
+qerror_report(QERR_MISSING_PARAMETER, "id");
+return -1;
+}
+}
+
+name = qemu_opts_id(opts);
+if (!name) {
+name = qemu_opt_get(opts, "name");
+}
+
+hostdev_device_add(mon, opts, (char *)name, NULL);
+
+return 0;
+}
+
 static int net_host_check_device(const char *device)
 {
 int i;
@@ -1188,7 +1240,7 @@ static int net_init_client(QemuOpts *opts, void *dummy)
 
 static int net_init_netdev(QemuOpts *opts, void *dummy)
 {
-return net_client_init(NULL, opts, 1);
+return net_client_netdev_init(NULL, opts, 1);
 }
 
 int net_init_clients(void)
diff --git a/net.h b/net.h
index 60837ab..0926a42 100644
--- a/net.h
+++ b/net.h
@@ -7,6 +7,7 @@
 #include "qemu-option.h"
 #include "net/queue.h"
 #include "vmstate.h"
+#include "qemu/hostdev.h"
 
 struct MACAddr {
 uint8_t a[6];
@@ -61,6 +62,7 @@ typedef struct NetClientInfo {
 } NetClientInfo;
 
 struct NetClientState {
+HOSTDevice host_dev;
 NetClientInfo *info;
 int link_down;
 QTAILQ_ENTRY(NetClientState) next;
diff --git a/net/slirp.c b/net/slirp.c
index d3e56fc..a30b4f0 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -777,3 +777,36 @@ int net_slirp_parse_legacy(QemuOptsList *opts_list, const 
char *optarg, int *ret
 return 1;
 }
 
+static hostdevProperty net_user_properties[] = {
+//DEFINE_PROP_STRING("type", NetClientState, info->type),
+DEFINE_HOSTDEV_PROP_INT32("link_down", NetClientState,link_down, 0),
+DEFINE_HOSTDEV_PROP_PEER("peer", NetClientState, peer),
+//DEFINE_PROP_STRING("model", NetClientState, model),
+DEFINE_HOSTDEV_PROP_STRING("name", NetClientState, name),
+//DEFINE_PROP_BIT("receive_disabled", NetClientState, receive_disabled, 0, 
true),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void net_user_class_init(ObjectClass *klass, void *data)
+{
+HOSTDeviceClass *k = HOSTDEV_CLASS(klass);
+
+k->init = net_init_slirp;
+k->props = net_user_properties;
+}
+
+static TypeInfo net_user_type = {
+.name  = "user",
+.parent= TYPE_HOSTDEV,
+.instance_size = sizeof(NetClientState),
+.class_init= net_user_class_init,
+};
+
+static void net_user_register_types(void)
+{
+#ifdef CONFIG_SLIRP
+type_register_static(&net_user_type);
+#endif
+}
+
+type_init(net_user_register_types)
diff --git a/net/slirp.h b/net/slirp.h
index e6000af..c6f5079 100644
--- a/net/slirp.h
+++ b/net/slirp.h
@@ -27,6 +27,7 @@
 #include "qemu-common.h"
 #include "qdict.h"
 #include "qemu-option.h"
+#include "qemu/hostdev.h"
 
 #ifdef CONFIG_SLIRP
 
diff --git a/net/socket.c b/net/socket.c
index 55d9820..778a5a3 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -31,6 +31,7 @@
 #include "qemu-error.h"
 #include "qemu-option.h"
 #include "qemu_socket.h"
+#include "qemu/hostdev.h"
 
 typedef struct NetSocketState {
 NetClientState nc;
@@ -587,10 +588,8 @@ static int net_socket_udp_init(NetClientState *peer,
 return 0;
 }
 
-int net_init_socket(QemuOpts *opts,
-Monitor *mon,
-const char *name,
-NetClientState *peer)
+int net_init_socket(QemuOpts *opts, Monitor *mon,
+const char *name, NetClientState *peer)

[Qemu-devel] [RFC 6/9] net: qomify -netdev user

2012-03-25 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 net/slirp.c |   42 ++
 net/slirp.h |7 +++
 2 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index d3e56fc..62fea09 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -676,10 +676,7 @@ static int net_init_slirp_configs(const char *name, const 
char *value, void *opa
 return 0;
 }
 
-int net_init_slirp(QemuOpts *opts,
-   Monitor *mon,
-   const char *name,
-   NetClientState *peer)
+int net_init_slirp(NETDevice *net_dev)
 {
 struct slirp_config_str *config;
 const char *vhost;
@@ -695,6 +692,11 @@ int net_init_slirp(QemuOpts *opts,
 int restricted = 0;
 int ret;
 
+QemuOpts *opts = net_dev->opts;
+//Monitor *mon = net_dev->mon;
+char *name = g_strdup(net_dev->name);
+NetClientState *peer = net_dev->peer;
+
 vhost   = qemu_opt_get(opts, "host");
 vhostname   = qemu_opt_get(opts, "hostname");
 vdhcp_start = qemu_opt_get(opts, "dhcpstart");
@@ -777,3 +779,35 @@ int net_slirp_parse_legacy(QemuOptsList *opts_list, const 
char *optarg, int *ret
 return 1;
 }
 
+static hostdevProperty net_user_properties[] = {
+//DEFINE_HOSTDEV_PROP_INT32("link_down", NetClientState,link_down, 0),
+DEFINE_HOSTDEV_PROP_PEER("peer", NetClientState, peer),
+DEFINE_HOSTDEV_PROP_STRING("name", NetClientState, name),
+//DEFINE_HOSTDEV_PROP_BIT("receive_disabled", NetClientState, 
receive_disabled, 0, true),
+DEFINE_HOSTDEV_PROP_END_OF_LIST(),
+};
+
+static void net_user_class_init(ObjectClass *klass, void *data)
+{
+NETDeviceClass *k = NETDEV_CLASS(klass);
+HOSTDeviceClass *dc = HOSTDEV_CLASS(klass);
+
+k->init = net_init_slirp;
+dc->props = net_user_properties;
+}
+
+static TypeInfo net_user_type = {
+.name  = "user",
+.parent= TYPE_NETDEV,
+.instance_size = sizeof(NETDevice),
+.class_init= net_user_class_init,
+};
+
+static void net_user_register_types(void)
+{
+#ifdef CONFIG_SLIRP
+type_register_static(&net_user_type);
+#endif
+}
+
+type_init(net_user_register_types)
diff --git a/net/slirp.h b/net/slirp.h
index e6000af..1364347 100644
--- a/net/slirp.h
+++ b/net/slirp.h
@@ -27,13 +27,12 @@
 #include "qemu-common.h"
 #include "qdict.h"
 #include "qemu-option.h"
+#include "qemu/hostdev.h"
+#include "net.h"
 
 #ifdef CONFIG_SLIRP
 
-int net_init_slirp(QemuOpts *opts,
-   Monitor *mon,
-   const char *name,
-   NetClientState *peer);
+int net_init_slirp(NETDevice *net_dev);
 
 void net_slirp_hostfwd_add(Monitor *mon, const QDict *qdict);
 void net_slirp_hostfwd_remove(Monitor *mon, const QDict *qdict);
-- 
1.7.6




[Qemu-devel] [RFC 4/9] net: adjust nic init API

2012-03-25 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 net.c |   10 ++
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/net.c b/net.c
index ff8ddaf..22ed51b 100644
--- a/net.c
+++ b/net.c
@@ -549,15 +549,17 @@ int net_handle_fd_param(Monitor *mon, const char *param)
 return fd;
 }
 
-static int net_init_nic(QemuOpts *opts,
-Monitor *mon,
-const char *name,
-NetClientState *peer)
+static int net_init_nic(NETDevice *host_dev)
 {
 int idx;
 NICInfo *nd;
 const char *netdev;
 
+QemuOpts *opts = host_dev->opts;
+//Monitor *mon = host_dev->mon;
+char *name = g_strdup(host_dev->name);
+NetClientState *peer = host_dev->peer;
+
 idx = nic_get_free_idx();
 if (idx == -1 || nb_nics >= MAX_NICS) {
 error_report("Too Many NICs");
-- 
1.7.6




[Qemu-devel] [PATCH] net: qomify -netdev

2012-03-25 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 cpu-common.h  |   13 +-
 hw/qdev-monitor.c |4 ++-
 hw/qdev.h |2 +
 net.c |   62 +++-
 net.h |5 
 net/dump.c|6 -
 net/dump.h|   14 ++-
 net/slirp.c   |   35 +
 net/slirp.h   |   13 +++
 net/socket.c  |   53 
 net/socket.h  |   18 +-
 net/tap-win32.c   |8 +-
 net/tap.c |   56 ++-
 net/tap.h |   26 -
 net/vde.c |4 ++-
 net/vde.h |3 +-
 qemu-log.h|6 ++--
 qemu-timer.c  |2 +-
 qom/Makefile  |2 +-
 qom/object.c  |1 -
 vl.c  |   17 --
 21 files changed, 304 insertions(+), 46 deletions(-)

diff --git a/cpu-common.h b/cpu-common.h
index dca5175..81279aa 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -3,9 +3,7 @@
 
 /* CPU interfaces that are target independent.  */
 
-#ifdef TARGET_PHYS_ADDR_BITS
 #include "targphys.h"
-#endif
 
 #ifndef NEED_CPU_H
 #include "poison.h"
@@ -23,6 +21,7 @@ enum device_endian {
 };
 
 /* address in the RAM (different from a physical address) */
+#define TARGET_PHYS_ADDR_BITS 64
 #if defined(CONFIG_XEN_BACKEND) && TARGET_PHYS_ADDR_BITS == 64
 typedef uint64_t ram_addr_t;
 #  define RAM_ADDR_MAX UINT64_MAX
@@ -35,6 +34,16 @@ typedef uintptr_t ram_addr_t;
 
 /* memory API */
 
+#if TARGET_PHYS_ADDR_BITS == 32
+typedef uint32_t target_phys_addr_t;
+#define TARGET_PHYS_ADDR_MAX UINT32_MAX
+#define TARGET_FMT_plx "%08x"
+#elif TARGET_PHYS_ADDR_BITS == 64
+typedef uint64_t target_phys_addr_t;
+#define TARGET_PHYS_ADDR_MAX UINT64_MAX
+#define TARGET_FMT_plx "%016" PRIx64
+#endif
+
 typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, 
uint32_t value);
 typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
 
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index a310cc7..82d5c50 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -19,6 +19,7 @@
 
 #include "qdev.h"
 #include "monitor.h"
+#include "net.h"
 
 /*
  * Aliases were a bad idea from the start.  Let's keep them
@@ -97,6 +98,8 @@ static int set_property(const char *name, const char *value, 
void *opaque)
 return 0;
 if (strcmp(name, "bus") == 0)
 return 0;
+if (strcmp(name, "type") == 0)
+return 0;
 
 if (qdev_prop_parse(dev, name, value) == -1) {
 return -1;
@@ -480,7 +483,6 @@ DeviceState *qdev_device_add(QemuOpts *opts)
 return qdev;
 }
 
-
 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## 
__VA_ARGS__)
 static void qbus_print(Monitor *mon, BusState *bus, int indent);
 
diff --git a/hw/qdev.h b/hw/qdev.h
index c638b98..e0c8ffa 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -144,6 +144,8 @@ DeviceState *qdev_try_create(BusState *bus, const char 
*name);
 bool qdev_exists(const char *name);
 int qdev_device_help(QemuOpts *opts);
 DeviceState *qdev_device_add(QemuOpts *opts);
+void *qdev_hostdev_add(Monitor *mon, QemuOpts *opts,
+   char *name, NetClientState *peer);
 int qdev_init(DeviceState *dev) QEMU_WARN_UNUSED_RESULT;
 void qdev_init_nofail(DeviceState *dev);
 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
diff --git a/net.c b/net.c
index dd67d16..5e4f871 100644
--- a/net.c
+++ b/net.c
@@ -624,10 +624,7 @@ static int net_init_nic(QemuOpts *opts,
 .help = "identifier for monitor commands", \
  }
 
-typedef int NetClientInitFunc(QemuOpts *opts,
-  Monitor *mon,
-  const char *name,
-  NetClientState *peer);
+typedef int NetClientInitFunc(QemuOpts *opts, Monitor *mon, const char *name, 
NetClientState *peer);
 
 /* magic number, but compiler will warn if too small */
 #define NET_MAX_DESC 20
@@ -972,6 +969,58 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int 
is_netdev)
 return -1;
 }
 
+static int net_client_netdev_init(Monitor *mon, QemuOpts *opts, int is_netdev)
+{
+const char *name;
+const char *type;
+
+type = qemu_opt_get(opts, "type");
+if (!type) {
+qerror_report(QERR_MISSING_PARAMETER, "type");
+return -1;
+}
+
+if (is_netdev) {
+if (strcmp(type, "tap") != 0 &&
+#ifdef CONFIG_NET_BRIDGE
+strcmp(type, "bridge") != 0 &&
+#endif
+#ifdef CONFIG_SLIRP
+strcmp(type, "user") != 0 &&
+#endif
+#ifdef CONFIG_VDE
+strcmp(type, "vde") != 0 &&
+#endif
+strcmp(type, "socket") != 0) {
+qerror_report(QERR_INVALID_PARAMETER_VALUE, "type",
+  "a netdev backend type");
+return -1;
+}
+
+if (qemu_opt_get(opts, "vlan")) {
+qerror_report(QERR_INVALID_PARAM

[Qemu-devel] [RFC 8/9] net: qomify -netdev vde

2012-03-25 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 net/vde.c |   34 --
 net/vde.h |4 ++--
 2 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/net/vde.c b/net/vde.c
index 8d9e1c6..c06716d 100644
--- a/net/vde.c
+++ b/net/vde.c
@@ -110,13 +110,17 @@ static int net_vde_init(NetClientState *peer, const char 
*model,
 return 0;
 }
 
-int net_init_vde(QemuOpts *opts, Monitor *mon, const char *name,
- NetClientState *peer)
+int net_init_vde(HOSTDevice *net_dev)
 {
 const char *sock;
 const char *group;
 int port, mode;
 
+QemuOpts *opts = net_dev->opts;
+Monitor *mon = net_dev->mon;
+char *name = g_strdup(net_dev->name);
+NetClientState *peer = net_dev->peer;
+
 sock  = qemu_opt_get(opts, "sock");
 group = qemu_opt_get(opts, "group");
 
@@ -129,3 +133,29 @@ int net_init_vde(QemuOpts *opts, Monitor *mon, const char 
*name,
 
 return 0;
 }
+
+static hostdevProperty net_vde_properties[] = {
+DEFINE_HOSTDEV_PROP_END_OF_LIST(),
+};
+
+static void net_vde_class_init(ObjectClass *klass, void *data)
+{
+HOSTDeviceClass *k = HOSTDEV_CLASS(klass);
+
+k->init = net_init_vde;
+k->props = net_vde_properties;
+}
+
+static TypeInfo net_vde_type = {
+.name  = "vde",
+.parent= TYPE_HOSTDEV,
+.instance_size = sizeof(NetClientState),
+.class_init= net_vde_class_init,
+};
+
+static void net_vde_register_types(void)
+{
+type_register_static(&net_user_type);
+}
+
+type_init(net_vde_register_types)
diff --git a/net/vde.h b/net/vde.h
index 276e1ff..c99a3a9 100644
--- a/net/vde.h
+++ b/net/vde.h
@@ -26,11 +26,11 @@
 
 #include "qemu-common.h"
 #include "qemu-option.h"
+#include "qemu/hostdev.h"
 
 #ifdef CONFIG_VDE
 
-int net_init_vde(QemuOpts *opts, Monitor *mon, const char *name,
- NetClientState *peer);
+int net_init_vde(NETDevice *net_dev);
 
 #endif /* CONFIG_VDE */
 
-- 
1.7.6




[Qemu-devel] [RFC 5/9] net: adjust dump init API

2012-03-25 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 net/dump.c |8 ++--
 net/dump.h |3 +--
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/net/dump.c b/net/dump.c
index 0f191d3..16e6efc 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -145,13 +145,17 @@ static int net_dump_init(NetClientState *peer, const char 
*device,
 return 0;
 }
 
-int net_init_dump(QemuOpts *opts, Monitor *mon, const char *name,
-  NetClientState *peer)
+int net_init_dump(NETDevice *net_dev)
 {
 int len;
 const char *file;
 char def_file[128];
 
+QemuOpts *opts = net_dev->opts;
+//Monitor *mon = net_dev->mon;
+char *name = g_strdup(net_dev->name);
+NetClientState *peer = net_dev->peer;
+
 assert(peer);
 
 file = qemu_opt_get(opts, "file");
diff --git a/net/dump.h b/net/dump.h
index df22afe..4bccdcf 100644
--- a/net/dump.h
+++ b/net/dump.h
@@ -27,7 +27,6 @@
 #include "net.h"
 #include "qemu-common.h"
 
-int net_init_dump(QemuOpts *opts, Monitor *mon,
-  const char *name, NetClientState *peer);
+int net_init_dump(NETDevice *net_dev);
 
 #endif /* QEMU_NET_DUMP_H */
-- 
1.7.6




[Qemu-devel] [RFC 3/9] net: adjust net common part for qomify -netdev

2012-03-25 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 net.c |  108 +---
 net.h |1 +
 vl.c  |   12 +++---
 3 files changed, 109 insertions(+), 12 deletions(-)

diff --git a/net.c b/net.c
index 608c090..ff8ddaf 100644
--- a/net.c
+++ b/net.c
@@ -624,10 +624,7 @@ static int net_init_nic(QemuOpts *opts,
 .help = "identifier for monitor commands", \
  }
 
-typedef int NetClientInitFunc(QemuOpts *opts,
-  Monitor *mon,
-  const char *name,
-  NetClientState *peer);
+typedef int NetClientInitFunc(NETDevice *host_dev);
 
 /* magic number, but compiler will warn if too small */
 #define NET_MAX_DESC 20
@@ -956,7 +953,13 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int 
is_netdev)
 
 ret = 0;
 if (net_client_types[i].init) {
-ret = net_client_types[i].init(opts, mon, name, peer);
+NETDevice host_dev;
+host_dev.mon = mon;
+host_dev.opts = opts;
+host_dev.name = g_strdup(name);
+host_dev.peer = peer;
+ret = net_client_types[i].init(&host_dev);
+//ret = net_client_types[i].init(opts, mon, name, peer);
 if (ret < 0) {
 /* TODO push error reporting into init() methods */
 qerror_report(QERR_DEVICE_INIT_FAILED, type);
@@ -972,6 +975,99 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int 
is_netdev)
 return -1;
 }
 
+static bool netdev_device_add(Monitor *mon,
+  QemuOpts *opts,
+  const char *name,
+  NetClientState *peer)
+{
+const char *type, *id;
+NETDevice *net_dev;
+HOSTDevice *host_dev;
+
+type = qemu_opt_get(opts, "type");
+if (!type) {
+qerror_report(QERR_MISSING_PARAMETER, "type");
+return false;
+}
+
+host_dev = hostdev_device_create(type);
+if (!host_dev) {
+return false;
+}
+
+net_dev = NET_DEVICE(host_dev);
+net_dev->mon = mon;
+net_dev->opts = opts;
+net_dev->name = g_strdup(name);
+net_dev->peer = peer;
+
+hostdev_prop_set_peer(&net_dev->host_dev, "peer", peer);
+//hostdev_prop_set_string(&net_dev->host_dev, "name", g_strdup(name));
+//hostdev_prop_set_string(&net_dev->host_dev, "model", g_strdup(model));
+//hostdev_prop_set_bit(&net_dev->host_dev, "receive_disabled", 
receive_disabled);
+
+id = qemu_opts_id(opts);
+if (hostdev_device_init(&net_dev->host_dev, type, id)) {
+return false;
+}
+
+return true;
+}
+
+static int net_client_netdev_init(Monitor *mon, QemuOpts *opts, int is_netdev)
+{
+const char *name;
+const char *type;
+
+type = qemu_opt_get(opts, "type");
+if (!type) {
+qerror_report(QERR_MISSING_PARAMETER, "type");
+return -1;
+}
+
+if (is_netdev) {
+if (strcmp(type, "tap") != 0 &&
+#ifdef CONFIG_NET_BRIDGE
+strcmp(type, "bridge") != 0 &&
+#endif
+#ifdef CONFIG_SLIRP
+strcmp(type, "user") != 0 &&
+#endif
+#ifdef CONFIG_VDE
+strcmp(type, "vde") != 0 &&
+#endif
+strcmp(type, "socket") != 0) {
+qerror_report(QERR_INVALID_PARAMETER_VALUE, "type",
+  "a netdev backend type");
+return -1;
+}
+
+if (qemu_opt_get(opts, "vlan")) {
+qerror_report(QERR_INVALID_PARAMETER, "vlan");
+return -1;
+}
+if (qemu_opt_get(opts, "name")) {
+qerror_report(QERR_INVALID_PARAMETER, "name");
+return -1;
+}
+if (!qemu_opts_id(opts)) {
+qerror_report(QERR_MISSING_PARAMETER, "id");
+return -1;
+}
+}
+
+name = qemu_opts_id(opts);
+if (!name) {
+name = qemu_opt_get(opts, "name");
+}
+
+if (!netdev_device_add(mon, opts, (char *)name, NULL)) {
+return -1;
+}
+
+return 0;
+}
+
 static int net_host_check_device(const char *device)
 {
 int i;
@@ -1188,7 +1284,7 @@ static int net_init_client(QemuOpts *opts, void *dummy)
 
 static int net_init_netdev(QemuOpts *opts, void *dummy)
 {
-return net_client_init(NULL, opts, 1);
+return net_client_netdev_init(NULL, opts, 1);
 }
 
 int net_init_clients(void)
diff --git a/net.h b/net.h
index 912fa2d..3de60d4 100644
--- a/net.h
+++ b/net.h
@@ -88,6 +88,7 @@ typedef struct NetClientInfo {
 } NetClientInfo;
 
 struct NetClientState {
+NETDevice net_dev;
 NetClientInfo *info;
 int link_down;
 QTAILQ_ENTRY(NetClientState) next;
diff --git a/vl.c b/vl.c
index 112b0e0..0fa8e03 100644
--- a/vl.c
+++ b/vl.c
@@ -2299,8 +2299,6 @@ int main(int argc, char **argv, char **envp)
 #endif
 }
 
-module_call_init(MODULE_INIT_QOM);
-
 runstate_init();
 
 init_clocks();
@@ -3381,10 +3

[Qemu-devel] [RFC 9/9] net: qomify -netdev tap & -netdev bridge

2012-03-25 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 net/tap.c |   64 +---
 net/tap.h |8 +++---
 2 files changed, 64 insertions(+), 8 deletions(-)

diff --git a/net/tap.c b/net/tap.c
index 65f45b8..81d022b 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -512,12 +512,16 @@ static int net_bridge_run_helper(const char *helper, 
const char *bridge)
 return -1;
 }
 
-int net_init_bridge(QemuOpts *opts, Monitor *mon, const char *name,
-NetClientState *peer)
+int net_init_bridge(NETDevice *net_dev)
 {
 TAPState *s;
 int fd, vnet_hdr;
 
+QemuOpts *opts = net_dev->opts;
+//Monitor *mon = net_dev->mon;
+char *name = g_strdup(net_dev->name);
+NetClientState *peer = net_dev->peer;
+
 if (!qemu_opt_get(opts, "br")) {
 qemu_opt_set(opts, "br", DEFAULT_BRIDGE_INTERFACE);
 }
@@ -583,13 +587,17 @@ static int net_tap_init(QemuOpts *opts, int *vnet_hdr)
 return fd;
 }
 
-int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name,
- NetClientState *peer)
+int net_init_tap(NETDevice *net_dev)
 {
 TAPState *s;
 int fd, vnet_hdr = 0;
 const char *model;
 
+QemuOpts *opts = net_dev->opts;
+Monitor *mon = net_dev->mon;
+char *name = g_strdup(net_dev->name);
+NetClientState *peer = net_dev->peer;
+
 if (qemu_opt_get(opts, "fd")) {
 if (qemu_opt_get(opts, "ifname") ||
 qemu_opt_get(opts, "script") ||
@@ -715,3 +723,51 @@ VHostNetState *tap_get_vhost_net(NetClientState *nc)
 assert(nc->info->type == NET_CLIENT_TYPE_TAP);
 return s->vhost_net;
 }
+
+static hostdevProperty net_tap_properties[] = {
+DEFINE_HOSTDEV_PROP_END_OF_LIST(),
+};
+
+static void net_tap_class_init(ObjectClass *klass, void *data)
+{
+NETDeviceClass *k = NETDEV_CLASS(klass);
+HOSTDeviceClass *dc = HOSTDEV_CLASS(klass);
+
+k->init = net_init_tap;
+dc->props = net_tap_properties;
+}
+
+static TypeInfo net_tap_type = {
+.name  = "tap",
+.parent= TYPE_NETDEV,
+.instance_size = sizeof(NetClientState),
+.class_init= net_tap_class_init,
+};
+
+static hostdevProperty net_bridge_properties[] = {
+DEFINE_HOSTDEV_PROP_END_OF_LIST(),
+};
+
+static void net_bridge_class_init(ObjectClass *klass, void *data)
+{
+NETDeviceClass *k = NETDEV_CLASS(klass);
+HOSTDeviceClass *dc = HOSTDEV_CLASS(klass);
+
+k->init = net_init_bridge;
+dc->props = net_bridge_properties;
+}
+
+static TypeInfo net_bridge_type = {
+.name  = "bridge",
+.parent= TYPE_NETDEV,
+.instance_size = sizeof(NetClientState),
+.class_init= net_bridge_class_init,
+};
+
+static void net_tap_register_types(void)
+{
+type_register_static(&net_tap_type);
+type_register_static(&net_bridge_type);
+}
+
+type_init(net_tap_register_types)
diff --git a/net/tap.h b/net/tap.h
index 0e35e81..5344d24 100644
--- a/net/tap.h
+++ b/net/tap.h
@@ -28,12 +28,13 @@
 
 #include "qemu-common.h"
 #include "qemu-option.h"
+#include "qemu/hostdev.h"
+#include "net.h"
 
 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
 #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
 
-int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name,
- NetClientState *peer);
+int net_init_tap(NETDevice *net_dev);
 
 int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int 
vnet_hdr_required);
 
@@ -58,7 +59,6 @@ int tap_get_fd(NetClientState *nc);
 struct vhost_net;
 struct vhost_net *tap_get_vhost_net(NetClientState *nc);
 
-int net_init_bridge(QemuOpts *opts, Monitor *mon, const char *name,
-NetClientState *peer);
+int net_init_bridge(NETDevice *net_dev);
 
 #endif /* QEMU_NET_TAP_H */
-- 
1.7.6




[Qemu-devel] [RFC 2/9] net: introduce one net host device class

2012-03-25 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 net.c |   35 +++
 net.h |   27 +++
 2 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/net.c b/net.c
index dd67d16..608c090 100644
--- a/net.c
+++ b/net.c
@@ -1231,3 +1231,38 @@ int net_client_parse(QemuOptsList *opts_list, const char 
*optarg)
 default_net = 0;
 return 0;
 }
+
+static int net_dev_init(HOSTDevice *host_dev)
+{
+NETDevice *net_dev = NET_DEVICE(host_dev);
+NETDeviceClass *dc = NETDEV_GET_CLASS(host_dev);
+
+if (dc->init) {
+return dc->init(net_dev);
+}
+
+return 0;
+}
+
+static void net_class_init(ObjectClass *klass, void *data)
+{
+
+HOSTDeviceClass *k = HOSTDEV_CLASS(klass);
+
+k->init = net_dev_init;
+}
+
+static TypeInfo net_type = {
+.name  = TYPE_NETDEV,
+.parent= TYPE_HOSTDEV,
+.instance_size = sizeof(NETDevice),
+.class_init= net_class_init,
+};
+
+static void net_register_types(void)
+{
+type_register_static(&net_type);
+}
+
+type_init(net_register_types)
+
diff --git a/net.h b/net.h
index 60837ab..912fa2d 100644
--- a/net.h
+++ b/net.h
@@ -7,6 +7,33 @@
 #include "qemu-option.h"
 #include "net/queue.h"
 #include "vmstate.h"
+#include "qemu/hostdev.h"
+
+typedef struct NETDevice NETDevice;
+
+#define TYPE_NETDEV "net-dev"
+#define NET_DEVICE(obj) \
+ OBJECT_CHECK(NETDevice, (obj), TYPE_NETDEV)
+#define NETDEV_CLASS(klass) \
+ OBJECT_CLASS_CHECK(NETDeviceClass, (klass), TYPE_NETDEV)
+#define NETDEV_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(NETDeviceClass, (obj), TYPE_NETDEV)
+
+typedef struct NETDeviceClass {
+HOSTDeviceClass parent_class;
+int (*init)(NETDevice *net_dev);
+} NETDeviceClass;
+
+struct NETDevice {
+/*< private >*/
+HOSTDevice host_dev;
+
+/*< public >*/
+QemuOpts *opts;
+Monitor *mon;
+const char *name;
+NetClientState *peer;
+};
 
 struct MACAddr {
 uint8_t a[6];
-- 
1.7.6




[Qemu-devel] [RFC 7/9] net: qomify -netdev socket

2012-03-25 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 net/socket.c |   38 ++
 net/socket.h |4 ++--
 2 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index 55d9820..fe18e87 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -31,6 +31,7 @@
 #include "qemu-error.h"
 #include "qemu-option.h"
 #include "qemu_socket.h"
+#include "qemu/hostdev.h"
 
 typedef struct NetSocketState {
 NetClientState nc;
@@ -587,11 +588,13 @@ static int net_socket_udp_init(NetClientState *peer,
 return 0;
 }
 
-int net_init_socket(QemuOpts *opts,
-Monitor *mon,
-const char *name,
-NetClientState *peer)
+int net_init_socket(NETDevice *net_dev)
 {
+QemuOpts *opts = net_dev->opts;
+Monitor *mon = net_dev->mon;
+char *name = g_strdup(net_dev->name);
+NetClientState *peer = net_dev->peer;
+
 if (qemu_opt_get(opts, "fd")) {
 int fd;
 
@@ -690,3 +693,30 @@ int net_init_socket(QemuOpts *opts,
 }
 return 0;
 }
+
+static hostdevProperty net_socket_properties[] = {
+DEFINE_HOSTDEV_PROP_END_OF_LIST(),
+};
+
+static void net_socket_class_init(ObjectClass *klass, void *data)
+{
+NETDeviceClass *k = NETDEV_CLASS(klass);
+HOSTDeviceClass *dc = HOSTDEV_CLASS(klass);
+
+k->init = net_init_socket;
+dc->props = net_socket_properties;
+}
+
+static TypeInfo net_socket_type = {
+.name  = "socket",
+.parent= TYPE_NETDEV,
+.instance_size = sizeof(NetClientState),
+.class_init= net_socket_class_init,
+};
+
+static void net_socket_register_types(void)
+{
+type_register_static(&net_socket_type);
+}
+
+type_init(net_socket_register_types)
diff --git a/net/socket.h b/net/socket.h
index 5edf17c..1ac7c85 100644
--- a/net/socket.h
+++ b/net/socket.h
@@ -26,8 +26,8 @@
 
 #include "net.h"
 #include "qemu-common.h"
+#include "qemu/hostdev.h"
 
-int net_init_socket(QemuOpts *opts, Monitor *mon,
-const char *name, NetClientState *peer);
+int net_init_socket(NETDevice *net_dev);
 
 #endif /* QEMU_NET_SOCKET_H */
-- 
1.7.6




[Qemu-devel] [PATCH 1/2] block: add the support to drain throttled requests

2012-03-26 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 block.c |   16 +++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/block.c b/block.c
index b88ee90..1fbf4dd 100644
--- a/block.c
+++ b/block.c
@@ -862,8 +862,22 @@ void bdrv_close_all(void)
 void bdrv_drain_all(void)
 {
 BlockDriverState *bs;
+bool busy;
 
-qemu_aio_flush();
+do {
+busy = false;
+qemu_aio_flush();
+
+/* FIXME: We do not have timer support here, so this is effectively
+ * a busy wait.
+ */
+QTAILQ_FOREACH(bs, &bdrv_states, list) {
+if (!qemu_co_queue_empty(&bs->throttled_reqs)) {
+qemu_co_queue_restart_all(&bs->throttled_reqs);
+busy = true;
+}
+}
+} while (busy);
 
 /* If requests are still pending there is a bug somewhere */
 QTAILQ_FOREACH(bs, &bdrv_states, list) {
-- 
1.7.6




[Qemu-devel] [PATCH 2/2] block: disable I/O throttling on sync api

2012-03-26 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 block.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/block.c b/block.c
index 1fbf4dd..5baf340 100644
--- a/block.c
+++ b/block.c
@@ -1477,6 +1477,12 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t 
sector_num, uint8_t *buf,
 
 qemu_iovec_init_external(&qiov, &iov, 1);
 
+if (bs->io_limits_enabled) {
+fprintf(stderr, "Disabling I/O throttling on '%s' due "
+"to synchronous I/O.\n", bdrv_get_device_name(bs));
+bdrv_io_limits_disable(bs);
+}
+
 if (qemu_in_coroutine()) {
 /* Fast-path if already in coroutine context */
 bdrv_rw_co_entry(&rwco);
-- 
1.7.6




[Qemu-devel] [PATCH 1/2] block: add the support to drain throttled requests

2012-03-26 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Paolo Bonzini 
Signed-off-by: Zhi Yong Wu 
---
 block.c |   16 +++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/block.c b/block.c
index b88ee90..1fbf4dd 100644
--- a/block.c
+++ b/block.c
@@ -862,8 +862,22 @@ void bdrv_close_all(void)
 void bdrv_drain_all(void)
 {
 BlockDriverState *bs;
+bool busy;
 
-qemu_aio_flush();
+do {
+busy = false;
+qemu_aio_flush();
+
+/* FIXME: We do not have timer support here, so this is effectively
+ * a busy wait.
+ */
+QTAILQ_FOREACH(bs, &bdrv_states, list) {
+if (!qemu_co_queue_empty(&bs->throttled_reqs)) {
+qemu_co_queue_restart_all(&bs->throttled_reqs);
+busy = true;
+}
+}
+} while (busy);
 
 /* If requests are still pending there is a bug somewhere */
 QTAILQ_FOREACH(bs, &bdrv_states, list) {
-- 
1.7.6




[Qemu-devel] [PATCH 2/2] block: disable I/O throttling on sync api

2012-03-26 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 block.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/block.c b/block.c
index 1fbf4dd..5baf340 100644
--- a/block.c
+++ b/block.c
@@ -1477,6 +1477,12 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t 
sector_num, uint8_t *buf,
 
 qemu_iovec_init_external(&qiov, &iov, 1);
 
+if (bs->io_limits_enabled) {
+fprintf(stderr, "Disabling I/O throttling on '%s' due "
+"to synchronous I/O.\n", bdrv_get_device_name(bs));
+bdrv_io_limits_disable(bs);
+}
+
 if (qemu_in_coroutine()) {
 /* Fast-path if already in coroutine context */
 bdrv_rw_co_entry(&rwco);
-- 
1.7.6




[Qemu-devel] [PATCH v2 2/2] block: disable I/O throttling on sync api

2012-03-27 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 block.c |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/block.c b/block.c
index 1fbf4dd..f0b4f38 100644
--- a/block.c
+++ b/block.c
@@ -1477,6 +1477,12 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t 
sector_num, uint8_t *buf,
 
 qemu_iovec_init_external(&qiov, &iov, 1);
 
+if (bs->io_limits_enabled) {
+fprintf(stderr, "Disabling I/O throttling on '%s' due "
+"to synchronous I/O.\n", bdrv_get_device_name(bs));
+bdrv_io_limits_disable(bs);
+}
+
 if (qemu_in_coroutine()) {
 /* Fast-path if already in coroutine context */
 bdrv_rw_co_entry(&rwco);
@@ -1983,10 +1989,14 @@ static int guess_disk_lchs(BlockDriverState *bs,
 struct partition *p;
 uint32_t nr_sects;
 uint64_t nb_sectors;
+bool enabled;
 
 bdrv_get_geometry(bs, &nb_sectors);
 
+enabled = bs->io_limits_enabled;
+bs->io_limits_enabled = false;
 ret = bdrv_read(bs, 0, buf, 1);
+bs->io_limits_enabled = enabled;
 if (ret < 0)
 return -1;
 /* test msdos magic */
-- 
1.7.6




[Qemu-devel] [PATCH v3 2/2] block: disable I/O throttling on sync api

2012-03-30 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 block.c |   22 ++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/block.c b/block.c
index 1fbf4dd..6de6f89 100644
--- a/block.c
+++ b/block.c
@@ -1477,6 +1477,17 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t 
sector_num, uint8_t *buf,
 
 qemu_iovec_init_external(&qiov, &iov, 1);
 
+/**
+ * In sync call context, when the vcpu is blocked, this throttling timer
+ * will not fire; so the I/O throttling function has to be disabled here
+ * if it has been enabled.
+ */
+if (bs->io_limits_enabled) {
+fprintf(stderr, "Disabling I/O throttling on '%s' due "
+"to synchronous I/O.\n", bdrv_get_device_name(bs));
+bdrv_io_limits_disable(bs);
+}
+
 if (qemu_in_coroutine()) {
 /* Fast-path if already in coroutine context */
 bdrv_rw_co_entry(&rwco);
@@ -1983,10 +1994,21 @@ static int guess_disk_lchs(BlockDriverState *bs,
 struct partition *p;
 uint32_t nr_sects;
 uint64_t nb_sectors;
+bool enabled;
 
 bdrv_get_geometry(bs, &nb_sectors);
 
+/**
+ * The function will be invoked during startup not only in sync I/O mode,
+ * but also in async I/O mode. So the I/O throttling function has to
+ * be disabled temporarily here, not permanently.
+ * When all sync I/O drivers are converted to async I/O, it will be 
restored
+ * to the original state.
+ */
+enabled = bs->io_limits_enabled;
+bs->io_limits_enabled = false;
 ret = bdrv_read(bs, 0, buf, 1);
+bs->io_limits_enabled = enabled;
 if (ret < 0)
 return -1;
 /* test msdos magic */
-- 
1.7.6




[Qemu-devel] [PATCH v4 13/16] net: Make "info network" output more readable info

2012-05-25 Thread zwu . kernel
From: Zhi Yong Wu 

Reviewed-by:   Jan Kiszka  
Signed-off-by: Zhi Yong Wu 
---
 net.c |   18 ++
 net.h |   12 
 net/hub.c |   23 +--
 net/hub.h |1 +
 4 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/net.c b/net.c
index 61dc28d..ae0deec 100644
--- a/net.c
+++ b/net.c
@@ -887,6 +887,12 @@ static const struct {
 },
 },
 #endif /* CONFIG_NET_BRIDGE */
+[NET_CLIENT_TYPE_HUB] = {
+.type = "hubport",
+.desc = {
+{ /* end of list */ }
+},
+},
 };
 
 int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
@@ -1068,7 +1074,7 @@ int do_netdev_del(Monitor *mon, const QDict *qdict, 
QObject **ret_data)
 return 0;
 }
 
-static void print_net_client(Monitor *mon, NetClientState *vc)
+void print_net_client(Monitor *mon, NetClientState *vc)
 {
 monitor_printf(mon, "%s: type=%s,%s\n", vc->name,
net_client_types[vc->info->type].type, vc->info_str);
@@ -1079,12 +1085,17 @@ void do_info_network(Monitor *mon)
 NetClientState *nc, *peer;
 net_client_type type;
 
-monitor_printf(mon, "Devices not on any VLAN:\n");
+net_hub_info(mon);
+
 QTAILQ_FOREACH(nc, &net_clients, next) {
 peer = nc->peer;
 type = nc->info->type;
+
+if (net_hub_port_peer_nc(nc)) {
+continue;
+}
+
 if (!peer || type == NET_CLIENT_TYPE_NIC) {
-monitor_printf(mon, "  ");
 print_net_client(mon, nc);
 } /* else it's a netdev connected to a NIC, printed with the NIC */
 if (peer && type == NET_CLIENT_TYPE_NIC) {
@@ -1092,7 +1103,6 @@ void do_info_network(Monitor *mon)
 print_net_client(mon, peer);
 }
 }
-net_hub_info(mon);
 }
 
 void qmp_set_link(const char *name, bool up, Error **errp)
diff --git a/net.h b/net.h
index 250669a..08306a4 100644
--- a/net.h
+++ b/net.h
@@ -112,6 +112,18 @@ void qemu_check_nic_model(NICInfo *nd, const char *model);
 int qemu_find_nic_model(NICInfo *nd, const char * const *models,
 const char *default_model);
 
+ssize_t qemu_deliver_packet(NetClientState *sender,
+unsigned flags,
+const uint8_t *data,
+size_t size,
+void *opaque);
+ssize_t qemu_deliver_packet_iov(NetClientState *sender,
+unsigned flags,
+const struct iovec *iov,
+int iovcnt,
+void *opaque);
+
+void print_net_client(Monitor *mon, NetClientState *vc);
 void do_info_network(Monitor *mon);
 
 /* NIC info */
diff --git a/net/hub.c b/net/hub.c
index 122de69..8c77d03 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -184,6 +184,25 @@ NetClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
 }
 
 /**
+ * Determine if one nc peers with one hub port
+ */
+bool net_hub_port_peer_nc(NetClientState *nc)
+{
+NetHub *hub;
+NetHubPort *port;
+
+QLIST_FOREACH(hub, &hubs, next) {
+QLIST_FOREACH(port, &hub->ports, next) {
+if (nc == port->nc.peer) {
+return true;
+}
+}
+}
+
+return false;
+}
+
+/**
  * Print hub configuration
  */
 void net_hub_info(Monitor *mon)
@@ -194,8 +213,8 @@ void net_hub_info(Monitor *mon)
 QLIST_FOREACH(hub, &hubs, next) {
 monitor_printf(mon, "hub %u\n", hub->id);
 QLIST_FOREACH(port, &hub->ports, next) {
-monitor_printf(mon, "port %u peer %s\n", port->id,
-   port->nc.peer ? port->nc.peer->name : "");
+monitor_printf(mon, "   \\ ");
+print_net_client(mon, port->nc.peer);
 }
 }
 }
diff --git a/net/hub.h b/net/hub.h
index ff5024a..550189b 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -23,5 +23,6 @@ NetClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
 void net_hub_info(Monitor *mon);
 int net_hub_id_for_client(NetClientState *nc, unsigned int *id);
 void net_hub_check_clients(void);
+bool net_hub_port_peer_nc(NetClientState *nc);
 
 #endif /* NET_HUB_H */
-- 
1.7.6




[Qemu-devel] [PATCH v4 13/16] net: Make "info network" output more readable info

2012-05-25 Thread zwu . kernel
From: Zhi Yong Wu 

Reviewed-by:   Jan Kiszka  
Signed-off-by: Zhi Yong Wu 
---
 net.c |   18 ++
 net.h |1 +
 net/hub.c |   23 +--
 net/hub.h |1 +
 4 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/net.c b/net.c
index 61dc28d..ae0deec 100644
--- a/net.c
+++ b/net.c
@@ -887,6 +887,12 @@ static const struct {
 },
 },
 #endif /* CONFIG_NET_BRIDGE */
+[NET_CLIENT_TYPE_HUB] = {
+.type = "hubport",
+.desc = {
+{ /* end of list */ }
+},
+},
 };
 
 int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
@@ -1068,7 +1074,7 @@ int do_netdev_del(Monitor *mon, const QDict *qdict, 
QObject **ret_data)
 return 0;
 }
 
-static void print_net_client(Monitor *mon, NetClientState *vc)
+void print_net_client(Monitor *mon, NetClientState *vc)
 {
 monitor_printf(mon, "%s: type=%s,%s\n", vc->name,
net_client_types[vc->info->type].type, vc->info_str);
@@ -1079,12 +1085,17 @@ void do_info_network(Monitor *mon)
 NetClientState *nc, *peer;
 net_client_type type;
 
-monitor_printf(mon, "Devices not on any VLAN:\n");
+net_hub_info(mon);
+
 QTAILQ_FOREACH(nc, &net_clients, next) {
 peer = nc->peer;
 type = nc->info->type;
+
+if (net_hub_port_peer_nc(nc)) {
+continue;
+}
+
 if (!peer || type == NET_CLIENT_TYPE_NIC) {
-monitor_printf(mon, "  ");
 print_net_client(mon, nc);
 } /* else it's a netdev connected to a NIC, printed with the NIC */
 if (peer && type == NET_CLIENT_TYPE_NIC) {
@@ -1092,7 +1103,6 @@ void do_info_network(Monitor *mon)
 print_net_client(mon, peer);
 }
 }
-net_hub_info(mon);
 }
 
 void qmp_set_link(const char *name, bool up, Error **errp)
diff --git a/net.h b/net.h
index 250669a..0692283 100644
--- a/net.h
+++ b/net.h
@@ -112,6 +112,7 @@ void qemu_check_nic_model(NICInfo *nd, const char *model);
 int qemu_find_nic_model(NICInfo *nd, const char * const *models,
 const char *default_model);
 
+void print_net_client(Monitor *mon, NetClientState *vc);
 void do_info_network(Monitor *mon);
 
 /* NIC info */
diff --git a/net/hub.c b/net/hub.c
index 122de69..8c77d03 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -184,6 +184,25 @@ NetClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
 }
 
 /**
+ * Determine if one nc peers with one hub port
+ */
+bool net_hub_port_peer_nc(NetClientState *nc)
+{
+NetHub *hub;
+NetHubPort *port;
+
+QLIST_FOREACH(hub, &hubs, next) {
+QLIST_FOREACH(port, &hub->ports, next) {
+if (nc == port->nc.peer) {
+return true;
+}
+}
+}
+
+return false;
+}
+
+/**
  * Print hub configuration
  */
 void net_hub_info(Monitor *mon)
@@ -194,8 +213,8 @@ void net_hub_info(Monitor *mon)
 QLIST_FOREACH(hub, &hubs, next) {
 monitor_printf(mon, "hub %u\n", hub->id);
 QLIST_FOREACH(port, &hub->ports, next) {
-monitor_printf(mon, "port %u peer %s\n", port->id,
-   port->nc.peer ? port->nc.peer->name : "");
+monitor_printf(mon, "   \\ ");
+print_net_client(mon, port->nc.peer);
 }
 }
 }
diff --git a/net/hub.h b/net/hub.h
index ff5024a..550189b 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -23,5 +23,6 @@ NetClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
 void net_hub_info(Monitor *mon);
 int net_hub_id_for_client(NetClientState *nc, unsigned int *id);
 void net_hub_check_clients(void);
+bool net_hub_port_peer_nc(NetClientState *nc);
 
 #endif /* NET_HUB_H */
-- 
1.7.6




[Qemu-devel] [PULL 1.2 00/16] hub-based networking patches

2012-06-03 Thread zwu . kernel
From: Zhi Yong Wu 

All comments from other guys were addressed.

The following changes since commit a854972f8cdec0148087789d62777d8f7176933d:

 Update version to open the 1.2 development branch (Fri Jun 1 16:56:16 2012 
+0800)

are available in the git repository at:

 g...@github.com:wuzhy/qemu.git for-anthony

Stefan Hajnoczi (12):
  net: Add a hub net client
  net: Use hubs for the vlan feature
  net: Look up 'vlan' net clients using hubs
  hub: Check that hubs are configured correctly
  net: Drop vlan argument to qemu_new_net_client()
  net: Remove vlan qdev property
  net: Remove vlan code from net.c
  net: Remove VLANState
  net: Rename non_vlan_clients to net_clients
  net: Rename VLANClientState to NetClientState
  net: Rename vc local variables to nc
  net: Rename qemu_del_vlan_client() to qemu_del_net_client()

Zhi Yong Wu (4):
  net: Make "info network" output more readable info
  net: cleanup deliver/deliver_iov func pointers
  net: determine if packets can be sent before net queue deliver
packets
  hub: add the support for hub own flow control

 Makefile.objs   |2 +-
 hw/cadence_gem.c|8 +-
 hw/dp8393x.c|6 +-
 hw/e1000.c  |   10 +-
 hw/eepro100.c   |8 +-
 hw/etraxfs_eth.c|8 +-
 hw/lan9118.c|8 +-
 hw/lance.c  |2 +-
 hw/mcf_fec.c|6 +-
 hw/milkymist-minimac2.c |6 +-
 hw/mipsnet.c|6 +-
 hw/musicpal.c   |6 +-
 hw/ne2000-isa.c |2 +-
 hw/ne2000.c |8 +-
 hw/ne2000.h |4 +-
 hw/opencores_eth.c  |8 +-
 hw/pcnet-pci.c  |4 +-
 hw/pcnet.c  |6 +-
 hw/pcnet.h  |6 +-
 hw/qdev-properties.c|   78 +--
 hw/qdev.c   |2 -
 hw/qdev.h   |8 +-
 hw/rtl8139.c|   10 +-
 hw/smc91c111.c  |6 +-
 hw/spapr_llan.c |4 +-
 hw/stellaris_enet.c |6 +-
 hw/usb/dev-network.c|8 +-
 hw/vhost_net.c  |   24 +-
 hw/vhost_net.h  |2 +-
 hw/virtio-net.c |   12 +-
 hw/xen_nic.c|7 +-
 hw/xgmac.c  |6 +-
 hw/xilinx_axienet.c |6 +-
 hw/xilinx_ethlite.c |6 +-
 net.c   |  605 ++-
 net.h   |   86 
 net/dump.c  |   28 ++-
 net/dump.h  |2 +-
 net/hub.c   |  310 
 net/hub.h   |   28 +++
 net/queue.c |   37 ++--
 net/queue.h |   25 +--
 net/slirp.c |   32 +--
 net/slirp.h |2 +-
 net/socket.c|   66 +++---
 net/socket.h|2 +-
 net/tap-win32.c |   27 +-
 net/tap.c   |   45 ++--
 net/tap.h   |   21 +-
 net/vde.c   |   17 +-
 net/vde.h   |3 +-
 qemu-common.h   |3 +-
 slirp/if.c  |5 -
 slirp/libslirp.h|1 -
 54 files changed, 818 insertions(+), 826 deletions(-)
 create mode 100644 net/hub.c
 create mode 100644 net/hub.h

-- 
1.7.6




[Qemu-devel] [PATCH v4 00/16] hub-based networking patches

2012-06-03 Thread zwu . kernel
From: Zhi Yong Wu 

All comments from other guys were addressed.

The following changes since commit a854972f8cdec0148087789d62777d8f7176933d:

 Update version to open the 1.2 development branch (Fri Jun 1 16:56:16 2012 
+0800)

are available in the git repository at:

 g...@github.com:wuzhy/qemu.git for-anthony

Changelog from v3:
 1.) refactor hub own flow control [paolo]
 2.) refactor the output for monitor command "info network" [jan kiszka]

v3:
 1.) add the support for hub own flow control [paolo]
 2.) make the monitor output more reasonable hub info [jan kiszka]

v2:
 1.) cleanup some obsolete vlan info
 2.) cleanup deliver/deliver_iov func pointers [paolo]
 3.) support more flexible flow control [paolo]

Stefan Hajnoczi (12):
  net: Add a hub net client
  net: Use hubs for the vlan feature
  net: Look up 'vlan' net clients using hubs
  hub: Check that hubs are configured correctly
  net: Drop vlan argument to qemu_new_net_client()
  net: Remove vlan qdev property
  net: Remove vlan code from net.c
  net: Remove VLANState
  net: Rename non_vlan_clients to net_clients
  net: Rename VLANClientState to NetClientState
  net: Rename vc local variables to nc
  net: Rename qemu_del_vlan_client() to qemu_del_net_client()

Zhi Yong Wu (4):
  net: Make "info network" output more readable info
  net: cleanup deliver/deliver_iov func pointers
  net: determine if packets can be sent before net queue deliver
packets
  hub: add the support for hub own flow control

 Makefile.objs   |2 +-
 hw/cadence_gem.c|8 +-
 hw/dp8393x.c|6 +-
 hw/e1000.c  |   10 +-
 hw/eepro100.c   |8 +-
 hw/etraxfs_eth.c|8 +-
 hw/lan9118.c|8 +-
 hw/lance.c  |2 +-
 hw/mcf_fec.c|6 +-
 hw/milkymist-minimac2.c |6 +-
 hw/mipsnet.c|6 +-
 hw/musicpal.c   |6 +-
 hw/ne2000-isa.c |2 +-
 hw/ne2000.c |8 +-
 hw/ne2000.h |4 +-
 hw/opencores_eth.c  |8 +-
 hw/pcnet-pci.c  |4 +-
 hw/pcnet.c  |6 +-
 hw/pcnet.h  |6 +-
 hw/qdev-properties.c|   78 +--
 hw/qdev.c   |2 -
 hw/qdev.h   |8 +-
 hw/rtl8139.c|   10 +-
 hw/smc91c111.c  |6 +-
 hw/spapr_llan.c |4 +-
 hw/stellaris_enet.c |6 +-
 hw/usb/dev-network.c|8 +-
 hw/vhost_net.c  |   24 +-
 hw/vhost_net.h  |2 +-
 hw/virtio-net.c |   12 +-
 hw/xen_nic.c|7 +-
 hw/xgmac.c  |6 +-
 hw/xilinx_axienet.c |6 +-
 hw/xilinx_ethlite.c |6 +-
 net.c   |  605 ++-
 net.h   |   86 
 net/dump.c  |   28 ++-
 net/dump.h  |2 +-
 net/hub.c   |  310 
 net/hub.h   |   28 +++
 net/queue.c |   37 ++--
 net/queue.h |   25 +--
 net/slirp.c |   32 +--
 net/slirp.h |2 +-
 net/socket.c|   66 +++---
 net/socket.h|2 +-
 net/tap-win32.c |   27 +-
 net/tap.c   |   45 ++--
 net/tap.h   |   21 +-
 net/vde.c   |   17 +-
 net/vde.h   |3 +-
 qemu-common.h   |3 +-
 slirp/if.c  |5 -
 slirp/libslirp.h|1 -
 54 files changed, 818 insertions(+), 826 deletions(-)
 create mode 100644 net/hub.c
 create mode 100644 net/hub.h

-- 
1.7.6




[Qemu-devel] [PATCH v4 02/16] net: Use hubs for the vlan feature

2012-06-03 Thread zwu . kernel
From: Stefan Hajnoczi 

Stop using the special-case vlan code in net.c.  Instead use the hub net
client to implement the vlan feature.  The next patch will remove vlan
code from net.c completely.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c   |   46 +-
 net/dump.c  |   20 ++--
 net/dump.h  |2 +-
 net/slirp.c |8 
 net/slirp.h |2 +-
 net/socket.c|   48 ++--
 net/socket.h|2 +-
 net/tap-win32.c |9 +
 net/tap.c   |7 ---
 net/tap.h   |3 ++-
 net/vde.c   |9 +
 net/vde.h   |3 ++-
 12 files changed, 90 insertions(+), 69 deletions(-)

diff --git a/net.c b/net.c
index 1922d8a..8c02559 100644
--- a/net.c
+++ b/net.c
@@ -25,6 +25,7 @@
 
 #include "config-host.h"
 
+#include "net/hub.h"
 #include "net/tap.h"
 #include "net/socket.h"
 #include "net/dump.h"
@@ -153,23 +154,25 @@ void qemu_macaddr_default_if_unset(MACAddr *macaddr)
 macaddr->a[5] = 0x56 + index++;
 }
 
+/**
+ * Generate a name for net client
+ *
+ * Only net clients created with the legacy -net option need this.  Naming is
+ * mandatory for net clients created with -netdev.
+ */
 static char *assign_name(VLANClientState *vc1, const char *model)
 {
-VLANState *vlan;
 VLANClientState *vc;
 char buf[256];
 int id = 0;
 
-QTAILQ_FOREACH(vlan, &vlans, next) {
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-if (vc != vc1 && strcmp(vc->model, model) == 0) {
-id++;
-}
-}
-}
-
 QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
-if (vc != vc1 && strcmp(vc->model, model) == 0) {
+if (vc == vc1) {
+continue;
+}
+/* For compatibility only bump id for net clients on a vlan */
+if (strcmp(vc->model, model) == 0 &&
+net_hub_id_for_client(vc, NULL) == 0) {
 id++;
 }
 }
@@ -748,7 +751,7 @@ int net_handle_fd_param(Monitor *mon, const char *param)
 static int net_init_nic(QemuOpts *opts,
 Monitor *mon,
 const char *name,
-VLANState *vlan)
+VLANClientState *peer)
 {
 int idx;
 NICInfo *nd;
@@ -771,8 +774,8 @@ static int net_init_nic(QemuOpts *opts,
 return -1;
 }
 } else {
-assert(vlan);
-nd->vlan = vlan;
+assert(peer);
+nd->netdev = peer;
 }
 if (name) {
 nd->name = g_strdup(name);
@@ -820,17 +823,17 @@ static int net_init_nic(QemuOpts *opts,
 .help = "identifier for monitor commands", \
  }
 
-typedef int (*net_client_init_func)(QemuOpts *opts,
-Monitor *mon,
-const char *name,
-VLANState *vlan);
+typedef int NetClientInitFunc(QemuOpts *opts,
+  Monitor *mon,
+  const char *name,
+  VLANClientState *peer);
 
 /* magic number, but compiler will warn if too small */
 #define NET_MAX_DESC 20
 
 static const struct {
 const char *type;
-net_client_init_func init;
+NetClientInitFunc *init;
 QemuOptDesc desc[NET_MAX_DESC];
 } net_client_types[NET_CLIENT_TYPE_MAX] = {
 [NET_CLIENT_TYPE_NONE] = {
@@ -1136,7 +1139,7 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int 
is_netdev)
 for (i = 0; i < NET_CLIENT_TYPE_MAX; i++) {
 if (net_client_types[i].type != NULL &&
 !strcmp(net_client_types[i].type, type)) {
-VLANState *vlan = NULL;
+VLANClientState *peer = NULL;
 int ret;
 
 if (qemu_opts_validate(opts, &net_client_types[i].desc[0]) == -1) {
@@ -1147,12 +1150,12 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int 
is_netdev)
  * netdev= parameter. */
 if (!(is_netdev ||
   (strcmp(type, "nic") == 0 && qemu_opt_get(opts, "netdev" 
{
-vlan = qemu_find_vlan(qemu_opt_get_number(opts, "vlan", 0), 1);
+peer = net_hub_add_port(qemu_opt_get_number(opts, "vlan", 0));
 }
 
 ret = 0;
 if (net_client_types[i].init) {
-ret = net_client_types[i].init(opts, mon, name, vlan);
+ret = net_client_types[i].init(opts, mon, name, peer);
 if (ret < 0) {
 /* TODO push error reporting into init() methods */
 qerror_report(QERR_DEVICE_INIT_FAILED, type);
@@ -1297,6 +1300,7 @@ void do_info_network(Monitor *mon)
 print_net_client(mon, peer);
 }
 }
+net_hub_info(mon);
 }
 
 void qmp_set_link(const char *name, bool up, Error **errp)
diff --git a/net/dump.c b/net/dump.c
index 4b48d48..37cec3c 100644
--- a/net/dump.

[Qemu-devel] [PATCH v4 03/16] net: Look up 'vlan' net clients using hubs

2012-06-03 Thread zwu . kernel
From: Stefan Hajnoczi 

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c   |   28 +---
 net/hub.c   |   24 
 net/hub.h   |2 ++
 net/slirp.c |5 +++--
 4 files changed, 30 insertions(+), 29 deletions(-)

diff --git a/net.c b/net.c
index 8c02559..d9c7eac 100644
--- a/net.c
+++ b/net.c
@@ -312,32 +312,6 @@ void qemu_del_vlan_client(VLANClientState *vc)
 qemu_free_vlan_client(vc);
 }
 
-VLANClientState *
-qemu_find_vlan_client_by_name(Monitor *mon, int vlan_id,
-  const char *client_str)
-{
-VLANState *vlan;
-VLANClientState *vc;
-
-vlan = qemu_find_vlan(vlan_id, 0);
-if (!vlan) {
-monitor_printf(mon, "unknown VLAN %d\n", vlan_id);
-return NULL;
-}
-
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-if (!strcmp(vc->name, client_str)) {
-break;
-}
-}
-if (!vc) {
-monitor_printf(mon, "can't find device %s on VLAN %d\n",
-   client_str, vlan_id);
-}
-
-return vc;
-}
-
 void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
 {
 VLANClientState *nc;
@@ -1223,7 +1197,7 @@ void net_host_device_remove(Monitor *mon, const QDict 
*qdict)
 int vlan_id = qdict_get_int(qdict, "vlan_id");
 const char *device = qdict_get_str(qdict, "device");
 
-vc = qemu_find_vlan_client_by_name(mon, vlan_id, device);
+vc = net_hub_find_client_by_name(vlan_id, device);
 if (!vc) {
 return;
 }
diff --git a/net/hub.c b/net/hub.c
index 28ff45c..56efc2c 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -160,6 +160,30 @@ VLANClientState *net_hub_add_port(unsigned int hub_id)
 }
 
 /**
+ * Find a specific client on a hub
+ */
+VLANClientState *net_hub_find_client_by_name(unsigned int hub_id,
+ const char *name)
+{
+NetHub *hub;
+NetHubPort *port;
+VLANClientState *peer;
+
+QLIST_FOREACH(hub, &hubs, next) {
+if (hub->id == hub_id) {
+QLIST_FOREACH(port, &hub->ports, next) {
+peer = port->nc.peer;
+
+if (peer && strcmp(peer->name, name) == 0) {
+return peer;
+}
+}
+}
+}
+return NULL;
+}
+
+/**
  * Print hub configuration
  */
 void net_hub_info(Monitor *mon)
diff --git a/net/hub.h b/net/hub.h
index bf8798b..e149e04 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -18,6 +18,8 @@
 #include "qemu-common.h"
 
 VLANClientState *net_hub_add_port(unsigned int hub_id);
+VLANClientState *net_hub_find_client_by_name(unsigned int hub_id,
+ const char *name);
 void net_hub_info(Monitor *mon);
 int net_hub_id_for_client(VLANClientState *nc, unsigned int *id);
 
diff --git a/net/slirp.c b/net/slirp.c
index fa7c7fc..edb4621 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -29,6 +29,7 @@
 #include 
 #endif
 #include "net.h"
+#include "net/hub.h"
 #include "monitor.h"
 #include "qemu_socket.h"
 #include "slirp/libslirp.h"
@@ -283,7 +284,7 @@ static SlirpState *slirp_lookup(Monitor *mon, const char 
*vlan,
 
 if (vlan) {
 VLANClientState *nc;
-nc = qemu_find_vlan_client_by_name(mon, strtol(vlan, NULL, 0), stack);
+nc = net_hub_find_client_by_name(strtol(vlan, NULL, 0), stack);
 if (!nc) {
 return NULL;
 }
@@ -648,7 +649,7 @@ void do_info_usernet(Monitor *mon)
 
 QTAILQ_FOREACH(s, &slirp_stacks, entry) {
 monitor_printf(mon, "VLAN %d (%s):\n",
-   s->nc.vlan ? s->nc.vlan->id : -1,
+   -1, /* TODO */
s->nc.name);
 slirp_connection_info(s->slirp, mon);
 }
-- 
1.7.6




[Qemu-devel] [PATCH v4 05/16] net: Drop vlan argument to qemu_new_net_client()

2012-06-03 Thread zwu . kernel
From: Stefan Hajnoczi 

Since hubs are now used to implement the 'vlan' feature and the vlan
argument is always NULL, remove the argument entirely and update all net
clients that use qemu_new_net_client().

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c   |   27 ++-
 net.h   |1 -
 net/dump.c  |2 +-
 net/hub.c   |2 +-
 net/slirp.c |2 +-
 net/socket.c|4 ++--
 net/tap-win32.c |2 +-
 net/tap.c   |2 +-
 net/vde.c   |2 +-
 9 files changed, 18 insertions(+), 26 deletions(-)

diff --git a/net.c b/net.c
index 88b9e1f..96252f9 100644
--- a/net.c
+++ b/net.c
@@ -194,7 +194,6 @@ static ssize_t qemu_deliver_packet_iov(VLANClientState 
*sender,
void *opaque);
 
 VLANClientState *qemu_new_net_client(NetClientInfo *info,
- VLANState *vlan,
  VLANClientState *peer,
  const char *model,
  const char *name)
@@ -213,22 +212,16 @@ VLANClientState *qemu_new_net_client(NetClientInfo *info,
 vc->name = assign_name(vc, model);
 }
 
-if (vlan) {
-assert(!peer);
-vc->vlan = vlan;
-QTAILQ_INSERT_TAIL(&vc->vlan->clients, vc, next);
-} else {
-if (peer) {
-assert(!peer->peer);
-vc->peer = peer;
-peer->peer = vc;
-}
-QTAILQ_INSERT_TAIL(&non_vlan_clients, vc, next);
-
-vc->send_queue = qemu_new_net_queue(qemu_deliver_packet,
-qemu_deliver_packet_iov,
-vc);
+if (peer) {
+assert(!peer->peer);
+vc->peer = peer;
+peer->peer = vc;
 }
+QTAILQ_INSERT_TAIL(&non_vlan_clients, vc, next);
+
+vc->send_queue = qemu_new_net_queue(qemu_deliver_packet,
+qemu_deliver_packet_iov,
+vc);
 
 return vc;
 }
@@ -245,7 +238,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
 assert(info->type == NET_CLIENT_TYPE_NIC);
 assert(info->size >= sizeof(NICState));
 
-nc = qemu_new_net_client(info, conf->vlan, conf->peer, model, name);
+nc = qemu_new_net_client(info, conf->peer, model, name);
 
 nic = DO_UPCAST(NICState, nc, nc);
 nic->conf = conf;
diff --git a/net.h b/net.h
index 50c55ad..d3d6e4c 100644
--- a/net.h
+++ b/net.h
@@ -92,7 +92,6 @@ struct VLANState {
 VLANState *qemu_find_vlan(int id, int allocate);
 VLANClientState *qemu_find_netdev(const char *id);
 VLANClientState *qemu_new_net_client(NetClientInfo *info,
- VLANState *vlan,
  VLANClientState *peer,
  const char *model,
  const char *name);
diff --git a/net/dump.c b/net/dump.c
index 37cec3c..621f4e7 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -129,7 +129,7 @@ static int net_dump_init(VLANClientState *peer, const char 
*device,
 return -1;
 }
 
-nc = qemu_new_net_client(&net_dump_info, NULL, peer, device, name);
+nc = qemu_new_net_client(&net_dump_info, peer, device, name);
 
 snprintf(nc->info_str, sizeof(nc->info_str),
  "dump to %s (len=%d)", filename, len);
diff --git a/net/hub.c b/net/hub.c
index e4a3980..fe78a72 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -125,7 +125,7 @@ static NetHubPort *net_hub_port_new(NetHub *hub)
 
 snprintf(name, sizeof name, "hub%uport%u", hub->id, id);
 
-nc = qemu_new_net_client(&net_hub_port_info, NULL, NULL, "hub", name);
+nc = qemu_new_net_client(&net_hub_port_info, NULL, "hub", name);
 port = DO_UPCAST(NetHubPort, nc, nc);
 port->id = id;
 port->hub = hub;
diff --git a/net/slirp.c b/net/slirp.c
index edb4621..5ed7036 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -238,7 +238,7 @@ static int net_slirp_init(VLANClientState *peer, const char 
*model,
 }
 #endif
 
-nc = qemu_new_net_client(&net_slirp_info, NULL, peer, model, name);
+nc = qemu_new_net_client(&net_slirp_info, peer, model, name);
 
 snprintf(nc->info_str, sizeof(nc->info_str),
  "net=%s,restrict=%s", inet_ntoa(net),
diff --git a/net/socket.c b/net/socket.c
index ed28cbd..bf7a793 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -286,7 +286,7 @@ static NetSocketState 
*net_socket_fd_init_dgram(VLANClientState *peer,
 }
 }
 
-nc = qemu_new_net_client(&net_dgram_socket_info, NULL, peer, model, name);
+nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name);
 
 snprintf(nc->info_str, sizeof(nc->info_str),
 "socket: fd=%d (%s mcast=%s:%d)",
@@ -330,7 +330,7 @@ static NetSocketState 
*net_socket_fd_init_stream(VLANClientState *peer,
 VLANClientState *nc;
 NetSocketState *s;
 
-nc = qemu_new_net_

[Qemu-devel] [PATCH v4 15/16] net: determine if packets can be sent before net queue deliver packets

2012-06-03 Thread zwu . kernel
From: Zhi Yong Wu 

Reviewed-by:   Paolo Bonzini 
Signed-off-by: Zhi Yong Wu 
---
 net/queue.c  |8 
 net/slirp.c  |7 ---
 slirp/if.c   |5 -
 slirp/libslirp.h |1 -
 4 files changed, 4 insertions(+), 17 deletions(-)

diff --git a/net/queue.c b/net/queue.c
index 0afd783..7484d2a 100644
--- a/net/queue.c
+++ b/net/queue.c
@@ -176,8 +176,8 @@ ssize_t qemu_net_queue_send(NetQueue *queue,
 {
 ssize_t ret;
 
-if (queue->delivering) {
-return qemu_net_queue_append(queue, sender, flags, data, size, NULL);
+if (queue->delivering || !qemu_can_send_packet(sender)) {
+return qemu_net_queue_append(queue, sender, flags, data, size, 
sent_cb);
 }
 
 ret = qemu_net_queue_deliver(queue, sender, flags, data, size);
@@ -200,8 +200,8 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue,
 {
 ssize_t ret;
 
-if (queue->delivering) {
-return qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt, 
NULL);
+if (queue->delivering || !qemu_can_send_packet(sender)) {
+return qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt, 
sent_cb);
 }
 
 ret = qemu_net_queue_deliver_iov(queue, sender, flags, iov, iovcnt);
diff --git a/net/slirp.c b/net/slirp.c
index a6ede2b..248f7ff 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -96,13 +96,6 @@ static void slirp_smb_cleanup(SlirpState *s);
 static inline void slirp_smb_cleanup(SlirpState *s) { }
 #endif
 
-int slirp_can_output(void *opaque)
-{
-SlirpState *s = opaque;
-
-return qemu_can_send_packet(&s->nc);
-}
-
 void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
 {
 SlirpState *s = opaque;
diff --git a/slirp/if.c b/slirp/if.c
index 096cf6f..533295d 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -177,11 +177,6 @@ void if_start(Slirp *slirp)
 }
 
 while (ifm_next) {
-/* check if we can really output */
-if (!slirp_can_output(slirp->opaque)) {
-break;
-}
-
 ifm = ifm_next;
 from_batchq = next_from_batchq;
 
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 77527ad..9b471b5 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -25,7 +25,6 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, 
fd_set *xfds,
 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
 
 /* you must provide the following functions: */
-int slirp_can_output(void *opaque);
 void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len);
 
 int slirp_add_hostfwd(Slirp *slirp, int is_udp,
-- 
1.7.6




[Qemu-devel] [PATCH v4 01/16] net: Add a hub net client

2012-06-03 Thread zwu . kernel
From: Stefan Hajnoczi 

The vlan feature can be implemented in terms of hubs.  By introducing a
hub net client it becomes possible to remove the special case vlan code
from net.c and push the vlan feature out of generic networking code.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 Makefile.objs |2 +-
 net.h |1 +
 net/hub.c |  201 +
 net/hub.h |   24 +++
 4 files changed, 227 insertions(+), 1 deletions(-)
 create mode 100644 net/hub.c
 create mode 100644 net/hub.h

diff --git a/Makefile.objs b/Makefile.objs
index 70c5c79..a3a3a8a 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -63,7 +63,7 @@ block-nested-$(CONFIG_RBD) += rbd.o
 block-obj-y +=  $(addprefix block/, $(block-nested-y))
 
 net-obj-y = net.o
-net-nested-y = queue.o checksum.o util.o
+net-nested-y = queue.o checksum.o util.o hub.o
 net-nested-y += socket.o
 net-nested-y += dump.o
 net-nested-$(CONFIG_POSIX) += tap.o
diff --git a/net.h b/net.h
index 64993b4..50c55ad 100644
--- a/net.h
+++ b/net.h
@@ -38,6 +38,7 @@ typedef enum {
 NET_CLIENT_TYPE_VDE,
 NET_CLIENT_TYPE_DUMP,
 NET_CLIENT_TYPE_BRIDGE,
+NET_CLIENT_TYPE_HUB,
 
 NET_CLIENT_TYPE_MAX
 } net_client_type;
diff --git a/net/hub.c b/net/hub.c
new file mode 100644
index 000..28ff45c
--- /dev/null
+++ b/net/hub.c
@@ -0,0 +1,201 @@
+/*
+ * Hub net client
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Stefan Hajnoczi   
+ *  Zhi Yong Wu   
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "monitor.h"
+#include "net.h"
+#include "hub.h"
+
+/*
+ * A hub broadcasts incoming packets to all its ports except the source port.
+ * Hubs can be used to provide independent network segments, also confusingly
+ * named the QEMU 'vlan' feature.
+ */
+
+typedef struct NetHub NetHub;
+
+typedef struct NetHubPort {
+VLANClientState nc;
+QLIST_ENTRY(NetHubPort) next;
+NetHub *hub;
+unsigned int id;
+} NetHubPort;
+
+struct NetHub {
+unsigned int id;
+QLIST_ENTRY(NetHub) next;
+unsigned int num_ports;
+QLIST_HEAD(, NetHubPort) ports;
+};
+
+static QLIST_HEAD(, NetHub) hubs = QLIST_HEAD_INITIALIZER(&hubs);
+
+static ssize_t net_hub_receive(NetHub *hub, NetHubPort *source_port,
+   const uint8_t *buf, size_t len)
+{
+NetHubPort *port;
+
+QLIST_FOREACH(port, &hub->ports, next) {
+if (port == source_port) {
+continue;
+}
+
+qemu_send_packet(&port->nc, buf, len);
+}
+return len;
+}
+
+static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port,
+   const struct iovec *iov, int iovcnt)
+{
+NetHubPort *port;
+ssize_t ret = 0;
+
+QLIST_FOREACH(port, &hub->ports, next) {
+if (port == source_port) {
+continue;
+}
+
+ret = qemu_sendv_packet(&port->nc, iov, iovcnt);
+}
+return ret;
+}
+
+static NetHub *net_hub_new(unsigned int id)
+{
+NetHub *hub;
+
+hub = g_malloc(sizeof(*hub));
+hub->id = id;
+hub->num_ports = 0;
+QLIST_INIT(&hub->ports);
+
+QLIST_INSERT_HEAD(&hubs, hub, next);
+
+return hub;
+}
+
+static ssize_t net_hub_port_receive(VLANClientState *nc,
+const uint8_t *buf, size_t len)
+{
+NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
+
+return net_hub_receive(port->hub, port, buf, len);
+}
+
+static ssize_t net_hub_port_receive_iov(VLANClientState *nc,
+const struct iovec *iov, int iovcnt)
+{
+NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
+
+return net_hub_receive_iov(port->hub, port, iov, iovcnt);
+}
+
+static void net_hub_port_cleanup(VLANClientState *nc)
+{
+NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc);
+
+QLIST_REMOVE(port, next);
+}
+
+static NetClientInfo net_hub_port_info = {
+.type = NET_CLIENT_TYPE_HUB,
+.size = sizeof(NetHubPort),
+.receive = net_hub_port_receive,
+.receive_iov = net_hub_port_receive_iov,
+.cleanup = net_hub_port_cleanup,
+};
+
+static NetHubPort *net_hub_port_new(NetHub *hub)
+{
+VLANClientState *nc;
+NetHubPort *port;
+unsigned int id = hub->num_ports++;
+char name[128];
+
+snprintf(name, sizeof name, "hub%uport%u", hub->id, id);
+
+nc = qemu_new_net_client(&net_hub_port_info, NULL, NULL, "hub", name);
+port = DO_UPCAST(NetHubPort, nc, nc);
+port->id = id;
+port->hub = hub;
+
+QLIST_INSERT_HEAD(&hub->ports, port, next);
+
+return port;
+}
+
+/**
+ * Create a port on a given hub
+ *
+ * If there is no existing hub with the given id then a new hub is created.
+ */
+VLANClientState *net_hub_add_port(unsigned int hub_id)
+{
+NetHub *hub;
+NetHubPort *port;
+
+QLIST_FOREACH(hub, &hubs, next) {
+if (hub->id == hub_id) {
+

[Qemu-devel] [PATCH v4 04/16] hub: Check that hubs are configured correctly

2012-06-03 Thread zwu . kernel
From: Stefan Hajnoczi 

Checks can be performed to make sure that hubs have at least one NIC and
one host device, warning the user if this is not the case.
Configurations which do not meet this rule tend to be broken but just
emit a warning.  This patch preserves compatibility with the checks
performed by net core on vlans.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c |   25 +
 net/hub.c |   45 +
 net/hub.h |1 +
 3 files changed, 47 insertions(+), 24 deletions(-)

diff --git a/net.c b/net.c
index d9c7eac..88b9e1f 100644
--- a/net.c
+++ b/net.c
@@ -1337,7 +1337,6 @@ void net_cleanup(void)
 
 void net_check_clients(void)
 {
-VLANState *vlan;
 VLANClientState *vc;
 int i;
 
@@ -1353,30 +1352,8 @@ void net_check_clients(void)
 return;
 }
 
-QTAILQ_FOREACH(vlan, &vlans, next) {
-int has_nic = 0, has_host_dev = 0;
+net_hub_check_clients();
 
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-switch (vc->info->type) {
-case NET_CLIENT_TYPE_NIC:
-has_nic = 1;
-break;
-case NET_CLIENT_TYPE_USER:
-case NET_CLIENT_TYPE_TAP:
-case NET_CLIENT_TYPE_SOCKET:
-case NET_CLIENT_TYPE_VDE:
-has_host_dev = 1;
-break;
-default: ;
-}
-}
-if (has_host_dev && !has_nic)
-fprintf(stderr, "Warning: vlan %d with no nics\n", vlan->id);
-if (has_nic && !has_host_dev)
-fprintf(stderr,
-"Warning: vlan %d is not connected to host network\n",
-vlan->id);
-}
 QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
 if (!vc->peer) {
 fprintf(stderr, "Warning: %s %s has no peer\n",
diff --git a/net/hub.c b/net/hub.c
index 56efc2c..e4a3980 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -223,3 +223,48 @@ int net_hub_id_for_client(VLANClientState *nc, unsigned 
int *id)
 }
 return -ENOENT;
 }
+
+/**
+ * Warn if hub configurations are likely wrong
+ */
+void net_hub_check_clients(void)
+{
+NetHub *hub;
+NetHubPort *port;
+VLANClientState *peer;
+
+QLIST_FOREACH(hub, &hubs, next) {
+int has_nic = 0, has_host_dev = 0;
+
+QLIST_FOREACH(port, &hub->ports, next) {
+peer = port->nc.peer;
+if (!peer) {
+fprintf(stderr, "Warning: hub port %s has no peer\n",
+port->nc.name);
+continue;
+}
+
+switch (peer->info->type) {
+case NET_CLIENT_TYPE_NIC:
+has_nic = 1;
+break;
+case NET_CLIENT_TYPE_USER:
+case NET_CLIENT_TYPE_TAP:
+case NET_CLIENT_TYPE_SOCKET:
+case NET_CLIENT_TYPE_VDE:
+has_host_dev = 1;
+break;
+default:
+break;
+}
+}
+if (has_host_dev && !has_nic) {
+fprintf(stderr, "Warning: vlan %u with no nics\n", hub->id);
+}
+if (has_nic && !has_host_dev) {
+fprintf(stderr,
+"Warning: vlan %u is not connected to host network\n",
+hub->id);
+}
+}
+}
diff --git a/net/hub.h b/net/hub.h
index e149e04..10bf036 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -22,5 +22,6 @@ VLANClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
  const char *name);
 void net_hub_info(Monitor *mon);
 int net_hub_id_for_client(VLANClientState *nc, unsigned int *id);
+void net_hub_check_clients(void);
 
 #endif /* NET_HUB_H */
-- 
1.7.6




[Qemu-devel] [PATCH v4 14/16] net: cleanup deliver/deliver_iov func pointers

2012-06-03 Thread zwu . kernel
From: Zhi Yong Wu 

Reviewed-by:   Paolo Bonzini 
Signed-off-by: Zhi Yong Wu 
---
 net.c   |   35 +++
 net.h   |   11 +++
 net/queue.c |   13 -
 net/queue.h |   17 ++---
 4 files changed, 28 insertions(+), 48 deletions(-)

diff --git a/net.c b/net.c
index 6cedc7a..3a92d87 100644
--- a/net.c
+++ b/net.c
@@ -181,17 +181,6 @@ static char *assign_name(NetClientState *nc1, const char 
*model)
 return g_strdup(buf);
 }
 
-static ssize_t qemu_deliver_packet(NetClientState *sender,
-   unsigned flags,
-   const uint8_t *data,
-   size_t size,
-   void *opaque);
-static ssize_t qemu_deliver_packet_iov(NetClientState *sender,
-   unsigned flags,
-   const struct iovec *iov,
-   int iovcnt,
-   void *opaque);
-
 NetClientState *qemu_new_net_client(NetClientInfo *info,
 NetClientState *peer,
 const char *model,
@@ -218,9 +207,7 @@ NetClientState *qemu_new_net_client(NetClientInfo *info,
 }
 QTAILQ_INSERT_TAIL(&net_clients, nc, next);
 
-nc->send_queue = qemu_new_net_queue(qemu_deliver_packet,
-qemu_deliver_packet_iov,
-nc);
+nc->send_queue = qemu_new_net_queue(nc);
 
 return nc;
 }
@@ -324,11 +311,11 @@ int qemu_can_send_packet(NetClientState *sender)
 return 1;
 }
 
-static ssize_t qemu_deliver_packet(NetClientState *sender,
-   unsigned flags,
-   const uint8_t *data,
-   size_t size,
-   void *opaque)
+ssize_t qemu_deliver_packet(NetClientState *sender,
+unsigned flags,
+const uint8_t *data,
+size_t size,
+void *opaque)
 {
 NetClientState *nc = opaque;
 ssize_t ret;
@@ -421,11 +408,11 @@ static ssize_t nc_sendv_compat(NetClientState *nc, const 
struct iovec *iov,
 return nc->info->receive(nc, buffer, offset);
 }
 
-static ssize_t qemu_deliver_packet_iov(NetClientState *sender,
-   unsigned flags,
-   const struct iovec *iov,
-   int iovcnt,
-   void *opaque)
+ssize_t qemu_deliver_packet_iov(NetClientState *sender,
+unsigned flags,
+const struct iovec *iov,
+int iovcnt,
+void *opaque)
 {
 NetClientState *nc = opaque;
 
diff --git a/net.h b/net.h
index 0692283..08306a4 100644
--- a/net.h
+++ b/net.h
@@ -112,6 +112,17 @@ void qemu_check_nic_model(NICInfo *nd, const char *model);
 int qemu_find_nic_model(NICInfo *nd, const char * const *models,
 const char *default_model);
 
+ssize_t qemu_deliver_packet(NetClientState *sender,
+unsigned flags,
+const uint8_t *data,
+size_t size,
+void *opaque);
+ssize_t qemu_deliver_packet_iov(NetClientState *sender,
+unsigned flags,
+const struct iovec *iov,
+int iovcnt,
+void *opaque);
+
 void print_net_client(Monitor *mon, NetClientState *vc);
 void do_info_network(Monitor *mon);
 
diff --git a/net/queue.c b/net/queue.c
index 35c3463..0afd783 100644
--- a/net/queue.c
+++ b/net/queue.c
@@ -23,6 +23,7 @@
 
 #include "net/queue.h"
 #include "qemu-queue.h"
+#include "net.h"
 
 /* The delivery handler may only return zero if it will call
  * qemu_net_queue_flush() when it determines that it is once again able
@@ -48,8 +49,6 @@ struct NetPacket {
 };
 
 struct NetQueue {
-NetPacketDeliver *deliver;
-NetPacketDeliverIOV *deliver_iov;
 void *opaque;
 
 QTAILQ_HEAD(packets, NetPacket) packets;
@@ -57,16 +56,12 @@ struct NetQueue {
 unsigned delivering : 1;
 };
 
-NetQueue *qemu_new_net_queue(NetPacketDeliver *deliver,
- NetPacketDeliverIOV *deliver_iov,
- void *opaque)
+NetQueue *qemu_new_net_queue(void *opaque)
 {
 NetQueue *queue;
 
 queue = g_malloc0(sizeof(NetQueue));
 
-queue->deliver = deliver;
-queue->deliver_iov = deliver_iov;
 queue->opaque = opaque;
 
 QTAILQ_INIT(&queue->packets);
@@ -151,7 +146,7 @@ static ssize_t qemu_net_queue_deliver(NetQueue *queue,
 ssize_t ret = -1;
 
 queue->delivering = 1;
-

[Qemu-devel] [PATCH v4 16/16] hub: add the support for hub own flow control

2012-06-03 Thread zwu . kernel
From: Zhi Yong Wu 

Only when all other hub port's *peer* .can_receive() all return 1,
the source hub port .can_receive() return 1.

Reviewed-off-by: Paolo Bonzini 
Signed-off-by: Zhi Yong Wu 
---
 net/hub.c |   27 ---
 1 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/net/hub.c b/net/hub.c
index 230d86a..efd90b5 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -15,6 +15,7 @@
 #include "monitor.h"
 #include "net.h"
 #include "hub.h"
+#include "iov.h"
 
 /*
  * A hub broadcasts incoming packets to all its ports except the source port.
@@ -59,16 +60,16 @@ static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort 
*source_port,
const struct iovec *iov, int iovcnt)
 {
 NetHubPort *port;
-ssize_t ret = 0;
+ssize_t len = iov_size(iov, iovcnt);
 
 QLIST_FOREACH(port, &hub->ports, next) {
 if (port == source_port) {
 continue;
 }
 
-ret = qemu_sendv_packet(&port->nc, iov, iovcnt);
+qemu_sendv_packet(&port->nc, iov, iovcnt);
 }
-return ret;
+return len;
 }
 
 static NetHub *net_hub_new(unsigned int id)
@@ -85,6 +86,25 @@ static NetHub *net_hub_new(unsigned int id)
 return hub;
 }
 
+static int net_hub_port_can_receive(NetClientState *nc)
+{
+NetHubPort *port;
+NetHubPort *src_port = DO_UPCAST(NetHubPort, nc, nc);
+NetHub *hub = src_port->hub;
+
+QLIST_FOREACH(port, &hub->ports, next) {
+if (port == src_port) {
+continue;
+}
+
+if (!qemu_can_send_packet(&port->nc)) {
+return 0;
+}
+}
+
+return 1;
+}
+
 static ssize_t net_hub_port_receive(NetClientState *nc,
 const uint8_t *buf, size_t len)
 {
@@ -111,6 +131,7 @@ static void net_hub_port_cleanup(NetClientState *nc)
 static NetClientInfo net_hub_port_info = {
 .type = NET_CLIENT_TYPE_HUB,
 .size = sizeof(NetHubPort),
+.can_receive = net_hub_port_can_receive,
 .receive = net_hub_port_receive,
 .receive_iov = net_hub_port_receive_iov,
 .cleanup = net_hub_port_cleanup,
-- 
1.7.6




[Qemu-devel] [PATCH v4 07/16] net: Remove vlan code from net.c

2012-06-03 Thread zwu . kernel
From: Stefan Hajnoczi 

The vlan implementation in net.c has been replaced by hubs so we can
remove the code.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 hw/xen_nic.c |1 -
 net.c|  108 --
 net.h|1 -
 3 files changed, 0 insertions(+), 110 deletions(-)

diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index 9a59bda..85526fe 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -328,7 +328,6 @@ static int net_init(struct XenDevice *xendev)
 return -1;
 }
 
-netdev->conf.vlan = qemu_find_vlan(netdev->xendev.dev, 1);
 netdev->conf.peer = NULL;
 
 netdev->nic = qemu_new_nic(&net_xen_info, &netdev->conf,
diff --git a/net.c b/net.c
index 96252f9..abf5a3d 100644
--- a/net.c
+++ b/net.c
@@ -388,50 +388,6 @@ static ssize_t qemu_deliver_packet(VLANClientState *sender,
 return ret;
 }
 
-static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
-unsigned flags,
-const uint8_t *buf,
-size_t size,
-void *opaque)
-{
-VLANState *vlan = opaque;
-VLANClientState *vc;
-ssize_t ret = -1;
-
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-ssize_t len;
-
-if (vc == sender) {
-continue;
-}
-
-if (vc->link_down) {
-ret = size;
-continue;
-}
-
-if (vc->receive_disabled) {
-ret = 0;
-continue;
-}
-
-if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->info->receive_raw) {
-len = vc->info->receive_raw(vc, buf, size);
-} else {
-len = vc->info->receive(vc, buf, size);
-}
-
-if (len == 0) {
-vc->receive_disabled = 1;
-}
-
-ret = (ret >= 0) ? ret : len;
-
-}
-
-return ret;
-}
-
 void qemu_purge_queued_packets(VLANClientState *vc)
 {
 NetQueue *queue;
@@ -538,42 +494,6 @@ static ssize_t qemu_deliver_packet_iov(VLANClientState 
*sender,
 }
 }
 
-static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState *sender,
-unsigned flags,
-const struct iovec *iov,
-int iovcnt,
-void *opaque)
-{
-VLANState *vlan = opaque;
-VLANClientState *vc;
-ssize_t ret = -1;
-
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-ssize_t len;
-
-if (vc == sender) {
-continue;
-}
-
-if (vc->link_down) {
-ret = iov_size(iov, iovcnt);
-continue;
-}
-
-assert(!(flags & QEMU_NET_PACKET_FLAG_RAW));
-
-if (vc->info->receive_iov) {
-len = vc->info->receive_iov(vc, iov, iovcnt);
-} else {
-len = vc_sendv_compat(vc, iov, iovcnt);
-}
-
-ret = (ret >= 0) ? ret : len;
-}
-
-return ret;
-}
-
 ssize_t qemu_sendv_packet_async(VLANClientState *sender,
 const struct iovec *iov, int iovcnt,
 NetPacketSent *sent_cb)
@@ -601,34 +521,6 @@ qemu_sendv_packet(VLANClientState *vc, const struct iovec 
*iov, int iovcnt)
 return qemu_sendv_packet_async(vc, iov, iovcnt, NULL);
 }
 
-/* find or alloc a new VLAN */
-VLANState *qemu_find_vlan(int id, int allocate)
-{
-VLANState *vlan;
-
-QTAILQ_FOREACH(vlan, &vlans, next) {
-if (vlan->id == id) {
-return vlan;
-}
-}
-
-if (!allocate) {
-return NULL;
-}
-
-vlan = g_malloc0(sizeof(VLANState));
-vlan->id = id;
-QTAILQ_INIT(&vlan->clients);
-
-vlan->send_queue = qemu_new_net_queue(qemu_vlan_deliver_packet,
-  qemu_vlan_deliver_packet_iov,
-  vlan);
-
-QTAILQ_INSERT_TAIL(&vlans, vlan, next);
-
-return vlan;
-}
-
 VLANClientState *qemu_find_netdev(const char *id)
 {
 VLANClientState *vc;
diff --git a/net.h b/net.h
index 7d18b10..a4ac48d 100644
--- a/net.h
+++ b/net.h
@@ -87,7 +87,6 @@ struct VLANState {
 NetQueue *send_queue;
 };
 
-VLANState *qemu_find_vlan(int id, int allocate);
 VLANClientState *qemu_find_netdev(const char *id);
 VLANClientState *qemu_new_net_client(NetClientInfo *info,
  VLANClientState *peer,
-- 
1.7.6




[Qemu-devel] [PATCH v4 06/16] net: Remove vlan qdev property

2012-06-03 Thread zwu . kernel
From: Stefan Hajnoczi 

The vlan feature is implemented using hubs and no longer uses
special-purpose VLANState structs that are accessible as qdev
properties.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 hw/qdev-properties.c |   72 --
 hw/qdev.c|2 -
 hw/qdev.h|4 ---
 net.h|3 --
 4 files changed, 0 insertions(+), 81 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index b7b5597..d2e2afb 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -623,71 +623,6 @@ PropertyInfo qdev_prop_netdev = {
 .set   = set_netdev,
 };
 
-/* --- vlan --- */
-
-static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
-VLANState **ptr = qdev_get_prop_ptr(dev, prop);
-
-if (*ptr) {
-return snprintf(dest, len, "%d", (*ptr)->id);
-} else {
-return snprintf(dest, len, "");
-}
-}
-
-static void get_vlan(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
-{
-DeviceState *dev = DEVICE(obj);
-Property *prop = opaque;
-VLANState **ptr = qdev_get_prop_ptr(dev, prop);
-int64_t id;
-
-id = *ptr ? (*ptr)->id : -1;
-visit_type_int(v, &id, name, errp);
-}
-
-static void set_vlan(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
-{
-DeviceState *dev = DEVICE(obj);
-Property *prop = opaque;
-VLANState **ptr = qdev_get_prop_ptr(dev, prop);
-Error *local_err = NULL;
-int64_t id;
-VLANState *vlan;
-
-if (dev->state != DEV_STATE_CREATED) {
-error_set(errp, QERR_PERMISSION_DENIED);
-return;
-}
-
-visit_type_int(v, &id, name, &local_err);
-if (local_err) {
-error_propagate(errp, local_err);
-return;
-}
-if (id == -1) {
-*ptr = NULL;
-return;
-}
-vlan = qemu_find_vlan(id, 1);
-if (!vlan) {
-error_set(errp, QERR_INVALID_PARAMETER_VALUE,
-  name, prop->info->name);
-return;
-}
-*ptr = vlan;
-}
-
-PropertyInfo qdev_prop_vlan = {
-.name  = "vlan",
-.print = print_vlan,
-.get   = get_vlan,
-.set   = set_vlan,
-};
-
 /* --- pointer --- */
 
 /* Not a proper property, just for dirty hacks.  TODO Remove it!  */
@@ -1094,13 +1029,6 @@ void qdev_prop_set_netdev(DeviceState *dev, const char 
*name, VLANClientState *v
 assert_no_error(errp);
 }
 
-void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
-{
-Error *errp = NULL;
-object_property_set_int(OBJECT(dev), value ? value->id : -1, name, &errp);
-assert_no_error(errp);
-}
-
 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
 {
 Error *errp = NULL;
diff --git a/hw/qdev.c b/hw/qdev.c
index 6a8f6bd..49dd303 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -316,8 +316,6 @@ void qdev_connect_gpio_out(DeviceState * dev, int n, 
qemu_irq pin)
 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
 {
 qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
-if (nd->vlan)
-qdev_prop_set_vlan(dev, "vlan", nd->vlan);
 if (nd->netdev)
 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
diff --git a/hw/qdev.h b/hw/qdev.h
index 4e90119..0a50a40 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -222,7 +222,6 @@ extern PropertyInfo qdev_prop_macaddr;
 extern PropertyInfo qdev_prop_losttickpolicy;
 extern PropertyInfo qdev_prop_drive;
 extern PropertyInfo qdev_prop_netdev;
-extern PropertyInfo qdev_prop_vlan;
 extern PropertyInfo qdev_prop_pci_devfn;
 extern PropertyInfo qdev_prop_blocksize;
 
@@ -277,8 +276,6 @@ extern PropertyInfo qdev_prop_blocksize;
 DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
 #define DEFINE_PROP_NETDEV(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, VLANClientState*)
-#define DEFINE_PROP_VLAN(_n, _s, _f) \
-DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, VLANState*)
 #define DEFINE_PROP_DRIVE(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *)
 #define DEFINE_PROP_MACADDR(_n, _s, _f) \
@@ -305,7 +302,6 @@ void qdev_prop_set_uint64(DeviceState *dev, const char 
*name, uint64_t value);
 void qdev_prop_set_string(DeviceState *dev, const char *name, char *value);
 void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState 
*value);
 void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState 
*value);
-void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value);
 int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState 
*value) QEMU_WARN_UNUSED_RESULT;
 void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, 
BlockDriverState *value);
 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
diff --git a/net.h b/n

[Qemu-devel] [PATCH v4 09/16] net: Rename non_vlan_clients to net_clients

2012-06-03 Thread zwu . kernel
From: Stefan Hajnoczi 

There is no longer a distinction between vlan clients and non-vlan
clients in the net core.  The net core only knows about point-to-point
clients which are connected to a peer.  It's time to rename the global
list of net clients since it no longer refers to vlans at all.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c |   20 ++--
 1 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/net.c b/net.c
index eb2ad06..2ca4285 100644
--- a/net.c
+++ b/net.c
@@ -44,7 +44,7 @@
 # define CONFIG_NET_BRIDGE
 #endif
 
-static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
+static QTAILQ_HEAD(, VLANClientState) net_clients;
 
 int default_net = 1;
 
@@ -165,7 +165,7 @@ static char *assign_name(VLANClientState *vc1, const char 
*model)
 char buf[256];
 int id = 0;
 
-QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
+QTAILQ_FOREACH(vc, &net_clients, next) {
 if (vc == vc1) {
 continue;
 }
@@ -216,7 +216,7 @@ VLANClientState *qemu_new_net_client(NetClientInfo *info,
 vc->peer = peer;
 peer->peer = vc;
 }
-QTAILQ_INSERT_TAIL(&non_vlan_clients, vc, next);
+QTAILQ_INSERT_TAIL(&net_clients, vc, next);
 
 vc->send_queue = qemu_new_net_queue(qemu_deliver_packet,
 qemu_deliver_packet_iov,
@@ -248,7 +248,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
 
 static void qemu_cleanup_vlan_client(VLANClientState *vc)
 {
-QTAILQ_REMOVE(&non_vlan_clients, vc, next);
+QTAILQ_REMOVE(&net_clients, vc, next);
 
 if (vc->info->cleanup) {
 vc->info->cleanup(vc);
@@ -302,7 +302,7 @@ void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
 {
 VLANClientState *nc;
 
-QTAILQ_FOREACH(nc, &non_vlan_clients, next) {
+QTAILQ_FOREACH(nc, &net_clients, next) {
 if (nc->info->type == NET_CLIENT_TYPE_NIC) {
 func(DO_UPCAST(NICState, nc, nc), opaque);
 }
@@ -467,7 +467,7 @@ VLANClientState *qemu_find_netdev(const char *id)
 {
 VLANClientState *vc;
 
-QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
+QTAILQ_FOREACH(vc, &net_clients, next) {
 if (vc->info->type == NET_CLIENT_TYPE_NIC)
 continue;
 if (!strcmp(vc->name, id)) {
@@ -1080,7 +1080,7 @@ void do_info_network(Monitor *mon)
 net_client_type type;
 
 monitor_printf(mon, "Devices not on any VLAN:\n");
-QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
+QTAILQ_FOREACH(vc, &net_clients, next) {
 peer = vc->peer;
 type = vc->info->type;
 if (!peer || type == NET_CLIENT_TYPE_NIC) {
@@ -1133,7 +1133,7 @@ void net_cleanup(void)
 {
 VLANClientState *vc, *next_vc;
 
-QTAILQ_FOREACH_SAFE(vc, &non_vlan_clients, next, next_vc) {
+QTAILQ_FOREACH_SAFE(vc, &net_clients, next, next_vc) {
 qemu_del_vlan_client(vc);
 }
 }
@@ -1157,7 +1157,7 @@ void net_check_clients(void)
 
 net_hub_check_clients();
 
-QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
+QTAILQ_FOREACH(vc, &net_clients, next) {
 if (!vc->peer) {
 fprintf(stderr, "Warning: %s %s has no peer\n",
 vc->info->type == NET_CLIENT_TYPE_NIC ? "nic" : "netdev",
@@ -1204,7 +1204,7 @@ int net_init_clients(void)
 #endif
 }
 
-QTAILQ_INIT(&non_vlan_clients);
+QTAILQ_INIT(&net_clients);
 
 if (qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, 1) 
== -1)
 return -1;
-- 
1.7.6




[Qemu-devel] [PATCH v4 11/16] net: Rename vc local variables to nc

2012-06-03 Thread zwu . kernel
From: Stefan Hajnoczi 

Now that VLANClientState has been renamed to NetClientState all 'vc'
local variables should be 'nc'.  Much of the code already used 'nc' but
there are places where 'vc' needs to be renamed.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 hw/ne2000.h |4 +-
 hw/vhost_net.c  |   18 +++---
 net.c   |  214 +++---
 net.h   |   20 +++---
 net/tap-win32.c |8 +-
 net/tap.h   |   16 ++--
 6 files changed, 140 insertions(+), 140 deletions(-)

diff --git a/hw/ne2000.h b/hw/ne2000.h
index 6c196a2..1e7ab07 100644
--- a/hw/ne2000.h
+++ b/hw/ne2000.h
@@ -31,5 +31,5 @@ typedef struct NE2000State {
 void ne2000_setup_io(NE2000State *s, unsigned size);
 extern const VMStateDescription vmstate_ne2000;
 void ne2000_reset(NE2000State *s);
-int ne2000_can_receive(NetClientState *vc);
-ssize_t ne2000_receive(NetClientState *vc, const uint8_t *buf, size_t size_);
+int ne2000_can_receive(NetClientState *nc);
+ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_);
diff --git a/hw/vhost_net.c b/hw/vhost_net.c
index c3e6546..c2d90df 100644
--- a/hw/vhost_net.c
+++ b/hw/vhost_net.c
@@ -42,7 +42,7 @@ struct vhost_net {
 struct vhost_dev dev;
 struct vhost_virtqueue vqs[2];
 int backend;
-NetClientState *vc;
+NetClientState *nc;
 };
 
 unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
@@ -104,7 +104,7 @@ struct vhost_net *vhost_net_init(NetClientState *backend, 
int devfd,
 if (r < 0) {
 goto fail;
 }
-net->vc = backend;
+net->nc = backend;
 net->dev.backend_features = tap_has_vnet_hdr(backend) ? 0 :
 (1 << VHOST_NET_F_VIRTIO_NET_HDR);
 net->backend = r;
@@ -151,7 +151,7 @@ int vhost_net_start(struct vhost_net *net,
 goto fail_notifiers;
 }
 if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
-tap_set_vnet_hdr_len(net->vc,
+tap_set_vnet_hdr_len(net->nc,
  sizeof(struct virtio_net_hdr_mrg_rxbuf));
 }
 
@@ -160,7 +160,7 @@ int vhost_net_start(struct vhost_net *net,
 goto fail_start;
 }
 
-net->vc->info->poll(net->vc, false);
+net->nc->info->poll(net->nc, false);
 qemu_set_fd_handler(net->backend, NULL, NULL, NULL);
 file.fd = net->backend;
 for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
@@ -177,10 +177,10 @@ fail:
 int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
 assert(r >= 0);
 }
-net->vc->info->poll(net->vc, true);
+net->nc->info->poll(net->nc, true);
 vhost_dev_stop(&net->dev, dev);
 if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
-tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
+tap_set_vnet_hdr_len(net->nc, sizeof(struct virtio_net_hdr));
 }
 fail_start:
 vhost_dev_disable_notifiers(&net->dev, dev);
@@ -197,10 +197,10 @@ void vhost_net_stop(struct vhost_net *net,
 int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
 assert(r >= 0);
 }
-net->vc->info->poll(net->vc, true);
+net->nc->info->poll(net->nc, true);
 vhost_dev_stop(&net->dev, dev);
 if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
-tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
+tap_set_vnet_hdr_len(net->nc, sizeof(struct virtio_net_hdr));
 }
 vhost_dev_disable_notifiers(&net->dev, dev);
 }
@@ -209,7 +209,7 @@ void vhost_net_cleanup(struct vhost_net *net)
 {
 vhost_dev_cleanup(&net->dev);
 if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
-tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
+tap_set_vnet_hdr_len(net->nc, sizeof(struct virtio_net_hdr));
 }
 g_free(net);
 }
diff --git a/net.c b/net.c
index de18c76..10fb601 100644
--- a/net.c
+++ b/net.c
@@ -129,11 +129,11 @@ int parse_host_port(struct sockaddr_in *saddr, const char 
*str)
 return 0;
 }
 
-void qemu_format_nic_info_str(NetClientState *vc, uint8_t macaddr[6])
+void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6])
 {
-snprintf(vc->info_str, sizeof(vc->info_str),
+snprintf(nc->info_str, sizeof(nc->info_str),
  "model=%s,macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
- vc->model,
+ nc->model,
  macaddr[0], macaddr[1], macaddr[2],
  macaddr[3], macaddr[4], macaddr[5]);
 }
@@ -159,19 +159,19 @@ void qemu_macaddr_default_if_unset(MACAddr *macaddr)
  * Only net clients created with the legacy -net option need this.  Naming is
  * mandatory for net clients created with -netdev.
  */
-static char *assign_name(NetClientState *vc1, const char *model)
+static char *assign_name(NetClientState *nc1, const char *model)
 {
-NetClientState *vc;
+NetClientState *nc;
 char buf[256];
 int id = 0;
 
-QTAILQ_FOREACH(vc, &net_clients, 

[Qemu-devel] [PATCH v4 08/16] net: Remove VLANState

2012-06-03 Thread zwu . kernel
From: Stefan Hajnoczi 

VLANState is no longer used and can be removed.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c |  127 ++---
 net.h |8 
 net/socket.c  |6 +-
 net/tap.c |6 +-
 net/tap.h |2 +-
 qemu-common.h |1 -
 6 files changed, 29 insertions(+), 121 deletions(-)

diff --git a/net.c b/net.c
index abf5a3d..eb2ad06 100644
--- a/net.c
+++ b/net.c
@@ -44,7 +44,6 @@
 # define CONFIG_NET_BRIDGE
 #endif
 
-static QTAILQ_HEAD(, VLANState) vlans;
 static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
 
 int default_net = 1;
@@ -249,11 +248,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
 
 static void qemu_cleanup_vlan_client(VLANClientState *vc)
 {
-if (vc->vlan) {
-QTAILQ_REMOVE(&vc->vlan->clients, vc, next);
-} else {
-QTAILQ_REMOVE(&non_vlan_clients, vc, next);
-}
+QTAILQ_REMOVE(&non_vlan_clients, vc, next);
 
 if (vc->info->cleanup) {
 vc->info->cleanup(vc);
@@ -262,13 +257,11 @@ static void qemu_cleanup_vlan_client(VLANClientState *vc)
 
 static void qemu_free_vlan_client(VLANClientState *vc)
 {
-if (!vc->vlan) {
-if (vc->send_queue) {
-qemu_del_net_queue(vc->send_queue);
-}
-if (vc->peer) {
-vc->peer->peer = NULL;
-}
+if (vc->send_queue) {
+qemu_del_net_queue(vc->send_queue);
+}
+if (vc->peer) {
+vc->peer->peer = NULL;
 }
 g_free(vc->name);
 g_free(vc->model);
@@ -278,7 +271,7 @@ static void qemu_free_vlan_client(VLANClientState *vc)
 void qemu_del_vlan_client(VLANClientState *vc)
 {
 /* If there is a peer NIC, delete and cleanup client, but do not free. */
-if (!vc->vlan && vc->peer && vc->peer->info->type == NET_CLIENT_TYPE_NIC) {
+if (vc->peer && vc->peer->info->type == NET_CLIENT_TYPE_NIC) {
 NICState *nic = DO_UPCAST(NICState, nc, vc->peer);
 if (nic->peer_deleted) {
 return;
@@ -294,7 +287,7 @@ void qemu_del_vlan_client(VLANClientState *vc)
 }
 
 /* If this is a peer NIC and peer has already been deleted, free it now. */
-if (!vc->vlan && vc->peer && vc->info->type == NET_CLIENT_TYPE_NIC) {
+if (vc->peer && vc->info->type == NET_CLIENT_TYPE_NIC) {
 NICState *nic = DO_UPCAST(NICState, nc, vc);
 if (nic->peer_deleted) {
 qemu_free_vlan_client(vc->peer);
@@ -308,52 +301,25 @@ void qemu_del_vlan_client(VLANClientState *vc)
 void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
 {
 VLANClientState *nc;
-VLANState *vlan;
 
 QTAILQ_FOREACH(nc, &non_vlan_clients, next) {
 if (nc->info->type == NET_CLIENT_TYPE_NIC) {
 func(DO_UPCAST(NICState, nc, nc), opaque);
 }
 }
-
-QTAILQ_FOREACH(vlan, &vlans, next) {
-QTAILQ_FOREACH(nc, &vlan->clients, next) {
-if (nc->info->type == NET_CLIENT_TYPE_NIC) {
-func(DO_UPCAST(NICState, nc, nc), opaque);
-}
-}
-}
 }
 
 int qemu_can_send_packet(VLANClientState *sender)
 {
-VLANState *vlan = sender->vlan;
-VLANClientState *vc;
-
-if (sender->peer) {
-if (sender->peer->receive_disabled) {
-return 0;
-} else if (sender->peer->info->can_receive &&
-   !sender->peer->info->can_receive(sender->peer)) {
-return 0;
-} else {
-return 1;
-}
-}
-
-if (!sender->vlan) {
+if (!sender->peer) {
 return 1;
 }
 
-QTAILQ_FOREACH(vc, &vlan->clients, next) {
-if (vc == sender) {
-continue;
-}
-
-/* no can_receive() handler, they can always receive */
-if (vc->info->can_receive && !vc->info->can_receive(vc)) {
-return 0;
-}
+if (sender->peer->receive_disabled) {
+return 0;
+} else if (sender->peer->info->can_receive &&
+   !sender->peer->info->can_receive(sender->peer)) {
+return 0;
 }
 return 1;
 }
@@ -390,34 +356,18 @@ static ssize_t qemu_deliver_packet(VLANClientState 
*sender,
 
 void qemu_purge_queued_packets(VLANClientState *vc)
 {
-NetQueue *queue;
-
-if (!vc->peer && !vc->vlan) {
+if (!vc->peer) {
 return;
 }
 
-if (vc->peer) {
-queue = vc->peer->send_queue;
-} else {
-queue = vc->vlan->send_queue;
-}
-
-qemu_net_queue_purge(queue, vc);
+qemu_net_queue_purge(vc->peer->send_queue, vc);
 }
 
 void qemu_flush_queued_packets(VLANClientState *vc)
 {
-NetQueue *queue;
-
 vc->receive_disabled = 0;
 
-if (vc->vlan) {
-queue = vc->vlan->send_queue;
-} else {
-queue = vc->send_queue;
-}
-
-qemu_net_queue_flush(queue);
+qemu_net_queue_flush(vc->send_queue);
 }
 
 static ssize_t qemu_send_packet_async_with_flags(VLANClientState *sender,
@@ -432,15 +382,11 @@ static ssize_t 
qemu_send_packet_async_with_flags(V

[Qemu-devel] [PATCH v4 12/16] net: Rename qemu_del_vlan_client() to qemu_del_net_client()

2012-06-04 Thread zwu . kernel
From: Stefan Hajnoczi 

Another step in moving the vlan feature out of net core.  Users only
deal with NetClientState and therefore qemu_del_vlan_client() should be
named qemu_del_net_client().

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 hw/e1000.c   |2 +-
 hw/eepro100.c|2 +-
 hw/ne2000.c  |2 +-
 hw/pcnet-pci.c   |2 +-
 hw/rtl8139.c |2 +-
 hw/usb/dev-network.c |2 +-
 hw/virtio-net.c  |2 +-
 hw/xen_nic.c |2 +-
 net.c|   20 ++--
 net.h|2 +-
 net/slirp.c  |2 +-
 11 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/hw/e1000.c b/hw/e1000.c
index 8c7fd3b..cf1e124 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1201,7 +1201,7 @@ pci_e1000_uninit(PCIDevice *dev)
 qemu_free_timer(d->autoneg_timer);
 memory_region_destroy(&d->mmio);
 memory_region_destroy(&d->io);
-qemu_del_vlan_client(&d->nic->nc);
+qemu_del_net_client(&d->nic->nc);
 return 0;
 }
 
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 5725ccf..0217795 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1840,7 +1840,7 @@ static int pci_nic_uninit(PCIDevice *pci_dev)
 memory_region_destroy(&s->flash_bar);
 vmstate_unregister(&pci_dev->qdev, s->vmstate, s);
 eeprom93xx_free(&pci_dev->qdev, s->eeprom);
-qemu_del_vlan_client(&s->nic->nc);
+qemu_del_net_client(&s->nic->nc);
 return 0;
 }
 
diff --git a/hw/ne2000.c b/hw/ne2000.c
index 2339725..e8b1d68 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -750,7 +750,7 @@ static int pci_ne2000_exit(PCIDevice *pci_dev)
 NE2000State *s = &d->ne2000;
 
 memory_region_destroy(&s->io);
-qemu_del_vlan_client(&s->nic->nc);
+qemu_del_net_client(&s->nic->nc);
 return 0;
 }
 
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 8c82667..8bbad47 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -279,7 +279,7 @@ static int pci_pcnet_uninit(PCIDevice *dev)
 memory_region_destroy(&d->io_bar);
 qemu_del_timer(d->state.poll_timer);
 qemu_free_timer(d->state.poll_timer);
-qemu_del_vlan_client(&d->state.nic->nc);
+qemu_del_net_client(&d->state.nic->nc);
 return 0;
 }
 
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 1e4f4eb..3642fcb 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3448,7 +3448,7 @@ static int pci_rtl8139_uninit(PCIDevice *dev)
 }
 qemu_del_timer(s->timer);
 qemu_free_timer(s->timer);
-qemu_del_vlan_client(&s->nic->nc);
+qemu_del_net_client(&s->nic->nc);
 return 0;
 }
 
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 21e0069..4bd4243 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -1309,7 +1309,7 @@ static void usb_net_handle_destroy(USBDevice *dev)
 
 /* TODO: remove the nd_table[] entry */
 rndis_clear_responsequeue(s);
-qemu_del_vlan_client(&s->nic->nc);
+qemu_del_net_client(&s->nic->nc);
 }
 
 static NetClientInfo net_usbnet_info = {
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index a73c523..d5527d4 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -1077,6 +1077,6 @@ void virtio_net_exit(VirtIODevice *vdev)
 qemu_bh_delete(n->tx_bh);
 }
 
-qemu_del_vlan_client(&n->nic->nc);
+qemu_del_net_client(&n->nic->nc);
 virtio_cleanup(&n->vdev);
 }
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index 6391a04..ba4a45c 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -409,7 +409,7 @@ static void net_disconnect(struct XenDevice *xendev)
 netdev->rxs = NULL;
 }
 if (netdev->nic) {
-qemu_del_vlan_client(&netdev->nic->nc);
+qemu_del_net_client(&netdev->nic->nc);
 netdev->nic = NULL;
 }
 }
diff --git a/net.c b/net.c
index 10fb601..61dc28d 100644
--- a/net.c
+++ b/net.c
@@ -246,7 +246,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
 return nic;
 }
 
-static void qemu_cleanup_vlan_client(NetClientState *nc)
+static void qemu_cleanup_net_client(NetClientState *nc)
 {
 QTAILQ_REMOVE(&net_clients, nc, next);
 
@@ -255,7 +255,7 @@ static void qemu_cleanup_vlan_client(NetClientState *nc)
 }
 }
 
-static void qemu_free_vlan_client(NetClientState *nc)
+static void qemu_free_net_client(NetClientState *nc)
 {
 if (nc->send_queue) {
 qemu_del_net_queue(nc->send_queue);
@@ -268,7 +268,7 @@ static void qemu_free_vlan_client(NetClientState *nc)
 g_free(nc);
 }
 
-void qemu_del_vlan_client(NetClientState *nc)
+void qemu_del_net_client(NetClientState *nc)
 {
 /* If there is a peer NIC, delete and cleanup client, but do not free. */
 if (nc->peer && nc->peer->info->type == NET_CLIENT_TYPE_NIC) {
@@ -282,7 +282,7 @@ void qemu_del_vlan_client(NetClientState *nc)
 if (nc->peer->info->link_status_changed) {
 nc->peer->info->link_status_changed(nc->peer);
 }
-qemu_cleanup_vlan_client(nc);
+qemu_cleanup_net_client(nc);
 return;
 }
 
@@ -290,12 +290,12 @@ void qemu_del_v

[Qemu-devel] [PATCH v4 13/16] net: Make "info network" output more readable info

2012-06-04 Thread zwu . kernel
From: Zhi Yong Wu 

Reviewed-by:   Jan Kiszka  
Signed-off-by: Zhi Yong Wu 
---
 net.c |   14 +-
 net.h |1 +
 net/hub.c |   23 +--
 net/hub.h |1 +
 4 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/net.c b/net.c
index 61dc28d..6cedc7a 100644
--- a/net.c
+++ b/net.c
@@ -1068,7 +1068,7 @@ int do_netdev_del(Monitor *mon, const QDict *qdict, 
QObject **ret_data)
 return 0;
 }
 
-static void print_net_client(Monitor *mon, NetClientState *vc)
+void print_net_client(Monitor *mon, NetClientState *vc)
 {
 monitor_printf(mon, "%s: type=%s,%s\n", vc->name,
net_client_types[vc->info->type].type, vc->info_str);
@@ -1079,20 +1079,24 @@ void do_info_network(Monitor *mon)
 NetClientState *nc, *peer;
 net_client_type type;
 
-monitor_printf(mon, "Devices not on any VLAN:\n");
+net_hub_info(mon);
+
 QTAILQ_FOREACH(nc, &net_clients, next) {
 peer = nc->peer;
 type = nc->info->type;
+
+if (net_hub_port_peer_nc(nc)) {
+continue;
+}
+
 if (!peer || type == NET_CLIENT_TYPE_NIC) {
-monitor_printf(mon, "  ");
 print_net_client(mon, nc);
 } /* else it's a netdev connected to a NIC, printed with the NIC */
 if (peer && type == NET_CLIENT_TYPE_NIC) {
-monitor_printf(mon, "   \\ ");
+monitor_printf(mon, " \\ ");
 print_net_client(mon, peer);
 }
 }
-net_hub_info(mon);
 }
 
 void qmp_set_link(const char *name, bool up, Error **errp)
diff --git a/net.h b/net.h
index 250669a..0692283 100644
--- a/net.h
+++ b/net.h
@@ -112,6 +112,7 @@ void qemu_check_nic_model(NICInfo *nd, const char *model);
 int qemu_find_nic_model(NICInfo *nd, const char * const *models,
 const char *default_model);
 
+void print_net_client(Monitor *mon, NetClientState *vc);
 void do_info_network(Monitor *mon);
 
 /* NIC info */
diff --git a/net/hub.c b/net/hub.c
index 122de69..230d86a 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -184,6 +184,25 @@ NetClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
 }
 
 /**
+ * Determine if one nc peers with one hub port
+ */
+bool net_hub_port_peer_nc(NetClientState *nc)
+{
+NetHub *hub;
+NetHubPort *port;
+
+QLIST_FOREACH(hub, &hubs, next) {
+QLIST_FOREACH(port, &hub->ports, next) {
+if (nc == port->nc.peer) {
+return true;
+}
+}
+}
+
+return false;
+}
+
+/**
  * Print hub configuration
  */
 void net_hub_info(Monitor *mon)
@@ -194,8 +213,8 @@ void net_hub_info(Monitor *mon)
 QLIST_FOREACH(hub, &hubs, next) {
 monitor_printf(mon, "hub %u\n", hub->id);
 QLIST_FOREACH(port, &hub->ports, next) {
-monitor_printf(mon, "port %u peer %s\n", port->id,
-   port->nc.peer ? port->nc.peer->name : "");
+monitor_printf(mon, " \\ ");
+print_net_client(mon, port->nc.peer);
 }
 }
 }
diff --git a/net/hub.h b/net/hub.h
index ff5024a..550189b 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -23,5 +23,6 @@ NetClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
 void net_hub_info(Monitor *mon);
 int net_hub_id_for_client(NetClientState *nc, unsigned int *id);
 void net_hub_check_clients(void);
+bool net_hub_port_peer_nc(NetClientState *nc);
 
 #endif /* NET_HUB_H */
-- 
1.7.6




[Qemu-devel] [PATCH v3] net: add the support for -netdev socket, listen

2012-06-04 Thread zwu . kernel
From: Zhi Yong Wu 

The -net socket,listen option does not work with the newer -netdev
syntax:
 http://lists.gnu.org/archive/html/qemu-devel/2011-11/msg01508.html

This patch makes it work now.

For the case where one vlan has multiple listenning sockets,
the patch will also provide the support.

Supported syntax:
 1.) -net socket,listen=127.0.0.1:1234,vlan=0
 2.) -net socket,listen=127.0.0.1:1234,vlan=0 -net 
socket,listen=127.0.0.1:1235,vlan=0
 3.) -netdev socket,listen=127.0.0.1:1234,id=socket0

Suggested-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c|   24 
 net.h|3 ++
 net/socket.c |  115 +++---
 3 files changed, 113 insertions(+), 29 deletions(-)

diff --git a/net.c b/net.c
index 1922d8a..0114537 100644
--- a/net.c
+++ b/net.c
@@ -190,6 +190,30 @@ static ssize_t qemu_deliver_packet_iov(VLANClientState 
*sender,
int iovcnt,
void *opaque);
 
+VLANClientState *qemu_lookup_net_client(VLANState *vlan,
+const char *name)
+{
+VLANClientState *vc = NULL;
+
+if (vlan) {
+QTAILQ_FOREACH(vc, &vlan->clients, next) {
+if ((vc->info->type == NET_CLIENT_TYPE_SOCKET)
+&& (!vc->consumed)) {
+return vc;
+}
+}
+} else {
+QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
+if (!strcmp(vc->name, name)
+&& (!vc->consumed)) {
+return vc;
+}
+}
+}
+
+return NULL;
+}
+
 VLANClientState *qemu_new_net_client(NetClientInfo *info,
  VLANState *vlan,
  VLANClientState *peer,
diff --git a/net.h b/net.h
index 64993b4..6033f43 100644
--- a/net.h
+++ b/net.h
@@ -72,6 +72,7 @@ struct VLANClientState {
 char *name;
 char info_str[256];
 unsigned receive_disabled : 1;
+bool consumed;
 };
 
 typedef struct NICState {
@@ -90,6 +91,8 @@ struct VLANState {
 
 VLANState *qemu_find_vlan(int id, int allocate);
 VLANClientState *qemu_find_netdev(const char *id);
+VLANClientState *qemu_lookup_net_client(VLANState *vlan,
+const char *name);
 VLANClientState *qemu_new_net_client(NetClientInfo *info,
  VLANState *vlan,
  VLANClientState *peer,
diff --git a/net/socket.c b/net/socket.c
index 0bcf229..459b6a8 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -32,6 +32,10 @@
 #include "qemu-option.h"
 #include "qemu_socket.h"
 
+#define NET_SOCKET_CONNECT0x0001
+#define NET_SOCKET_LISTEN 0x0002
+#define NET_SOCKET_CREATE 0x0004
+
 typedef struct NetSocketState {
 VLANClientState nc;
 int fd;
@@ -47,6 +51,7 @@ typedef struct NetSocketListenState {
 char *model;
 char *name;
 int fd;
+bool consumed;
 } NetSocketListenState;
 
 /* XXX: we consider we can send the whole packet without blocking */
@@ -247,7 +252,7 @@ static NetClientInfo net_dgram_socket_info = {
 static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
 const char *model,
 const char *name,
-int fd, int is_connected)
+int fd, int flag)
 {
 struct sockaddr_in saddr;
 int newfd;
@@ -260,7 +265,7 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState 
*vlan,
  * by ONLY ONE process: we must "clone" this dgram socket --jjo
  */
 
-if (is_connected) {
+if (flag & NET_SOCKET_CONNECT) {
 if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
 /* must be bound */
 if (saddr.sin_addr.s_addr == 0) {
@@ -286,21 +291,36 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState 
*vlan,
 }
 }
 
-nc = qemu_new_net_client(&net_dgram_socket_info, vlan, NULL, model, name);
+
+if (flag & NET_SOCKET_CREATE) {
+nc = qemu_new_net_client(&net_dgram_socket_info,
+ vlan, NULL, model, name);
+} else {
+nc = qemu_lookup_net_client(vlan, name);
+if (!nc) {
+goto err;
+}
+}
+
+s = DO_UPCAST(NetSocketState, nc, nc);
+
+if (flag & NET_SOCKET_LISTEN) {
+return s;
+}
 
 snprintf(nc->info_str, sizeof(nc->info_str),
 "socket: fd=%d (%s mcast=%s:%d)",
-fd, is_connected ? "cloned" : "",
+fd, flag & NET_SOCKET_CONNECT ? "cloned" : "",
 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
 
-s = DO_UPCAST(NetSocketState, nc, nc);
-
 s->fd = fd;
 
 qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
 
 /* mcast: save bound address as dst */
-if (is

[Qemu-devel] [PATCH v4] net: add the support for -netdev socket, listen

2012-06-06 Thread zwu . kernel
From: Zhi Yong Wu 

The -net socket,listen option does not work with the newer -netdev
syntax:
 http://lists.gnu.org/archive/html/qemu-devel/2011-11/msg01508.html

This patch makes it work now.

For the case where one vlan has multiple listenning sockets,
the patch will also provide the support.

Supported syntax:
 1.) -net socket,listen=127.0.0.1:1234,vlan=0
 2.) -net socket,listen=127.0.0.1:1234,vlan=0 -net 
socket,listen=127.0.0.1:1235,vlan=0
 3.) -netdev socket,listen=127.0.0.1:1234,id=socket0

Suggested-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net.c|   24 +++
 net.h|3 +
 net/socket.c |  123 ++---
 3 files changed, 117 insertions(+), 33 deletions(-)

diff --git a/net.c b/net.c
index 1922d8a..0114537 100644
--- a/net.c
+++ b/net.c
@@ -190,6 +190,30 @@ static ssize_t qemu_deliver_packet_iov(VLANClientState 
*sender,
int iovcnt,
void *opaque);
 
+VLANClientState *qemu_lookup_net_client(VLANState *vlan,
+const char *name)
+{
+VLANClientState *vc = NULL;
+
+if (vlan) {
+QTAILQ_FOREACH(vc, &vlan->clients, next) {
+if ((vc->info->type == NET_CLIENT_TYPE_SOCKET)
+&& (!vc->consumed)) {
+return vc;
+}
+}
+} else {
+QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
+if (!strcmp(vc->name, name)
+&& (!vc->consumed)) {
+return vc;
+}
+}
+}
+
+return NULL;
+}
+
 VLANClientState *qemu_new_net_client(NetClientInfo *info,
  VLANState *vlan,
  VLANClientState *peer,
diff --git a/net.h b/net.h
index 64993b4..6033f43 100644
--- a/net.h
+++ b/net.h
@@ -72,6 +72,7 @@ struct VLANClientState {
 char *name;
 char info_str[256];
 unsigned receive_disabled : 1;
+bool consumed;
 };
 
 typedef struct NICState {
@@ -90,6 +91,8 @@ struct VLANState {
 
 VLANState *qemu_find_vlan(int id, int allocate);
 VLANClientState *qemu_find_netdev(const char *id);
+VLANClientState *qemu_lookup_net_client(VLANState *vlan,
+const char *name);
 VLANClientState *qemu_new_net_client(NetClientInfo *info,
  VLANState *vlan,
  VLANClientState *peer,
diff --git a/net/socket.c b/net/socket.c
index 0bcf229..2ddca64 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -32,8 +32,21 @@
 #include "qemu-option.h"
 #include "qemu_socket.h"
 
+#define NET_SOCKET_CONNECT0x0001
+#define NET_SOCKET_LISTEN 0x0002
+#define NET_SOCKET_CREATE 0x0004
+
+typedef struct NetSocketListenState {
+VLANState *vlan;
+char *model;
+char *name;
+int fd;
+bool consumed;
+} NetSocketListenState;
+
 typedef struct NetSocketState {
 VLANClientState nc;
+NetSocketListenState *nls;
 int fd;
 int state; /* 0 = getting length, 1 = getting data */
 unsigned int index;
@@ -42,13 +55,6 @@ typedef struct NetSocketState {
 struct sockaddr_in dgram_dst; /* contains inet host and port destination 
iff connectionless (SOCK_DGRAM) */
 } NetSocketState;
 
-typedef struct NetSocketListenState {
-VLANState *vlan;
-char *model;
-char *name;
-int fd;
-} NetSocketListenState;
-
 /* XXX: we consider we can send the whole packet without blocking */
 static ssize_t net_socket_receive(VLANClientState *nc, const uint8_t *buf, 
size_t size)
 {
@@ -86,6 +92,17 @@ static void net_socket_send(void *opaque)
 eoc:
 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
 closesocket(s->fd);
+s->fd = 0;
+s->state = 0;
+s->index = 0;
+s->packet_len = 0;
+memset(s->buf, 0, sizeof(s->buf));
+if (s->nls) {
+s->nls->consumed = false;
+s->nc.consumed = false;
+memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
+}
+
 return;
 }
 buf = buf1;
@@ -247,7 +264,7 @@ static NetClientInfo net_dgram_socket_info = {
 static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
 const char *model,
 const char *name,
-int fd, int is_connected)
+int fd, int flag)
 {
 struct sockaddr_in saddr;
 int newfd;
@@ -260,7 +277,7 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState 
*vlan,
  * by ONLY ONE process: we must "clone" this dgram socket --jjo
  */
 
-if (is_connected) {
+if (flag & NET_SOCKET_CONNECT) {
 if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
 /* must be bound */
 if (saddr.sin_addr.s_addr == 0)

[Qemu-devel] [PATCH v5 1/2] net: fix the coding style

2012-06-07 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 net/socket.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index fcd0a3c..7194345 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -301,7 +301,9 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState 
*vlan,
 qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
 
 /* mcast: save bound address as dst */
-if (is_connected) s->dgram_dst=saddr;
+if (is_connected) {
+s->dgram_dst = saddr;
+}
 
 return s;
 
-- 
1.7.6




[Qemu-devel] [PATCH v5 2/2] net: add the support for -netdev socket, listen

2012-06-07 Thread zwu . kernel
From: Zhi Yong Wu 

The -net socket,listen option does not work with the newer -netdev
syntax:
 http://lists.gnu.org/archive/html/qemu-devel/2011-11/msg01508.html

This patch makes it work now.

For the case where one vlan has multiple listenning sockets,
the patch will also provide the support.

Supported syntax:
 1.) -net socket,listen=127.0.0.1:1234,vlan=0
 2.) -net socket,listen=127.0.0.1:1234,vlan=0 -net 
socket,listen=127.0.0.1:1235,vlan=0
 3.) -netdev socket,listen=127.0.0.1:1234,id=socket0

Changelog from v4:
 Adopted the suggestion from stefan [stefan]

 Drop the NetSocketListenState struct and add a listen_fd field
to NetSocketState.  When a -netdev socket,listen= instance is created
there will be a NetSocketState with fd=-1 and a valid listen_fd.  The
net_socket_accept() handler waits for listen_fd to become readable and
then accepts the connection.  When this state transition happens, we no
longer monitor listen_fd for incoming connections...until the client
disconnects again.

Suggested-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net/socket.c |   58 +++---
 1 files changed, 31 insertions(+), 27 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index 7194345..27e8c4e 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -35,6 +35,7 @@
 
 typedef struct NetSocketState {
 VLANClientState nc;
+int listen_fd;
 int fd;
 int state; /* 0 = getting length, 1 = getting data */
 unsigned int index;
@@ -43,12 +44,7 @@ typedef struct NetSocketState {
 struct sockaddr_in dgram_dst; /* contains inet host and port destination 
iff connectionless (SOCK_DGRAM) */
 } NetSocketState;
 
-typedef struct NetSocketListenState {
-VLANState *vlan;
-char *model;
-char *name;
-int fd;
-} NetSocketListenState;
+static void net_socket_accept(void *opaque);
 
 /* XXX: we consider we can send the whole packet without blocking */
 static ssize_t net_socket_receive(VLANClientState *nc, const uint8_t *buf, 
size_t size)
@@ -86,7 +82,16 @@ static void net_socket_send(void *opaque)
 /* end of connection */
 eoc:
 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
+qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
 closesocket(s->fd);
+
+s->fd = 0;
+s->state = 0;
+s->index = 0;
+s->packet_len = 0;
+memset(s->buf, 0, sizeof(s->buf));
+memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
+
 return;
 }
 buf = buf1;
@@ -377,27 +382,28 @@ static NetSocketState *net_socket_fd_init(VLANState *vlan,
 
 static void net_socket_accept(void *opaque)
 {
-NetSocketListenState *s = opaque;
-NetSocketState *s1;
+NetSocketState *s = opaque;
 struct sockaddr_in saddr;
 socklen_t len;
 int fd;
 
 for(;;) {
 len = sizeof(saddr);
-fd = qemu_accept(s->fd, (struct sockaddr *)&saddr, &len);
+fd = qemu_accept(s->listen_fd, (struct sockaddr *)&saddr, &len);
 if (fd < 0 && errno != EINTR) {
 return;
 } else if (fd >= 0) {
+qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
 break;
 }
 }
-s1 = net_socket_fd_init(s->vlan, s->model, s->name, fd, 1);
-if (s1) {
-snprintf(s1->nc.info_str, sizeof(s1->nc.info_str),
- "socket: connection from %s:%d",
- inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
-}
+
+s->fd = fd;
+s->nc.link_down = false;
+net_socket_connect(s);
+snprintf(s->nc.info_str, sizeof(s->nc.info_str),
+ "socket: connection from %s:%d",
+ inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
 }
 
 static int net_socket_listen_init(VLANState *vlan,
@@ -405,19 +411,17 @@ static int net_socket_listen_init(VLANState *vlan,
   const char *name,
   const char *host_str)
 {
-NetSocketListenState *s;
-int fd, val, ret;
+VLANClientState *nc;
+NetSocketState *s;
 struct sockaddr_in saddr;
+int fd, val, ret;
 
 if (parse_host_port(&saddr, host_str) < 0)
 return -1;
 
-s = g_malloc0(sizeof(NetSocketListenState));
-
 fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
 if (fd < 0) {
 perror("socket");
-g_free(s);
 return -1;
 }
 socket_set_nonblock(fd);
@@ -429,22 +433,22 @@ static int net_socket_listen_init(VLANState *vlan,
 ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
 if (ret < 0) {
 perror("bind");
-g_free(s);
 closesocket(fd);
 return -1;
 }
 ret = listen(fd, 0);
 if (ret < 0) {
 perror("listen");
-g_free(s);
 closesocket(fd);
 return -1;
 }
-s->vlan = vlan;
-s->model = g_strdup(model);
-s->name = name ? g_strdup(name) : NULL;
-s->fd = fd;
-qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
+
+

[Qemu-devel] [PATCH v6 1/2] net: fix the coding style

2012-06-11 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 net/socket.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index fcd0a3c..7194345 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -301,7 +301,9 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState 
*vlan,
 qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
 
 /* mcast: save bound address as dst */
-if (is_connected) s->dgram_dst=saddr;
+if (is_connected) {
+s->dgram_dst = saddr;
+}
 
 return s;
 
-- 
1.7.6




[Qemu-devel] [PATCH v6 2/2] net: add the support for -netdev socket, listen

2012-06-11 Thread zwu . kernel
From: Zhi Yong Wu 

The -net socket,listen option does not work with the newer -netdev
syntax:
 http://lists.gnu.org/archive/html/qemu-devel/2011-11/msg01508.html

This patch makes it work now.

For the case where one vlan has multiple listenning sockets,
the patch will also provide the support.

Supported syntax:
 1.) -net socket,listen=127.0.0.1:1234,vlan=0
 2.) -net socket,listen=127.0.0.1:1234,vlan=0 -net 
socket,listen=127.0.0.1:1235,vlan=0
 3.) -netdev socket,listen=127.0.0.1:1234,id=socket0

Changelog from v5:
 Adjust fd invalid value to -1 [stefan]

v4:
 Adopted the suggestion from stefan [stefan]

 Drop the NetSocketListenState struct and add a listen_fd field
to NetSocketState.  When a -netdev socket,listen= instance is created
there will be a NetSocketState with fd=-1 and a valid listen_fd.  The
net_socket_accept() handler waits for listen_fd to become readable and
then accepts the connection.  When this state transition happens, we no
longer monitor listen_fd for incoming connections...until the client
disconnects again.

Suggested-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 net/socket.c |   58 +++---
 1 files changed, 31 insertions(+), 27 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index 7194345..f67de47 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -35,6 +35,7 @@
 
 typedef struct NetSocketState {
 VLANClientState nc;
+int listen_fd;
 int fd;
 int state; /* 0 = getting length, 1 = getting data */
 unsigned int index;
@@ -43,12 +44,7 @@ typedef struct NetSocketState {
 struct sockaddr_in dgram_dst; /* contains inet host and port destination 
iff connectionless (SOCK_DGRAM) */
 } NetSocketState;
 
-typedef struct NetSocketListenState {
-VLANState *vlan;
-char *model;
-char *name;
-int fd;
-} NetSocketListenState;
+static void net_socket_accept(void *opaque);
 
 /* XXX: we consider we can send the whole packet without blocking */
 static ssize_t net_socket_receive(VLANClientState *nc, const uint8_t *buf, 
size_t size)
@@ -86,7 +82,16 @@ static void net_socket_send(void *opaque)
 /* end of connection */
 eoc:
 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
+qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
 closesocket(s->fd);
+
+s->fd = -1;
+s->state = 0;
+s->index = 0;
+s->packet_len = 0;
+memset(s->buf, 0, sizeof(s->buf));
+memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
+
 return;
 }
 buf = buf1;
@@ -377,27 +382,28 @@ static NetSocketState *net_socket_fd_init(VLANState *vlan,
 
 static void net_socket_accept(void *opaque)
 {
-NetSocketListenState *s = opaque;
-NetSocketState *s1;
+NetSocketState *s = opaque;
 struct sockaddr_in saddr;
 socklen_t len;
 int fd;
 
 for(;;) {
 len = sizeof(saddr);
-fd = qemu_accept(s->fd, (struct sockaddr *)&saddr, &len);
+fd = qemu_accept(s->listen_fd, (struct sockaddr *)&saddr, &len);
 if (fd < 0 && errno != EINTR) {
 return;
 } else if (fd >= 0) {
+qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
 break;
 }
 }
-s1 = net_socket_fd_init(s->vlan, s->model, s->name, fd, 1);
-if (s1) {
-snprintf(s1->nc.info_str, sizeof(s1->nc.info_str),
- "socket: connection from %s:%d",
- inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
-}
+
+s->fd = fd;
+s->nc.link_down = false;
+net_socket_connect(s);
+snprintf(s->nc.info_str, sizeof(s->nc.info_str),
+ "socket: connection from %s:%d",
+ inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
 }
 
 static int net_socket_listen_init(VLANState *vlan,
@@ -405,19 +411,17 @@ static int net_socket_listen_init(VLANState *vlan,
   const char *name,
   const char *host_str)
 {
-NetSocketListenState *s;
-int fd, val, ret;
+VLANClientState *nc;
+NetSocketState *s;
 struct sockaddr_in saddr;
+int fd, val, ret;
 
 if (parse_host_port(&saddr, host_str) < 0)
 return -1;
 
-s = g_malloc0(sizeof(NetSocketListenState));
-
 fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
 if (fd < 0) {
 perror("socket");
-g_free(s);
 return -1;
 }
 socket_set_nonblock(fd);
@@ -429,22 +433,22 @@ static int net_socket_listen_init(VLANState *vlan,
 ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
 if (ret < 0) {
 perror("bind");
-g_free(s);
 closesocket(fd);
 return -1;
 }
 ret = listen(fd, 0);
 if (ret < 0) {
 perror("listen");
-g_free(s);
 closesocket(fd);
 return -1;
 }
-s->vlan = vlan;
-s->model = g_strdup(model);
-s->name = name ? g_strdup(name) : NULL;
-s->fd = fd;
-qemu_set_fd_ha

[Qemu-devel] [PATCH] net: roll back qdev_prop_vlan

2012-06-16 Thread zwu . kernel
From: Zhi Yong Wu 

We're trying to preserve backward compatibility.  This
command-line break:

x86_64-softmmu/qemu-system-x86_64 -net user,vlan=1 -device virtio-net-pci,vlan=1

Instead of dropping the qdev_prop_vlan completely the
hw/qdev-properties.c code needs to call net/hub.h external functions
to implement equivalent functionality.

Signed-off-by: Zhi Yong Wu 
---
 hw/qdev-properties.c |   76 ++
 hw/qdev.h|3 ++
 net.h|1 +
 net/hub.c|   25 
 net/hub.h|1 +
 5 files changed, 106 insertions(+), 0 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 1c13bda..91328eb 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -2,6 +2,7 @@
 #include "qdev.h"
 #include "qerror.h"
 #include "blockdev.h"
+#include "net/hub.h"
 
 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
 {
@@ -623,6 +624,81 @@ PropertyInfo qdev_prop_netdev = {
 .set   = set_netdev,
 };
 
+/* --- vlan --- */
+
+static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
+
+if (*ptr) {
+unsigned int id;
+if (!net_hub_id_for_client(*ptr, &id)) {
+return snprintf(dest, len, "%d", id);
+}
+}
+
+return snprintf(dest, len, "");
+}
+
+static void get_vlan(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
+NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
+int64_t id = -1;
+
+if (*ptr) {
+unsigned int hub_id;
+net_hub_id_for_client(*ptr, &hub_id);
+id = (int64_t)hub_id;
+}
+
+visit_type_int(v, &id, name, errp);
+}
+
+static void set_vlan(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
+NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
+Error *local_err = NULL;
+int64_t id;
+NetClientState *hubport;
+
+if (dev->state != DEV_STATE_CREATED) {
+error_set(errp, QERR_PERMISSION_DENIED);
+return;
+}
+
+visit_type_int(v, &id, name, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
+if (id == -1) {
+*ptr = NULL;
+return;
+}
+
+hubport = net_hub_port_find(id);
+if (!hubport) {
+error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+  name, prop->info->name);
+return;
+}
+*ptr = hubport;
+}
+
+PropertyInfo qdev_prop_vlan = {
+.name  = "vlan",
+.print = print_vlan,
+.get   = get_vlan,
+.set   = set_vlan,
+};
+
 /* --- pointer --- */
 
 /* Not a proper property, just for dirty hacks.  TODO Remove it!  */
diff --git a/hw/qdev.h b/hw/qdev.h
index edbf8fa..f4aea27 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -222,6 +222,7 @@ extern PropertyInfo qdev_prop_macaddr;
 extern PropertyInfo qdev_prop_losttickpolicy;
 extern PropertyInfo qdev_prop_drive;
 extern PropertyInfo qdev_prop_netdev;
+extern PropertyInfo qdev_prop_vlan;
 extern PropertyInfo qdev_prop_pci_devfn;
 extern PropertyInfo qdev_prop_blocksize;
 
@@ -276,6 +277,8 @@ extern PropertyInfo qdev_prop_blocksize;
 DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
 #define DEFINE_PROP_NETDEV(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, NetClientState*)
+#define DEFINE_PROP_VLAN(_n, _s, _f) \
+DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, NetClientState*)
 #define DEFINE_PROP_DRIVE(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *)
 #define DEFINE_PROP_MACADDR(_n, _s, _f) \
diff --git a/net.h b/net.h
index 08306a4..c4e56cc 100644
--- a/net.h
+++ b/net.h
@@ -22,6 +22,7 @@ typedef struct NICConf {
 
 #define DEFINE_NIC_PROPERTIES(_state, _conf)\
 DEFINE_PROP_MACADDR("mac",   _state, _conf.macaddr),\
+DEFINE_PROP_VLAN("vlan", _state, _conf.peer),   \
 DEFINE_PROP_NETDEV("netdev", _state, _conf.peer),   \
 DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1)
 
diff --git a/net/hub.c b/net/hub.c
index efd90b5..001f818 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -205,6 +205,31 @@ NetClientState *net_hub_find_client_by_name(unsigned int 
hub_id,
 }
 
 /**
+ * Find a available port on a hub; otherwise create one new port
+ */
+NetClientState *net_hub_port_find(unsigned int hub_id)
+{
+NetHub *hub;
+NetHubPort *port;
+NetClientState *nc;
+
+QLIST_FOREACH(hub, &hubs, next) {
+if (hub->id == hub_id) {
+QLIST_FOREACH(port, &hub->ports, next) {
+nc = port->nc.peer;
+if (!nc) {
+return &(port->nc);
+}
+

[Qemu-devel] [PATCH v4 2/2] block: disable I/O throttling on sync api

2012-04-02 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 block.c |   20 
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/block.c b/block.c
index 1fbf4dd..058ef17 100644
--- a/block.c
+++ b/block.c
@@ -1477,6 +1477,17 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t 
sector_num, uint8_t *buf,
 
 qemu_iovec_init_external(&qiov, &iov, 1);
 
+/**
+ * In sync call context, when the vcpu is blocked, this throttling timer
+ * will not fire; so the I/O throttling function has to be disabled here
+ * if it has been enabled.
+ */
+if (bs->io_limits_enabled) {
+fprintf(stderr, "Disabling I/O throttling on '%s' due "
+"to synchronous I/O.\n", bdrv_get_device_name(bs));
+bdrv_io_limits_disable(bs);
+}
+
 if (qemu_in_coroutine()) {
 /* Fast-path if already in coroutine context */
 bdrv_rw_co_entry(&rwco);
@@ -1983,10 +1994,19 @@ static int guess_disk_lchs(BlockDriverState *bs,
 struct partition *p;
 uint32_t nr_sects;
 uint64_t nb_sectors;
+bool enabled;
 
 bdrv_get_geometry(bs, &nb_sectors);
 
+/**
+ * The function will be invoked during startup not only in sync I/O mode,
+ * but also in async I/O mode. So the I/O throttling function has to
+ * be disabled temporarily here, not permanently.
+ */
+enabled = bs->io_limits_enabled;
+bs->io_limits_enabled = false;
 ret = bdrv_read(bs, 0, buf, 1);
+bs->io_limits_enabled = enabled;
 if (ret < 0)
 return -1;
 /* test msdos magic */
-- 
1.7.6




[Qemu-devel] [PATCH] vhost-net: adjust vhost_net.[c|h] -> vhost-net.[c|h]

2012-04-18 Thread zwu . kernel
From: Zhi Yong Wu 

Keep the consistent file naming style with other files

Signed-off-by: Zhi Yong Wu 
---
 Makefile.target |2 +-
 hw/vhost-net.c  |  250 +++
 hw/vhost-net.h  |   20 +
 hw/vhost_net.c  |  250 ---
 hw/vhost_net.h  |   20 -
 hw/virtio-net.c |2 +-
 net/tap.c   |2 +-
 7 files changed, 273 insertions(+), 273 deletions(-)
 create mode 100644 hw/vhost-net.c
 create mode 100644 hw/vhost-net.h
 delete mode 100644 hw/vhost_net.c
 delete mode 100644 hw/vhost_net.h

diff --git a/Makefile.target b/Makefile.target
index 84951a0..4bccdb1 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -219,7 +219,7 @@ obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o 
balloon.o ioport.o
 obj-$(CONFIG_NO_PCI) += pci-stub.o
 obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o 
virtio-serial-bus.o
 obj-$(CONFIG_VIRTIO) += virtio-scsi.o
-obj-y += vhost_net.o
+obj-y += vhost-net.o
 obj-$(CONFIG_VHOST_NET) += vhost.o
 obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
 obj-$(CONFIG_KVM) += kvm.o kvm-all.o
diff --git a/hw/vhost-net.c b/hw/vhost-net.c
new file mode 100644
index 000..48937d2
--- /dev/null
+++ b/hw/vhost-net.c
@@ -0,0 +1,250 @@
+/*
+ * vhost-net support
+ *
+ * Copyright Red Hat, Inc. 2010
+ *
+ * Authors:
+ *  Michael S. Tsirkin 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include "net.h"
+#include "net/tap.h"
+
+#include "virtio-net.h"
+#include "vhost-net.h"
+#include "qemu-error.h"
+
+#include "config.h"
+
+#ifdef CONFIG_VHOST_NET
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "vhost.h"
+
+struct vhost_net {
+struct vhost_dev dev;
+struct vhost_virtqueue vqs[2];
+int backend;
+VLANClientState *vc;
+};
+
+unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
+{
+/* Clear features not supported by host kernel. */
+if (!(net->dev.features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY))) {
+features &= ~(1 << VIRTIO_F_NOTIFY_ON_EMPTY);
+}
+if (!(net->dev.features & (1 << VIRTIO_RING_F_INDIRECT_DESC))) {
+features &= ~(1 << VIRTIO_RING_F_INDIRECT_DESC);
+}
+if (!(net->dev.features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
+features &= ~(1 << VIRTIO_RING_F_EVENT_IDX);
+}
+if (!(net->dev.features & (1 << VIRTIO_NET_F_MRG_RXBUF))) {
+features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
+}
+return features;
+}
+
+void vhost_net_ack_features(struct vhost_net *net, unsigned features)
+{
+net->dev.acked_features = net->dev.backend_features;
+if (features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) {
+net->dev.acked_features |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
+}
+if (features & (1 << VIRTIO_RING_F_INDIRECT_DESC)) {
+net->dev.acked_features |= (1 << VIRTIO_RING_F_INDIRECT_DESC);
+}
+if (features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+net->dev.acked_features |= (1 << VIRTIO_RING_F_EVENT_IDX);
+}
+if (features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
+net->dev.acked_features |= (1 << VIRTIO_NET_F_MRG_RXBUF);
+}
+}
+
+static int vhost_net_get_fd(VLANClientState *backend)
+{
+switch (backend->info->type) {
+case NET_CLIENT_TYPE_TAP:
+return tap_get_fd(backend);
+default:
+fprintf(stderr, "vhost-net requires tap backend\n");
+return -EBADFD;
+}
+}
+
+struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd,
+ bool force)
+{
+int r;
+struct vhost_net *net = g_malloc(sizeof *net);
+if (!backend) {
+fprintf(stderr, "vhost-net requires backend to be setup\n");
+goto fail;
+}
+r = vhost_net_get_fd(backend);
+if (r < 0) {
+goto fail;
+}
+net->vc = backend;
+net->dev.backend_features = tap_has_vnet_hdr(backend) ? 0 :
+(1 << VHOST_NET_F_VIRTIO_NET_HDR);
+net->backend = r;
+
+r = vhost_dev_init(&net->dev, devfd, force);
+if (r < 0) {
+goto fail;
+}
+if (!tap_has_vnet_hdr_len(backend,
+  sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
+net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
+}
+if (~net->dev.features & net->dev.backend_features) {
+fprintf(stderr, "vhost lacks feature mask %" PRIu64 " for backend\n",
+(uint64_t)(~net->dev.features & net->dev.backend_features));
+vhost_dev_cleanup(&net->dev);
+goto fail;
+}
+
+/* Set sane init value. Override when guest acks. */
+vhost_net_ack_features(net, 0);
+return net;
+fail:
+g_free(net);
+return 

[Qemu-devel] [PATCH 02/16] vhost: Pass device path to vhost_dev_init()

2012-04-18 Thread zwu . kernel
From: Stefan Hajnoczi 

The path to /dev/vhost-net is currently hardcoded in vhost_dev_init().
This needs to be changed so that /dev/vhost-scsi can be used.  Pass in
the device path instead of hardcoding it.

Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Zhi Yong Wu 
---
 hw/vhost.c |5 +++--
 hw/vhost.h |3 ++-
 hw/vhost_net.c |2 +-
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/hw/vhost.c b/hw/vhost.c
index 43664e7..e24a9b8 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -747,14 +747,15 @@ static void vhost_eventfd_del(MemoryListener *listener,
 {
 }
 
-int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force)
+int vhost_dev_init(struct vhost_dev *hdev, int devfd, const char *devpath,
+   bool force)
 {
 uint64_t features;
 int r;
 if (devfd >= 0) {
 hdev->control = devfd;
 } else {
-hdev->control = open("/dev/vhost-net", O_RDWR);
+hdev->control = open(devpath, O_RDWR);
 if (hdev->control < 0) {
 return -errno;
 }
diff --git a/hw/vhost.h b/hw/vhost.h
index 80e64df..0c47229 100644
--- a/hw/vhost.h
+++ b/hw/vhost.h
@@ -44,7 +44,8 @@ struct vhost_dev {
 bool force;
 };
 
-int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force);
+int vhost_dev_init(struct vhost_dev *hdev, int devfd, const char *devpath,
+   bool force);
 void vhost_dev_cleanup(struct vhost_dev *hdev);
 bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev);
 int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
diff --git a/hw/vhost_net.c b/hw/vhost_net.c
index f672e9d..30e7e31 100644
--- a/hw/vhost_net.c
+++ b/hw/vhost_net.c
@@ -109,7 +109,7 @@ struct vhost_net *vhost_net_init(VLANClientState *backend, 
int devfd,
 (1 << VHOST_NET_F_VIRTIO_NET_HDR);
 net->backend = r;
 
-r = vhost_dev_init(&net->dev, devfd, force);
+r = vhost_dev_init(&net->dev, devfd, "/dev/vhost-net", force);
 if (r < 0) {
 goto fail;
 }
-- 
1.7.6




[Qemu-devel] [PATCH 05/16] virtio-scsi: Build virtio-scsi.o against vhost.o

2012-04-18 Thread zwu . kernel
From: Stefan Hajnoczi 

For the time being virtio-scsi.c will directly use vhost without a host
device abstraction like virtio-net does.  This patch builds virtio-scsi
with vhost on KVM targets.

Also make sure that virtio-pci.o can be built without virtio-scsi.o.

Signed-off-by: Stefan Hajnoczi 
---
 configure |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/configure b/configure
index 2d62d12..efd8685 100755
--- a/configure
+++ b/configure
@@ -3682,6 +3682,8 @@ case "$target_arch2" in
   if test "$vhost_net" = "yes" ; then
 echo "CONFIG_VHOST_NET=y" >> $config_target_mak
   fi
+  echo "CONFIG_VIRTIO_SCSI=y" >> $config_target_mak
+  echo "CONFIG_VHOST=y" >> $config_target_mak
 fi
 esac
 if test "$target_arch2" = "ppc64" -a "$fdt" = "yes"; then
-- 
1.7.6




  1   2   >