Commit 02fc8695 authored by Pavel Emelyanov's avatar Pavel Emelyanov

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: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 8801f596
...@@ -41,6 +41,7 @@ obj-y += tty.o ...@@ -41,6 +41,7 @@ obj-y += tty.o
obj-y += cr-exec.o obj-y += cr-exec.o
obj-y += file-lock.o obj-y += file-lock.o
obj-y += page-pipe.o obj-y += page-pipe.o
obj-y += page-xfer.o
ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),clean)
incdeps := y incdeps := y
......
#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
#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 @@ ...@@ -23,6 +23,7 @@
#include "pstree.h" #include "pstree.h"
#include "net.h" #include "net.h"
#include "page-pipe.h" #include "page-pipe.h"
#include "page-xfer.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -549,11 +550,12 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, int vpid, ...@@ -549,11 +550,12 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, int vpid,
{ {
struct parasite_dump_pages_args *args; struct parasite_dump_pages_args *args;
u64 *map; u64 *map;
int pagemap, fd, fd_pg; int pagemap;
struct page_pipe *pp; struct page_pipe *pp;
struct page_pipe_buf *ppb; struct page_pipe_buf *ppb;
struct vma_area *vma_area; struct vma_area *vma_area;
int ret = -1; int ret = -1;
struct page_xfer xfer;
pr_info("\n"); pr_info("\n");
pr_info("Dumping pages (type: %d pid: %d)\n", CR_FD_PAGES, ctl->pid); 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, ...@@ -604,12 +606,9 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, int vpid,
args->off += args->nr; args->off += args->nr;
} }
fd = open_image(CR_FD_PAGEMAP, O_DUMP, (long)vpid); ret = open_page_xfer(&xfer, CR_FD_PAGEMAP, vpid);
if (fd < 0) if (ret < 0)
goto out_pp; goto out_pp;
fd_pg = open_pages_image(O_DUMP, fd);
if (fd_pg < 0)
goto out_fd;
ret = -1; ret = -1;
list_for_each_entry(ppb, &pp->bufs, l) { list_for_each_entry(ppb, &pp->bufs, l) {
...@@ -618,30 +617,19 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, int vpid, ...@@ -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); pr_debug("Dump pages %d/%d\n", ppb->pages_in, ppb->nr_segs);
for (i = 0; i < ppb->nr_segs; i++) { for (i = 0; i < ppb->nr_segs; i++) {
PagemapEntry pe = PAGEMAP_ENTRY__INIT;
struct iovec *iov = &ppb->iov[i]; 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, pr_debug("\t%p [%u]\n", iov->iov_base,
(unsigned int)(iov->iov_len / PAGE_SIZE)); (unsigned int)(iov->iov_len / PAGE_SIZE));
if (pb_write_one(fd, &pe, PB_PAGEMAP) < 0) if (xfer.write_pagemap(&xfer, iov, ppb->p[0]))
break; goto out_xfer;
if (splice(ppb->p[0], NULL, fd_pg, NULL, iov->iov_len,
SPLICE_F_MOVE) != iov->iov_len)
break;
} }
if (i != ppb->nr_segs)
goto out_fds;
} }
ret = 0; ret = 0;
out_fds: out_xfer:
close(fd_pg); xfer.close(&xfer);
out_fd:
close(fd);
out_pp: out_pp:
destroy_page_pipe(pp); destroy_page_pipe(pp);
out_close: out_close:
......
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