From bb8a9a2b0ea8ced4c285c24e98d2e14656130841 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 17 Jun 2009 14:22:57 -0700 Subject: [PATCH] dpif: Change dpif_port_group_get() semantics. This function is easier for callers to use if they do not have to guess how many ports are in the group. Since it's not performance critical at all, introduce these easier semantics. --- lib/dpif.c | 38 ++++++++++++++++++++++++++++---------- lib/dpif.h | 2 +- utilities/ovs-dpctl.c | 6 +++--- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/lib/dpif.c b/lib/dpif.c index 877cfc823..b538c4cae 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -391,21 +391,39 @@ dpif_port_group_set(struct dpif *dpif, uint16_t group, return do_ioctl(dpif, ODP_PORT_GROUP_SET, "ODP_PORT_GROUP_SET", &pg); } -/* Careful: '*n_out' can be greater than 'n_ports' on return, if 'n_ports' is - * less than the number of ports in 'group'. */ int dpif_port_group_get(const struct dpif *dpif, uint16_t group, - uint16_t ports[], size_t n_ports, size_t *n_out) + uint16_t **ports, size_t *n_ports) { - struct odp_port_group pg; int error; - assert(n_ports <= UINT16_MAX); - pg.group = group; - pg.ports = ports; - pg.n_ports = n_ports; - error = do_ioctl(dpif, ODP_PORT_GROUP_GET, "ODP_PORT_GROUP_GET", &pg); - *n_out = error ? 0 : pg.n_ports; + *ports = NULL; + *n_ports = 0; + for (;;) { + struct odp_port_group pg; + pg.group = group; + pg.ports = *ports; + pg.n_ports = *n_ports; + + error = do_ioctl(dpif, ODP_PORT_GROUP_GET, "ODP_PORT_GROUP_GET", &pg); + if (error) { + /* Hard error. */ + free(*ports); + *ports = NULL; + *n_ports = 0; + break; + } else if (pg.n_ports <= *n_ports) { + /* Success. */ + *n_ports = pg.n_ports; + break; + } else { + /* Soft error: there were more ports than we expected in the + * group. Try again. */ + free(*ports); + *ports = xcalloc(pg.n_ports, sizeof **ports); + *n_ports = pg.n_ports; + } + } return error; } diff --git a/lib/dpif.h b/lib/dpif.h index 164bb2bf9..a76778831 100644 --- a/lib/dpif.h +++ b/lib/dpif.h @@ -60,7 +60,7 @@ int dpif_port_list(const struct dpif *, struct odp_port **, size_t *n_ports); int dpif_port_group_set(struct dpif *, uint16_t group, const uint16_t ports[], size_t n_ports); int dpif_port_group_get(const struct dpif *, uint16_t group, - uint16_t ports[], size_t n_ports, size_t *n_out); + uint16_t **ports, size_t *n_ports); int dpif_flow_flush(struct dpif *); int dpif_flow_put(struct dpif *, struct odp_flow_put *); diff --git a/utilities/ovs-dpctl.c b/utilities/ovs-dpctl.c index 92d1d2d6a..9f45b3add 100644 --- a/utilities/ovs-dpctl.c +++ b/utilities/ovs-dpctl.c @@ -515,11 +515,10 @@ do_dump_groups(int argc UNUSED, char *argv[]) run(dpif_open(argv[1], &dpif), "opening datapath"); run(dpif_get_dp_stats(dpif, &stats), "get datapath stats"); for (i = 0; i < stats.max_groups; i++) { - uint16_t ports[UINT16_MAX]; + uint16_t *ports; size_t n_ports; - if (!dpif_port_group_get(dpif, i, ports, - ARRAY_SIZE(ports), &n_ports) && n_ports) { + if (!dpif_port_group_get(dpif, i, &ports, &n_ports) && n_ports) { size_t j; printf("group %u:", i); @@ -528,6 +527,7 @@ do_dump_groups(int argc UNUSED, char *argv[]) } printf("\n"); } + free(ports); } dpif_close(dpif); } -- 2.43.0