From nobody Sun Feb 8 21:33:36 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1571225874; cv=none; d=zoho.com; s=zohoarc; b=Hk7ES/6Pu/E/4HUa37dr8N0UXdBv9OeAX4Ncg0UNtWAlsoEDOvGgB+e9lw5Vyd2tiimAj9KheuTBSY7liMwOEJ05RlhOywVqHDMeebIu/uvAj+xXURz8CGgCqXsABT1lGylp6SLsy+CPcRhdVztRI90bnlpCs9kv8S3CNXEem1k= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1571225874; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=e/gY377MWUtHVbvH8ZWeYB6zSJUfYghXHwft18zBuGY=; b=DfecMQ9cp5asbBQbg5ZlFgDt5eGibQ1hLf7MtYNMhcHhPQ1ii+J5LvSZLICwuv4UHwOPSaafNn3AXr94keJVaDiOpkIeFJKfpV1aqaJFQfuWAS1CLQcb61KWnjUEaihBpLMGZIjfvQiKQZO9wgSL7reKpBEZzb+Mi1DXMz2zCXI= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1571225874174873.8970667336836; Wed, 16 Oct 2019 04:37:54 -0700 (PDT) Received: from localhost ([::1]:41312 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iKhcm-0000W6-S6 for importer@patchew.org; Wed, 16 Oct 2019 07:37:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42670) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iKhUA-00010h-LS for qemu-devel@nongnu.org; Wed, 16 Oct 2019 07:29:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iKhU8-0005On-Qs for qemu-devel@nongnu.org; Wed, 16 Oct 2019 07:28:58 -0400 Received: from mga07.intel.com ([134.134.136.100]:55310) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iKhU8-0005O1-I3 for qemu-devel@nongnu.org; Wed, 16 Oct 2019 07:28:56 -0400 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Oct 2019 04:28:49 -0700 Received: from unknown (HELO localhost.localdomain) ([10.239.13.19]) by fmsmga001.fm.intel.com with ESMTP; 16 Oct 2019 04:28:48 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,303,1566889200"; d="scan'208";a="208393364" From: Zhang Chen To: Jason Wang , Paolo Bonzini , qemu-dev Subject: [RFC PATCH 1/4] net/awd.c: Introduce Advanced Watch Dog module framework Date: Wed, 16 Oct 2019 19:22:06 +0800 Message-Id: <20191016112209.9024-2-chen.zhang@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191016112209.9024-1-chen.zhang@intel.com> References: <20191016112209.9024-1-chen.zhang@intel.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 134.134.136.100 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Zhang Chen , Zhang Chen Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Zhang Chen This patch introduce a new module named Advanced Watch Dog, and defined the input and output parameter. AWD use standard chardev as the way of communicationg with the outside world. Demo command: -object advanced-watchdog,id=3Dheart1,server=3Don,awd_node=3Dh1,notificatio= n_node=3Dheartbeat0,opt_script=3Dopt_script_path,iothread=3Diothread1,pulse= _interval=3D1000,timeout=3D5000 Signed-off-by: Zhang Chen --- net/Makefile.objs | 1 + net/awd.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++ qemu-options.hx | 6 ++ 3 files changed, 268 insertions(+) create mode 100644 net/awd.c diff --git a/net/Makefile.objs b/net/Makefile.objs index c5d076d19c..139b1394e9 100644 --- a/net/Makefile.objs +++ b/net/Makefile.objs @@ -19,6 +19,7 @@ common-obj-y +=3D colo-compare.o common-obj-y +=3D colo.o common-obj-y +=3D filter-rewriter.o common-obj-y +=3D filter-replay.o +common-obj-y +=3D awd.o =20 tap-obj-$(CONFIG_LINUX) =3D tap-linux.o tap-obj-$(CONFIG_BSD) =3D tap-bsd.o diff --git a/net/awd.c b/net/awd.c new file mode 100644 index 0000000000..d42b4a7372 --- /dev/null +++ b/net/awd.c @@ -0,0 +1,261 @@ +/* + * Advanced Watch Dog + * + * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO) + * (a.k.a. Fault Tolerance or Continuous Replication) + * + * Copyright (c) 2019 Intel Corporation + * + * Author: Zhang Chen + * + * 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 "qemu/osdep.h" +#include "qemu/error-report.h" +#include "trace.h" +#include "qemu-common.h" +#include "qapi/error.h" +#include "net/net.h" +#include "qom/object_interfaces.h" +#include "qom/object.h" +#include "chardev/char-fe.h" +#include "qemu/sockets.h" +#include "sysemu/iothread.h" + +#define TYPE_AWD "advanced-watchdog" +#define AWD(obj) OBJECT_CHECK(AwdState, (obj), TYPE_AWD) + +#define AWD_READ_LEN_MAX NET_BUFSIZE +/* Default advanced watchdog pulse interval */ +#define AWD_PULSE_INTERVAL_DEFAULT 5000 +/* Default advanced watchdog timeout */ +#define AWD_TIMEOUT_DEFAULT 2000 + +typedef struct AwdState { + Object parent; + + bool server; + char *awd_node; + char *notification_node; + char *opt_script; + uint32_t pulse_interval; + uint32_t timeout; + IOThread *iothread; +} AwdState; + +typedef struct AwdClass { + ObjectClass parent_class; +} AwdClass; + +static char *awd_get_node(Object *obj, Error **errp) +{ + AwdState *s =3D AWD(obj); + + return g_strdup(s->awd_node); +} + +static void awd_set_node(Object *obj, const char *value, Error **errp) +{ + AwdState *s =3D AWD(obj); + + g_free(s->awd_node); + s->awd_node =3D g_strdup(value); +} + +static char *noti_get_node(Object *obj, Error **errp) +{ + AwdState *s =3D AWD(obj); + + return g_strdup(s->notification_node); +} + +static void noti_set_node(Object *obj, const char *value, Error **errp) +{ + AwdState *s =3D AWD(obj); + + g_free(s->notification_node); + s->notification_node =3D g_strdup(value); +} + +static char *opt_script_get_node(Object *obj, Error **errp) +{ + AwdState *s =3D AWD(obj); + + return g_strdup(s->opt_script); +} + +static void opt_script_set_node(Object *obj, const char *value, Error **er= rp) +{ + AwdState *s =3D AWD(obj); + + g_free(s->opt_script); + s->opt_script =3D g_strdup(value); +} + +static bool awd_get_server(Object *obj, Error **errp) +{ + AwdState *s =3D AWD(obj); + + return s->server; +} + +static void awd_set_server(Object *obj, bool value, Error **errp) +{ + AwdState *s =3D AWD(obj); + + s->server =3D value; +} + +static void awd_get_interval(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + AwdState *s =3D AWD(obj); + uint32_t value =3D s->pulse_interval; + + visit_type_uint32(v, name, &value, errp); +} + +static void awd_set_interval(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + AwdState *s =3D AWD(obj); + Error *local_err =3D NULL; + uint32_t value; + + visit_type_uint32(v, name, &value, &local_err); + if (local_err) { + goto out; + } + if (!value) { + error_setg(&local_err, "Property '%s.%s' requires a positive value= ", + object_get_typename(obj), name); + goto out; + } + s->pulse_interval =3D value; + +out: + error_propagate(errp, local_err); +} + +static void awd_get_timeout(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + AwdState *s =3D AWD(obj); + uint32_t value =3D s->timeout; + + visit_type_uint32(v, name, &value, errp); +} + +static void awd_set_timeout(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + AwdState *s =3D AWD(obj); + Error *local_err =3D NULL; + uint32_t value; + + visit_type_uint32(v, name, &value, &local_err); + if (local_err) { + goto out; + } + + if (!value) { + error_setg(&local_err, "Property '%s.%s' requires a positive value= ", + object_get_typename(obj), name); + goto out; + } + s->timeout =3D value; + +out: + error_propagate(errp, local_err); +} + +static void awd_complete(UserCreatable *uc, Error **errp) +{ + AwdState *s =3D AWD(uc); + + if (!s->awd_node || !s->iothread || + !s->notification_node || !s->opt_script) { + error_setg(errp, "advanced-watchdog needs 'awd_node', " + "'notification_node', 'opt_script' " + "and 'server' property set"); + return; + } + + return; +} + +static void awd_class_init(ObjectClass *oc, void *data) +{ + UserCreatableClass *ucc =3D USER_CREATABLE_CLASS(oc); + + ucc->complete =3D awd_complete; +} + +static void awd_init(Object *obj) +{ + AwdState *s =3D AWD(obj); + + object_property_add_str(obj, "awd_node", + awd_get_node, awd_set_node, + NULL); + + object_property_add_str(obj, "notification_node", + noti_get_node, noti_set_node, + NULL); + + object_property_add_str(obj, "opt_script", + opt_script_get_node, opt_script_set_node, + NULL); + + object_property_add_bool(obj, "server", + awd_get_server, + awd_set_server, NULL); + + object_property_add(obj, "pulse_interval", "uint32", + awd_get_interval, + awd_set_interval, NULL, NULL, NULL); + + object_property_add(obj, "timeout", "uint32", + awd_get_timeout, + awd_set_timeout, NULL, NULL, NULL); + + object_property_add_link(obj, "iothread", TYPE_IOTHREAD, + (Object **)&s->iothread, + object_property_allow_set_link, + OBJ_PROP_LINK_STRONG, NULL); +} + +static void awd_finalize(Object *obj) +{ + AwdState *s =3D AWD(obj); + + g_free(s->awd_node); + g_free(s->notification_node); +} + +static const TypeInfo awd_info =3D { + .name =3D TYPE_AWD, + .parent =3D TYPE_OBJECT, + .instance_size =3D sizeof(AwdState), + .instance_init =3D awd_init, + .instance_finalize =3D awd_finalize, + .class_size =3D sizeof(AwdClass), + .class_init =3D awd_class_init, + .interfaces =3D (InterfaceInfo[]) { + { TYPE_USER_CREATABLE }, + { } + } +}; + +static void register_types(void) +{ + type_register_static(&awd_info); +} + +type_init(register_types); diff --git a/qemu-options.hx b/qemu-options.hx index 793d70ff93..a4c1e2e2d1 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4520,6 +4520,12 @@ Dump the network traffic on netdev @var{dev} to the = file specified by The file format is libpcap, so it can be analyzed with tools such as tcpdu= mp or Wireshark. =20 +@item -object advanced-watchdog,id=3D@var{id},awd_node=3D@var{chardevid},n= otification_node=3D@var{chardevid},server=3D@var{server},iothread=3D@var{id= }[,pulse_interval=3D@var{time_ms},timeout=3D@var{time_ms}] + +Advanced Watch Dog is an universal monitoring module on VMM side, it can b= e used to detect network down(VMM to guest, VMM to VMM, VMM to another remo= te server) and do previously set operation. +for example: send message to admin, notify another VMM, send qmp command t= o qemu do some operation like restart the VM, build VMM heartbeat system, e= tc. +It make user have basic VM/Host network monitoring tools and basic false t= olerance and recovery solution. + @item -object colo-compare,id=3D@var{id},primary_in=3D@var{chardevid},seco= ndary_in=3D@var{chardevid},outdev=3D@var{chardevid},iothread=3D@var{id}[,vn= et_hdr_support][,notify_dev=3D@var{id}] =20 Colo-compare gets packet from primary_in@var{chardevid} and secondary_in@v= ar{chardevid}, than compare primary packet with --=20 2.17.1