Commit ed4db723 authored by Andrey Ryabinin's avatar Andrey Ryabinin Committed by Pavel Emelyanov

sk-unix: ignore shutdown mismatch in unix sockets

Usually unix stream sockets have consistent shutdown state
(if one end shutdown for read than other end will be shut down for write).
However sometimes it's possible to have stream sockets with mismatched
shutdown state. This happens if we connect() already shut down socket
(see upcoming sockets03.c test for example).

On read()/write() kernel always checks shutdown state on both ends, so
from userspace POV sockets with mismatched shutdown state behave the same
way as with matched state. So I think that we can just ignore shutdown
mismatch during dump, and just restore sockets with matching shutdown
state. Process should not see the differences.
Signed-off-by: 's avatarAndrey Ryabinin <aryabinin@virtuozzo.com>
Acked-by: 's avatarAndrew Vagin <avagin@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 8239be8f
...@@ -368,12 +368,15 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p) ...@@ -368,12 +368,15 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
((ue->shutdown == SK_SHUTDOWN__BOTH) && ((ue->shutdown == SK_SHUTDOWN__BOTH) &&
(peer->shutdown != SK_SHUTDOWN__BOTH)) )) { (peer->shutdown != SK_SHUTDOWN__BOTH)) )) {
/* /*
* On restore we assume, that stream pairs must * Usually this doesn't happen, however it's possible if
* be shut down from one end only * socket was shut down before connect() (see sockets03.c test).
* On restore we will shutdown both end (iow socktes will be in
* matched state). This shoudn't be a problem, since kernel seems
* to check both ends on read()/write(). Thus mismatched sockets behave
* the same way as matched.
*/ */
pr_err("Shutdown mismatch %u:%d -> %u:%d\n", pr_warn("Shutdown mismatch %u:%d -> %u:%d\n",
ue->ino, ue->shutdown, peer->sd.ino, peer->shutdown); ue->ino, ue->shutdown, peer->sd.ino, peer->shutdown);
goto err;
} }
} else if (ue->state == TCP_ESTABLISHED) { } else if (ue->state == TCP_ESTABLISHED) {
const struct unix_sk_listen_icon *e; const struct unix_sk_listen_icon *e;
...@@ -1063,13 +1066,8 @@ static int open_unixsk_pair_slave(struct unix_sk_info *ui) ...@@ -1063,13 +1066,8 @@ static int open_unixsk_pair_slave(struct unix_sk_info *ui)
if (restore_socket_opts(sk, ui->ue->opts)) if (restore_socket_opts(sk, ui->ue->opts))
return -1; return -1;
if (ui->ue->type == SOCK_DGRAM) if (shutdown_unix_sk(sk, ui))
/* return -1;
* Stream socket's "slave" end will be shut down
* together with master
*/
if (shutdown_unix_sk(sk, ui))
return -1;
return sk; return sk;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment