[CRIU] [PATCH 01/12] pstree: Bind CoreEntry to pstree and fill it with registers early
Pavel Emelyanov
xemul at parallels.com
Fri Mar 1 13:44:27 EST 2013
On 02/28/2013 07:35 PM, Cyrill Gorcunov wrote:
>
> When parasite daemon mode will be implemented we get deprived of ability
> to fetch registers at the late moment of dumping as we were, thus just
> bind CoreEntry to pstree item and allocate CoreEntry'ies for every
> thread found, once process tree is in seized state.
>
> Then immediately fill CoreEntry'ies with registers. We use prctl
> opcode for that but fetch a complete set of registers including
> FPU state, and convert them into protobuf format.
>
> Zombie tasks remains untouched, we allocate CoreEntry for them
> right at moment of dumping becuase we don't need registers there
> to be written on disk.
>
> This way get_task_regs no longer need parasite_ctl argument
> and it's zapped.
>
> Still parasite_ctl has own copy of general registers set but
> this is because we need them to be in cpu native format unlike
> ones kept in CoreEntry.
>
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
> arch/arm/crtools.c | 12 ++---
> arch/arm/include/asm/dump.h | 2 +-
> arch/x86/crtools.c | 12 ++---
> arch/x86/include/asm/dump.h | 2 +-
> cr-dump.c | 119 +++++++++++++++++---------------------------
> include/pstree.h | 5 ++
> pstree.c | 70 ++++++++++++++++++++++++++
> 7 files changed, 131 insertions(+), 91 deletions(-)
>
> - if (ctl)
> - regs = ctl->regs_orig;
> - else {
> - if (ptrace(PTRACE_GETREGS, pid, NULL, ®s)) {
> - pr_err("Can't obtain GP registers for %d\n", pid);
> - goto err;
> - }
> + if (ptrace(PTRACE_GETREGS, pid, NULL, ®s)) {
> + pr_err("Can't obtain GP registers for %d\n", pid);
> + goto err;
> }
So, do we still have regs duplication?
> +static int collect_regs_seized(struct pstree_item *item)
> +{
> + unsigned int i;
> + int ret;
> +
> + if (pstree_alloc_cores(item))
> + return -1;
> +
> + for (i = 0; i < item->nr_threads; i++) {
> + pid_t pid = item->threads[i].real;
> + ret = get_task_regs(pid, item->core[i]);
> + if (ret) {
> + pr_err("Can't obtain regs for thread %d\n", pid);
> + return -1;
> + }
> +
> + if (item->threads[i].real == item->pid.real)
> + item->this_core = item->core[i];
We've already done this in pstree_alloc_cores()
> + }
> +
> + return 0;
> +}
> +int pstree_alloc_cores(struct pstree_item *item)
> +{
> + unsigned int i;
> +
> + item->core = xzalloc(sizeof(*item->core) * item->nr_threads);
> + if (!item->core)
> + return -1;
> +
> + for (i = 0; i < item->nr_threads; i++) {
> + int is_leader = (item->threads[i].real == item->pid.real);
> +
> + item->core[i] = core_entry_alloc(item->state != TASK_DEAD, is_leader);
> + if (!item->core[i])
> + goto err;
> +
> + if (is_leader)
> + item->this_core = item->core[i];
The version in collect_regs_seized() without is_leader looks nicer.
> + }
> +
> + return 0;
> +err:
> + pstree_free_cores(item);
> + return -1;
> +}
> +
More information about the CRIU
mailing list