[CRIU] Re: [PATCH 2/5] fifo: Add checkpoint restore for fifos
Pavel Emelyanov
xemul at parallels.com
Tue Jun 26 05:37:36 EDT 2012
On 06/26/2012 12:07 PM, Cyrill Gorcunov wrote:
> Checpoint and restore of fifo is similar to
> pipes c/r except the pipe end-points are named
> file.
>
> Because the fifo has a name we use regular files
> facility for fifo path c/r.
>
> Still there is a trick used to "open" fifo:
> the opening procedure migh sleep if a fifo's peer
> is not yet opened, so before doing a real open
> we yield a fake open procedure (with O_RDWR flag)
> which prevents us from sleeping even if peer
> is not yet ready.
>
> Other than that -- nothing special.
The patch got corrupted. Use attach.
> +static int dump_one_fifo(int lfd, u32 id, const struct fd_parms *p)
> +{
> + int img_data = fdset_fd(glob_fdset, CR_FD_FIFO_DATA);
> + int img = fdset_fd(glob_fdset, CR_FD_FIFO);
> + struct fifo_entry e;
> +
> + /*
> + * It's a trick here, we use regular files dumping
> + * code to save path to a fifo, then we reuse it
> + * on restore.
> + */
> + if (dump_one_reg_file(lfd, id, p))
> + return -1;
Good. But the dump_ghost_file on unlinked fifo will try to copy out
its contents. Not good.
> + pr_info("Dumping fifo %d with id %#x pipe_id %#x\n",
> + lfd, id, (u32)p->stat.st_ino);
> +
> + e.id = id;
> + e.pipe_id = p->stat.st_ino;
> +
> + if (write_img(img, &e) < 0)
> + return -1;
> +
> + return dump_one_pipe_data(img_data, lfd, id, p);
> +}
> +
> +static int open_fifo_fd(struct file_desc *d)
> +{
> + struct fifo_info *info = container_of(d, struct fifo_info, d);
> + int new_fifo, fake_fifo = -1, img = -1;
> +
> + struct reg_file_info *rfi;
> + struct file_desc *rd;
> +
> + pr_info("\t\tCreating fifo pipe_id=%#x id=%#x\n",
> + info->fe.pipe_id, info->fe.id);
> +
> + rd = find_file_desc_raw(FDINFO_REG, info->fe.id);
> + if (!rd) {
> + pr_perror("Can't find regfile for fifo %#x\n", info->fe.id);
> + return -1;
> + }
> +
> + rfi = container_of(rd, struct reg_file_info, d);
> + if (!rfi->path) {
> + pr_err("Nil path found on regfile %#x for fifo %#x\n",
> + rfi->rfe.id, info->fe.id);
> + return -1;
> + }
> +
> + if (rfi->remap_path) {
> + if (link(rfi->remap_path, rfi->path) < 0) {
> + pr_perror("Can't link %s -> %s\n",
> + rfi->remap_path, rfi->path);
> + return -1;
> + }
> + }
> +
> + /*
> + * The fifos (except read-write fifos) do wait until
> + * another pipe-end get connected, so to be able to
> + * proceed the restoration procedure we open a fake
> + * fifo here.
> + */
> + fake_fifo = open(rfi->path, O_RDWR);
> + if (fake_fifo < 0) {
> + pr_perror("Can't open fake fifo %#08x [%s]",
> + info->fe.id, rfi->path);
> + return -1;
> + }
> +
> + new_fifo = open(rfi->path, rfi->rfe.flags);
> + if (new_fifo < 0) {
> + pr_perror("Can't open fifo %#08x [%s]",
> + info->fe.id, rfi->path);
> + goto err_close_fake;
> + }
> +
> + img = open_image_ro(CR_FD_FIFO_DATA);
> + if (img < 0)
> + goto err_close_new;
> +
> + if (restore_pipe_data(img, fake_fifo, info->fe.id,
> + info->bytes, info->off))
> + goto err_unlink;
> +
> + if (rfi->remap_path)
> + unlink(rfi->path);
> +
> + if (restore_fown(new_fifo, &rfi->rfe.fown) < 0) {
> + pr_perror("Can't restore owner on fifo %#08x",
> + info->fe.id);
> + goto err_close_new;
> + }
Most of the above is done by the open_fe_fd fn. Try to merge.
> +err_close_fake:
> + close_safe(&img);
> + close_safe(&fake_fifo);
> + return new_fifo;
> +
> +err_close_new:
> + close_safe(&new_fifo);
> + goto err_close_fake;
> +
> +err_unlink:
> + if (rfi->remap_path)
> + unlink(rfi->path);
> + goto err_close_new;
> +}
> +static int handle_fifo_data(void)
> +{
> + int img, ret;
> +
> + img = open_image_ro(CR_FD_FIFO_DATA);
> + if (img < 0)
> + return -1;
> +
> + while (1) {
> + struct pipe_data_entry pde;
> + struct fifo_info *info;
> +
> + ret = read_img_eof(img, &pde);
> + if (ret <= 0)
> + break;
> +
> + list_for_each_entry(info, &fifo_head, list) {
> + if (info->fe.pipe_id != pde.pipe_id)
> + continue;
> +
> + info->off = lseek(img, 0, SEEK_CUR) + pde.off;
> + info->bytes = pde.bytes;
> +
> + lseek(img, pde.bytes + pde.off, SEEK_CUR);
> + break;
> + }
> + }
This looks like handle_pipes_data.
> + close(img);
> + return ret;
> +}
More information about the CRIU
mailing list