init/remove colo nic devices when add/cleanup tap devices Signed-off-by: Yang Hongyang <yan...@cn.fujitsu.com> Cc: Stefan Hajnoczi <stefa...@redhat.com> --- include/net/colo-nic.h | 18 +++++++++++++++++ include/net/net.h | 3 +++ net/Makefile.objs | 1 + net/colo-nic.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ net/tap.c | 45 +++++++++++++++++++++++++++++++++-------- 5 files changed, 113 insertions(+), 8 deletions(-) create mode 100644 include/net/colo-nic.h create mode 100644 net/colo-nic.c
diff --git a/include/net/colo-nic.h b/include/net/colo-nic.h new file mode 100644 index 0000000..fe6874b --- /dev/null +++ b/include/net/colo-nic.h @@ -0,0 +1,18 @@ +/* + * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO) + * (a.k.a. Fault Tolerance or Continuous Replication) + * + * Copyright (C) 2014 FUJITSU LIMITED + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#ifndef COLO_NIC_H +#define COLO_NIC_H + +void colo_add_nic_devices(NetClientState *nc); +void colo_remove_nic_devices(NetClientState *nc); + +#endif diff --git a/include/net/net.h b/include/net/net.h index ed594f9..62050c5 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -85,6 +85,9 @@ struct NetClientState { char *model; char *name; char info_str[256]; + char colo_script[1024]; + char colo_nicname[128]; + char ifname[128]; unsigned receive_disabled : 1; NetClientDestructor *destructor; unsigned int queue_index; diff --git a/net/Makefile.objs b/net/Makefile.objs index ec19cb3..73f4a81 100644 --- a/net/Makefile.objs +++ b/net/Makefile.objs @@ -13,3 +13,4 @@ common-obj-$(CONFIG_HAIKU) += tap-haiku.o common-obj-$(CONFIG_SLIRP) += slirp.o common-obj-$(CONFIG_VDE) += vde.o common-obj-$(CONFIG_NETMAP) += netmap.o +common-obj-$(CONFIG_COLO) += colo-nic.o diff --git a/net/colo-nic.c b/net/colo-nic.c new file mode 100644 index 0000000..2f7ca23 --- /dev/null +++ b/net/colo-nic.c @@ -0,0 +1,54 @@ +/* + * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO) + * (a.k.a. Fault Tolerance or Continuous Replication) + * + * Copyright (C) 2014 FUJITSU LIMITED + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + * + */ +#include "net/net.h" +#include "net/colo-nic.h" + +typedef struct nic_device { + NetClientState *nc; + bool (*support_colo)(NetClientState *nc); + int (*configure)(NetClientState *nc, bool up, bool is_slave); + QTAILQ_ENTRY(nic_device) next; + bool is_up; +} nic_device; + +QTAILQ_HEAD(, nic_device) nic_devices = QTAILQ_HEAD_INITIALIZER(nic_devices); + +void colo_add_nic_devices(NetClientState *nc) +{ + struct nic_device *nic = g_malloc0(sizeof(*nic)); + + /* TODO: init colo function pointers */ + /* + * TODO + * only support "-netdev tap,colo_scripte..." options + * "-net nic -net tap..." options is not supported + */ + nic->nc = nc; + + QTAILQ_INSERT_TAIL(&nic_devices, nic, next); +} + +void colo_remove_nic_devices(NetClientState *nc) +{ + struct nic_device *nic, *next_nic; + + if (!nc) { + return; + } + + QTAILQ_FOREACH_SAFE(nic, &nic_devices, next, next_nic) { + if (nic->nc == nc) { + /* TODO: teardown colo nic */ + QTAILQ_REMOVE(&nic_devices, nic, next); + g_free(nic); + } + } +} diff --git a/net/tap.c b/net/tap.c index a40f7f0..d1a1dab 100644 --- a/net/tap.c +++ b/net/tap.c @@ -41,6 +41,7 @@ #include "qemu/error-report.h" #include "net/tap.h" +#include "net/colo-nic.h" #include "net/vhost_net.h" @@ -284,6 +285,8 @@ static void tap_cleanup(NetClientState *nc) qemu_purge_queued_packets(nc); + colo_remove_nic_devices(nc); + if (s->down_script[0]) launch_script(s->down_script, s->down_script_arg, s->fd); @@ -591,10 +594,11 @@ static int net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, const char *model, const char *name, const char *ifname, const char *script, const char *downscript, const char *vhostfdname, - int vnet_hdr, int fd) + int vnet_hdr, int fd, bool setup_colo) { TAPState *s; int vhostfd; + NetClientState *nc = NULL; s = net_tap_fd_init(peer, model, name, fd, vnet_hdr); if (!s) { @@ -623,6 +627,21 @@ static int net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, } } + nc = &(s->nc); + snprintf(nc->ifname, sizeof(nc->ifname), "%s", ifname); + if (tap->has_colo_script) { + snprintf(nc->colo_script, sizeof(nc->colo_script), "%s", + tap->colo_script); + } + if (tap->has_colo_nicname) { + snprintf(nc->colo_nicname, sizeof(nc->colo_nicname), "%s", + tap->colo_nicname); + } + + if (setup_colo) { + colo_add_nic_devices(nc); + } + if (tap->has_vhost ? tap->vhost : vhostfdname || (tap->has_vhostforce && tap->vhostforce)) { VhostNetOptions options; @@ -729,7 +748,7 @@ int net_init_tap(const NetClientOptions *opts, const char *name, if (net_init_tap_one(tap, peer, "tap", name, NULL, script, downscript, - vhostfdname, vnet_hdr, fd)) { + vhostfdname, vnet_hdr, fd, true)) { return -1; } } else if (tap->has_fds) { @@ -739,9 +758,10 @@ int net_init_tap(const NetClientOptions *opts, const char *name, if (tap->has_ifname || tap->has_script || tap->has_downscript || tap->has_vnet_hdr || tap->has_helper || tap->has_queues || - tap->has_vhostfd) { + tap->has_vhostfd || tap->has_colo_script || tap->has_colo_nicname) { error_report("ifname=, script=, downscript=, vnet_hdr=, " "helper=, queues=, and vhostfd= " + "colo_script=, and colo_nicname= " "are invalid with fds="); return -1; } @@ -774,15 +794,17 @@ int net_init_tap(const NetClientOptions *opts, const char *name, if (net_init_tap_one(tap, peer, "tap", name, ifname, script, downscript, tap->has_vhostfds ? vhost_fds[i] : NULL, - vnet_hdr, fd)) { + vnet_hdr, fd, false)) { return -1; } } } else if (tap->has_helper) { if (tap->has_ifname || tap->has_script || tap->has_downscript || - tap->has_vnet_hdr || tap->has_queues || tap->has_vhostfds) { + tap->has_vnet_hdr || tap->has_queues || tap->has_vhostfds || + tap->has_colo_script || tap->has_colo_nicname) { error_report("ifname=, script=, downscript=, and vnet_hdr= " - "queues=, and vhostfds= are invalid with helper="); + "queues=, vhostfds=, colo_script=, and " + "colo_nicname= are invalid with helper="); return -1; } @@ -796,10 +818,16 @@ int net_init_tap(const NetClientOptions *opts, const char *name, if (net_init_tap_one(tap, peer, "bridge", name, ifname, script, downscript, vhostfdname, - vnet_hdr, fd)) { + vnet_hdr, fd, false)) { return -1; } } else { + if (queues > 1 && (tap->has_colo_script || tap->has_colo_nicname)) { + error_report("queues > 1 is invalid if colo_script or " + "colo_nicname is specified"); + return -1; + } + if (tap->has_vhostfds) { error_report("vhostfds= is invalid if fds= wasn't specified"); return -1; @@ -831,7 +859,8 @@ int net_init_tap(const NetClientOptions *opts, const char *name, if (net_init_tap_one(tap, peer, "tap", name, ifname, i >= 1 ? "no" : script, i >= 1 ? "no" : downscript, - vhostfdname, vnet_hdr, fd)) { + vhostfdname, vnet_hdr, fd, + i == 0)) { return -1; } } -- 1.9.1