Commit 0fa83b03 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

socket: increase socket buffers for restoring queues (v2)

Sizes of send and recv buffers are set to maximum to restore queues,
after that sizes of buffers are restored.

O_NONBLOCK is set to a socket to prevent blocking during restore.

#2411

v2: do the same for unix sockets.
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 9f8ef2b8
......@@ -30,6 +30,7 @@ extern int dump_socket(struct fd_parms *p, int lfd, const struct cr_fdset *cr_fd
extern int dump_socket_opts(int sk, SkOptsEntry *soe);
extern int restore_socket_opts(int sk, SkOptsEntry *soe);
extern void release_skopts(SkOptsEntry *);
extern int restore_prepare_socket(int sk);
extern int sk_collect_one(int ino, int family, struct socket_desc *d);
extern int collect_sockets(int pid);
......
......@@ -16,6 +16,7 @@
#include "crtools.h"
#include "util.h"
#include "util-net.h"
#include "sockets.h"
#include "sk-queue.h"
......@@ -189,19 +190,12 @@ void show_sk_queues(int fd, struct cr_options *o)
int restore_sk_queue(int fd, unsigned int peer_id)
{
struct sk_packet *pkt, *tmp;
int ret, img_fd, flags;
int ret, img_fd;
pr_info("Trying to restore recv queue for %u\n", peer_id);
flags = fcntl(fd, F_GETFL, 0);
if (flags == -1) {
pr_perror("Unable to get flags for %d", fd);
if (restore_prepare_socket(fd))
return -1;
}
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) ) {
pr_perror("Unable to set O_NONBLOCK for %d", fd);
return -1;
}
img_fd = open_image_ro(CR_FD_SK_QUEUES);
if (img_fd < 0)
......@@ -255,11 +249,6 @@ int restore_sk_queue(int fd, unsigned int peer_id)
xfree(pkt);
}
if (fcntl(fd, F_SETFL, flags) ) {
pr_perror("Unable to restore flags for %d", fd);
goto err;
}
close(img_fd);
return 0;
err:
......
......@@ -379,6 +379,9 @@ static int send_tcp_queue(int sk, int queue, u32 len, int imgfd)
static int restore_tcp_queues(int sk, TcpStreamEntry *tse, int fd)
{
if (restore_prepare_socket(sk))
return -1;
if (tse->inq_len &&
send_tcp_queue(sk, TCP_RECV_QUEUE, tse->inq_len, fd))
return -1;
......
......@@ -204,6 +204,38 @@ int do_restore_opt(int sk, int level, int name, void *val, int len)
return 0;
}
/*
* Set sizes of buffers to maximum and prevent blocking
* Caller of this fn should call other socket restoring
* routines to drop the non-blocking and set proper send
* and receive buffers.
*/
int restore_prepare_socket(int sk)
{
int flags;
/* In kernel a bufsize has type int and a value is doubled. */
u32 maxbuf = INT_MAX / 2;
if (restore_opt(sk, SOL_SOCKET, SO_SNDBUFFORCE, &maxbuf))
return -1;
if (restore_opt(sk, SOL_SOCKET, SO_RCVBUFFORCE, &maxbuf))
return -1;
/* Prevent blocking on restore */
flags = fcntl(sk, F_GETFL, 0);
if (flags == -1) {
pr_perror("Unable to get flags for %d", sk);
return -1;
}
if (fcntl(sk, F_SETFL, flags | O_NONBLOCK) ) {
pr_perror("Unable to set O_NONBLOCK for %d", sk);
return -1;
}
return 0;
}
int restore_socket_opts(int sk, SkOptsEntry *soe)
{
int ret = 0, val;
......
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