mirror of
https://github.com/openvswitch/ovs
synced 2025-09-03 15:55:19 +00:00
rconn: Discover errors in rconn_run() even if rconn_recv() is never called.
rconn_recv() calls vconn_recv(), which will report a connection error and cause rconn_recv() to disconnect the rconn. Most rconn users regularly call rconn_recv(), so that disconnection happens promptly. However, the lswitch code only calls rconn_recv() after the connection negotiates an OpenFlow version, so a connection that failed before negotiation would never be detected as failed. This commit fixes the problem by making rconn_run() also detect and handle connection errors. The lswitch code is only used by the test-controller program, so this is not an important bug fix. Reported-by: Vasu Dasari <vdasari@gmail.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
10
lib/rconn.c
10
lib/rconn.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
|
||||
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -592,7 +592,15 @@ rconn_run(struct rconn *rc)
|
||||
|
||||
ovs_mutex_lock(&rc->mutex);
|
||||
if (rc->vconn) {
|
||||
int error;
|
||||
|
||||
vconn_run(rc->vconn);
|
||||
|
||||
error = vconn_get_status(rc->vconn);
|
||||
if (error) {
|
||||
report_error(rc, error);
|
||||
disconnect(rc, error);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < rc->n_monitors; ) {
|
||||
struct ofpbuf *msg;
|
||||
|
11
lib/vconn.c
11
lib/vconn.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
|
||||
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -293,6 +293,15 @@ vconn_run_wait(struct vconn *vconn)
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns 0 if 'vconn' is healthy (connecting or connected), a positive errno
|
||||
* value if the connection died abnormally (connection failed or aborted), or
|
||||
* EOF if the connection was closed in a normal way. */
|
||||
int
|
||||
vconn_get_status(const struct vconn *vconn)
|
||||
{
|
||||
return vconn->error;
|
||||
}
|
||||
|
||||
int
|
||||
vconn_open_block(const char *name, uint32_t allowed_versions, uint8_t dscp,
|
||||
struct vconn **vconnp)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
|
||||
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -57,6 +57,8 @@ int vconn_transact_multiple_noreply(struct vconn *, struct list *requests,
|
||||
void vconn_run(struct vconn *);
|
||||
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 *);
|
||||
|
Reference in New Issue
Block a user