[CRIU] Re: [PATCH 10/10] files: Use sys_kcmp to find file descriptor duplicates

Pavel Emelyanov xemul at parallels.com
Tue Feb 28 05:26:31 EST 2012


On 02/27/2012 07:21 PM, Cyrill Gorcunov wrote:
> On Mon, Feb 27, 2012 at 06:01:41PM +0400, Cyrill Gorcunov wrote:
>>
>> Yes, 0 will work as well but I would prefer to keep some predefined
>> value other than 0 which actually gives us a good hint in debugging
>> purpose.
>>
> 
> Does this one look better?

Almost perfect. See comments inline.

> @@ -120,10 +124,21 @@ static int dump_one_reg_file(int type, struct fd_parms *p, int lfd,
>         e.flags = p->flags;
>         e.pos   = p->pos;
>         e.addr  = p->fd_name;
> -       if (p->id)
> -               memcpy(e.id, p->id, FD_ID_SIZE);
> -       else
> -               memzero(e.id, FD_ID_SIZE);
> +
> +       if (likely(!fd_is_special(&e))) {
> +               struct fd_id_entry *fd_id_entry;
> +
> +               fd_id_entry = fd_id_entry_collect((u32)p->id, p->pid, p->fd_name);
> +               if (!fd_id_entry) {
> +                       pr_err("No memory to collect fidinfo for file %li (pid %d)\n",
> +                               p->fd_name, p->pid);

Useless pr_err -- the fd_id_entry_collect emits one itself.

> +       e = xmalloc(sizeof(*e));
> +       if (!e) {
> +               pr_err("No memory to allocate fd_id_entry: "
> +                      "genid %8x pid %6d fd %4d\n",
> +                       genid, pid, fd);

xmalloc prints the message himself as well.

> +               goto err;
> +       }
> +
> +       e->u.key.subid  = -2U; /* Just for easier parsing on dumps */

For symmetry this should be fd_id_entries_subid++;

> +       e->u.key.genid  = genid;
> +       e->pid          = pid;
> +       e->fd           = fd;
> +
> +       rb_init_node(&e->node);
> +       rb_init_node(&e->subtree_node);
> +       rb_attach_node(&e->subtree_root, &e->subtree_node);
> +err:
> +       return e;
> +}
> +
> +static struct fd_id_entry *
> +lookup_alloc_subtree(struct fd_id_entry *e, u32 genid, pid_t pid, int fd)
> +{
> +       struct rb_node *node = e->subtree_root.rb_node;
> +       struct fd_id_entry *sub = NULL;
> +
> +       struct rb_node **new = &e->subtree_root.rb_node;
> +       struct rb_node *parent = NULL;
> +
> +       while (node) {
> +               struct fd_id_entry *this = rb_entry(node, struct fd_id_entry, subtree_node);
> +               int ret = sys_kcmp(this->pid, pid, KCMP_FILE, this->fd, fd);
> +
> +               parent = *new;
> +               if (ret < 0)
> +                       node = node->rb_left, new = &((*new)->rb_left);
> +               else if (ret > 0)
> +                       node = node->rb_right, new = &((*new)->rb_right);
> +               else
> +                       return this;
> +       }
> +
> +       sub = alloc_fd_id_entry(genid, pid, fd);
> +       if (!sub)
> +               goto err;
> +
> +       sub->u.key.subid = fd_id_entries_subid++;
> +
> +       rb_link_and_balance(&e->subtree_root, &sub->subtree_node, parent, new);
> +err:
> +       return sub;
> +}
> +
> +struct fd_id_entry *fd_id_entry_collect(u32 genid, pid_t pid, int fd)
> +{
> +       struct rb_node *node = fd_id_root.rb_node;
> +       struct fd_id_entry *e = NULL;
> +
> +       struct rb_node **new = &fd_id_root.rb_node;
> +       struct rb_node *parent = NULL;
> +
> +       while (node) {
> +               struct fd_id_entry *this = rb_entry(node, struct fd_id_entry, node);
> +
> +               parent = *new;
> +               if (genid < this->u.key.genid)
> +                       node = node->rb_left, new = &((*new)->rb_left);
> +               else if (genid > this->u.key.genid)
> +                       node = node->rb_right, new = &((*new)->rb_right);
> +               else
> +                       return lookup_alloc_subtree(this, genid, pid, fd);
> +       }
> +
> +       e = alloc_fd_id_entry(genid, pid, fd);
> +       if (!e)
> +               goto err;
> +
> +       /*
> +        * Make sure the union is still correlate with structure
> +        * we write to disk.
> +        */
> +       {
> +               struct fdinfo_entry __entry __always_unused;
> +               BUILD_BUG_ON(sizeof(e->u.key) != sizeof(__entry.id));

This build bug on should be where you assign entry's id to image entry's id, not here.

> +       }
> +
> +       rb_link_and_balance(&fd_id_root, &e->node, parent, new);
> +err:
> +       return e;
> +}


More information about the CRIU mailing list