From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38373) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bf1hb-0004MT-8R for qemu-devel@nongnu.org; Wed, 31 Aug 2016 05:21:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bf1hX-0000a3-4v for qemu-devel@nongnu.org; Wed, 31 Aug 2016 05:20:59 -0400 Received: from mx1.redhat.com ([209.132.183.28]:54802) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bf1hW-0000Zb-PL for qemu-devel@nongnu.org; Wed, 31 Aug 2016 05:20:55 -0400 References: <1471421428-26379-1-git-send-email-zhangchen.fnst@cn.fujitsu.com> <1471421428-26379-3-git-send-email-zhangchen.fnst@cn.fujitsu.com> From: Jason Wang Message-ID: <62a74753-145e-3d02-47e8-40af7dbf1ce1@redhat.com> Date: Wed, 31 Aug 2016 17:20:47 +0800 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH V12 02/10] colo-compare: introduce colo compare initialization List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Zhang Chen , qemu devel Cc: "Dr . David Alan Gilbert" , "eddie . dong" , Li Zhijian , zhanghailiang On 2016=E5=B9=B408=E6=9C=8831=E6=97=A5 17:03, Zhang Chen wrote: > > > On 08/31/2016 03:53 PM, Jason Wang wrote: >> >> >> On 2016=E5=B9=B408=E6=9C=8817=E6=97=A5 16:10, Zhang Chen wrote: >>> This a COLO net ascii figure: >>> >>> Primary qemu Secondary qemu >>> +--------------------------------------------------------------+=20 >>> +----------------------------------------------------------------+ >>> | +----------------------------------------------------------+=20 >>> | |=20 >>> +-----------------------------------------------------------+ | >>> | | |=20 >>> | |=20 >>> | | | >>> | | guest |=20 >>> | | | guest | | >>> | | |=20 >>> | |=20 >>> | | | >>> | +-------^--------------------------+-----------------------+=20 >>> | |=20 >>> +---------------------+--------+----------------------------+ | >>> | | | | | ^=20 >>> | | >>> | | | | | |=20 >>> | | >>> | | +------------------------------------------------------+=20 >>> | | | | >>> |netfilter| | | | | |=20 >>> netfilter | | | >>> | +----------+ +----------------------------+ | | |=20 >>> +-----------------------------------------------------------+ | >>> | | | | | | out | | | =20 >>> | | | filter excute order | | >>> | | | | +-----------------------------+ | | | =20 >>> | | | +-------------------> | | >>> | | | | | | | | | | | =20 >>> | | | TCP | | >>> | | +-----+--+-+ +-----v----+ +-----v----+ |pri +----+----+sec| =20 >>> | | | +------------+ +---+----+---v+rewriter++ +------------+ | | >>> | | | | | | | | |in | |in | =20 >>> | | | | | | | | | | | | >>> | | | filter | | filter | | filter +------> colo <------+=20 >>> +--------> filter +--> adjust | adjust +--> filter | | | >>> | | | mirror | |redirector| |redirector| | | compare | | | =20 >>> | | | redirector | | ack | seq | | redirector | | | >>> | | | | | | | | | | | | | =20 >>> | | | | | | | | | | | >>> | | +----^-----+ +----+-----+ +----------+ | +---------+ | | =20 >>> | | +------------+ +--------+--------------+ +---+--------+ | | >>> | | | tx | rx rx | | | | | =20 >>> tx all | rx | | >>> | | | | | | | |=20 >>> +-----------------------------------------------------------+ | >>> | | | +--------------+ | | | | | = | >>> | | | filter excute order | | | | | | = | >>> | | | +----------------> | | |=20 >>> +--------------------------------------------------------+ | >>> | +-----------------------------------------+ | | | >>> | | | | | | >>> +--------------------------------------------------------------+=20 >>> +----------------------------------------------------------------+ >>> |guest receive | guest send >>> | | >>> +--------+----------------------------v------------------------+ >>> | | NOTE: filter direction is rx/tx/all >>> | tap | rx:receive packets sent to the netdev >>> | | tx:receive packets sent by the netdev >>> +--------------------------------------------------------------+ >> >> It's better to add a doc under docs to explain this configuration in=20 >> detail on top of this series. >> > > As you say, Am I add /docs/colo-proxy.txt to explain it or add this in=20 > hailiang's COLO-FT.txt after merge? > >>> In COLO-compare, we do packet comparing job. >>> Packets coming from the primary char indev will be sent to outdev. >>> Packets coming from the secondary char dev will be dropped after=20 >>> comparing. >>> colo-comapre need two input chardev and one output chardev: >>> primary_in=3Dchardev1-id (source: primary send packet) >>> secondary_in=3Dchardev2-id (source: secondary send packet) >>> outdev=3Dchardev3-id >>> >>> usage: >>> >>> primary: >>> -netdev=20 >>> tap,id=3Dhn0,vhost=3Doff,script=3D/etc/qemu-ifup,downscript=3D/etc/qe= mu-ifdown >>> -device e1000,id=3De0,netdev=3Dhn0,mac=3D52:a4:00:12:78:66 >>> -chardev socket,id=3Dmirror0,host=3D3.3.3.3,port=3D9003,server,nowait >>> -chardev socket,id=3Dcompare1,host=3D3.3.3.3,port=3D9004,server,nowai= t >>> -chardev socket,id=3Dcompare0,host=3D3.3.3.3,port=3D9001,server,nowai= t >>> -chardev socket,id=3Dcompare0-0,host=3D3.3.3.3,port=3D9001 >>> -chardev socket,id=3Dcompare_out,host=3D3.3.3.3,port=3D9005,server,no= wait >>> -chardev socket,id=3Dcompare_out0,host=3D3.3.3.3,port=3D9005 >>> -object filter-mirror,id=3Dm0,netdev=3Dhn0,queue=3Dtx,outdev=3Dmirror= 0 >>> -object=20 >>> filter-redirector,netdev=3Dhn0,id=3Dredire0,queue=3Drx,indev=3Dcompar= e_out >>> -object=20 >>> filter-redirector,netdev=3Dhn0,id=3Dredire1,queue=3Drx,outdev=3Dcompa= re0 >>> -object=20 >>> colo-compare,id=3Dcomp0,primary_in=3Dcompare0-0,secondary_in=3Dcompar= e1,outdev=3Dcompare_out0 >>> >>> secondary: >>> -netdev tap,id=3Dhn0,vhost=3Doff,script=3D/etc/qemu-ifup,down=20 >>> script=3D/etc/qemu-ifdown >>> -device e1000,netdev=3Dhn0,mac=3D52:a4:00:12:78:66 >>> -chardev socket,id=3Dred0,host=3D3.3.3.3,port=3D9003 >>> -chardev socket,id=3Dred1,host=3D3.3.3.3,port=3D9004 >>> -object filter-redirector,id=3Df1,netdev=3Dhn0,queue=3Dtx,indev=3Dred= 0 >>> -object filter-redirector,id=3Df2,netdev=3Dhn0,queue=3Drx,outdev=3Dre= d1 >>> >>> Signed-off-by: Zhang Chen >>> Signed-off-by: Li Zhijian >>> Signed-off-by: Wen Congyang >>> --- >>> net/Makefile.objs | 1 + >>> net/colo-compare.c | 284=20 >>> +++++++++++++++++++++++++++++++++++++++++++++++++++++ >>> qemu-options.hx | 39 ++++++++ >>> vl.c | 3 +- >>> 4 files changed, 326 insertions(+), 1 deletion(-) >>> create mode 100644 net/colo-compare.c >>> >>> diff --git a/net/Makefile.objs b/net/Makefile.objs >>> index b7c22fd..ba92f73 100644 >>> --- a/net/Makefile.objs >>> +++ b/net/Makefile.objs >>> @@ -16,3 +16,4 @@ common-obj-$(CONFIG_NETMAP) +=3D netmap.o >>> common-obj-y +=3D filter.o >>> common-obj-y +=3D filter-buffer.o >>> common-obj-y +=3D filter-mirror.o >>> +common-obj-y +=3D colo-compare.o >>> diff --git a/net/colo-compare.c b/net/colo-compare.c >>> new file mode 100644 >>> index 0000000..cdc3e0e >>> --- /dev/null >>> +++ b/net/colo-compare.c >>> @@ -0,0 +1,284 @@ >>> +/* >>> + * COarse-grain LOck-stepping Virtual Machines for Non-stop Service=20 >>> (COLO) >>> + * (a.k.a. Fault Tolerance or Continuous Replication) >>> + * >>> + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. >>> + * Copyright (c) 2016 FUJITSU LIMITED >>> + * Copyright (c) 2016 Intel Corporation >>> + * >>> + * Author: Zhang Chen >>> + * >>> + * This work is licensed under the terms of the GNU GPL, version 2 o= r >>> + * later. See the COPYING file in the top-level directory. >>> + */ >>> + >>> +#include "qemu/osdep.h" >>> +#include "qemu/error-report.h" >>> +#include "qemu-common.h" >>> +#include "qapi/qmp/qerror.h" >>> +#include "qapi/error.h" >>> +#include "net/net.h" >>> +#include "net/vhost_net.h" >> >> Looks unnecessary. > > I will remove it. > >> >>> +#include "qom/object_interfaces.h" >>> +#include "qemu/iov.h" >>> +#include "qom/object.h" >>> +#include "qemu/typedefs.h" >>> +#include "net/queue.h" >>> +#include "sysemu/char.h" >>> +#include "qemu/sockets.h" >>> +#include "qapi-visit.h" >>> + >>> +#define TYPE_COLO_COMPARE "colo-compare" >>> +#define COLO_COMPARE(obj) \ >>> + OBJECT_CHECK(CompareState, (obj), TYPE_COLO_COMPARE) >>> + >>> +#define COMPARE_READ_LEN_MAX NET_BUFSIZE >>> + >>> +typedef struct CompareState { >>> + Object parent; >>> + >>> + char *pri_indev; >>> + char *sec_indev; >>> + char *outdev; >>> + CharDriverState *chr_pri_in; >>> + CharDriverState *chr_sec_in; >>> + CharDriverState *chr_out; >>> + QTAILQ_ENTRY(CompareState) next; >> >> This looks not used in this series but in commit "colo-compare and=20 >> filter-rewriter work with colo-frame". We'd better delay the=20 >> introducing to that patch. > > OK~ I got your point. > >> >>> + SocketReadState pri_rs; >>> + SocketReadState sec_rs; >>> +} CompareState; >>> + >>> +typedef struct CompareClass { >>> + ObjectClass parent_class; >>> +} CompareClass; >>> + >>> +typedef struct CompareChardevProps { >>> + bool is_socket; >>> + bool is_unix; >>> +} CompareChardevProps; >>> + >>> +static char *compare_get_pri_indev(Object *obj, Error **errp) >>> +{ >>> + CompareState *s =3D COLO_COMPARE(obj); >>> + >>> + return g_strdup(s->pri_indev); >>> +} >>> + >>> +static void compare_set_pri_indev(Object *obj, const char *value,=20 >>> Error **errp) >>> +{ >>> + CompareState *s =3D COLO_COMPARE(obj); >>> + >>> + g_free(s->pri_indev); >>> + s->pri_indev =3D g_strdup(value); >>> +} >>> + >>> +static char *compare_get_sec_indev(Object *obj, Error **errp) >>> +{ >>> + CompareState *s =3D COLO_COMPARE(obj); >>> + >>> + return g_strdup(s->sec_indev); >>> +} >>> + >>> +static void compare_set_sec_indev(Object *obj, const char *value,=20 >>> Error **errp) >>> +{ >>> + CompareState *s =3D COLO_COMPARE(obj); >>> + >>> + g_free(s->sec_indev); >>> + s->sec_indev =3D g_strdup(value); >>> +} >>> + >>> +static char *compare_get_outdev(Object *obj, Error **errp) >>> +{ >>> + CompareState *s =3D COLO_COMPARE(obj); >>> + >>> + return g_strdup(s->outdev); >>> +} >>> + >>> +static void compare_set_outdev(Object *obj, const char *value,=20 >>> Error **errp) >>> +{ >>> + CompareState *s =3D COLO_COMPARE(obj); >>> + >>> + g_free(s->outdev); >>> + s->outdev =3D g_strdup(value); >>> +} >>> + >>> +static void compare_pri_rs_finalize(SocketReadState *pri_rs) >>> +{ >>> + /* if packet_enqueue pri pkt failed we will send unsupported=20 >>> packet */ >>> +} >>> + >>> +static void compare_sec_rs_finalize(SocketReadState *sec_rs) >>> +{ >>> + /* if packet_enqueue sec pkt failed we will notify trace */ >>> +} >>> + >>> +static int compare_chardev_opts(void *opaque, >>> + const char *name, const char *value, >>> + Error **errp) >>> +{ >>> + CompareChardevProps *props =3D opaque; >>> + >>> + if (strcmp(name, "backend") =3D=3D 0 && strcmp(value, "socket") = =3D=3D=20 >>> 0) { >>> + props->is_socket =3D true; >>> + } else if (strcmp(name, "host") =3D=3D 0) { >> >> Typo? net_vhost_chardev_opts() did: >> >> } else if (strcmp(name, "path") =3D=3D 0) { >> props->is_unix =3D true; >> } >> >> > > No, In colo-compare we use chardev like this: > > -chardev socket,id=3Dmirror0,host=3D3.3.3.3,port=3D9003,server,nowait > > If we only use "path" here will trigger a error. > Should I add anthor "path" here? If I understand the code correctly, "is_unix" means "is unix domain=20 socket"? If yes, according to the help: -chardev=20 socket,id=3Did[,host=3Dhost],port=3Dport[,to=3Dto][,ipv4][,ipv6][,nodelay= ][,reconnect=3Dseconds] [,server][,nowait][,telnet][,reconnect=3Dseconds][,mux=3Don|off] [,logfile=3DPATH][,logappend=3Don|off][,tls-creds=3DID] (tcp) -chardev=20 socket,id=3Did,path=3Dpath[,server][,nowait][,telnet][,reconnect=3Dsecond= s] [,mux=3Don|off][,logfile=3DPATH][,logappend=3Don|off] (unix) "host" will not be used for UNIX domain socket. And if UNIX domain socket is not supported, there's probably no need to=20 differentiate it from other types. > > >> >>> + props->is_unix =3D true; >>> + } else if (strcmp(name, "port") =3D=3D 0) { >>> + } else if (strcmp(name, "server") =3D=3D 0) { >>> + } else if (strcmp(name, "wait") =3D=3D 0) { >>> + } else { >>> + error_setg(errp, >>> + "COLO-compare does not support a chardev with=20 >>> option %s=3D%s", >>> + name, value); >>> + return -1; >>> + } >>> + return 0; >>> +} >>> + >>> +/* >>> + * called from the main thread on the primary >>> + * to setup colo-compare. >>> + */ >>> +static void colo_compare_complete(UserCreatable *uc, Error **errp) >>> +{ >>> + CompareState *s =3D COLO_COMPARE(uc); >>> + CompareChardevProps props; >>> + >>> + if (!s->pri_indev || !s->sec_indev || !s->outdev) { >>> + error_setg(errp, "colo compare needs 'primary_in' ," >>> + "'secondary_in','outdev' property set"); >>> + return; >>> + } else if (!strcmp(s->pri_indev, s->outdev) || >>> + !strcmp(s->sec_indev, s->outdev) || >>> + !strcmp(s->pri_indev, s->sec_indev)) { >>> + error_setg(errp, "'indev' and 'outdev' could not be same " >>> + "for compare module"); >>> + return; >>> + } >>> + >>> + s->chr_pri_in =3D qemu_chr_find(s->pri_indev); >>> + if (s->chr_pri_in =3D=3D NULL) { >>> + error_setg(errp, "Primary IN Device '%s' not found", >>> + s->pri_indev); >>> + return; >>> + } >>> + >>> + /* inspect chardev opts */ >>> + memset(&props, 0, sizeof(props)); >>> + if (qemu_opt_foreach(s->chr_pri_in->opts, compare_chardev_opts,=20 >>> &props, errp)) { >>> + return; >>> + } >>> + >>> + if (!props.is_socket || !props.is_unix) { >>> + error_setg(errp, "chardev \"%s\" is not a unix socket", >>> + s->pri_indev); >>> + return; >>> + } >>> + >>> + s->chr_sec_in =3D qemu_chr_find(s->sec_indev); >>> + if (s->chr_sec_in =3D=3D NULL) { >>> + error_setg(errp, "Secondary IN Device '%s' not found", >>> + s->sec_indev); >>> + return; >>> + } >>> + >>> + memset(&props, 0, sizeof(props)); >>> + if (qemu_opt_foreach(s->chr_sec_in->opts, compare_chardev_opts,=20 >>> &props, errp)) { >>> + return; >>> + } >>> + >>> + if (!props.is_socket || !props.is_unix) { >>> + error_setg(errp, "chardev \"%s\" is not a unix socket", >>> + s->sec_indev); >> >> I believe tcp socket is also supported? > > If I understand correctly, "tcp socket" in here is the "-chardev socket= ". > I will rename "unix socket" to "tcp socket". > >> >>> + return; >>> + } >>> + >>> + s->chr_out =3D qemu_chr_find(s->outdev); >>> + if (s->chr_out =3D=3D NULL) { >>> + error_setg(errp, "OUT Device '%s' not found", s->outdev); >>> + return; >>> + } >>> + >>> + memset(&props, 0, sizeof(props)); >>> + if (qemu_opt_foreach(s->chr_out->opts, compare_chardev_opts,=20 >>> &props, errp)) { >>> + return; >>> + } >>> + >>> + if (!props.is_socket || !props.is_unix) { >>> + error_setg(errp, "chardev \"%s\" is not a unix socket", >>> + s->outdev); >> >> Ditto, and there's code duplication, please introduce a helper to do=20 >> above. > > I don't understand what the "helper"? > In here we check each chardev, will I change to "goto error;" ? A helper to avoid the code duplication for socket type inspection for=20 pri_in,scr_in and chr_out. > >> >>> + return; >>> + } >>> + >>> + qemu_chr_fe_claim_no_fail(s->chr_pri_in); >>> + >>> + qemu_chr_fe_claim_no_fail(s->chr_sec_in); >>> + >>> + qemu_chr_fe_claim_no_fail(s->chr_out); >>> + >>> + net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize); >>> + net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize); >>> + >>> + return; >>> +} >>> + >>> +static void colo_compare_class_init(ObjectClass *oc, void *data) >>> +{ >>> + UserCreatableClass *ucc =3D USER_CREATABLE_CLASS(oc); >>> + >>> + ucc->complete =3D colo_compare_complete; >>> +} >>> + >>> +static void colo_compare_init(Object *obj) >>> +{ >>> + object_property_add_str(obj, "primary_in", >>> + compare_get_pri_indev,=20 >>> compare_set_pri_indev, >>> + NULL); >>> + object_property_add_str(obj, "secondary_in", >>> + compare_get_sec_indev,=20 >>> compare_set_sec_indev, >>> + NULL); >>> + object_property_add_str(obj, "outdev", >>> + compare_get_outdev, compare_set_outdev, >>> + NULL); >>> +} >>> + >>> +static void colo_compare_finalize(Object *obj) >>> +{ >>> + CompareState *s =3D COLO_COMPARE(obj); >>> + >>> + if (s->chr_pri_in) { >>> + qemu_chr_add_handlers(s->chr_pri_in, NULL, NULL, NULL, NULL)= ; >>> + qemu_chr_fe_release(s->chr_pri_in); >>> + } >>> + if (s->chr_sec_in) { >>> + qemu_chr_add_handlers(s->chr_sec_in, NULL, NULL, NULL, NULL)= ; >>> + qemu_chr_fe_release(s->chr_sec_in); >>> + } >>> + if (s->chr_out) { >>> + qemu_chr_fe_release(s->chr_out); >>> + } >>> + >>> + g_free(s->pri_indev); >>> + g_free(s->sec_indev); >>> + g_free(s->outdev); >>> +} >>> + >>> +static const TypeInfo colo_compare_info =3D { >>> + .name =3D TYPE_COLO_COMPARE, >>> + .parent =3D TYPE_OBJECT, >>> + .instance_size =3D sizeof(CompareState), >>> + .instance_init =3D colo_compare_init, >>> + .instance_finalize =3D colo_compare_finalize, >>> + .class_size =3D sizeof(CompareClass), >>> + .class_init =3D colo_compare_class_init, >>> + .interfaces =3D (InterfaceInfo[]) { >>> + { TYPE_USER_CREATABLE }, >>> + { } >>> + } >>> +}; >>> + >>> +static void register_types(void) >>> +{ >>> + type_register_static(&colo_compare_info); >>> +} >>> + >>> +type_init(register_types); >>> diff --git a/qemu-options.hx b/qemu-options.hx >>> index 587de8f..33d5d0b 100644 >>> --- a/qemu-options.hx >>> +++ b/qemu-options.hx >>> @@ -3866,6 +3866,45 @@ Dump the network traffic on netdev @var{dev}=20 >>> to the file specified by >>> The file format is libpcap, so it can be analyzed with tools such=20 >>> as tcpdump >>> or Wireshark. >>> +@item -object=20 >>> colo-compare,id=3D@var{id},primary_in=3D@var{chardevid},secondary_in=3D= @var{chardevid}, >>> +outdev=3D@var{chardevid} >>> + >>> +Colo-compare gets packet from primary_in@var{chardevid} and=20 >>> secondary_in@var{chardevid}, than compare primary packet with >>> +secondary packet. If the packet same, we will output primary >> >> s/If the packet same/If the packets are same/. > > OK. > >> >>> +packet to outdev@var{chardevid}, else we will notify colo-frame >>> +do checkpoint and send primary packet to outdev@var{chardevid}. >>> + >>> +we can use it with the help of filter-mirror and filter-redirector. >> >> s/we/We/ and looks like colo compare must be used with the help of=20 >> mirror and redirector? > > Currently yes. Then please change the doc here. Thanks > >> >>> + >>> +@example >>> + >>> +primary: >>> +-netdev=20 >>> tap,id=3Dhn0,vhost=3Doff,script=3D/etc/qemu-ifup,downscript=3D/etc/qe= mu-ifdown >>> +-device e1000,id=3De0,netdev=3Dhn0,mac=3D52:a4:00:12:78:66 >>> +-chardev socket,id=3Dmirror0,host=3D3.3.3.3,port=3D9003,server,nowai= t >>> +-chardev socket,id=3Dcompare1,host=3D3.3.3.3,port=3D9004,server,nowa= it >>> +-chardev socket,id=3Dcompare0,host=3D3.3.3.3,port=3D9001,server,nowa= it >>> +-chardev socket,id=3Dcompare0-0,host=3D3.3.3.3,port=3D9001 >>> +-chardev socket,id=3Dcompare_out,host=3D3.3.3.3,port=3D9005,server,n= owait >>> +-chardev socket,id=3Dcompare_out0,host=3D3.3.3.3,port=3D9005 >>> +-object filter-mirror,id=3Dm0,netdev=3Dhn0,queue=3Dtx,outdev=3Dmirro= r0 >>> +-object=20 >>> filter-redirector,netdev=3Dhn0,id=3Dredire0,queue=3Drx,indev=3Dcompar= e_out >>> +-object=20 >>> filter-redirector,netdev=3Dhn0,id=3Dredire1,queue=3Drx,outdev=3Dcompa= re0 >>> +-object=20 >>> colo-compare,id=3Dcomp0,primary_in=3Dcompare0-0,secondary_in=3Dcompar= e1,outdev=3Dcompare_out0 >>> + >>> +secondary: >>> +-netdev tap,id=3Dhn0,vhost=3Doff,script=3D/etc/qemu-ifup,down=20 >>> script=3D/etc/qemu-ifdown >>> +-device e1000,netdev=3Dhn0,mac=3D52:a4:00:12:78:66 >>> +-chardev socket,id=3Dred0,host=3D3.3.3.3,port=3D9003 >>> +-chardev socket,id=3Dred1,host=3D3.3.3.3,port=3D9004 >>> +-object filter-redirector,id=3Df1,netdev=3Dhn0,queue=3Dtx,indev=3Dre= d0 >>> +-object filter-redirector,id=3Df2,netdev=3Dhn0,queue=3Drx,outdev=3Dr= ed1 >>> + >>> +@end example >>> + >>> +If you want to know the detail of above command line, you can read >>> +the colo-compare git log. >>> + >>> @item -object=20 >>> secret,id=3D@var{id},data=3D@var{string},format=3D@var{raw|base64}[,k= eyid=3D@var{secretid},iv=3D@var{string}] >>> @item -object=20 >>> secret,id=3D@var{id},file=3D@var{filename},format=3D@var{raw|base64}[= ,keyid=3D@var{secretid},iv=3D@var{string}] >>> diff --git a/vl.c b/vl.c >>> index cbe51ac..c6b9a6f 100644 >>> --- a/vl.c >>> +++ b/vl.c >>> @@ -2865,7 +2865,8 @@ static bool object_create_initial(const char=20 >>> *type) >>> if (g_str_equal(type, "filter-buffer") || >>> g_str_equal(type, "filter-dump") || >>> g_str_equal(type, "filter-mirror") || >>> - g_str_equal(type, "filter-redirector")) { >>> + g_str_equal(type, "filter-redirector") || >>> + g_str_equal(type, "colo-compare")) { >>> return false; >>> } >> >> >> >> . >> >