Commit 20ec5859 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

mem: add a guard page only if here is enough space for it

Currently we don't add a guard page to a second consecutive growsdonw vma,
even if here is enough space for it. It's wrong. Look at the following test
output:

Execute zdtm/live/static/grow_map03
./grow_map03 --pidfile=grow_map03.pid --outfile=grow_map03.out
Dump 3888
Restore
Test: zdtm/live/static/grow_map03, Result: FAIL
==================================== ERROR ====================================
Test: zdtm/live/static/grow_map03, Namespace:
Dump log   : /root/git/criu/test/dump/grow_map03/3888/1/dump.log
--------------------------------- grep Error ---------------------------------
------------------------------------- END -------------------------------------
Restore log: /root/git/criu/test/dump/grow_map03/3888/1/restore.log
--------------------------------- grep Error ---------------------------------
pie: Error (pie/restorer.c:465): Unable to remap 0x7f0da2c99000 -> 0x7f46425fc000
pie: Error (pie/restorer.c:969): Restorer fail 3888
(00.035621) Error (cr-restore.c:1590): Restoring FAILED.
------------------------------------- END -------------------------------------
================================= ERROR OVER =================================

strace:
mremap(0x7fc3de5b6000, 0, 0, MREMAP_MAYMOVE|MREMAP_FIXED, 0x7f38dd4e0000) = -1 EINVAL (Invalid argument)
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 3a9c6a3d
...@@ -272,8 +272,7 @@ static char smaps_buf[PAGE_SIZE]; ...@@ -272,8 +272,7 @@ static char smaps_buf[PAGE_SIZE];
int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list, bool use_map_files) int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list, bool use_map_files)
{ {
struct vma_area *vma_area = NULL; struct vma_area *vma_area = NULL;
unsigned long start, end, pgoff; unsigned long start, end, pgoff, prev_end = 0;
bool prev_growsdown = false;
char r, w, x, s; char r, w, x, s;
int ret = -1; int ret = -1;
struct vma_file_info vfi; struct vma_file_info vfi;
...@@ -327,10 +326,11 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list, bool use_map_file ...@@ -327,10 +326,11 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list, bool use_map_file
} }
if (vma_area) { if (vma_area) {
/* If we've split the stack vma, only the lowest one has the guard page. */ /* Add a guard page only if here is enough space for it */
if ((vma_area->e->flags & MAP_GROWSDOWN) && !prev_growsdown) if ((vma_area->e->flags & MAP_GROWSDOWN) &&
prev_end < vma_area->e->start)
vma_area->e->start -= PAGE_SIZE; /* Guard page */ vma_area->e->start -= PAGE_SIZE; /* Guard page */
prev_growsdown = (bool)(vma_area->e->flags & MAP_GROWSDOWN); prev_end = vma_area->e->end;
list_add_tail(&vma_area->list, &vma_area_list->h); list_add_tail(&vma_area->list, &vma_area_list->h);
vma_area_list->nr++; vma_area_list->nr++;
......
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