Thx a lot for fixing this, pushed to branch-2.3

On Fri, May 30, 2014 at 1:07 PM, Alex Wang <al...@nicira.com> wrote:

> Acked-by: Alex Wang <al...@nicira.com>
>
> I'm about to apply it with the following additional fold in.
>
> Basically, move the 'bool force' before the struct which holds
> returned bfd/cfm status.
>
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index bae5e6a..7f59b94 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -1826,8 +1826,8 @@ out:
>  }
>
>  static int
> -get_cfm_status(const struct ofport *ofport_,
> -               struct ofproto_cfm_status *status, bool force)
> +get_cfm_status(const struct ofport *ofport_, bool force,
> +               struct ofproto_cfm_status *status)
>  {
>      struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
>      int ret = 0;
> @@ -1868,7 +1868,7 @@ set_bfd(struct ofport *ofport_, const struct smap
> *cfg)
>  }
>
>  static int
> -get_bfd_status(struct ofport *ofport_, struct smap *smap, bool force)
> +get_bfd_status(struct ofport *ofport_, bool force, struct smap *smap)
>  {
>      struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
>      int ret = 0;
> diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
> index 84b726d..639b501 100644
> --- a/ofproto/ofproto-provider.h
> +++ b/ofproto/ofproto-provider.h
> @@ -1449,8 +1449,8 @@ struct ofproto_class {
>       * The caller must provide and own '*status', and it must free the
> array
>        * returned in 'status->rmps'.  '*status' is indeterminate if the
> return
>       * value is non-zero. */
> -    int (*get_cfm_status)(const struct ofport *ofport,
> -                          struct ofproto_cfm_status *status, bool force);
> +    int (*get_cfm_status)(const struct ofport *ofport, bool force,
> +                          struct ofproto_cfm_status *status);
>
>      /* Configures BFD on 'ofport'.
>        *
> @@ -1472,7 +1472,7 @@ struct ofproto_class {
>       *
>       * EOPNOTSUPP as a return value indicates that this ofproto_class
> does not
>       * support BFD, as does a null pointer. */
> -    int (*get_bfd_status)(struct ofport *ofport, struct smap *smap, bool
> force);
> +    int (*get_bfd_status)(struct ofport *ofport, bool force, struct smap
> *smap);
>
>      /* Configures spanning tree protocol (STP) on 'ofproto' using the
>       * settings defined in 's'.
> diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
> index a501032..608ddad 100644
> --- a/ofproto/ofproto.c
> +++ b/ofproto/ofproto.c
> @@ -1026,11 +1026,11 @@ ofproto_port_set_bfd(struct ofproto *ofproto,
> ofp_port_t ofp_port,
>   * The caller must provide and own '*status'. */
>  int
>  ofproto_port_get_bfd_status(struct ofproto *ofproto, ofp_port_t ofp_port,
> -                            struct smap *status, bool force)
> +                            bool force, struct smap *status)
>  {
>      struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
>      return (ofport && ofproto->ofproto_class->get_bfd_status
> -            ? ofproto->ofproto_class->get_bfd_status(ofport, status,
> force)
> +            ? ofproto->ofproto_class->get_bfd_status(ofport, force,
> status)
>              : EOPNOTSUPP);
>  }
>
> @@ -3730,11 +3730,11 @@ ofproto_get_netflow_ids(const struct ofproto
> *ofproto,
>   * '*status' is indeterminate if the return value is non-zero. */
>  int
>  ofproto_port_get_cfm_status(const struct ofproto *ofproto, ofp_port_t
> ofp_port,
> -                            struct ofproto_cfm_status *status, bool force)
> +                            bool force, struct ofproto_cfm_status *status)
>   {
>      struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
>      return (ofport && ofproto->ofproto_class->get_cfm_status
> -            ? ofproto->ofproto_class->get_cfm_status(ofport, status,
> force)
> +            ? ofproto->ofproto_class->get_cfm_status(ofport, force,
> status)
>              : EOPNOTSUPP);
>  }
>
> diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
> index b18e11a..9a06849 100644
> --- a/ofproto/ofproto.h
> +++ b/ofproto/ofproto.h
> @@ -265,7 +265,7 @@ void ofproto_port_set_cfm(struct ofproto *, ofp_port_t
> ofp_port,
>  void ofproto_port_set_bfd(struct ofproto *, ofp_port_t ofp_port,
>                            const struct smap *cfg);
>  int ofproto_port_get_bfd_status(struct ofproto *, ofp_port_t ofp_port,
> -                                struct smap *, bool force);
> +                                bool force, struct smap *);
>  int ofproto_port_is_lacp_current(struct ofproto *, ofp_port_t ofp_port);
>  int ofproto_port_set_stp(struct ofproto *, ofp_port_t ofp_port,
>                           const struct ofproto_port_stp_settings *);
> @@ -420,9 +420,8 @@ struct ofproto_cfm_status {
>  };
>
>  int ofproto_port_get_cfm_status(const struct ofproto *,
> -                                ofp_port_t ofp_port,
> -                                struct ofproto_cfm_status *,
> -                                bool force);
> +                                ofp_port_t ofp_port, bool force,
> +                                struct ofproto_cfm_status *);
>  ^L
>   /* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.)
>   *
> diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
> index 57eb817..039c62e 100644
> --- a/vswitchd/bridge.c
> +++ b/vswitchd/bridge.c
> @@ -1913,8 +1913,8 @@ iface_refresh_ofproto_status(struct iface *iface)
>
>      smap_init(&smap);
>      error = ofproto_port_get_bfd_status(iface->port->bridge->ofproto,
> -                                        iface->ofp_port, &smap,
> -                                        force_status_commit);
> +                                        iface->ofp_port,
> force_status_commit,
> +                                        &smap);
>      if (error >= 0) {
>          ovsrec_interface_set_bfd_status(iface->cfg, &smap);
>      }
> @@ -1931,8 +1931,8 @@ iface_refresh_cfm_stats(struct iface *iface)
>       int error;
>
>      error = ofproto_port_get_cfm_status(iface->port->bridge->ofproto,
> -                                        iface->ofp_port, &status,
> -                                        force_status_commit);
> +                                        iface->ofp_port,
> force_status_commit,
> +                                        &status);
>      if (error < 0) {
>          /* Do nothing if there is no status change since last update. */
>      } else if (error > 0) {
>
>
>
>
> On Fri, May 30, 2014 at 11:38 AM, Ryan Wilson <wr...@nicira.com> wrote:
>
>> Bridge, port and interface status changes are not sent to the
>> database if the connectivity and netdev sequence numbers have not
>> changed. However, if the previous database transaction fails, then
>> status changes will not be updated in the database until the
>> connectivity and netdev sequence numbers change again. This could
>> leave the database in an incorrect state for a long period of time.
>>
>> This patch always sends status changes to the database if the last
>> transaction was not successful.
>>
>> Bug #1256577
>> Signed-off-by: Ryan Wilson <wr...@nicira.com>
>>
>> ---
>> v2: Addressed Alex's comments, edited commit message to be more
>> accurate
>> v3: Remove iface_refresh_netdev_status() from iface_create() upon
>> further discussion with Alex
>> v4: Changed force_status_update to force_status_commit since it now
>> is set to true when status == 'TXN_INCOMPLETE'. Status txn also
>> needs to be run every STATUS_CHECK_AGAIN_MSEC if last transaction
>> was not successful.
>> v5: Add static identifier to force_status_commit.Add force update
>> BFD and CFM status.
>> ---
>>  ofproto/ofproto-dpif.c     |    8 ++++----
>>  ofproto/ofproto-provider.h |   25 ++++++++++++++++---------
>>  ofproto/ofproto.c          |   31 ++++++++++++++++++-------------
>>  ofproto/ofproto.h          |    5 +++--
>>  vswitchd/bridge.c          |   41
>> ++++++++++++++++++++++++++++++-----------
>>  5 files changed, 71 insertions(+), 39 deletions(-)
>>
>> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
>> index 06be234..4b73158 100644
>> --- a/ofproto/ofproto-dpif.c
>> +++ b/ofproto/ofproto-dpif.c
>> @@ -1821,13 +1821,13 @@ out:
>>
>>  static int
>>  get_cfm_status(const struct ofport *ofport_,
>> -               struct ofproto_cfm_status *status)
>> +               struct ofproto_cfm_status *status, bool force)
>>  {
>>      struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
>>      int ret = 0;
>>
>>      if (ofport->cfm) {
>> -        if (cfm_check_status_change(ofport->cfm)) {
>> +        if (cfm_check_status_change(ofport->cfm) || force) {
>>              status->faults = cfm_get_fault(ofport->cfm);
>>              status->flap_count = cfm_get_flap_count(ofport->cfm);
>>              status->remote_opstate = cfm_get_opup(ofport->cfm);
>> @@ -1862,13 +1862,13 @@ set_bfd(struct ofport *ofport_, const struct smap
>> *cfg)
>>  }
>>
>>  static int
>> -get_bfd_status(struct ofport *ofport_, struct smap *smap)
>> +get_bfd_status(struct ofport *ofport_, struct smap *smap, bool force)
>>  {
>>      struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
>>      int ret = 0;
>>
>>      if (ofport->bfd) {
>> -        if (bfd_check_status_change(ofport->bfd)) {
>> +        if (bfd_check_status_change(ofport->bfd) || force) {
>>              bfd_get_status(ofport->bfd, smap);
>>          } else {
>>              ret = NO_STATUS_CHANGE;
>> diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
>> index ff539b9..212ed24 100644
>> --- a/ofproto/ofproto-provider.h
>> +++ b/ofproto/ofproto-provider.h
>> @@ -1442,10 +1442,13 @@ struct ofproto_class {
>>       * support CFM, as does a null pointer. */
>>      int (*set_cfm)(struct ofport *ofport, const struct cfm_settings *s);
>>
>> -    /* Checks the status of CFM configured on 'ofport'.  Returns 0 if the
>> -     * port's CFM status was successfully stored into '*status'.  Returns
>> -     * negative number if there is no status change since last update.
>> -     * Returns positive errno otherwise.
>> +    /* Checks the status of CFM configured on 'ofport' and stores port's
>> CFM
>> +     * status in '*status'.  If 'force' is set to true, status will be
>> returned
>> +     * even if there is no status change since last update.
>> +     *
>> +     * Returns 0 on success.  Returns a negative number if there is no
>> status
>> +     * change since last update and 'force' is set to false.  Returns
>> positive
>> +     * errno otherwise.
>>       *
>>       * EOPNOTSUPP as a return value indicates that this ofproto_class
>> does not
>>       * support CFM, as does a null pointer.
>> @@ -1454,7 +1457,7 @@ struct ofproto_class {
>>       * returned in 'status->rmps'.  '*status' is indeterminate if the
>> return
>>       * value is non-zero. */
>>      int (*get_cfm_status)(const struct ofport *ofport,
>> -                          struct ofproto_cfm_status *status);
>> +                          struct ofproto_cfm_status *status, bool force);
>>
>>      /* Configures BFD on 'ofport'.
>>       *
>> @@ -1466,13 +1469,17 @@ struct ofproto_class {
>>       * support BFD, as does a null pointer. */
>>      int (*set_bfd)(struct ofport *ofport, const struct smap *cfg);
>>
>> -    /* Populates 'smap' with the status of BFD on 'ofport'.  Returns 0 on
>> -     * success.  Returns a negative number if there is no status change
>> since
>> -     * last update.  Returns a positive errno otherwise.
>> +    /* Populates 'smap' with the status of BFD on 'ofport'.  If 'force'
>> is set
>> +     * to true, status will be returned even if there is no status
>> change since
>> +     * last update.
>> +     *
>> +     * Returns 0 on success.  Returns a negative number if there is no
>> status
>> +     * change since last update and 'force' is set to false.  Returns a
>> positive
>> +     * errno otherwise.
>>       *
>>       * EOPNOTSUPP as a return value indicates that this ofproto_class
>> does not
>>       * support BFD, as does a null pointer. */
>> -    int (*get_bfd_status)(struct ofport *ofport, struct smap *smap);
>> +    int (*get_bfd_status)(struct ofport *ofport, struct smap *smap, bool
>> force);
>>
>>      /* Configures spanning tree protocol (STP) on 'ofproto' using the
>>       * settings defined in 's'.
>> diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
>> index 24a709b..2b872b7 100644
>> --- a/ofproto/ofproto.c
>> +++ b/ofproto/ofproto.c
>> @@ -1020,19 +1020,22 @@ ofproto_port_set_bfd(struct ofproto *ofproto,
>> ofp_port_t ofp_port,
>>      }
>>  }
>>
>> -/* Populates 'status' with the status of BFD on 'ofport'.  Returns 0 on
>> - * success.  Returns a negative number if there is no status change since
>> - * last update.  Returns a positive errno otherwise.  Has no effect if
>> - * 'ofp_port' is not an OpenFlow port in 'ofproto'.
>> +/* Populates 'status' with the status of BFD on 'ofport'.  If 'force' is
>> set to
>> + * true, status will be returned even if there is no status change since
>> last
>> + * update.
>> + *
>> + * Returns 0 on success.  Returns a negative number if there is no
>> status change
>> + * since last update and 'force' is set to false.  Returns a positive
>> errno
>> + * otherwise.  Has no effect if 'ofp_port' is not an OpenFlow port in
>> 'ofproto'.
>>   *
>>   * The caller must provide and own '*status'. */
>>  int
>>  ofproto_port_get_bfd_status(struct ofproto *ofproto, ofp_port_t ofp_port,
>> -                            struct smap *status)
>> +                            struct smap *status, bool force)
>>  {
>>      struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
>>      return (ofport && ofproto->ofproto_class->get_bfd_status
>> -            ? ofproto->ofproto_class->get_bfd_status(ofport, status)
>> +            ? ofproto->ofproto_class->get_bfd_status(ofport, status,
>> force)
>>              : EOPNOTSUPP);
>>  }
>>
>> @@ -3738,21 +3741,23 @@ ofproto_get_netflow_ids(const struct ofproto
>> *ofproto,
>>      ofproto->ofproto_class->get_netflow_ids(ofproto, engine_type,
>> engine_id);
>>  }
>>
>> -/* Checks the status of CFM configured on 'ofp_port' within 'ofproto'.
>> - * Returns 0 if the port's CFM status was successfully stored into
>> - * '*status'.  Returns positive errno if the port did not have CFM
>> - * configured.  Returns negative number if there is no status change
>> - * since last update.
>> +/* Checks the status of CFM configured on 'ofp_port' within 'ofproto'
>> and stores
>> + * the port's CFM status in '*status'.  If 'force' is set to true,
>> status will
>> + * be returned even if there is no status change since last update.
>> + *
>> + * Returns 0 on success.  Returns a negative number if there is no status
>> + * change since last update and 'force' is set to false.  Returns
>> positive errno
>> + * if the port did not have CFM configured.
>>   *
>>   * The caller must provide and own '*status', and must free
>> 'status->rmps'.
>>   * '*status' is indeterminate if the return value is non-zero. */
>>  int
>>  ofproto_port_get_cfm_status(const struct ofproto *ofproto, ofp_port_t
>> ofp_port,
>> -                            struct ofproto_cfm_status *status)
>> +                            struct ofproto_cfm_status *status, bool
>> force)
>>  {
>>      struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
>>      return (ofport && ofproto->ofproto_class->get_cfm_status
>> -            ? ofproto->ofproto_class->get_cfm_status(ofport, status)
>> +            ? ofproto->ofproto_class->get_cfm_status(ofport, status,
>> force)
>>              : EOPNOTSUPP);
>>  }
>>
>> diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
>> index de078b7..aa7b95d 100644
>> --- a/ofproto/ofproto.h
>> +++ b/ofproto/ofproto.h
>> @@ -265,7 +265,7 @@ void ofproto_port_set_cfm(struct ofproto *,
>> ofp_port_t ofp_port,
>>  void ofproto_port_set_bfd(struct ofproto *, ofp_port_t ofp_port,
>>                            const struct smap *cfg);
>>  int ofproto_port_get_bfd_status(struct ofproto *, ofp_port_t ofp_port,
>> -                                struct smap *);
>> +                                struct smap *, bool force);
>>  int ofproto_port_is_lacp_current(struct ofproto *, ofp_port_t ofp_port);
>>  int ofproto_port_set_stp(struct ofproto *, ofp_port_t ofp_port,
>>                           const struct ofproto_port_stp_settings *);
>> @@ -424,7 +424,8 @@ struct ofproto_cfm_status {
>>
>>  int ofproto_port_get_cfm_status(const struct ofproto *,
>>                                  ofp_port_t ofp_port,
>> -                                struct ofproto_cfm_status *);
>> +                                struct ofproto_cfm_status *,
>> +                                bool force);
>>
>>  /* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.)
>>   *
>> diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
>> index 9764c1f..a20e950 100644
>> --- a/vswitchd/bridge.c
>> +++ b/vswitchd/bridge.c
>> @@ -172,9 +172,15 @@ static uint64_t connectivity_seqno = LLONG_MIN;
>>   * we check the return status of each update transaction and do not
>> start new
>>   * update if the previous transaction status is 'TXN_INCOMPLETE'.
>>   *
>> - * 'statux_txn' is NULL if there is no ongoing status update.
>> + * 'status_txn' is NULL if there is no ongoing status update.
>> + *
>> + * If the previous database transaction was incomplete or failed (is not
>> + * 'TXN_SUCCESS' or 'TXN_UNCHANGED'), 'force_status_commit' is set to
>> true.
>> + * This means that 'status_txn' must be committed next iteration of
>> bridge_run()
>> + * even if the connectivity or netdev sequence numbers do not change.
>>   */
>>  static struct ovsdb_idl_txn *status_txn;
>> +static bool force_status_commit = true;
>>
>>  /* When the status update transaction returns 'TXN_INCOMPLETE', should
>> register a
>>   * timeout in 'STATUS_CHECK_AGAIN_MSEC' to check again. */
>> @@ -1547,7 +1553,6 @@ iface_create(struct bridge *br, const struct
>> ovsrec_interface *iface_cfg,
>>
>>      /* Populate initial status in database. */
>>      iface_refresh_stats(iface);
>> -    iface_refresh_netdev_status(iface);
>>
>>      /* Add bond fake iface if necessary. */
>>      if (port_is_bond_fake_iface(port)) {
>> @@ -1820,7 +1825,8 @@ iface_refresh_netdev_status(struct iface *iface)
>>          return;
>>      }
>>
>> -    if (iface->change_seq == netdev_get_change_seq(iface->netdev)) {
>> +    if (iface->change_seq == netdev_get_change_seq(iface->netdev)
>> +        && !force_status_commit) {
>>          return;
>>      }
>>
>> @@ -1913,7 +1919,8 @@ iface_refresh_ofproto_status(struct iface *iface)
>>
>>      smap_init(&smap);
>>      error = ofproto_port_get_bfd_status(iface->port->bridge->ofproto,
>> -                                        iface->ofp_port, &smap);
>> +                                        iface->ofp_port, &smap,
>> +                                        force_status_commit);
>>      if (error >= 0) {
>>          ovsrec_interface_set_bfd_status(iface->cfg, &smap);
>>      }
>> @@ -1930,7 +1937,8 @@ iface_refresh_cfm_stats(struct iface *iface)
>>      int error;
>>
>>      error = ofproto_port_get_cfm_status(iface->port->bridge->ofproto,
>> -                                        iface->ofp_port, &status);
>> +                                        iface->ofp_port, &status,
>> +                                        force_status_commit);
>>      if (error < 0) {
>>          /* Do nothing if there is no status change since last update. */
>>      } else if (error > 0) {
>> @@ -2420,7 +2428,7 @@ bridge_run(void)
>>
>>          /* Check the need to update status. */
>>          seq = seq_read(connectivity_seq_get());
>> -        if (seq != connectivity_seqno) {
>> +        if (seq != connectivity_seqno || force_status_commit) {
>>              connectivity_seqno = seq;
>>              status_txn = ovsdb_idl_txn_create(idl);
>>              HMAP_FOR_EACH (br, node, &all_bridges) {
>> @@ -2444,6 +2452,17 @@ bridge_run(void)
>>          enum ovsdb_idl_txn_status status;
>>
>>          status = ovsdb_idl_txn_commit(status_txn);
>> +
>> +        /* If the transaction is incomplete or fails, 'status_txn'
>> +         * needs to be committed next iteration of bridge_run() even if
>> +         * connectivity or netdev sequence numbers do not change. */
>> +        if (status == TXN_SUCCESS || status == TXN_UNCHANGED)
>> +        {
>> +            force_status_commit = false;
>> +        } else {
>> +            force_status_commit = true;
>> +        }
>> +
>>          /* Do not destroy "status_txn" if the transaction is
>>           * "TXN_INCOMPLETE". */
>>          if (status != TXN_INCOMPLETE) {
>> @@ -2483,11 +2502,11 @@ bridge_wait(void)
>>          poll_timer_wait_until(stats_timer);
>>      }
>>
>> -    /* If the status database transaction is 'TXN_INCOMPLETE' in this
>> run,
>> -     * register a timeout in 'STATUS_CHECK_AGAIN_MSEC'.  Else, wait on
>> the
>> -     * global connectivity sequence number.  Note, this also helps batch
>> -     * multiple status changes into one transaction. */
>> -    if (status_txn) {
>> +    /* If the status database transaction is 'TXN_INCOMPLETE' or is
>> +     * unsuccessful, register a timeout in 'STATUS_CHECK_AGAIN_MSEC'.
>>  Else,
>> +     * wait on the global connectivity sequence number.  Note, this also
>> helps
>> +     * batch multiple status changes into one transaction. */
>> +    if (force_status_commit) {
>>          poll_timer_wait_until(time_msec() + STATUS_CHECK_AGAIN_MSEC);
>>      } else {
>>          seq_wait(connectivity_seq_get(), connectivity_seqno);
>> --
>> 1.7.9.5
>>
>> _______________________________________________
>> dev mailing list
>> dev@openvswitch.org
>> http://openvswitch.org/mailman/listinfo/dev
>>
>
>
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to