[ovs-dev] [multiple tables 4/8] ofproto: Make ->construct() and ->destruct() more symmetrical.
Ethan Jackson
ethan at nicira.com
Mon Aug 8 22:38:30 UTC 2011
Looks good,
Ethan
On Thu, Aug 4, 2011 at 16:29, Ben Pfaff <blp at nicira.com> wrote:
> The ofproto_provider's ->construct() was required to allocate and
> initialize the flow tables, but ->destruct() was not allowed to
> uninitialize and free them. This arrangement is oddly asymmetrical (and
> undocumented), so this commit changes the code so that the client is
> responsible for both allocation and freeing.
>
> Reported-by: Hao Zheng <hzheng at nicira.com>
> CC: Hao Zheng <hzheng at nicira.com>
> ---
> ofproto/ofproto-dpif.c | 7 ++-----
> ofproto/ofproto-provider.h | 36 ++++++++++++++++++++----------------
> ofproto/ofproto.c | 12 ++++++++++--
> 3 files changed, 32 insertions(+), 23 deletions(-)
>
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index 2aea4e1..137d1f9 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -419,7 +419,7 @@ dealloc(struct ofproto *ofproto_)
> }
>
> static int
> -construct(struct ofproto *ofproto_)
> +construct(struct ofproto *ofproto_, int *n_tablesp)
> {
> struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
> const char *name = ofproto->up.name;
> @@ -464,14 +464,11 @@ construct(struct ofproto *ofproto_)
>
> list_init(&ofproto->completions);
>
> - ofproto->up.tables = xmalloc(sizeof *ofproto->up.tables);
> - classifier_init(&ofproto->up.tables[0]);
> - ofproto->up.n_tables = 1;
> -
> ofproto_dpif_unixctl_init();
>
> ofproto->has_bundle_action = false;
>
> + *n_tablesp = 1;
> return 0;
> }
>
> diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
> index be1e4de..985f112 100644
> --- a/ofproto/ofproto-provider.h
> +++ b/ofproto/ofproto-provider.h
> @@ -255,17 +255,20 @@ struct ofproto_class {
> * Construction
> * ============
> *
> - * ->construct() should not modify most base members of the ofproto. In
> - * particular, the client will initialize the ofproto's 'ports' member
> - * after construction is complete.
> - *
> - * ->construct() should initialize the base 'n_tables' member to the number
> - * of flow tables supported by the datapath (between 1 and 255, inclusive),
> - * initialize the base 'tables' member with space for one classifier per
> - * table, and initialize each classifier with classifier_init. Each flow
> - * table should be initially empty, so ->construct() should delete flows
> - * from the underlying datapath, if necessary, rather than populating the
> - * tables.
> + * ->construct() should not modify any base members of the ofproto. The
> + * client will initialize the ofproto's 'ports' and 'tables' members after
> + * construction is complete.
> + *
> + * When ->construct() is called, the client does not yet know how many flow
> + * tables the datapath supports, so ofproto->n_tables will be 0 and
> + * ofproto->tables will be NULL. ->construct() should store the number of
> + * flow tables supported by the datapath (between 1 and 255, inclusive)
> + * into '*n_tables'. After a successful return, the client will initialize
> + * the base 'n_tables' member to '*n_tables' and allocate and initialize
> + * the base 'tables' member as the specified number of empty flow tables.
> + * Each flow table will be initially empty, so ->construct() should delete
> + * flows from the underlying datapath, if necessary, rather than populating
> + * the tables.
> *
> * Only one ofproto instance needs to be supported for any given datapath.
> * If a datapath is already open as part of one "ofproto", then another
> @@ -279,15 +282,16 @@ struct ofproto_class {
> * Destruction
> * ===========
> *
> - * ->destruct() must do at least the following:
> + * If 'ofproto' has any pending asynchronous operations, ->destruct()
> + * must complete all of them by calling ofoperation_complete().
> *
> - * - If 'ofproto' has any pending asynchronous operations, ->destruct()
> - * must complete all of them by calling ofoperation_complete().
> - *
> - * - If 'ofproto' has any rules left in any of its flow tables, ->
> + * ->destruct() must also destroy all remaining rules in the ofproto's
> + * tables, by passing each remaining rule to ofproto_rule_destroy(). The
> + * client will destroy the flow tables themselves after ->destruct()
> + * returns.
> */
> struct ofproto *(*alloc)(void);
> - int (*construct)(struct ofproto *ofproto);
> + int (*construct)(struct ofproto *ofproto, int *n_tables);
> void (*destruct)(struct ofproto *ofproto);
> void (*dealloc)(struct ofproto *ofproto);
>
> diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
> index f40f995..79c85a0 100644
> --- a/ofproto/ofproto.c
> +++ b/ofproto/ofproto.c
> @@ -290,7 +290,9 @@ ofproto_create(const char *datapath_name, const char *datapath_type,
> {
> const struct ofproto_class *class;
> struct ofproto *ofproto;
> + int n_tables;
> int error;
> + int i;
>
> *ofprotop = NULL;
>
> @@ -337,14 +339,20 @@ ofproto_create(const char *datapath_name, const char *datapath_type,
> list_init(&ofproto->pending);
> hmap_init(&ofproto->deletions);
>
> - error = ofproto->ofproto_class->construct(ofproto);
> + error = ofproto->ofproto_class->construct(ofproto, &n_tables);
> if (error) {
> VLOG_ERR("failed to open datapath %s: %s",
> datapath_name, strerror(error));
> ofproto_destroy__(ofproto);
> return error;
> }
> - assert(ofproto->n_tables > 0);
> +
> + assert(n_tables >= 1 && n_tables <= 255);
> + ofproto->n_tables = n_tables;
> + ofproto->tables = xmalloc(n_tables * sizeof *ofproto->tables);
> + for (i = 0; i < n_tables; i++) {
> + classifier_init(&ofproto->tables[i]);
> + }
>
> ofproto->datapath_id = pick_datapath_id(ofproto);
> VLOG_INFO("using datapath ID %016"PRIx64, ofproto->datapath_id);
> --
> 1.7.4.4
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
>
More information about the dev
mailing list