[CRIU] [PATCH 09/12] posix-timer: Add reading image and put it to shared memory
Pavel Tikhomirov
snorcht at gmail.com
Thu Jun 27 12:32:25 EDT 2013
Signed-off-by: Pavel Tikhomirov <snorcht at gmail.com>
---
cr-restore.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 83 insertions(+), 2 deletions(-)
diff --git a/cr-restore.c b/cr-restore.c
index 5ad4bf8..50b4ee1 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1539,6 +1539,61 @@ static inline int posix_timer_restore_and_fix(PosixTimerEntry *pte,
return 0;
}
+static int cmp_posix_timer_proc_id(const void *p1, const void *p2)
+{
+ return ((struct restore_posix_timer *)p1)->spt.it_id - ((struct restore_posix_timer *)p2)->spt.it_id;
+}
+
+static int open_posix_timers_image(int pid, struct restore_posix_timer **rpt,
+ unsigned long *size, int *nr)
+{
+ int fd;
+ int ret = -1;
+
+ fd = open_image(CR_FD_POSIX_TIMERS, O_RSTR, pid);
+ if (fd < 0)
+ return fd;
+
+ while (1) {
+ PosixTimerEntry *pte;
+
+ ret = pb_read_one_eof(fd, &pte, PB_POSIX_TIMERS);
+ if (ret <= 0) {
+ goto out;
+ }
+
+ if ((*nr + 1) * sizeof(struct restore_posix_timer) > *size) {
+ unsigned long new_size = *size + PAGE_SIZE;
+
+ if (*rpt == NULL)
+ *rpt = mmap(NULL, new_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON, 0, 0);
+ else
+ *rpt = mremap(*rpt, *size, new_size, MREMAP_MAYMOVE);
+ if (*rpt == MAP_FAILED) {
+ pr_perror("Can't allocate memory for posix timers");
+ ret = -1;
+ goto out;
+ }
+
+ *size = new_size;
+ }
+
+ ret = posix_timer_restore_and_fix(pte, *rpt + *nr);
+ if (ret < 0)
+ goto out;
+
+ posix_timer_entry__free_unpacked(pte, NULL);
+ (*nr)++;
+ }
+out:
+ if (*nr > 0) {
+ qsort(*rpt, *nr, sizeof(struct restore_posix_timer), cmp_posix_timer_proc_id);
+ }
+ close_safe(&fd);
+ return ret;
+}
+
static inline int verify_cap_size(CredsEntry *ce)
{
return ((ce->n_cap_inh == CR_CAP_SIZE) && (ce->n_cap_eff == CR_CAP_SIZE) &&
@@ -1880,6 +1935,10 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
unsigned long vdso_rt_size = 0;
unsigned long vdso_rt_delta = 0;
+ struct restore_posix_timer *posix_timers_info_chunk = NULL;
+ int posix_timers_nr = 0;
+ unsigned long posix_timers_size = 0;
+
struct vm_area_list self_vmas;
int i;
@@ -1932,13 +1991,22 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
siginfo_priv_nr[i] = ret;
}
+ ret = open_posix_timers_image(pid, &posix_timers_info_chunk,
+ &posix_timers_size, &posix_timers_nr);
+ if (ret < 0) {
+ if (errno != ENOENT) /* backward compatibility */
+ goto err;
+ ret = 0;
+ }
+
restore_bootstrap_len = restorer_len +
restore_task_vma_len +
restore_thread_vma_len +
SHMEMS_SIZE + TASK_ENTRIES_SIZE +
self_vmas_len + vmas_len +
rst_tcp_socks_size +
- siginfo_size;
+ siginfo_size +
+ posix_timers_size;
/*
* Figure out how much memory runtime vdso will need.
@@ -2014,6 +2082,19 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
task_args->siginfo = siginfo_chunk;
siginfo_chunk += task_args->siginfo_nr;
+ mem += siginfo_size;
+ if (posix_timers_info_chunk) {
+ posix_timers_info_chunk = mremap(posix_timers_info_chunk,
+ posix_timers_size, posix_timers_size,
+ MREMAP_FIXED | MREMAP_MAYMOVE, mem);
+ if(posix_timers_info_chunk == MAP_FAILED) {
+ pr_perror("mremap");
+ goto err;
+ }
+ }
+ task_args->timer_n = posix_timers_nr;
+ task_args->posix_timers = posix_timers_info_chunk;
+
/*
* Get a reference to shared memory area which is
* used to signal if shmem restoration complete
@@ -2025,7 +2106,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
* address.
*/
- mem += siginfo_size;
+ mem += posix_timers_size;
ret = shmem_remap(rst_shmems, mem, SHMEMS_SIZE);
if (ret < 0)
goto err;
--
1.7.9.5
More information about the CRIU
mailing list