diff mbox series

[V8,14/17] filter: Add handle_event method for NetFilterClass

Message ID 20180603050546.6827-15-zhangckid@gmail.com
State New
Headers show
Series COLO: integrate colo frame with block replication and COLO proxy | expand

Commit Message

Zhang Chen June 3, 2018, 5:05 a.m. UTC
Filter needs to process the event of checkpoint/failover or
other event passed by COLO frame.

Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
---
 include/net/filter.h |  5 +++++
 net/filter.c         | 17 +++++++++++++++++
 net/net.c            | 28 ++++++++++++++++++++++++++++
 3 files changed, 50 insertions(+)

Comments

Jason Wang June 4, 2018, 6:57 a.m. UTC | #1
On 2018年06月03日 13:05, Zhang Chen wrote:
> Filter needs to process the event of checkpoint/failover or
> other event passed by COLO frame.
>
> Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
> ---
>   include/net/filter.h |  5 +++++
>   net/filter.c         | 17 +++++++++++++++++
>   net/net.c            | 28 ++++++++++++++++++++++++++++
>   3 files changed, 50 insertions(+)
>
> diff --git a/include/net/filter.h b/include/net/filter.h
> index 435acd6f82..49da666ac0 100644
> --- a/include/net/filter.h
> +++ b/include/net/filter.h
> @@ -38,6 +38,8 @@ typedef ssize_t (FilterReceiveIOV)(NetFilterState *nc,
>   
>   typedef void (FilterStatusChanged) (NetFilterState *nf, Error **errp);
>   
> +typedef void (FilterHandleEvent) (NetFilterState *nf, int event, Error **errp);
> +
>   typedef struct NetFilterClass {
>       ObjectClass parent_class;
>   
> @@ -45,6 +47,7 @@ typedef struct NetFilterClass {
>       FilterSetup *setup;
>       FilterCleanup *cleanup;
>       FilterStatusChanged *status_changed;
> +    FilterHandleEvent *handle_event;
>       /* mandatory */
>       FilterReceiveIOV *receive_iov;
>   } NetFilterClass;
> @@ -77,4 +80,6 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
>                                       int iovcnt,
>                                       void *opaque);
>   
> +void colo_notify_filters_event(int event, Error **errp);
> +
>   #endif /* QEMU_NET_FILTER_H */
> diff --git a/net/filter.c b/net/filter.c
> index 2fd7d7d663..0f17eba143 100644
> --- a/net/filter.c
> +++ b/net/filter.c
> @@ -17,6 +17,8 @@
>   #include "net/vhost_net.h"
>   #include "qom/object_interfaces.h"
>   #include "qemu/iov.h"
> +#include "net/colo.h"
> +#include "migration/colo.h"
>   
>   static inline bool qemu_can_skip_netfilter(NetFilterState *nf)
>   {
> @@ -245,11 +247,26 @@ static void netfilter_finalize(Object *obj)
>       g_free(nf->netdev_id);
>   }
>   
> +static void dummy_handle_event(NetFilterState *nf, int event, Error **errp)
> +{
> +    switch (event) {
> +    case COLO_EVENT_CHECKPOINT:
> +        break;
> +    case COLO_EVENT_FAILOVER:
> +        object_property_set_str(OBJECT(nf), "off", "status", errp);
> +        break;
> +    default:
> +        break;
> +    }
> +}
> +
>   static void netfilter_class_init(ObjectClass *oc, void *data)
>   {
>       UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
> +    NetFilterClass *nfc = NETFILTER_CLASS(oc);
>   
>       ucc->complete = netfilter_complete;
> +    nfc->handle_event = dummy_handle_event;
>   }
>   
>   static const TypeInfo netfilter_info = {
> diff --git a/net/net.c b/net/net.c
> index efb9eaf779..378cd2f9ec 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -1329,6 +1329,34 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
>       }
>   }
>   
> +void colo_notify_filters_event(int event, Error **errp)
> +{
> +    NetClientState *nc, *peer;
> +    NetClientDriver type;
> +    NetFilterState *nf;
> +    NetFilterClass *nfc = NULL;
> +    Error *local_err = NULL;
> +
> +    QTAILQ_FOREACH(nc, &net_clients, next) {
> +        peer = nc->peer;
> +        type = nc->info->type;
> +        if (!peer || type != NET_CLIENT_DRIVER_TAP) {
> +            continue;

I think when COLO is enabled, qemu should reject all other types of 
backends.

> +        }
> +        QTAILQ_FOREACH(nf, &nc->filters, next) {
> +            nfc =  NETFILTER_GET_CLASS(OBJECT(nf));
> +            if (!nfc->handle_event) {
> +                continue;
> +            }

Is this still necessary?

Thanks

> +            nfc->handle_event(nf, event, &local_err);
> +            if (local_err) {
> +                error_propagate(errp, local_err);
> +                return;
> +            }
> +        }
> +    }
> +}
> +
>   void qmp_set_link(const char *name, bool up, Error **errp)
>   {
>       NetClientState *ncs[MAX_QUEUE_NUM];
Zhang Chen June 10, 2018, 2:09 p.m. UTC | #2
On Mon, Jun 4, 2018 at 2:57 PM, Jason Wang <jasowang@redhat.com> wrote:

>
>
> On 2018年06月03日 13:05, Zhang Chen wrote:
>
>> Filter needs to process the event of checkpoint/failover or
>> other event passed by COLO frame.
>>
>> Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
>> ---
>>   include/net/filter.h |  5 +++++
>>   net/filter.c         | 17 +++++++++++++++++
>>   net/net.c            | 28 ++++++++++++++++++++++++++++
>>   3 files changed, 50 insertions(+)
>>
>> diff --git a/include/net/filter.h b/include/net/filter.h
>> index 435acd6f82..49da666ac0 100644
>> --- a/include/net/filter.h
>> +++ b/include/net/filter.h
>> @@ -38,6 +38,8 @@ typedef ssize_t (FilterReceiveIOV)(NetFilterState *nc,
>>     typedef void (FilterStatusChanged) (NetFilterState *nf, Error **errp);
>>   +typedef void (FilterHandleEvent) (NetFilterState *nf, int event, Error
>> **errp);
>> +
>>   typedef struct NetFilterClass {
>>       ObjectClass parent_class;
>>   @@ -45,6 +47,7 @@ typedef struct NetFilterClass {
>>       FilterSetup *setup;
>>       FilterCleanup *cleanup;
>>       FilterStatusChanged *status_changed;
>> +    FilterHandleEvent *handle_event;
>>       /* mandatory */
>>       FilterReceiveIOV *receive_iov;
>>   } NetFilterClass;
>> @@ -77,4 +80,6 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState
>> *sender,
>>                                       int iovcnt,
>>                                       void *opaque);
>>   +void colo_notify_filters_event(int event, Error **errp);
>> +
>>   #endif /* QEMU_NET_FILTER_H */
>> diff --git a/net/filter.c b/net/filter.c
>> index 2fd7d7d663..0f17eba143 100644
>> --- a/net/filter.c
>> +++ b/net/filter.c
>> @@ -17,6 +17,8 @@
>>   #include "net/vhost_net.h"
>>   #include "qom/object_interfaces.h"
>>   #include "qemu/iov.h"
>> +#include "net/colo.h"
>> +#include "migration/colo.h"
>>     static inline bool qemu_can_skip_netfilter(NetFilterState *nf)
>>   {
>> @@ -245,11 +247,26 @@ static void netfilter_finalize(Object *obj)
>>       g_free(nf->netdev_id);
>>   }
>>   +static void dummy_handle_event(NetFilterState *nf, int event, Error
>> **errp)
>> +{
>> +    switch (event) {
>> +    case COLO_EVENT_CHECKPOINT:
>> +        break;
>> +    case COLO_EVENT_FAILOVER:
>> +        object_property_set_str(OBJECT(nf), "off", "status", errp);
>> +        break;
>> +    default:
>> +        break;
>> +    }
>> +}
>> +
>>   static void netfilter_class_init(ObjectClass *oc, void *data)
>>   {
>>       UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
>> +    NetFilterClass *nfc = NETFILTER_CLASS(oc);
>>         ucc->complete = netfilter_complete;
>> +    nfc->handle_event = dummy_handle_event;
>>   }
>>     static const TypeInfo netfilter_info = {
>> diff --git a/net/net.c b/net/net.c
>> index efb9eaf779..378cd2f9ec 100644
>> --- a/net/net.c
>> +++ b/net/net.c
>> @@ -1329,6 +1329,34 @@ void hmp_info_network(Monitor *mon, const QDict
>> *qdict)
>>       }
>>   }
>>   +void colo_notify_filters_event(int event, Error **errp)
>> +{
>> +    NetClientState *nc, *peer;
>> +    NetClientDriver type;
>> +    NetFilterState *nf;
>> +    NetFilterClass *nfc = NULL;
>> +    Error *local_err = NULL;
>> +
>> +    QTAILQ_FOREACH(nc, &net_clients, next) {
>> +        peer = nc->peer;
>> +        type = nc->info->type;
>> +        if (!peer || type != NET_CLIENT_DRIVER_TAP) {
>> +            continue;
>>
>
> I think when COLO is enabled, qemu should reject all other types of
> backends.


Yes, you are right.
May be we should add a assert here? Because we can not get backend info when
colo-compare start up.
Have any idea?


>
>
> +        }
>> +        QTAILQ_FOREACH(nf, &nc->filters, next) {
>> +            nfc =  NETFILTER_GET_CLASS(OBJECT(nf));
>> +            if (!nfc->handle_event) {
>> +                continue;
>> +            }
>>
>
> Is this still necessary?
>
>
Yes, may be user will use other filter(like filter-buffer) with COLO at
same time.

Thanks
Zhang Chen



> Thanks
>
>
> +            nfc->handle_event(nf, event, &local_err);
>> +            if (local_err) {
>> +                error_propagate(errp, local_err);
>> +                return;
>> +            }
>> +        }
>> +    }
>> +}
>> +
>>   void qmp_set_link(const char *name, bool up, Error **errp)
>>   {
>>       NetClientState *ncs[MAX_QUEUE_NUM];
>>
>
>
Jason Wang June 11, 2018, 1:56 a.m. UTC | #3
On 2018年06月10日 22:09, Zhang Chen wrote:
>> I think when COLO is enabled, qemu should reject all other types of
>> backends.
> Yes, you are right.
> May be we should add a assert here? Because we can not get backend info when
> colo-compare start up.
> Have any idea?
>
>

Is there a global variable or function to detect the COLO existence? If 
yes, maybe we could use that.

Thanks
Zhang Chen June 11, 2018, 6:46 a.m. UTC | #4
On Mon, Jun 11, 2018 at 9:56 AM, Jason Wang <jasowang@redhat.com> wrote:

>
>
> On 2018年06月10日 22:09, Zhang Chen wrote:
>
>> I think when COLO is enabled, qemu should reject all other types of
>>> backends.
>>>
>> Yes, you are right.
>> May be we should add a assert here? Because we can not get backend info
>> when
>> colo-compare start up.
>> Have any idea?
>>
>>
>>
> Is there a global variable or function to detect the COLO existence? If
> yes, maybe we could use that.
>

May be we can reuse the "qmp_query_colo_status" in 11/17 patch.
I will add this check in next version.


Thanks
Zhang Chen


>
> Thanks
>
>
Jason Wang June 11, 2018, 7:02 a.m. UTC | #5
On 2018年06月11日 14:46, Zhang Chen wrote:
> On Mon, Jun 11, 2018 at 9:56 AM, Jason Wang <jasowang@redhat.com> wrote:
>
>>
>> On 2018年06月10日 22:09, Zhang Chen wrote:
>>
>>> I think when COLO is enabled, qemu should reject all other types of
>>>> backends.
>>>>
>>> Yes, you are right.
>>> May be we should add a assert here? Because we can not get backend info
>>> when
>>> colo-compare start up.
>>> Have any idea?
>>>
>>>
>>>
>> Is there a global variable or function to detect the COLO existence? If
>> yes, maybe we could use that.
>>
> May be we can reuse the "qmp_query_colo_status" in 11/17 patch.
> I will add this check in next version.

I think it's better to have an internal helper. Calling qmp function 
from net is odd.

Thanks

>
> Thanks
> Zhang Chen
>
>
>> Thanks
>>
>>
Zhang Chen June 11, 2018, 3:36 p.m. UTC | #6
On Mon, Jun 11, 2018 at 3:02 PM, Jason Wang <jasowang@redhat.com> wrote:

>
>
> On 2018年06月11日 14:46, Zhang Chen wrote:
>
>> On Mon, Jun 11, 2018 at 9:56 AM, Jason Wang <jasowang@redhat.com> wrote:
>>
>>
>>> On 2018年06月10日 22:09, Zhang Chen wrote:
>>>
>>> I think when COLO is enabled, qemu should reject all other types of
>>>>
>>>>> backends.
>>>>>
>>>>> Yes, you are right.
>>>> May be we should add a assert here? Because we can not get backend info
>>>> when
>>>> colo-compare start up.
>>>> Have any idea?
>>>>
>>>>
>>>>
>>>> Is there a global variable or function to detect the COLO existence? If
>>> yes, maybe we could use that.
>>>
>>> May be we can reuse the "qmp_query_colo_status" in 11/17 patch.
>> I will add this check in next version.
>>
>
> I think it's better to have an internal helper. Calling qmp function from
> net is odd.
>
>
OK, I got it.

Thanks
Zhang Chen



> Thanks
>
>
>> Thanks
>> Zhang Chen
>>
>>
>> Thanks
>>>
>>>
>>>
>
diff mbox series

Patch

diff --git a/include/net/filter.h b/include/net/filter.h
index 435acd6f82..49da666ac0 100644
--- a/include/net/filter.h
+++ b/include/net/filter.h
@@ -38,6 +38,8 @@  typedef ssize_t (FilterReceiveIOV)(NetFilterState *nc,
 
 typedef void (FilterStatusChanged) (NetFilterState *nf, Error **errp);
 
+typedef void (FilterHandleEvent) (NetFilterState *nf, int event, Error **errp);
+
 typedef struct NetFilterClass {
     ObjectClass parent_class;
 
@@ -45,6 +47,7 @@  typedef struct NetFilterClass {
     FilterSetup *setup;
     FilterCleanup *cleanup;
     FilterStatusChanged *status_changed;
+    FilterHandleEvent *handle_event;
     /* mandatory */
     FilterReceiveIOV *receive_iov;
 } NetFilterClass;
@@ -77,4 +80,6 @@  ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
                                     int iovcnt,
                                     void *opaque);
 
+void colo_notify_filters_event(int event, Error **errp);
+
 #endif /* QEMU_NET_FILTER_H */
diff --git a/net/filter.c b/net/filter.c
index 2fd7d7d663..0f17eba143 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -17,6 +17,8 @@ 
 #include "net/vhost_net.h"
 #include "qom/object_interfaces.h"
 #include "qemu/iov.h"
+#include "net/colo.h"
+#include "migration/colo.h"
 
 static inline bool qemu_can_skip_netfilter(NetFilterState *nf)
 {
@@ -245,11 +247,26 @@  static void netfilter_finalize(Object *obj)
     g_free(nf->netdev_id);
 }
 
+static void dummy_handle_event(NetFilterState *nf, int event, Error **errp)
+{
+    switch (event) {
+    case COLO_EVENT_CHECKPOINT:
+        break;
+    case COLO_EVENT_FAILOVER:
+        object_property_set_str(OBJECT(nf), "off", "status", errp);
+        break;
+    default:
+        break;
+    }
+}
+
 static void netfilter_class_init(ObjectClass *oc, void *data)
 {
     UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+    NetFilterClass *nfc = NETFILTER_CLASS(oc);
 
     ucc->complete = netfilter_complete;
+    nfc->handle_event = dummy_handle_event;
 }
 
 static const TypeInfo netfilter_info = {
diff --git a/net/net.c b/net/net.c
index efb9eaf779..378cd2f9ec 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1329,6 +1329,34 @@  void hmp_info_network(Monitor *mon, const QDict *qdict)
     }
 }
 
+void colo_notify_filters_event(int event, Error **errp)
+{
+    NetClientState *nc, *peer;
+    NetClientDriver type;
+    NetFilterState *nf;
+    NetFilterClass *nfc = NULL;
+    Error *local_err = NULL;
+
+    QTAILQ_FOREACH(nc, &net_clients, next) {
+        peer = nc->peer;
+        type = nc->info->type;
+        if (!peer || type != NET_CLIENT_DRIVER_TAP) {
+            continue;
+        }
+        QTAILQ_FOREACH(nf, &nc->filters, next) {
+            nfc =  NETFILTER_GET_CLASS(OBJECT(nf));
+            if (!nfc->handle_event) {
+                continue;
+            }
+            nfc->handle_event(nf, event, &local_err);
+            if (local_err) {
+                error_propagate(errp, local_err);
+                return;
+            }
+        }
+    }
+}
+
 void qmp_set_link(const char *name, bool up, Error **errp)
 {
     NetClientState *ncs[MAX_QUEUE_NUM];