[CRIU] [PATCH 5/5] tty: Use regular files engine to save paths to the peers, v3

Pavel Emelyanov xemul at parallels.com
Wed Oct 15 02:53:21 PDT 2014


On 10/13/2014 07:51 PM, Cyrill Gorcunov wrote:

> @@ -242,18 +247,182 @@ static int tty_test_and_set(int bit, unsigned long *bitmap)
>  	return ret;
>  }
>  
> -static int pty_open_ptmx_index(int flags, int index)
> +/*
> + * Generate a regular file object in case if such is missed
> + * in the image file, ie obsolete interface has been used on
> + * checkpoint.
> + */
> +static struct file_desc *pty_alloc_fake_reg_d(struct tty_info *info, bool add)

I'm not sure I understand the idea behind this alloc_fake. Can you elaborate?

> +{
> +	TtyFileEntry *tfe = info->tfe;
> +	struct reg_file_info *r;
> +
> +	r = xzalloc(sizeof(*r) + sizeof(*r->rfe) + 64);
> +	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, 64, "/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);
> +	}
> +
> +	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 void pty_free_fake(struct tty_info **info)
> +{
> +	if (info) {
> +		struct tty_info *p = *info;
> +		struct reg_file_info *r;
> +
> +		r = container_of(p->reg_d, struct reg_file_info, d);
> +		xfree(r->rfe->name);
> +		xfree(p->reg_d);
> +		xfree(p);
> +		*info = NULL;
> +	}
> +}
> +
> +struct pty_open_args {
> +	struct tty_info	*info;
> +	unsigned int	flags;
> +};
> +
> +static int do_open_pty_reg(int ns_root_fd, struct reg_file_info *rfi, void *v)

This duplicates the do_open_reg_noseek_flags().

> +{
> +	struct pty_open_args *args = v;
> +	int fd;
> +
> +	fd = openat(ns_root_fd, rfi->path, args->flags);
> +	if (fd < 0) {
> +		pr_err("Can't open pty %#x [%s]\n", args->info->tfe->id, rfi->path);
> +		return -1;
> +	}
> +
> +	return fd;
> +}
> +

> @@ -988,6 +1168,25 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg)
>  	if (verify_info(info))
>  		return -1;
>  
> +	info->reg_d = find_file_desc_raw(FD_TYPES__REG, info->tfe->id);
> +	if (!info->reg_d) {
> +		info->reg_d = pty_alloc_fake_reg_d(info, true);
> +		if (!info->reg_d) {
> +			pr_err("Can't generate new reg_d descriptor for id %#x\n",
> +			       info->tfe->id);
> +			return -1;
> +		}
> +	}
> +
> +	/*
> +	 * Slave PTYs without master might have
> +	 * been postfixed as deleted, strip this
> +	 * part, we will need a valid path on their
> +	 * opening.
> +	 */

This should be done on dump side. We have a problem right now with these
"(deleted)" for link remaps and ghosts. Just introduce the function that
strips this part for those and call the same for PTYs on dump.

> +	if (info->type == TTY_TYPE_PTS)
> +		pty_undelete_reg(info);
> +
>  	/*
>  	 * The tty peers which have no @termios are hung up,
>  	 * so don't mark them as active, we create them with



More information about the CRIU mailing list