From: Ben Pfaff Date: Wed, 17 Jun 2009 21:22:57 +0000 (-0700) Subject: dpif: Change dpif_port_group_get() semantics. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bb8a9a2b0ea8ced4c285c24e98d2e14656130841;p=openvswitch 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. --- diff --git a/lib/dpif.c b/lib/dpif.c index 877cfc82..b538c4ca 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 164bb2bf..a7677883 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 92d1d2d6..9f45b3ad 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); }