[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