qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: zhanghailiang <zhang.zhanghailiang@huawei.com>
To: qemu-devel@nongnu.org
Cc: lizhijian@cn.fujitsu.com, quintela@redhat.com,
	Jason Wang <jasowang@redhat.com>,
	yunhong.jiang@intel.com, eddie.dong@intel.com,
	peter.huangpeng@huawei.com, dgilbert@redhat.com,
	arei.gonglei@huawei.com, Stefan Hajnoczi <stefanha@redhat.com>,
	amit.shah@redhat.com,
	zhanghailiang <zhang.zhanghailiang@huawei.com>
Subject: [Qemu-devel] [PATCH COLO-Frame v7 26/34] COLO NIC: Some init work related with proxy module
Date: Thu, 9 Jul 2015 11:16:34 +0800	[thread overview]
Message-ID: <1436411802-181876-27-git-send-email-zhang.zhanghailiang@huawei.com> (raw)
In-Reply-To: <1436411802-181876-1-git-send-email-zhang.zhanghailiang@huawei.com>

Implement communication protocol with proxy module by using
nfnetlink, which requires libnfnetlink libs.

Tell proxy module to do initialization work and moreover ask
kernel to acknowledge the request. It's is necessary for the first
time because Netlink is not a reliable protocol.

Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
---
 configure      |  22 +++++++-
 net/colo-nic.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 180 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index a2475db..50f7e05 100755
--- a/configure
+++ b/configure
@@ -2342,7 +2342,25 @@ EOF
     rdma="no"
   fi
 fi
-
+##########################################
+# COLO needs libnfnetlink libraries
+if test "$colo" != "no"; then
+  cat > $TMPC <<EOF
+#include <libnfnetlink/libnfnetlink.h>
+int main(void) { return 0; }
+EOF
+  colo_libs="-lnfnetlink"
+  if compile_prog "" "$colo_libs"; then
+    colo="yes"
+    libs_softmmu="$libs_softmmu $colo_libs"
+  else
+    if test "$colo" = "yes" ; then
+        error_exit "libnfnetlink is required for colo feature." \
+            "Make sure to have the libnfnetlink devel and headers installed."
+    fi
+    colo="no"
+  fi
+fi
 ##########################################
 # VNC TLS/WS detection
 if test "$vnc" = "yes" -a "$vnc_tls" != "no" ; then
@@ -2615,7 +2633,7 @@ EOF
     if compile_prog "$cfl" "$lib" ; then
         :
     else
-        error_exit "$drv check failed" \
+        rror_exit "$drv check failed" \
             "Make sure to have the $drv libs and headers installed."
     fi
 }
diff --git a/net/colo-nic.c b/net/colo-nic.c
index 5c24169..c8e7734 100644
--- a/net/colo-nic.c
+++ b/net/colo-nic.c
@@ -10,6 +10,12 @@
  * later.  See the COPYING file in the top-level directory.
  *
  */
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include <libnfnetlink/libnfnetlink.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
 #include "include/migration/migration.h"
 #include "migration/colo.h"
 #include "net/net.h"
@@ -17,6 +23,53 @@
 #include "qemu/error-report.h"
 #include "net/tap.h"
 
