Commit dd0f72f2 authored by Stanislav Kinsbursky's avatar Stanislav Kinsbursky Committed by Cyrill Gorcunov

restore: IPv4 listening sockets restore support

This patch adds support for restoring IPv4 listening sockets.
Based on unix sockets restore.
Signed-off-by: 's avatarStanislav Kinsbursky <skinsbursky@parallels.com>
Acked-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent 7fc6561c
...@@ -965,10 +965,98 @@ err: ...@@ -965,10 +965,98 @@ err:
return ret; return ret;
} }
static int open_inet_sk(struct inet_sk_entry *ie, int *img_fd)
{
int sk;
struct sockaddr_in addr;
show_one_inet_img("Restore", ie);
if (ie->family != AF_INET) {
pr_err("Unsupported socket family: %d\n", ie->family);
goto err;
}
if (ie->type != SOCK_STREAM) {
pr_err("Unsupported socket type: %d\n", ie->type);
goto err;
}
sk = socket(ie->family, ie->type, ie->proto);
if (sk < 0) {
pr_perror("Can't create unix socket\n");
return -1;
}
/*
* Listen sockets are easiest ones -- simply
* bind() and listen(), and that's all.
*/
memset(&addr, 0, sizeof(addr));
addr.sin_family = ie->family;
addr.sin_port = htons(ie->src_port);
memcpy(&addr.sin_addr.s_addr, ie->src_addr, sizeof(unsigned int) * 4);
if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
pr_err("Inet socket bind failed");
goto err;
}
if (listen(sk, ie->backlog) == -1) {
pr_err ("listen() failed %m");
goto err;
}
if (move_img_fd(img_fd, ie->fd))
return -1;
return reopen_fd_as(ie->fd, sk);
err:
close(sk);
return -1;
}
static int prepare_inet_sockets(int pid)
{
int isk_fd, ret = -1;
isk_fd = open_image_ro(CR_FD_INETSK, pid);
if (isk_fd < 0)
return -1;
while (1) {
struct inet_sk_entry ie;
ret = read(isk_fd, &ie, sizeof(ie));
if (ret == 0)
break;
if (ret != sizeof(ie)) {
pr_perror("%d: Bad inet sk entry (ret %d)\n", pid, ret);
ret = -1;
break;
}
ret = open_inet_sk(&ie, &isk_fd);
if (ret)
break;
}
close(isk_fd);
return ret;
}
int prepare_sockets(int pid) int prepare_sockets(int pid)
{ {
int err;
pr_info("%d: Opening sockets\n", pid); pr_info("%d: Opening sockets\n", pid);
return prepare_unix_sockets(pid); err = prepare_unix_sockets(pid);
if (err)
return err;
return prepare_inet_sockets(pid);
} }
void show_inetsk(int fd) void show_inetsk(int fd)
......
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