mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-29 05:18:00 +00:00
restore: socket queues support
This patch was designed to be generic and thus usable for all kinds of sockets. Not sure, thah this goal has been reached, but at least I tried. Key ideas: 1) sockets queue dump file have to be readed first and then packets entries with offset for it's data in image will be collected in doubly linked list by read_sockets_queue() function. Note: list will contain sockets queues for all (!) the sockets of the task. 2) socket queue can be restored by restore_socket_queue(), which selects packets from the list by passed id and use sendfile() top send them to the passed socket. It also removes packet from the list and frees it. Based on xemul@ patches. Signed-off-by: Stanislav Kinsbursky <skinsbursky@openvz.org> Acked-by: Pavel Emelyanov <xemul@parallels.com> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
This commit is contained in:
parent
c19012326d
commit
e6f39a41bf
76
sockets.c
76
sockets.c
@ -12,6 +12,7 @@
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/sendfile.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "libnetlink.h"
|
||||
@ -675,6 +676,81 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
struct sk_packet {
|
||||
struct list_head list;
|
||||
struct sk_packet_entry entry;
|
||||
off_t img_off;
|
||||
};
|
||||
|
||||
struct sk_packets_pool {
|
||||
struct list_head packets_list;
|
||||
int img_fd;
|
||||
};
|
||||
|
||||
static int read_sockets_queues(struct sk_packets_pool *pool)
|
||||
{
|
||||
struct sk_packet *pkt;
|
||||
int ret;
|
||||
|
||||
pr_info("Trying to read socket queues image\n");
|
||||
|
||||
lseek(pool->img_fd, MAGIC_OFFSET, SEEK_SET);
|
||||
while (1) {
|
||||
struct sk_packet_entry tmp;
|
||||
|
||||
pkt = xmalloc(sizeof(*pkt));
|
||||
if (!pkt) {
|
||||
pr_err("Failed to allocate packet header\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
ret = read_img_eof(pool->img_fd, &pkt->entry);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
pkt->img_off = lseek(pool->img_fd, 0, SEEK_CUR);
|
||||
/*
|
||||
* NOTE: packet must be added to the tail. Otherwise sequence
|
||||
* will be broken.
|
||||
*/
|
||||
list_add_tail(&pkt->list, &pool->packets_list);
|
||||
lseek(pool->img_fd, pkt->entry.length, SEEK_CUR);
|
||||
}
|
||||
xfree(pkt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int restore_socket_queue(struct sk_packets_pool *pool, int fd,
|
||||
unsigned int peer_id)
|
||||
{
|
||||
struct sk_packet *pkt, *tmp;
|
||||
int ret;
|
||||
|
||||
pr_info("Trying to restore recv queue for %u\n", peer_id);
|
||||
|
||||
list_for_each_entry_safe(pkt, tmp, &pool->packets_list, list) {
|
||||
struct sk_packet_entry *entry = &pkt->entry;
|
||||
|
||||
if (entry->id_for != peer_id)
|
||||
continue;
|
||||
|
||||
pr_info("\tRestoring %d-bytes skb for %u\n",
|
||||
entry->length, peer_id);
|
||||
|
||||
ret = sendfile(fd, pool->img_fd, &pkt->img_off, entry->length);
|
||||
if (ret < 0) {
|
||||
pr_perror("Failed to sendfile packet");
|
||||
return -1;
|
||||
}
|
||||
if (ret != entry->length) {
|
||||
pr_err("Restored skb trimmed to %d/%d\n",
|
||||
ret, entry->length);
|
||||
return -1;
|
||||
}
|
||||
list_del(&pkt->list);
|
||||
xfree(pkt);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void prep_conn_addr(int id, struct sockaddr_un *addr, int *addrlen)
|
||||
{
|
||||
addr->sun_family = AF_UNIX;
|
||||
|
Loading…
x
Reference in New Issue
Block a user