Commit 73a8b996 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

restorer: Use rst memory allocator for rlimits restore

Number of rlimits may vary depending on system version
criu is compiled against. So we use rst-allocator to
carry all limits read from file.
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent bd58fce1
...@@ -1888,11 +1888,13 @@ static unsigned long decode_rlim(u_int64_t ival) ...@@ -1888,11 +1888,13 @@ static unsigned long decode_rlim(u_int64_t ival)
return ival == -1 ? RLIM_INFINITY : ival; return ival == -1 ? RLIM_INFINITY : ival;
} }
static int prepare_rlimits(int pid, struct task_restore_core_args *ta) static int prepare_rlimits(int pid, unsigned long *addr)
{ {
struct rlimit *r;
int fd, ret; int fd, ret;
int nr_rlim = 0;
ta->nr_rlim = 0; *addr = rst_mem_cpos();
fd = open_image(CR_FD_RLIMIT, O_RSTR, pid); fd = open_image(CR_FD_RLIMIT, O_RSTR, pid);
if (fd < 0) { if (fd < 0) {
...@@ -1905,34 +1907,33 @@ static int prepare_rlimits(int pid, struct task_restore_core_args *ta) ...@@ -1905,34 +1907,33 @@ static int prepare_rlimits(int pid, struct task_restore_core_args *ta)
} }
while (1) { while (1) {
int l;
RlimitEntry *re; RlimitEntry *re;
ret = pb_read_one_eof(fd, &re, PB_RLIMIT); ret = pb_read_one_eof(fd, &re, PB_RLIMIT);
if (ret <= 0) if (ret <= 0)
break; break;
l = ta->nr_rlim; r = rst_mem_alloc(sizeof(*r));
if (l == RLIM_NLIMITS) { if (!r) {
pr_err("Too many rlimits in image for %d\n", pid); pr_err("Can't allocate memory for resource %d\n",
ret = -1; nr_rlim);
break; return -1;
} }
ta->rlims[l].rlim_cur = decode_rlim(re->cur); r->rlim_cur = decode_rlim(re->cur);
ta->rlims[l].rlim_max = decode_rlim(re->max); r->rlim_max = decode_rlim(re->max);
if (ta->rlims[l].rlim_cur > ta->rlims[l].rlim_max) { if (r->rlim_cur > r->rlim_max) {
pr_err("Can't restore cur > max for %d.%d\n", pid, l); pr_err("Can't restore cur > max for %d.%d\n", pid, nr_rlim);
ta->rlims[l].rlim_cur = ta->rlims[l].rlim_max; r->rlim_cur = r->rlim_max;
} }
rlimit_entry__free_unpacked(re, NULL); rlimit_entry__free_unpacked(re, NULL);
ta->nr_rlim++; nr_rlim++;
} }
close(fd); close(fd);
return ret; return nr_rlim;
} }
static int open_signal_image(int type, pid_t pid, unsigned long *ptr, int *nr) static int open_signal_image(int type, pid_t pid, unsigned long *ptr, int *nr)
...@@ -2001,6 +2002,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -2001,6 +2002,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
void *tcp_socks_mem; void *tcp_socks_mem;
unsigned long tcp_socks; unsigned long tcp_socks;
unsigned long rlimits_rst_addr;
int nr_rlim;
unsigned long vdso_rt_vma_size = 0; unsigned long vdso_rt_vma_size = 0;
unsigned long vdso_rt_size = 0; unsigned long vdso_rt_size = 0;
...@@ -2074,6 +2077,12 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -2074,6 +2077,12 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
memcpy(tcp_socks_mem, rst_tcp_socks, rst_tcp_socks_len()); memcpy(tcp_socks_mem, rst_tcp_socks, rst_tcp_socks_len());
nr_rlim = prepare_rlimits(pid, &rlimits_rst_addr);
if (nr_rlim < 0) {
pr_err("Failed preparing rlimits for pid %d\n", pid);
goto err;
}
restore_bootstrap_len = restorer_len + restore_bootstrap_len = restorer_len +
restore_task_vma_len + restore_task_vma_len +
restore_thread_vma_len + restore_thread_vma_len +
...@@ -2201,8 +2210,9 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -2201,8 +2210,9 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
strncpy(task_args->comm, core->tc->comm, sizeof(task_args->comm)); strncpy(task_args->comm, core->tc->comm, sizeof(task_args->comm));
if (prepare_rlimits(pid, task_args)) task_args->nr_rlim = nr_rlim;
goto err; if (nr_rlim)
task_args->rlims = rst_mem_raddr(rlimits_rst_addr);
/* /*
* Fill up per-thread data. * Fill up per-thread data.
......
...@@ -146,7 +146,7 @@ struct task_restore_core_args { ...@@ -146,7 +146,7 @@ struct task_restore_core_args {
char comm[TASK_COMM_LEN]; char comm[TASK_COMM_LEN];
int nr_rlim; int nr_rlim;
struct rlimit rlims[RLIM_NLIMITS]; struct rlimit *rlims;
struct rst_tcp_sock *tcp_socks; struct rst_tcp_sock *tcp_socks;
int tcp_socks_nr; int tcp_socks_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