summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/openvswitch/vconn.h4
-rw-r--r--lib/vconn.c22
-rw-r--r--ovn/utilities/ovn-sbctl.c2
-rw-r--r--ovn/utilities/ovn-trace.c2
-rw-r--r--tests/test-vconn.c14
-rw-r--r--utilities/ovs-ofctl.c2
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));