+/* Remove the follow define after proxy is merged into kernel,
+* using #include <libnfnetlink/libnfnetlink.h> instead.
+*/
+#define NFNL_SUBSYS_COLO 12
+
+/* Message Format
+* <---NLMSG_ALIGN(hlen)-----><-------------- NLMSG_ALIGN(len)----------------->
+* +--------------------+- - -+- - - - - - - - - - - - - - +- - - - - - + - - -+
+* |       Header       | Pad |   Netfilter Netlink Header | Attributes | Pad  |
+* |    struct nlmsghdr |     |     struct nfgenmsg        |            |      |
+* +--------------------+- - -+- - - - - - - - - - - - - - + - - - - - -+ - - -+
+*/
+
+enum nfnl_colo_msg_types {
+    NFCOLO_KERNEL_NOTIFY, /* Used by proxy module to notify qemu */
+
+    NFCOLO_DO_CHECKPOINT,
+    NFCOLO_DO_FAILOVER,
+    NFCOLO_PROXY_INIT,
+    NFCOLO_PROXY_RESET,
+
+    NFCOLO_MSG_MAX
+};
+
+enum nfnl_colo_kernel_notify_attributes {
+    NFNL_COLO_KERNEL_NOTIFY_UNSPEC,
+    NFNL_COLO_COMPARE_RESULT,
+    __NFNL_COLO_KERNEL_NOTIFY_MAX
+};
+
+#define NFNL_COLO_KERNEL_NOTIFY_MAX  (__NFNL_COLO_KERNEL_NOTIFY_MAX - 1)
+
+enum nfnl_colo_attributes {
+    NFNL_COLO_UNSPEC,
+    NFNL_COLO_MODE,
+    __NFNL_COLO_MAX
+};
+#define NFNL_COLO_MAX  (__NFNL_COLO_MAX - 1)
+
+struct nfcolo_msg_mode {
+    u_int8_t mode;
+};
+
+struct nfcolo_packet_compare { /* Unused */
+    int32_t different;
+};
+
 typedef struct nic_device {
     COLONicState *cns;
     int (*configure)(COLONicState *cns, bool up, int side, int index);
@@ -24,6 +77,9 @@ typedef struct nic_device {
     bool is_up;
 } nic_device;
 
+static struct nfnl_handle *nfnlh;
+static struct nfnl_subsys_handle *nfnlssh;
+
 static int launch_colo_script(COLONicState *cns, bool up, int side, int index)
 {
     NetClientState *nc = container_of(cns, NetClientState, cns);
@@ -209,19 +265,123 @@ void colo_remove_nic_devices(COLONicState *cns)
     }
 }
 
+static int colo_proxy_send(enum nfnl_colo_msg_types msg_type,
+                           enum COLOMode mode, int flag, void *unused)
+{
+    struct nfcolo_msg_mode params;
+    union {
+        char buf[NFNL_HEADER_LEN
+                 + NFA_LENGTH(sizeof(struct nfcolo_msg_mode))];
+        struct nlmsghdr nmh;
+    } u;
+    int ret;
+
+    if (!nfnlssh || !nfnlh) {
+        error_report("nfnlssh and nfnlh are uninited");
+        return -1;
+    }
+    nfnl_fill_hdr(nfnlssh, &u.nmh, 0, AF_UNSPEC, 1,
+                  msg_type, NLM_F_REQUEST | flag);
+    params.mode = mode;
+    u.nmh.nlmsg_pid = nfnl_portid(nfnlh);
+    ret = nfnl_addattr_l(&u.nmh, sizeof(u),  NFNL_COLO_MODE, &params,
+                         sizeof(params));
+    if (ret < 0) {
+        error_report("call nfnl_addattr_l failed");
+        return ret;
+    }
+    ret = nfnl_send(nfnlh, &u.nmh);
+    if (ret < 0) {
+        error_report("call nfnl_send failed");
+    }
+    return ret;
+}
+
+static int check_proxy_ack(void)
+{
+    unsigned char *buf = g_malloc0(2048);
+    struct nlmsghdr *nlmsg;
+    int len;
+    int ret = -1;
+
+    len = nfnl_recv(nfnlh, buf, 2048);
+    if (len <= 0) {
+        error_report("nfnl_recv received nothing");
+        goto err;
+    }
+    nlmsg = (struct nlmsghdr *)buf;
+
+    if (nlmsg->nlmsg_type == NLMSG_ERROR) {
+        struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(nlmsg);
+
+        if (err->error) {
+            error_report("Received error message:%d",  -err->error);
+            goto err;
+        }
+    }
+
+    ret = 0;
+err:
+    g_free(buf);
+    return ret;
+}
+
 int colo_proxy_init(enum COLOMode mode)
 {
     int ret = -1;
 
+    nfnlh = nfnl_open();
+    if (!nfnlh) {
+        error_report("call nfnl_open failed");
+        return -1;
+    }
+    /* Note:
+     *  Here we must ensure that the nl_pid (also nlmsg_pid in nlmsghdr ) equal
+     *  to the process ID of VM, becase we use it to identify the VM in proxy
+     *  module.
+     */
+    if (nfnl_portid(nfnlh) != getpid()) {
+        error_report("More than one netlink of NETLINK_NETFILTER type exist");
+        return -1;
+    }
+    /* disable netlink sequence tracking by default */
+    nfnl_unset_sequence_tracking(nfnlh);
+    nfnlssh = nfnl_subsys_open(nfnlh, NFNL_SUBSYS_COLO, NFCOLO_MSG_MAX, 0);
+    if (!nfnlssh) {
+        error_report("call nfnl_subsys_open failed");
+        goto err_out;
+    }
+
+    /* Netlink is not a reliable protocol, So it is necessary to request proxy
+     * module to acknowledge in the first time.
+     */
+    ret = colo_proxy_send(NFCOLO_PROXY_INIT, mode, NLM_F_ACK, NULL);
+    if (ret < 0) {
+        goto err_out;
+    }
+
+    ret = check_proxy_ack();
+    if (ret < 0) {
+        goto err_out;
+    }
+
     ret = configure_nic(mode, getpid());
     if (ret != 0) {
         error_report("excute colo-proxy-script failed");
+        goto err_out;
     }
 
+    return 0;
+err_out:
+    nfnl_close(nfnlh);
+    nfnlh = NULL;
     return ret;
 }
 
 void colo_proxy_destroy(enum COLOMode mode)
 {
+    if (nfnlh) {
+        nfnl_close(nfnlh);
+    }
     teardown_nic(mode, getpid());
 }
