mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-22 09:58:09 +00:00
shmem: Move shmem dumping code to shmem.c
This is also a code move plus two changes: * shmems renamed to dump_shmems * shmem area size is shared with restorer (it's one page for both for now) Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
parent
bc75b0f253
commit
26a53837f9
135
cr-dump.c
135
cr-dump.c
@ -35,6 +35,7 @@
|
||||
#include "parasite-syscall.h"
|
||||
#include "files.h"
|
||||
#include "pipes.h"
|
||||
#include "shmem.h"
|
||||
#include "sk-inet.h"
|
||||
|
||||
#ifndef CONFIG_X86_64
|
||||
@ -568,59 +569,6 @@ static int dump_task_fs(pid_t pid, struct cr_fdset *fdset)
|
||||
return write_img(fdset_fd(fdset, CR_FD_FS), &fe);
|
||||
}
|
||||
|
||||
struct shmem_info
|
||||
{
|
||||
unsigned long size;
|
||||
unsigned long shmid;
|
||||
unsigned long start;
|
||||
unsigned long end;
|
||||
int pid;
|
||||
};
|
||||
|
||||
static int nr_shmems;
|
||||
static struct shmem_info *shmems;
|
||||
|
||||
#define SHMEMS_SIZE 4096
|
||||
|
||||
static struct shmem_info* shmem_find(unsigned long shmid)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_shmems; i++)
|
||||
if (shmems[i].shmid == shmid)
|
||||
return &shmems[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int add_shmem_area(pid_t pid, struct vma_entry *vma)
|
||||
{
|
||||
struct shmem_info *si;
|
||||
unsigned long size = vma->pgoff + (vma->end - vma->start);
|
||||
|
||||
si = shmem_find(vma->shmid);
|
||||
if (si) {
|
||||
if (si->size < size)
|
||||
si->size = size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
nr_shmems++;
|
||||
if (nr_shmems * sizeof(*si) == SHMEMS_SIZE) {
|
||||
pr_err("OOM storing shmems\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
si = &shmems[nr_shmems - 1];
|
||||
si->size = size;
|
||||
si->pid = pid;
|
||||
si->start = vma->start;
|
||||
si->end = vma->end;
|
||||
si->shmid = vma->shmid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dump_filemap(pid_t pid, struct vma_entry *vma, int file_fd,
|
||||
const struct cr_fdset *fdset)
|
||||
{
|
||||
@ -1682,81 +1630,6 @@ err_cure:
|
||||
goto err;
|
||||
}
|
||||
|
||||
static int cr_dump_shmem(void)
|
||||
{
|
||||
int err, fd;
|
||||
struct cr_fdset *cr_fdset = NULL;
|
||||
unsigned char *map = NULL;
|
||||
void *addr = NULL;
|
||||
struct shmem_info *si;
|
||||
unsigned long pfn, nrpages;
|
||||
|
||||
for (si = shmems; si < &shmems[nr_shmems]; si++) {
|
||||
pr_info("Dumping shared memory 0x%lx\n", si->shmid);
|
||||
|
||||
nrpages = (si->size + PAGE_SIZE -1) / PAGE_SIZE;
|
||||
map = xmalloc(nrpages * sizeof(*map));
|
||||
if (!map)
|
||||
goto err;
|
||||
|
||||
fd = open_proc(si->pid, "map_files/%lx-%lx", si->start, si->end);
|
||||
if (fd < 0)
|
||||
goto err;
|
||||
|
||||
addr = mmap(NULL, si->size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
close(fd);
|
||||
if (addr == MAP_FAILED) {
|
||||
pr_err("Can't map shmem 0x%lx (0x%lx-0x%lx)\n",
|
||||
si->shmid, si->start, si->end);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't use pagemap here, because this vma is
|
||||
* not mapped to us at all, but mincore reports the
|
||||
* pagecache status of a file, which is correct in
|
||||
* this case.
|
||||
*/
|
||||
|
||||
err = mincore(addr, si->size, map);
|
||||
if (err)
|
||||
goto err_unmap;
|
||||
|
||||
fd = open_image(CR_FD_SHMEM_PAGES, O_DUMP, si->shmid);
|
||||
if (fd < 0)
|
||||
goto err_unmap;
|
||||
|
||||
for (pfn = 0; pfn < nrpages; pfn++) {
|
||||
u64 offset = pfn * PAGE_SIZE;
|
||||
|
||||
if (!(map[pfn] & PAGE_RSS))
|
||||
continue;
|
||||
|
||||
if (write_img_buf(fd, &offset, sizeof(offset)))
|
||||
break;
|
||||
if (write_img_buf(fd, addr + offset, PAGE_SIZE))
|
||||
break;
|
||||
}
|
||||
|
||||
if (pfn != nrpages)
|
||||
goto err_close;
|
||||
|
||||
close(fd);
|
||||
munmap(addr, si->size);
|
||||
xfree(map);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_close:
|
||||
close(fd);
|
||||
err_unmap:
|
||||
munmap(addr, si->size);
|
||||
err:
|
||||
xfree(map);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cr_dump_tasks(pid_t pid, const struct cr_options *opts)
|
||||
{
|
||||
LIST_HEAD(pstree_list);
|
||||
@ -1788,9 +1661,7 @@ int cr_dump_tasks(pid_t pid, const struct cr_options *opts)
|
||||
if (!glob_fdset)
|
||||
goto err;
|
||||
|
||||
nr_shmems = 0;
|
||||
shmems = xmalloc(SHMEMS_SIZE);
|
||||
if (!shmems)
|
||||
if (init_shmem_dump())
|
||||
goto err;
|
||||
|
||||
if (init_pipes_dump())
|
||||
@ -1814,7 +1685,7 @@ int cr_dump_tasks(pid_t pid, const struct cr_options *opts)
|
||||
|
||||
fd_id_show_tree();
|
||||
err:
|
||||
xfree(shmems);
|
||||
fini_shmem_dump();
|
||||
fini_pipes_dump();
|
||||
close_cr_fdset(&glob_fdset);
|
||||
|
||||
|
@ -8,4 +8,9 @@ int get_shmem_fd(int pid, struct vma_entry *vi);
|
||||
|
||||
struct shmems;
|
||||
extern struct shmems *rst_shmems;
|
||||
|
||||
int cr_dump_shmem(void);
|
||||
int add_shmem_area(pid_t pid, struct vma_entry *vma);
|
||||
int init_shmem_dump(void);
|
||||
void fini_shmem_dump(void);
|
||||
#endif
|
||||
|
138
shmem.c
138
shmem.c
@ -223,3 +223,141 @@ int prepare_shmem_restore(void)
|
||||
rst_shmems->nr_shmems = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct shmem_info_dump
|
||||
{
|
||||
unsigned long size;
|
||||
unsigned long shmid;
|
||||
unsigned long start;
|
||||
unsigned long end;
|
||||
int pid;
|
||||
};
|
||||
|
||||
static int nr_shmems;
|
||||
static struct shmem_info_dump *dump_shmems;
|
||||
|
||||
static struct shmem_info_dump* shmem_find(unsigned long shmid)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_shmems; i++)
|
||||
if (dump_shmems[i].shmid == shmid)
|
||||
return &dump_shmems[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int add_shmem_area(pid_t pid, struct vma_entry *vma)
|
||||
{
|
||||
struct shmem_info_dump *si;
|
||||
unsigned long size = vma->pgoff + (vma->end - vma->start);
|
||||
|
||||
si = shmem_find(vma->shmid);
|
||||
if (si) {
|
||||
if (si->size < size)
|
||||
si->size = size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
nr_shmems++;
|
||||
if (nr_shmems * sizeof(*si) == SHMEMS_SIZE) {
|
||||
pr_err("OOM storing shmems\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
si = &dump_shmems[nr_shmems - 1];
|
||||
si->size = size;
|
||||
si->pid = pid;
|
||||
si->start = vma->start;
|
||||
si->end = vma->end;
|
||||
si->shmid = vma->shmid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cr_dump_shmem(void)
|
||||
{
|
||||
int err, fd;
|
||||
struct cr_fdset *cr_fdset = NULL;
|
||||
unsigned char *map = NULL;
|
||||
void *addr = NULL;
|
||||
struct shmem_info_dump *si;
|
||||
unsigned long pfn, nrpages;
|
||||
|
||||
for (si = dump_shmems; si < &dump_shmems[nr_shmems]; si++) {
|
||||
pr_info("Dumping shared memory 0x%lx\n", si->shmid);
|
||||
|
||||
nrpages = (si->size + PAGE_SIZE -1) / PAGE_SIZE;
|
||||
map = xmalloc(nrpages * sizeof(*map));
|
||||
if (!map)
|
||||
goto err;
|
||||
|
||||
fd = open_proc(si->pid, "map_files/%lx-%lx", si->start, si->end);
|
||||
if (fd < 0)
|
||||
goto err;
|
||||
|
||||
addr = mmap(NULL, si->size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
close(fd);
|
||||
if (addr == MAP_FAILED) {
|
||||
pr_err("Can't map shmem 0x%lx (0x%lx-0x%lx)\n",
|
||||
si->shmid, si->start, si->end);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't use pagemap here, because this vma is
|
||||
* not mapped to us at all, but mincore reports the
|
||||
* pagecache status of a file, which is correct in
|
||||
* this case.
|
||||
*/
|
||||
|
||||
err = mincore(addr, si->size, map);
|
||||
if (err)
|
||||
goto err_unmap;
|
||||
|
||||
fd = open_image(CR_FD_SHMEM_PAGES, O_DUMP, si->shmid);
|
||||
if (fd < 0)
|
||||
goto err_unmap;
|
||||
|
||||
for (pfn = 0; pfn < nrpages; pfn++) {
|
||||
u64 offset = pfn * PAGE_SIZE;
|
||||
|
||||
if (!(map[pfn] & PAGE_RSS))
|
||||
continue;
|
||||
|
||||
if (write_img_buf(fd, &offset, sizeof(offset)))
|
||||
break;
|
||||
if (write_img_buf(fd, addr + offset, PAGE_SIZE))
|
||||
break;
|
||||
}
|
||||
|
||||
if (pfn != nrpages)
|
||||
goto err_close;
|
||||
|
||||
close(fd);
|
||||
munmap(addr, si->size);
|
||||
xfree(map);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_close:
|
||||
close(fd);
|
||||
err_unmap:
|
||||
munmap(addr, si->size);
|
||||
err:
|
||||
xfree(map);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int init_shmem_dump(void)
|
||||
{
|
||||
nr_shmems = 0;
|
||||
dump_shmems = xmalloc(SHMEMS_SIZE);
|
||||
return dump_shmems == NULL ? -1 : 0;
|
||||
}
|
||||
|
||||
void fini_shmem_dump(void)
|
||||
{
|
||||
xfree(dump_shmems);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user