diff --git a/cr-restore.c b/cr-restore.c index 4ef8c5ef2..e70c50974 100644 --- a/cr-restore.c +++ b/cr-restore.c @@ -1628,12 +1628,13 @@ static int prepare_creds(int pid, struct task_restore_core_args *args) static void sigreturn_restore(pid_t pid) { long restore_code_len, restore_task_vma_len; - long restore_thread_vma_len; + long restore_thread_vma_len, self_vmas_len; void *mem = MAP_FAILED; void *restore_thread_exec_start; void *restore_task_exec_start; void *restore_code_start; + struct vma_entry *self_vma; long new_sp, exec_mem_hint; long ret; @@ -1641,14 +1642,11 @@ static void sigreturn_restore(pid_t pid) struct task_restore_core_args *task_args; struct thread_restore_args *thread_args; - char self_vmas_path[PATH_MAX]; - LIST_HEAD(self_vma_list); struct vma_area *vma_area; - int fd_self_vmas = -1; int fd_fdinfo = -1; int fd_core = -1; - int num, i; + int i; int *fd_core_threads; @@ -1663,6 +1661,8 @@ static void sigreturn_restore(pid_t pid) if (ret < 0) goto err; + self_vmas_len = (ret + 1) * sizeof(*self_vma); + /* pr_info_vma_list(&self_vma_list); */ BUILD_BUG_ON(sizeof(struct task_restore_core_args) & 1); @@ -1682,33 +1682,6 @@ static void sigreturn_restore(pid_t pid) goto err; } - if (get_image_path(self_vmas_path, sizeof(self_vmas_path), - FMT_FNAME_VMAS, pid)) - goto err; - - fd_self_vmas = open(self_vmas_path, O_CREAT | O_RDWR | O_TRUNC, CR_FD_PERM); - - /* - * This is a temporary file used to pass vma info to - * restorer code, thus unlink it early to make it disappear - * as soon as we close it - */ - // unlink(self_vmas_path); - - if (fd_self_vmas < 0) { - pr_perror("Can't open %s", self_vmas_path); - goto err; - } - - num = 0; - list_for_each_entry(vma_area, &self_vma_list, list) { - ret = write(fd_self_vmas, &vma_area->vma, sizeof(vma_area->vma)); - if (ret != sizeof(vma_area->vma)) { - pr_perror("\nUnable to write vma entry (%d written)", num); - goto err; - } - num++; - } restore_code_len = sizeof(restorer_blob); restore_code_len = round_up(restore_code_len, 16); @@ -1738,6 +1711,7 @@ static void sigreturn_restore(pid_t pid) exec_mem_hint = restorer_get_vma_hint(pid, &self_vma_list, restore_task_vma_len + restore_thread_vma_len + + self_vmas_len + SHMEMS_SIZE + TASK_ENTRIES_SIZE); if (exec_mem_hint == -1) { pr_err("No suitable area for task_restore bootstrap (%ldK)\n", @@ -1748,8 +1722,6 @@ static void sigreturn_restore(pid_t pid) pr_info("Found bootstrap VMA hint at: %lx (needs ~%ldK)\n", exec_mem_hint, KBYTES(restore_task_vma_len + restore_thread_vma_len)); - free_mappings(&self_vma_list); - /* VMA we need to run task_restore code */ mem = mmap((void *)exec_mem_hint, restore_task_vma_len + restore_thread_vma_len, @@ -1806,12 +1778,28 @@ static void sigreturn_restore(pid_t pid) goto err; task_args->task_entries = mem; + mem += TASK_ENTRIES_SIZE; + self_vma = mmap(mem, self_vmas_len, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON | MAP_FIXED, 0, 0); + if (self_vma != mem) { + pr_perror("Can't map self vmas"); + goto err; + } + task_args->self_vmas = self_vma; + + list_for_each_entry(vma_area, &self_vma_list, list) { + *self_vma = vma_area->vma; + self_vma++; + } + + self_vma->start = 0; + free_mappings(&self_vma_list); + /* * Arguments for task restoration. */ task_args->pid = pid; task_args->fd_core = fd_core; - task_args->fd_self_vmas = fd_self_vmas; task_args->logfd = log_get_fd(); task_args->sigchld_act = sigchld_act; task_args->fd_fdinfo = fd_fdinfo; @@ -1860,13 +1848,13 @@ static void sigreturn_restore(pid_t pid) pr_info("task_args: %p\n" "task_args->pid: %d\n" "task_args->fd_core: %d\n" - "task_args->fd_self_vmas: %d\n" "task_args->nr_threads: %d\n" "task_args->clone_restore_fn: %p\n" "task_args->thread_args: %p\n", task_args, task_args->pid, - task_args->fd_core, task_args->fd_self_vmas, - task_args->nr_threads, task_args->clone_restore_fn, + task_args->fd_core, + task_args->nr_threads, + task_args->clone_restore_fn, task_args->thread_args); /* @@ -1889,7 +1877,6 @@ err: free_mappings(&self_vma_list); close_safe(&fd_core); close_safe(&fd_fdinfo); - close_safe(&fd_self_vmas); /* Just to be sure */ exit(1); diff --git a/include/crtools.h b/include/crtools.h index ac4f03ab8..795626f3f 100644 --- a/include/crtools.h +++ b/include/crtools.h @@ -72,7 +72,6 @@ extern struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX]; #define FMT_FNAME_PIPES "pipes-%d.img" #define FMT_FNAME_PSTREE "pstree-%d.img" #define FMT_FNAME_SHMEM "shmem-%d.img" -#define FMT_FNAME_VMAS "vmas-%d.img" #define FMT_FNAME_SIGACTS "sigacts-%d.img" #define FMT_FNAME_UNIXSK "unixsk-%d.img" #define FMT_FNAME_INETSK "inetsk-%d.img" diff --git a/include/restorer.h b/include/restorer.h index e0ecf6bb6..a84147b7a 100644 --- a/include/restorer.h +++ b/include/restorer.h @@ -66,7 +66,6 @@ struct task_restore_core_args { int pid; /* task pid */ int fd_core; /* opened core file */ int fd_fdinfo; /* opened files dump file */ - int fd_self_vmas; /* opened file with running VMAs to unmap */ int logfd; bool restore_threads; /* if to restore threads */ u32 rst_lock; @@ -77,6 +76,7 @@ struct task_restore_core_args { struct thread_restore_args *thread_args; /* array of thread arguments */ struct shmems *shmems; struct task_entries *task_entries; + struct vma_entry *self_vmas; rt_sigaction_t sigchld_act; struct itimerval itimers[3]; diff --git a/restorer.c b/restorer.c index ecffd7e5b..ecd423a63 100644 --- a/restorer.c +++ b/restorer.c @@ -355,7 +355,6 @@ long restore_task(struct task_restore_core_args *args) restorer_set_logfd(args->logfd); core_entry = first_on_heap(core_entry, args->mem_zone.heap); - vma_entry = next_on_heap(vma_entry, core_entry); #if 0 write_hex_n((long)args); @@ -371,18 +370,7 @@ long restore_task(struct task_restore_core_args *args) goto core_restore_end; } - /* Note no magic constant on fd_self_vmas */ - ret = sys_lseek(args->fd_self_vmas, 0, SEEK_SET); - while (1) { - ret = sys_read(args->fd_self_vmas, vma_entry, sizeof(*vma_entry)); - if (!ret) - break; - if (ret != sizeof(*vma_entry)) { - write_num_n(__LINE__); - write_num_n(ret); - goto core_restore_end; - } - + for (vma_entry = args->self_vmas; vma_entry->start != 0; vma_entry++) { if (!vma_entry_is(vma_entry, VMA_AREA_REGULAR)) continue; @@ -392,11 +380,13 @@ long restore_task(struct task_restore_core_args *args) } } - sys_close(args->fd_self_vmas); + sys_munmap(args->self_vmas, + ((void *)(vma_entry + 1) - ((void *)args->self_vmas))); /* * OK, lets try to map new one. */ + vma_entry = next_on_heap(vma_entry, core_entry); sys_lseek(args->fd_core, GET_FILE_OFF_AFTER(struct core_entry), SEEK_SET); while (1) { ret = sys_read(args->fd_core, vma_entry, sizeof(*vma_entry));