net: fix release and re-open of sockets

This commit is contained in:
Thomas Schoebel-Theuer 2012-11-30 11:52:21 +01:00 committed by Thomas Schoebel-Theuer
parent dd99340827
commit 43a6c2239c
3 changed files with 40 additions and 27 deletions

View File

@ -241,7 +241,7 @@ EXPORT_SYMBOL_GPL(mars_accept_socket);
bool mars_get_socket(struct mars_socket *msock)
{
MARS_LOW("#%d get socket %p s_dead = %d s_count=%d\n", msock->s_debug_nr, msock->s_socket, msock->s_dead, atomic_read(&msock->s_count));
MARS_LOW("#%d get socket %p s_count=%d\n", msock->s_debug_nr, msock->s_socket, atomic_read(&msock->s_count));
if (unlikely(atomic_read(&msock->s_count) <= 0)) {
MARS_ERR("#%d bad nesting on msock = %p\n", msock->s_debug_nr, msock);
return false;
@ -249,7 +249,7 @@ bool mars_get_socket(struct mars_socket *msock)
atomic_inc(&msock->s_count);
if (unlikely(!msock->s_socket || msock->s_dead)) {
if (unlikely(!msock->s_socket)) {
mars_put_socket(msock);
return false;
}
@ -260,7 +260,7 @@ EXPORT_SYMBOL_GPL(mars_get_socket);
void mars_put_socket(struct mars_socket *msock)
{
MARS_LOW("#%d put socket %p s_dead = %d s_count=%d\n", msock->s_debug_nr, msock->s_socket, msock->s_dead, atomic_read(&msock->s_count));
MARS_LOW("#%d put socket %p s_count=%d\n", msock->s_debug_nr, msock->s_socket, atomic_read(&msock->s_count));
if (unlikely(atomic_read(&msock->s_count) <= 0)) {
MARS_ERR("#%d bad nesting on msock = %p sock = %p\n", msock->s_debug_nr, msock, msock->s_socket);
} else if (atomic_dec_and_test(&msock->s_count)) {
@ -269,8 +269,13 @@ void mars_put_socket(struct mars_socket *msock)
MARS_DBG("#%d closing socket %p\n", msock->s_debug_nr, sock);
if (likely(sock)) {
msock->s_socket = NULL;
kernel_sock_shutdown(sock, SHUT_WR);
sock_release(sock);
msock->s_release_socket = sock;
}
if (likely(msock->s_release_socket)) {
MARS_DBG("#%d releasing socket %p\n", msock->s_debug_nr, msock->s_release_socket);
sock_release(msock->s_release_socket);
}
for (i = 0; i < MAX_DESC_CACHE; i++) {
if (msock->s_desc_send[i])
@ -286,21 +291,21 @@ EXPORT_SYMBOL_GPL(mars_put_socket);
void mars_shutdown_socket(struct mars_socket *msock)
{
bool ok;
MARS_IO("#%d shutdown socket %p s_count=%d\n", msock->s_debug_nr, msock->s_socket, atomic_read(&msock->s_count));
MARS_IO("#%d shutdown socket %p s_dead = %d s_count=%d\n", msock->s_debug_nr, msock->s_socket, msock->s_dead, atomic_read(&msock->s_count));
ok = mars_get_socket(msock);
if (likely(ok)) {
struct socket *sock = msock->s_socket;
if (likely(sock)) {
if (!msock->s_dead) {
msock->s_dead = true;
MARS_DBG("shutdown socket #%d %p\n", msock->s_debug_nr, sock);
if (msock->s_socket) {
bool ok = mars_get_socket(msock);
if (likely(ok)) {
struct socket *sock = msock->s_socket;
if (likely(sock)) {
msock->s_socket = NULL;
MARS_DBG("#%d shutdown socket %p\n", msock->s_debug_nr, sock);
kernel_sock_shutdown(sock, SHUT_WR);
// delay sock_release() until the last reference has gone
msock->s_release_socket = sock;
}
mars_put_socket(msock);
}
mars_put_socket(msock);
}
}
EXPORT_SYMBOL_GPL(mars_shutdown_socket);
@ -314,11 +319,9 @@ bool mars_socket_is_alive(struct mars_socket *msock)
MARS_ERR("#%d bad nesting on msock = %p sock = %p\n", msock->s_debug_nr, msock, msock->s_socket);
goto done;
}
if (msock->s_dead)
goto done;
res = true;
done:
MARS_LOW("#%d %p s_count = %d s_dead = %d\n", msock->s_debug_nr, msock->s_socket, atomic_read(&msock->s_count), msock->s_dead);
MARS_LOW("#%d %p s_count = %d\n", msock->s_debug_nr, msock->s_socket, atomic_read(&msock->s_count));
return res;
}
EXPORT_SYMBOL_GPL(mars_socket_is_alive);
@ -514,7 +517,7 @@ int mars_recv_raw(struct mars_socket *msock, void *buf, int minlen, int maxlen)
#endif
};
if (unlikely(msock->s_dead)) {
if (unlikely(!msock->s_socket)) {
MARS_WRN("#%d socket has disappeared\n", msock->s_debug_nr);
status = -EIDRM;
goto err;

View File

@ -38,11 +38,11 @@ struct mars_desc_item {
*/
struct mars_socket {
struct socket *s_socket;
struct socket *s_release_socket;
void *s_buffer;
atomic_t s_count;
int s_pos;
int s_debug_nr;
bool s_dead;
bool s_shutdown_on_err;
struct mars_desc_cache *s_desc_send[MAX_DESC_CACHE];
struct mars_desc_cache *s_desc_recv[MAX_DESC_CACHE];

View File

@ -1008,12 +1008,11 @@ static
void _peer_cleanup(struct mars_peerinfo *peer)
{
MARS_DBG("cleanup\n");
if (peer->socket.s_socket) {
if (mars_socket_is_alive(&peer->socket)) {
MARS_DBG("really shutdown socket\n");
mars_shutdown_socket(&peer->socket);
mars_put_socket(&peer->socket);
}
mars_put_socket(&peer->socket);
}
static DECLARE_WAIT_QUEUE_HEAD(remote_event);
@ -1027,6 +1026,7 @@ int peer_thread(void *data)
char *real_peer;
struct sockaddr_storage sockaddr = {};
int pause_time = 0;
bool do_kill = false;
bool flip = false;
int status;
@ -1055,7 +1055,8 @@ int peer_thread(void *data)
};
if (!mars_socket_is_alive(&peer->socket)) {
if (peer->socket.s_socket) {
if (do_kill) {
do_kill = false;
_peer_cleanup(peer);
brick_msleep(5000);
continue;
@ -1071,6 +1072,7 @@ int peer_thread(void *data)
brick_msleep(5000);
continue;
}
do_kill = true;
peer->socket.s_shutdown_on_err = true;
MARS_DBG("successfully opened socket to '%s'\n", real_peer);
brick_msleep(100);
@ -1091,7 +1093,10 @@ int peer_thread(void *data)
status = mars_send_struct(&peer->socket, &cmd, mars_cmd_meta);
if (unlikely(status < 0)) {
MARS_WRN("communication error on send, status = %d\n", status);
_peer_cleanup(peer);
if (do_kill) {
do_kill = false;
_peer_cleanup(peer);
}
brick_msleep(2000);
continue;
}
@ -1106,7 +1111,10 @@ int peer_thread(void *data)
status = mars_recv_dent_list(&peer->socket, &tmp_list);
if (unlikely(status < 0)) {
MARS_WRN("communication error on receive, status = %d\n", status);
_peer_cleanup(peer);
if (do_kill) {
do_kill = false;
_peer_cleanup(peer);
}
mars_free_dent_all(NULL, &tmp_list);
brick_msleep(5000);
continue;
@ -1138,7 +1146,9 @@ int peer_thread(void *data)
MARS_INF("-------- peer thread terminating\n");
_peer_cleanup(peer);
if (do_kill) {
_peer_cleanup(peer);
}
done:
atomic_dec(&peer_thread_count);