mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 05:48:05 +00:00
mem: Abstraction layer for putting pages into image
We'll send them over network soon, so prepare abstraction layer for this. Shmem is not on this scheme yet. Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
parent
8801f59615
commit
02fc86958e
@ -41,6 +41,7 @@ obj-y += tty.o
|
||||
obj-y += cr-exec.o
|
||||
obj-y += file-lock.o
|
||||
obj-y += page-pipe.o
|
||||
obj-y += page-xfer.o
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
incdeps := y
|
||||
|
13
include/page-xfer.h
Normal file
13
include/page-xfer.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef __CR_PAGE_XFER__H__
|
||||
#define __CR_PAGE_XFER__H__
|
||||
struct page_xfer {
|
||||
int (*write_pagemap)(struct page_xfer *self, struct iovec *iov, int pipe);
|
||||
void (*close)(struct page_xfer *self);
|
||||
int fd;
|
||||
union {
|
||||
int fd_pg;
|
||||
};
|
||||
};
|
||||
|
||||
int open_page_xfer(struct page_xfer *xfer, int fd_type, long id);
|
||||
#endif
|
48
page-xfer.c
Normal file
48
page-xfer.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "crtools.h"
|
||||
#include "page-xfer.h"
|
||||
|
||||
#include "protobuf.h"
|
||||
#include "protobuf/pagemap.pb-c.h"
|
||||
|
||||
static int write_pagemap_loc(struct page_xfer *xfer,
|
||||
struct iovec *iov, int p)
|
||||
{
|
||||
PagemapEntry pe = PAGEMAP_ENTRY__INIT;
|
||||
|
||||
pe.vaddr = encode_pointer(iov->iov_base);
|
||||
pe.nr_pages = iov->iov_len / PAGE_SIZE;
|
||||
|
||||
if (pb_write_one(xfer->fd, &pe, PB_PAGEMAP) < 0)
|
||||
return -1;
|
||||
|
||||
if (splice(p, NULL, xfer->fd_pg, NULL, iov->iov_len,
|
||||
SPLICE_F_MOVE) != iov->iov_len)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void close_page_xfer(struct page_xfer *xfer)
|
||||
{
|
||||
close(xfer->fd_pg);
|
||||
close(xfer->fd);
|
||||
}
|
||||
|
||||
int open_page_xfer(struct page_xfer *xfer, int fd_type, long id)
|
||||
{
|
||||
xfer->fd = open_image(fd_type, O_DUMP, id);
|
||||
if (xfer->fd < 0)
|
||||
return -1;
|
||||
|
||||
xfer->fd_pg = open_pages_image(O_DUMP, xfer->fd);
|
||||
if (xfer->fd_pg < 0) {
|
||||
close(xfer->fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
xfer->write_pagemap = write_pagemap_loc;
|
||||
xfer->close = close_page_xfer;
|
||||
return 0;
|
||||
}
|
@ -23,6 +23,7 @@
|
||||
#include "pstree.h"
|
||||
#include "net.h"
|
||||
#include "page-pipe.h"
|
||||
#include "page-xfer.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@ -549,11 +550,12 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, int vpid,
|
||||
{
|
||||
struct parasite_dump_pages_args *args;
|
||||
u64 *map;
|
||||
int pagemap, fd, fd_pg;
|
||||
int pagemap;
|
||||
struct page_pipe *pp;
|
||||
struct page_pipe_buf *ppb;
|
||||
struct vma_area *vma_area;
|
||||
int ret = -1;
|
||||
struct page_xfer xfer;
|
||||
|
||||
pr_info("\n");
|
||||
pr_info("Dumping pages (type: %d pid: %d)\n", CR_FD_PAGES, ctl->pid);
|
||||
@ -604,12 +606,9 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, int vpid,
|
||||
args->off += args->nr;
|
||||
}
|
||||
|
||||
fd = open_image(CR_FD_PAGEMAP, O_DUMP, (long)vpid);
|
||||
if (fd < 0)
|
||||
ret = open_page_xfer(&xfer, CR_FD_PAGEMAP, vpid);
|
||||
if (ret < 0)
|
||||
goto out_pp;
|
||||
fd_pg = open_pages_image(O_DUMP, fd);
|
||||
if (fd_pg < 0)
|
||||
goto out_fd;
|
||||
|
||||
ret = -1;
|
||||
list_for_each_entry(ppb, &pp->bufs, l) {
|
||||
@ -618,30 +617,19 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, int vpid,
|
||||
pr_debug("Dump pages %d/%d\n", ppb->pages_in, ppb->nr_segs);
|
||||
|
||||
for (i = 0; i < ppb->nr_segs; i++) {
|
||||
PagemapEntry pe = PAGEMAP_ENTRY__INIT;
|
||||
struct iovec *iov = &ppb->iov[i];
|
||||
|
||||
pe.vaddr = encode_pointer(iov->iov_base);
|
||||
pe.nr_pages = iov->iov_len / PAGE_SIZE;
|
||||
|
||||
pr_debug("\t%p [%u]\n", iov->iov_base,
|
||||
(unsigned int)(iov->iov_len / PAGE_SIZE));
|
||||
|
||||
if (pb_write_one(fd, &pe, PB_PAGEMAP) < 0)
|
||||
break;
|
||||
if (splice(ppb->p[0], NULL, fd_pg, NULL, iov->iov_len,
|
||||
SPLICE_F_MOVE) != iov->iov_len)
|
||||
break;
|
||||
if (xfer.write_pagemap(&xfer, iov, ppb->p[0]))
|
||||
goto out_xfer;
|
||||
}
|
||||
|
||||
if (i != ppb->nr_segs)
|
||||
goto out_fds;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out_fds:
|
||||
close(fd_pg);
|
||||
out_fd:
|
||||
close(fd);
|
||||
out_xfer:
|
||||
xfer.close(&xfer);
|
||||
out_pp:
|
||||
destroy_page_pipe(pp);
|
||||
out_close:
|
||||
|
Loading…
x
Reference in New Issue
Block a user