X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fdpif.c;h=85d05bb714ce61df9078aa8654f71a183c02dab7;hb=f4ba4c4f954f565facc204c2f42947a37704eb1e;hp=e0e5f36425529163626066ea44ae90964e22d65a;hpb=f1aa2072c80dc8d4fb7a776801537172a656dbdd;p=openvswitch diff --git a/lib/dpif.c b/lib/dpif.c index e0e5f364..85d05bb7 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -337,33 +337,48 @@ dpif_port_get_name(struct dpif *dpif, uint16_t port_no, int dpif_port_list(const struct dpif *dpif, - struct odp_port **ports, size_t *n_ports) + struct odp_port **portsp, size_t *n_portsp) { - struct odp_portvec pv; - struct odp_stats stats; + struct odp_port *ports; + size_t n_ports; int error; - do { + for (;;) { + struct odp_stats stats; + struct odp_portvec pv; + error = dpif_get_dp_stats(dpif, &stats); if (error) { - goto error; + goto exit; } - *ports = xcalloc(1, stats.n_ports * sizeof **ports); - pv.ports = *ports; + ports = xcalloc(stats.n_ports, sizeof *ports); + pv.ports = ports; pv.n_ports = stats.n_ports; error = do_ioctl(dpif, ODP_PORT_LIST, "ODP_PORT_LIST", &pv); if (error) { - free(*ports); - goto error; + /* Hard error. */ + free(ports); + goto exit; + } else if (pv.n_ports <= stats.n_ports) { + /* Success. */ + error = 0; + n_ports = pv.n_ports; + goto exit; + } else { + /* Soft error: port count increased behind our back. Try again. */ + free(ports); } - } while (pv.n_ports != stats.n_ports); - *n_ports = pv.n_ports; - return 0; + } -error: - *ports = NULL; - *n_ports = 0; +exit: + if (error) { + *portsp = NULL; + *n_portsp = 0; + } else { + *portsp = ports; + *n_portsp = n_ports; + } return error; }