diff options
-rw-r--r-- | include/openvswitch/vconn.h | 4 | ||||
-rw-r--r-- | lib/vconn.c | 22 | ||||
-rw-r--r-- | ovn/utilities/ovn-sbctl.c | 2 | ||||
-rw-r--r-- | ovn/utilities/ovn-trace.c | 2 | ||||
-rw-r--r-- | tests/test-vconn.c | 14 | ||||
-rw-r--r-- | utilities/ovs-ofctl.c | 2 |
6 files changed, 30 insertions, 16 deletions
diff --git a/include/openvswitch/vconn.h b/include/openvswitch/vconn.h index b30d46af0..dfb7f7522 100644 --- a/include/openvswitch/vconn.h +++ b/include/openvswitch/vconn.h @@ -73,8 +73,8 @@ void vconn_run_wait(struct vconn *); int vconn_get_status(const struct vconn *); int vconn_open_block(const char *name, uint32_t allowed_versions, uint8_t dscp, - struct vconn **); -int vconn_connect_block(struct vconn *); + long long int timeout, struct vconn **); +int vconn_connect_block(struct vconn *, long long int timeout); int vconn_send_block(struct vconn *, struct ofpbuf *); int vconn_recv_block(struct vconn *, struct ofpbuf **); diff --git a/lib/vconn.c b/lib/vconn.c index 4d5f308d8..40ebc5818 100644 --- a/lib/vconn.c +++ b/lib/vconn.c @@ -306,7 +306,7 @@ vconn_get_status(const struct vconn *vconn) int vconn_open_block(const char *name, uint32_t allowed_versions, uint8_t dscp, - struct vconn **vconnp) + long long int timeout, struct vconn **vconnp) { struct vconn *vconn; int error; @@ -315,7 +315,7 @@ vconn_open_block(const char *name, uint32_t allowed_versions, uint8_t dscp, error = vconn_open(name, allowed_versions, dscp, &vconn); if (!error) { - error = vconn_connect_block(vconn); + error = vconn_connect_block(vconn, timeout); } if (error) { @@ -697,16 +697,28 @@ do_send(struct vconn *vconn, struct ofpbuf *msg) } /* Same as vconn_connect(), except that it waits until the connection on - * 'vconn' completes or fails. Thus, it will never return EAGAIN. */ + * 'vconn' completes or fails, but no more than 'timeout' milliseconds. + * Thus, it will never return EAGAIN. Negative value of 'timeout' means + * infinite waiting.*/ int -vconn_connect_block(struct vconn *vconn) +vconn_connect_block(struct vconn *vconn, long long int timeout) { - int error; + long long int deadline = (timeout >= 0 + ? time_msec() + deadline + : LLONG_MAX); + int error; while ((error = vconn_connect(vconn)) == EAGAIN) { + if (time_msec() > deadline) { + error = ETIMEDOUT; + break; + } vconn_run(vconn); vconn_run_wait(vconn); vconn_connect_wait(vconn); + if (deadline != LLONG_MAX) { + poll_timer_wait_until(deadline); + } poll_block(); } ovs_assert(error != EINPROGRESS); diff --git a/ovn/utilities/ovn-sbctl.c b/ovn/utilities/ovn-sbctl.c index d0af83fa0..ee97a4710 100644 --- a/ovn/utilities/ovn-sbctl.c +++ b/ovn/utilities/ovn-sbctl.c @@ -777,7 +777,7 @@ sbctl_open_vconn(struct shash *options) char *remote = ovs->data ? xstrdup(ovs->data) : default_ovs(); struct vconn *vconn; - int retval = vconn_open_block(remote, 1 << OFP13_VERSION, 0, &vconn); + int retval = vconn_open_block(remote, 1 << OFP13_VERSION, 0, -1, &vconn); if (retval) { VLOG_WARN("%s: connection failed (%s)", remote, ovs_strerror(retval)); } diff --git a/ovn/utilities/ovn-trace.c b/ovn/utilities/ovn-trace.c index cbf3e54d2..8899496a5 100644 --- a/ovn/utilities/ovn-trace.c +++ b/ovn/utilities/ovn-trace.c @@ -2244,7 +2244,7 @@ trace(const char *dp_s, const char *flow_s) ds_put_char(&output, '\n'); if (ovs) { - int retval = vconn_open_block(ovs, 1 << OFP13_VERSION, 0, &vconn); + int retval = vconn_open_block(ovs, 1 << OFP13_VERSION, 0, -1, &vconn); if (retval) { VLOG_WARN("%s: connection failed (%s)", ovs, ovs_strerror(retval)); } diff --git a/tests/test-vconn.c b/tests/test-vconn.c index 8b8d12e36..73ef9a958 100644 --- a/tests/test-vconn.c +++ b/tests/test-vconn.c @@ -37,6 +37,8 @@ #include "timeval.h" #include "util.h" +#define TIMEOUT 10 + struct fake_pvconn { const char *type; char *pvconn_name; @@ -152,9 +154,9 @@ test_refuse_connection(struct ovs_cmdl_context *ctx) fpv_close(&fpv); vconn_run(vconn); - error = vconn_connect_block(vconn); + error = vconn_connect_block(vconn, (TIMEOUT - 2) * 1000); if (!strcmp(type, "tcp")) { - if (error != ECONNRESET && error != EPIPE + if (error != ECONNRESET && error != EPIPE && error != ETIMEDOUT #ifdef _WIN32 && error != WSAECONNRESET #endif @@ -165,7 +167,7 @@ test_refuse_connection(struct ovs_cmdl_context *ctx) } else if (!strcmp(type, "unix")) { CHECK_ERRNO(error, EPIPE); } else if (!strcmp(type, "ssl")) { - if (error != EPROTO && error != ECONNRESET) { + if (error != EPROTO && error != ECONNRESET && error != ETIMEDOUT) { ovs_fatal(0, "unexpected vconn_connect() return value %d (%s)", error, ovs_strerror(error)); } @@ -194,7 +196,7 @@ test_accept_then_close(struct ovs_cmdl_context *ctx) stream_close(fpv_accept(&fpv)); fpv_close(&fpv); - error = vconn_connect_block(vconn); + error = vconn_connect_block(vconn, -1); if (!strcmp(type, "tcp") || !strcmp(type, "unix")) { if (error != ECONNRESET && error != EPIPE #ifdef _WIN32 @@ -254,7 +256,7 @@ test_read_hello(struct ovs_cmdl_context *ctx) poll_block(); } stream_close(stream); - error = vconn_connect_block(vconn); + error = vconn_connect_block(vconn, -1); if (error != ECONNRESET && error != EPIPE) { ovs_fatal(0, "unexpected vconn_connect() return value %d (%s)", error, ovs_strerror(error)); @@ -451,7 +453,7 @@ test_vconn_main(int argc, char *argv[]) vlog_set_levels(NULL, VLF_CONSOLE, VLL_DBG); fatal_ignore_sigpipe(); - time_alarm(10); + time_alarm(TIMEOUT); ovs_cmdl_run_command(&ctx, commands); } diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 8a713e370..0ff4ed259 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -601,7 +601,7 @@ open_vconn__(const char *name, enum open_target target, free(socket_name); VLOG_DBG("connecting to %s", vconn_get_name(*vconnp)); - error = vconn_connect_block(*vconnp); + error = vconn_connect_block(*vconnp, -1); if (error) { ovs_fatal(0, "%s: failed to connect to socket (%s)", name, ovs_strerror(error)); |