[Devel] [PATCH 4/4] Handle unconnected DGRAM sockets with buffers in-flight
Dan Smith
danms at us.ibm.com
Thu Aug 13 12:29:10 PDT 2009
This patch avoids connecting an unconnected DGRAM socket to a fake peer as
part of the restore process. Note that it will appear to rewrite all packets
received as coming from a single unbound sender.
Signed-off-by: Dan Smith <danms at us.ibm.com>
---
net/unix/checkpoint.c | 41 +++++++++++++++++++++++++++--------------
1 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/net/unix/checkpoint.c b/net/unix/checkpoint.c
index eb19e66..a499246 100644
--- a/net/unix/checkpoint.c
+++ b/net/unix/checkpoint.c
@@ -118,7 +118,8 @@ int sock_unix_checkpoint(struct ckpt_ctx *ctx,
return ret;
}
-static int sock_read_buffer_sendmsg(struct ckpt_ctx *ctx, struct sock *sock)
+static int sock_read_buffer_sendmsg(struct ckpt_ctx *ctx, struct sock *sock,
+ struct sockaddr *addr, unsigned int alen)
{
struct msghdr msg;
struct kvec kvec;
@@ -146,6 +147,11 @@ static int sock_read_buffer_sendmsg(struct ckpt_ctx *ctx, struct sock *sock)
if (ret < 0)
goto out;
+ if (addr) {
+ msg.msg_name = addr;
+ msg.msg_namelen = alen;
+ }
+
ret = kernel_sendmsg(sock->sk_socket, &msg, &kvec, 1, len);
ckpt_debug("kernel_sendmsg(%i): %i\n", len, ret);
if ((ret > 0) && (ret != len))
@@ -158,7 +164,8 @@ static int sock_read_buffer_sendmsg(struct ckpt_ctx *ctx, struct sock *sock)
static int sock_unix_read_buffers(struct ckpt_ctx *ctx,
struct sock *sock,
- uint32_t *bufsize)
+ uint32_t *bufsize,
+ struct ckpt_hdr_socket_unix *un)
{
uint8_t sock_shutdown;
struct ckpt_hdr_socket_queue *h;
@@ -174,7 +181,16 @@ static int sock_unix_read_buffers(struct ckpt_ctx *ctx,
sock->sk_shutdown &= ~SHUTDOWN_MASK;
for (i = 0; i < h->skb_count; i++) {
- ret = sock_read_buffer_sendmsg(ctx, sock);
+ struct sockaddr *addr = NULL;
+ unsigned int len = un->laddr_len;
+
+ /* If we don't have a real peer, then we're not connected,
+ * and thus need to send this to a specific address
+ */
+ if (!un->peer)
+ addr = (struct sockaddr *)&un->laddr;
+
+ ret = sock_read_buffer_sendmsg(ctx, sock, addr, len);
ckpt_debug("read_buffer_sendmsg(%i): %i\n", i, ret);
if (ret < 0)
break;
@@ -283,10 +299,12 @@ static int sock_unix_restore_connected(struct ckpt_ctx *ctx,
if (ret < 0)
goto out;
- ret = sock_unix_join(ctx, this, peer, un);
- ckpt_debug("sock_unix_join: %i\n", ret);
- if (ret)
- goto out;
+ if (h->sock.state == TCP_ESTABLISHED) {
+ ret = sock_unix_join(ctx, this, peer, un);
+ ckpt_debug("sock_unix_join: %i\n", ret);
+ if (ret)
+ goto out;
+ }
} else {
ckpt_debug("Order Error\n");
@@ -314,18 +332,13 @@ static int sock_unix_restore_connected(struct ckpt_ctx *ctx,
peer->sk_sndbuf = sysctl_wmem_max;
/* Read my buffers and sendmsg() them back to me via my peer */
-
- /* TODO: handle the unconnected case, as well, as the case
- * where sendto() has been used on some of the buffers
- */
-
- ret = sock_unix_read_buffers(ctx, peer, &peer->sk_sndbuf);
+ ret = sock_unix_read_buffers(ctx, peer, &peer->sk_sndbuf, un);
ckpt_debug("sock_unix_read_buffers: %i\n", ret);
if (ret)
goto out;
/* Read peer's buffers and expect 0 */
- ret = sock_unix_read_buffers(ctx, peer, NULL);
+ ret = sock_unix_read_buffers(ctx, peer, NULL, un);
out:
if (tmp && ret)
sock_release(tmp);
--
1.6.0.4
_______________________________________________
Containers mailing list
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
More information about the Devel
mailing list