[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH v2 21/23] COLO nic: implement colo nic device in
From: |
Yang Hongyang |
Subject: |
[Qemu-devel] [RFC PATCH v2 21/23] COLO nic: implement colo nic device interface configure() |
Date: |
Tue, 23 Sep 2014 17:23:53 +0800 |
implement colo nic device interface configure()
add a script to configure nic devices:
${QEMU_SCRIPT_DIR}/network-colo
Script for configuring the network of Master & Slaver.
Usage:
network-colo (master|slaver) (install|uninstall) vif pif [ifb1 ifb2]
Signed-off-by: Yang Hongyang <address@hidden>
---
include/net/net.h | 1 +
net/colo-nic.c | 106 +++++++++++++++++++++++++++++
network-colo | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 301 insertions(+)
create mode 100755 network-colo
diff --git a/include/net/net.h b/include/net/net.h
index 62050c5..9cc9b5c 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -88,6 +88,7 @@ struct NetClientState {
char colo_script[1024];
char colo_nicname[128];
char ifname[128];
+ char ifb[2][128];
unsigned receive_disabled : 1;
NetClientDestructor *destructor;
unsigned int queue_index;
diff --git a/net/colo-nic.c b/net/colo-nic.c
index 7255a48..d661d8b 100644
--- a/net/colo-nic.c
+++ b/net/colo-nic.c
@@ -10,6 +10,7 @@
*/
#include "net/net.h"
#include "net/colo-nic.h"
+#include "qemu/error-report.h"
typedef struct nic_device {
NetClientState *nc;
@@ -26,11 +27,116 @@ static bool nic_support_colo(NetClientState *nc)
return nc && nc->colo_script[0] && nc->colo_nicname[0];
}
+#define STDOUT_BUF_LEN 1024
+static char stdout_buf[STDOUT_BUF_LEN];
+
+static int launch_colo_script(char *argv[])
+{
+ int pid, status;
+ char *script = argv[0];
+ int fds[2];
+
+ bzero(stdout_buf, sizeof(stdout_buf));
+
+ if (pipe(fds) < 0) {
+ return -1;
+ }
+ /* try to launch network script */
+ pid = fork();
+ if (pid == 0) {
+ close(fds[0]);
+ dup2(fds[1], STDOUT_FILENO);
+ execv(script, argv);
+ _exit(1);
+ } else if (pid > 0) {
+ FILE *stream;
+ int n;
+ close(fds[1]);
+ stream = fdopen(fds[0], "r");
+ n = fread(stdout_buf, 1, STDOUT_BUF_LEN - 1, stream);
+ stdout_buf[n] = '\0';
+ close(fds[0]);
+
+ while (waitpid(pid, &status, 0) != pid) {
+ /* loop */
+ }
+
+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+ return 0;
+ }
+ }
+ fprintf(stderr, "%s\n", stdout_buf);
+ fprintf(stderr, "%s: could not launch network script\n", script);
+ return -1;
+}
+
+static void store_ifbname(NetClientState *nc)
+{
+ char *str_b = NULL, *str_e = NULL;
+
+ str_b = strstr(stdout_buf, "ifb0=");
+ if (str_b) {
+ str_e = strstr(str_b, "\n");
+ }
+ if (str_e) {
+ snprintf(nc->ifb[0], str_e - str_b - 5 + 1, "%s", str_b + 5);
+ }
+
+ str_b = str_e = NULL;
+ str_b = strstr(stdout_buf, "ifb1=");
+ if (str_b) {
+ str_e = strstr(str_b, "\n");
+ }
+ if (str_e) {
+ snprintf(nc->ifb[1], str_e - str_b - 5 + 1, "%s", str_b + 5);
+ }
+}
+
+static int nic_configure(NetClientState *nc, bool up, bool is_slave)
+{
+ char *argv[8];
+ char **parg;
+ int ret = -1, i;
+ int argc = (!is_slave && !up) ? 7 : 5;
+
+ if (!nc) {
+ error_report("Can not parse colo_script or colo_nicname");
+ return ret;
+ }
+
+ parg = argv;
+ *parg++ = nc->colo_script;
+ *parg++ = (char *)(is_slave ? "slaver" : "master");
+ *parg++ = (char *)(up ? "install" : "uninstall");
+ *parg++ = nc->ifname;
+ *parg++ = nc->colo_nicname;
+ if (!is_slave && !up) {
+ *parg++ = nc->ifb[0];
+ *parg++ = nc->ifb[1];
+ }
+ *parg = NULL;
+
+ for (i = 0; i < argc; i++) {
+ if (!argv[i][0]) {
+ error_report("Can not get colo_script argument");
+ return ret;
+ }
+ }
+
+ ret = launch_colo_script(argv);
+ if (!is_slave && up && ret == 0) {
+ store_ifbname(nc);
+ }
+
+ return ret;
+}
+
void colo_add_nic_devices(NetClientState *nc)
{
struct nic_device *nic = g_malloc0(sizeof(*nic));
nic->support_colo = nic_support_colo;
+ nic->configure = nic_configure;
/*
* TODO
diff --git a/network-colo b/network-colo
new file mode 100755
index 0000000..9112888
--- /dev/null
+++ b/network-colo
@@ -0,0 +1,194 @@
+#! /bin/bash
+#============================================================================
+# ${QEMU_SCRIPT_DIR}/network-colo
+#
+# Script for configuring the network of Master & Slaver.
+#
+# Usage:
+# network-colo (master|slaver) (install|uninstall) vif pif [ifb1 ifb2]
+#============================================================================
+
+sides=$1
+op=$2
+vif=$3
+pif=$4
+ifb1=$5
+ifb2=$6
+BR=br1
+
+qlen=40960
+module="HA_compare"
+device="HA_compare"
+
+# start_master ifbx
+function start_master() {
+
+ # In colo mode, we don't use gso, gro...
+ ip link set dev $vif qlen $qlen
+
+ # copy and foward input packets to $pif
+ tc qdisc add dev $vif root handle 1: prio
+ tc filter add dev $vif parent 1: protocol ip prio 10 u32 match u32 0 0
flowid 1:2 action mirred egress mirror dev $pif
+ tc filter add dev $vif parent 1: protocol arp prio 11 u32 match u32 0 0
flowid 1:2 action mirred egress mirror dev $pif
+
+ # foward output packets to ifbx
+ tc qdisc add dev $vif ingress
+ tc filter add dev $vif parent ffff: protocol ip prio 10 u32 match u32 0 0
flowid 1:2 action mirred egress redirect dev $1
+ tc filter add dev $vif parent ffff: protocol arp prio 11 u32 match u32 0 0
flowid 1:2 action mirred egress redirect dev $1
+}
+
+function stop_master() {
+ # don't copy and foward input packets to $pif
+ tc filter del dev $vif parent 1: protocol ip prio 10 u32
+ tc filter del dev $vif parent 1: protocol arp prio 11 u32
+ tc qdisc del dev $vif root handle 1: prio
+
+ # don't foward output packets to ifbx
+ tc filter del dev $vif parent ffff: protocol ip prio 10 u32
+ tc filter del dev $vif parent ffff: protocol arp prio 11 u32
+ tc qdisc del dev $vif ingress
+}
+
+# load_module module parameter
+function load_module()
+{
+ local module=$1
+ shift
+
+ lsmod | grep -q "$module"
+ if [[ $? -eq 0 ]]; then
+ # The module has been loaded
+ return
+ fi
+
+ modprobe $module "$@"
+}
+
+function select_ifb()
+{
+ local -i index
+
+ for (( index = 0; index < 100; index++)); do
+ state=$(ip link show dev ifb$index | sed -n -e 's/.*state
\([a-zA-Z]*\) .*/\1/p')
+ if [[ $state == "DOWN" ]]; then
+ return $index
+ fi
+ done
+
+ return 100
+}
+
+
+function install_master() {
+ load_module sch_colo
+ load_module HA_compare
+ load_module HA_compare_icmp
+
+ if [[ ! -e "/dev/$device" ]]; then
+ major=$(awk "\$2==\"$module\" {print \$1}" /proc/devices)
+ mknod /dev/$device c $major 0
+ fi
+
+ load_module ifb numifbs=100
+
+ select_ifb
+ index1=$?
+ if [[ $index1 -eq 100 ]]; then
+ echo "index1 $index1 overflow" >>/root/network-colo.log
+ exit 1
+ fi
+ ip link set ifb$index1 up
+ ip link set ifb$index1 qlen $qlen
+
+ select_ifb
+ index2=$?
+ if [[ $index2 -eq 100 ]]; then
+ echo "index1 $index1 overflow" >>/root/network-colo.log
+ exit 1
+ fi
+ ip link set ifb$index2 up
+ ip link set ifb$index2 qlen $qlen
+ colo_tc qdisc add dev ifb$index1 root handle 1: colo dev ifb$index2 master
+ colo_tc qdisc add dev ifb$index2 root handle 1: colo dev ifb$index1 slaver
+
+ ifconfig $pif promisc
+ ip link set $pif qlen $qlen
+
+ # forward packets from $pif to ifb$index2
+ tc qdisc add dev $pif ingress
+ tc filter add dev $pif parent ffff: protocol ip prio 10 u32 match u32 0 0
flowid 1:2 action mirred egress redirect dev ifb$index2
+ tc filter add dev $pif parent ffff: protocol arp prio 11 u32 match u32 0 0
flowid 1:2 action mirred egress redirect dev ifb$index2
+
+ start_master ifb$index1
+}
+
+function uninstall_master() {
+ stop_master
+
+ # shutdown $ifb1
+ tc qdisc del dev $ifb1 root handle 1: colo
+ ip link set $ifb1 down
+
+ # don't forward packets from $pif to $ifb2
+ tc filter del dev $pif parent ffff: protocol ip prio 10 u32
+ tc qdisc del dev $pif ingress
+
+ # shutdown $ifb2
+ tc qdisc del dev $ifb2 root handle 1: colo
+ ip link set $ifb2 down
+
+ ifconfig $pif -promisc
+}
+
+function install_slaver()
+{
+ ifconfig $pif promisc
+ ip link set $pif qlen $qlen
+
+ # forward packets from $pif to $vif
+ tc qdisc add dev $pif ingress
+ tc filter add dev $pif parent ffff: protocol ip prio 10 u32 match u32 0 0
flowid 1:2 action mirred egress redirect dev $vif
+ tc filter add dev $pif parent ffff: protocol arp prio 11 u32 match u32 0 0
flowid 1:2 action mirred egress redirect dev $vif
+
+ ip link set $vif qlen $qlen
+ # forward packets from $vif to $pif
+ tc qdisc add dev $vif ingress
+ tc filter add dev $vif parent ffff: protocol ip prio 10 u32 match u32 0 0
flowid 1:2 action mirred egress redirect dev $pif
+ tc filter add dev $vif parent ffff: protocol arp prio 11 u32 match u32 0 0
flowid 1:2 action mirred egress redirect dev $pif
+
+ brctl delif $BR $vif
+}
+
+function uninstall_slaver()
+{
+ # don't forward packets from $pif to $vif
+ tc filter del dev $pif parent ffff: protocol ip prio 10 u32
+ tc filter del dev $pif parent ffff: protocol arp prio 11 u32
+ tc qdisc del dev $pif ingress
+
+ # don't forward packets from $vif to $pif
+ tc filter del dev $vif parent ffff: protocol ip prio 10 u32
+ tc filter del dev $vif parent ffff: protocol arp prio 11 u32
+ tc qdisc del dev $vif ingress
+
+ ifconfig $pif -promisc
+
+ brctl addif $BR $vif
+}
+
+echo "$@" >/root/network-colo.log
+if [[ $1 != "master" && $1 != "slaver" ]]; then
+ echo "$1 != master/slaver" >>/root/network-colo.log
+ exit 1
+fi
+
+if [[ $2 != "install" && $2 != "uninstall" ]]; then
+ echo "$2 != install/uninstall" >>/root/network-colo.log
+ exit 1
+fi
+
+${op}_$sides 1>>/root/network-colo.log 2>&1
+if [[ $1 == "master" && $2 == "install" ]]; then
+ echo ifb0=ifb$index1
+ echo ifb1=ifb$index2
+fi
--
1.9.1
- [Qemu-devel] [RFC PATCH v2 12/23] COLO ctl: add a RunState RUN_STATE_COLO, (continued)
- [Qemu-devel] [RFC PATCH v2 12/23] COLO ctl: add a RunState RUN_STATE_COLO, Yang Hongyang, 2014/09/23
- [Qemu-devel] [RFC PATCH v2 13/23] COLO ctl: implement colo save, Yang Hongyang, 2014/09/23
- [Qemu-devel] [RFC PATCH v2 14/23] COLO ctl: implement colo restore, Yang Hongyang, 2014/09/23
- [Qemu-devel] [RFC PATCH v2 16/23] COLO ram cache: implement colo ram cache on slave, Yang Hongyang, 2014/09/23
- [Qemu-devel] [RFC PATCH v2 17/23] HACK: trigger checkpoint every 500ms, Yang Hongyang, 2014/09/23
- [Qemu-devel] [RFC PATCH v2 15/23] COLO save: reuse migration bitmap under colo checkpoint, Yang Hongyang, 2014/09/23
- [Qemu-devel] [RFC PATCH v2 18/23] COLO nic: add command line switch, Yang Hongyang, 2014/09/23
- [Qemu-devel] [RFC PATCH v2 19/23] COLO nic: init/remove colo nic devices when add/cleanup tap devices, Yang Hongyang, 2014/09/23
- [Qemu-devel] [RFC PATCH v2 20/23] COLO nic: implement colo nic device interface support_colo(), Yang Hongyang, 2014/09/23
- [Qemu-devel] [RFC PATCH v2 21/23] COLO nic: implement colo nic device interface configure(),
Yang Hongyang <=
- [Qemu-devel] [RFC PATCH v2 22/23] COLO nic: export colo nic APIs, Yang Hongyang, 2014/09/23
- [Qemu-devel] [RFC PATCH v2 23/23] COLO nic: setup/teardown colo nic devices, Yang Hongyang, 2014/09/23