2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-31 06:15:24 +00:00

aio: Dump AIO rings

When AIO context is set up kernel does two things:

1. creates an in-kernel aioctx object
2. maps a ring into process memory

The 2nd thing gives us all the needed information
about how the AIO was set up. So, in order to dump
one we need to pick the ring in memory and get all
the information we need from it.

One thing to note -- we cannot dump tasks if there
are any AIO requests pending. So we also need to
go to parasite and check the ring to be empty.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
Pavel Emelyanov
2014-12-19 16:01:54 +03:00
parent 80cf042695
commit 08c204820f
11 changed files with 266 additions and 8 deletions

View File

@@ -43,6 +43,12 @@ static char *buf = __buf.buf;
#define BUF_SIZE sizeof(__buf.buf)
/*
* This is how AIO ring buffers look like in proc
*/
#define AIO_FNAME "/[aio]"
int parse_cpuinfo_features(int (*handler)(char *tok))
{
FILE *cpuinfo;
@@ -191,7 +197,7 @@ static inline int vfi_equal(struct vma_file_info *a, struct vma_file_info *b)
(a->dev_min ^ b->dev_min)) == 0;
}
static int vma_get_mapfile(struct vma_area *vma, DIR *mfd,
static int vma_get_mapfile(char *fname, struct vma_area *vma, DIR *mfd,
struct vma_file_info *vfi, struct vma_file_info *prev_vfi)
{
char path[32];
@@ -244,13 +250,22 @@ static int vma_get_mapfile(struct vma_area *vma, DIR *mfd,
if (fstatat(dirfd(mfd), path, &buf, 0))
return -1;
if (!S_ISSOCK(buf.st_mode))
return -1;
if (S_ISSOCK(buf.st_mode)) {
pr_info("Found socket mapping @%"PRIx64"\n", vma->e->start);
vma->vm_socket_id = buf.st_ino;
vma->e->status |= VMA_AREA_SOCKET | VMA_AREA_REGULAR;
return 0;
}
vma->vm_socket_id = buf.st_ino;
pr_info("Found socket mapping @%"PRIx64"\n", vma->e->start);
vma->e->status |= VMA_AREA_SOCKET | VMA_AREA_REGULAR;
return 0;
if ((buf.st_mode & S_IFMT) == 0 && !strcmp(fname, AIO_FNAME)) {
/* AIO ring, let's try */
close(vma->vm_file_fd);
vma->aio_nr_req = -1;
vma->e->status = VMA_AREA_AIORING;
return 0;
}
pr_err("Unknown shit %o (%s)\n", buf.st_mode, fname);
}
return -1;
@@ -325,6 +340,7 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list)
struct bfd f;
vma_area_list->nr = 0;
vma_area_list->nr_aios = 0;
vma_area_list->longest = 0;
vma_area_list->priv_size = 0;
INIT_LIST_HEAD(&vma_area_list->h);
@@ -417,7 +433,7 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list)
vma_area->e->pgoff = pgoff;
vma_area->e->prot = PROT_NONE;
if (vma_get_mapfile(vma_area, map_files_dir, &vfi, &prev_vfi))
if (vma_get_mapfile(file_path, vma_area, map_files_dir, &vfi, &prev_vfi))
goto err_bogus_mapfile;
if (r == 'r')
@@ -437,6 +453,8 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list)
}
if (vma_area->e->status != 0) {
if (vma_area->e->status & VMA_AREA_AIORING)
vma_area_list->nr_aios++;
continue;
} else if (!strcmp(file_path, "[vsyscall]") ||
!strcmp(file_path, "[vectors]")) {