-- 
1.7.12.4

  parent reply	other threads:[~2015-07-09  3:19 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-09  3:16 [Qemu-devel] [PATCH COLO-Frame v7 00/34] COarse-grain LOck-stepping(COLO) Virtual Machines for Non-stop Service (FT) zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 01/34] configure: Add parameter for configure to enable/disable COLO support zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 02/34] migration: Introduce capability 'colo' to migration zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 03/34] COLO: migrate colo related info to slave zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 04/34] colo-comm/migration: skip colo info section for special cases zhanghailiang
2015-07-17 17:07   ` Dr. David Alan Gilbert
2015-07-20  8:42     ` zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 05/34] migration: Integrate COLO checkpoint process into migration zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 06/34] migration: Integrate COLO checkpoint process into loadvm zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 07/34] COLO: Implement colo checkpoint protocol zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 08/34] COLO: Add a new RunState RUN_STATE_COLO zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 09/34] QEMUSizedBuffer: Introduce two help functions for qsb zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 10/34] COLO: Save VM state to slave when do checkpoint zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 11/34] COLO RAM: Load PVM's dirty page into SVM's RAM cache temporarily zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 12/34] COLO VMstate: Load VM state into qsb before restore it zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 13/34] arch_init: Start to trace dirty pages of SVM zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 14/34] COLO RAM: Flush cached RAM into SVM's memory zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 15/34] COLO failover: Introduce a new command to trigger a failover zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 16/34] COLO failover: Introduce state to record failover process zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 17/34] COLO failover: Implement COLO primary/secondary vm failover work zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 18/34] qmp event: Add event notification for COLO error zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 19/34] COLO failover: Don't do failover during loading VM's state zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 20/34] COLO: Add new command parameter 'forward_nic' 'colo_script' for net zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 21/34] COLO NIC: Init/remove colo nic devices when add/cleanup tap devices zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 22/34] tap: Make launch_script() public zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 23/34] COLO NIC: Implement colo nic device interface configure() zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 24/34] colo-nic: Handle secondary VM's original net device configure zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 25/34] COLO NIC: Implement colo nic init/destroy function zhanghailiang
2015-07-09  3:16 ` zhanghailiang [this message]
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 27/34] COLO: Handle nfnetlink message from proxy module zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 28/34] COLO: Do checkpoint according to the result of packets comparation zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 29/34] COLO: Improve checkpoint efficiency by do additional periodic checkpoint zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 30/34] COLO: Add colo-set-checkpoint-period command zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 31/34] COLO NIC: Implement NIC checkpoint and failover zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 32/34] COLO: Disable qdev hotplug when VM is in COLO mode zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 33/34] COLO: Implement shutdown checkpoint zhanghailiang
2015-07-09  3:16 ` [Qemu-devel] [PATCH COLO-Frame v7 34/34] COLO: Add block replication into colo process zhanghailiang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1436411802-181876-27-git-send-email-zhang.zhanghailiang@huawei.com \
    --to=zhang.zhanghailiang@huawei.com \
    --cc=amit.shah@redhat.com \
    --cc=arei.gonglei@huawei.com \
    --cc=dgilbert@redhat.com \
    --cc=eddie.dong@intel.com \
    --cc=jasowang@redhat.com \
    --cc=lizhijian@cn.fujitsu.com \
    --cc=peter.huangpeng@huawei.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=stefanha@redhat.com \
    --cc=yunhong.jiang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).