[CRIU] [PATCH 8/9] tty: Use regular files engine to save paths to the peers, v4
Pavel Emelyanov
xemul at parallels.com
Fri Oct 17 05:07:57 PDT 2014
> +static struct file_desc *pty_alloc_reg(struct tty_info *info, bool add)
> +{
> + TtyFileEntry *tfe = info->tfe;
> + const size_t namelen = 64;
> + struct reg_file_info *r;
> +
> + r = xzalloc(sizeof(*r) + sizeof(*r->rfe) + namelen);
> + if (!r)
> + return NULL;
> +
> + r->rfe = (void *)r + sizeof(*r);
> + reg_file_entry__init(r->rfe);
> +
> + r->rfe->name = (void *)r + sizeof(*r) + sizeof(*r->rfe);
> + if (tty_is_master(info))
> + strcpy(r->rfe->name, "/dev/ptmx");
> + else
> + snprintf(r->rfe->name, namelen, "/dev/pts/%u",
> + info->tie->pty->index);
> +
> + if (add)
> + file_desc_add(&r->d, tfe->id, NULL);
> + else {
> + r->d.id = tfe->id;
> + INIT_LIST_HEAD(&r->d.fd_info_head);
> + INIT_HLIST_NODE(&r->d.hash);
This should be file_desc_init from patch #4, shouldn't it?
> + }
> +
> + r->rfe->id = tfe->id;
> + r->rfe->flags = tfe->flags;
> + r->rfe->fown = tfe->fown;
> + r->path = &r->rfe->name[1];
> +
> + return &r->d;
> +}
> +
> +static struct reg_file_info *pty_alloc_fake_reg(struct tty_info *info, int type)
> +{
> + struct reg_file_info *new, *orig;
> + struct file_desc *fake_desc;
> +
> + pr_debug("Allocating fake descriptor for %#x (reg_d %p)\n",
> + info->tfe->id, info->reg_d);
> +
> + BUG_ON(!info->reg_d);
> +
> + fake_desc = pty_alloc_reg(info, false);
> + if (!fake_desc)
> + return NULL;
> +
> + orig = container_of(info->reg_d, struct reg_file_info, d);
> + new = container_of(fake_desc, struct reg_file_info, d);
Some comment about what's going on below would be great.
> + if ((type == TTY_TYPE_PTM && tty_is_master(info)) ||
> + (type == TTY_TYPE_PTS && !tty_is_master(info))) {
> + new->path = xstrdup(orig->path);
> + new->rfe->name = &new->path[1];
> + } else {
> + char *pos = strrchr(orig->rfe->name, '/');
> + size_t len = strlen(orig->rfe->name) + 1;
> + size_t slash_at = pos - orig->rfe->name;
> + char *inverted_path = xmalloc(len + 32);
> +
> + BUG_ON(!pos || !inverted_path);
> +
> + memcpy(inverted_path, orig->rfe->name, slash_at + 1);
> + if (type == TTY_TYPE_PTM)
> + strcat(inverted_path, "ptmx");
> + else {
> + if (slash_at >= 4 && strcmp(&inverted_path[slash_at - 4], "pts"))
> + snprintf(&inverted_path[slash_at + 1], 10, "pts/%u",
> + info->tie->pty->index);
> + else
> + snprintf(&inverted_path[slash_at + 1], 10, "%u",
> + info->tie->pty->index);
> + }
> +
> + new->rfe->name = inverted_path;
> + new->path = &inverted_path[1];
> + }
> +
> + return new;
> +}
> @@ -974,6 +1091,24 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg)
> return -1;
>
> /*
> + * The image might have no reg file record in old CRIU, so
> + * lets don't fail for a while. After a couple of releases
> + * simply require the record to present.
> + */
> + info->reg_d = find_file_desc_raw(FD_TYPES__REG, info->tfe->id);
> + if (!info->reg_d) {
> + info->reg_d = pty_alloc_reg(info, true);
> + if (!info->reg_d) {
> + pr_err("Can't generate new reg descriptor for id %#x\n",
> + info->tfe->id);
> + return -1;
> + }
> + } else {
> + info->reg_d = collect_special_file(info->tfe->id);
This results in double list lookup.
> + BUG_ON(!info->reg_d);
> + }
> +
> + /*
> * The tty peers which have no @termios are hung up,
> * so don't mark them as active, we create them with
> * faked master and they are rather a rudiment which
More information about the CRIU
mailing list