Patch resubmitted!! New file(fuse-kcr.c) should go to fs/fuse/ directory. I will look into unliked files and update you soon! regards, Vishnumurthy Prabhu On Sat, Apr 2, 2011 at 7:29 AM, Vishnumurthy Prabhu < prabhuvishnumurthy@xxxxxxxxx> wrote: > Thank you very much for your kind and immediate reply! > first thing, I do agree that this is not a submittable patch and as you > said, I just 'diff' ed two linux sources(having with FUSE-cr support that is > what I modified and non FUSE-cr support). > what I wanted was to inform to community about FUSE-cr implementation and > comments on issues involved with that implementation. > > . > . > > . > > >Can you tell us about the testing you've done with this? What kind of > >additions/changes does this make to the FUSE userspace API? Can you > >please describe how it's supposed to work with FUSE userspace code? > > I have tested with two simple usecases(I know, it might not be sufficient). > they are, fuse-zip(fuse based filesystem for accessing zip files) and > simple-fuse(filesystem implementation in memory buffer). At user-space code, > I didn't do much modifications, I just added call back handles for > checkpointing in fuse library similar to that of other handles(open, close, > read, write etc) thinking that I might need those. but I never made use of > those. Thats why, if you have seen the code(fuse_kcr.c ie, a C file that I > have attached), though I wrote a code piece for user-space communication, I > have commented its use in actual checkpoint function and it just uses the > same approach as that of generic file checkpoint. According to present > implementation, user-space(fuse library or filesystem program) is unaware of > what is going on during checkpointing and restart. It just considers every > call as like others(ie open, read, write, close). > > MY CLAIM is that all required accounting information of an open file is > managed at kernel space(file object) and At user space, it just get a > request and replies to that. All information related to state of open file > is supplied from kernel space. > > ASSUMPTION: during checkpoint and restart mount remains same. in fact, I > hope there is no unmount and remount of userspace program. because, here the > support is for checkpointing file descriptors that involve fuse related > files so I dont think we need to bother about user implemented filesystem. > > I wanted to know any issues related to above comments? > > . > . > > . > >> .compat_ioctl = fuse_file_compat_ioctl, > >> .poll = fuse_file_poll, > >> + //#ifdef CONFIG_CHECKPOINT > >> + .checkpoint = fuse_file_checkpoint, > >> + //#endif > > >Why are these cpp lines commented out? > > I know I need to refine the patch file one thing and I commented out these > line because I was compiling fuse kernel module as loadable one so compiler > never used to take this checkpoint ops(I dont know why?) when #ifdef was > present. but in actual source compilation with kernel, I have removed the > comments. > . > . > > . > >Is the content below the missing pair of files? > > >> /* > >>fuse_cr: Checkpoint-Restart implementation for FUSE filesystem kernel > module. > >> > >> Authors: Manoj Kumar and Vishnumurthy Prabhu > >> NITK Surathkal > >> > >>*/ > . > . > . > > they are the two new additions to fuse kernel module. > > > >> /* > >> FUSE filesystem .It needs special handling > >> { > >> .file_name = "FUSE", > >> .file_type = CKPT_FILE_FUSE, > >> .restore = fuse_file_restore, > >> }, > >> */ > > >Huh? What's this comment supposed to tell us? > > It is just to tell I have added this code piece some where, need > implementation and it is just a comment. > > > >> > >> struct ckpt_hdr_file_fuse { > >> struct ckpt_hdr_file common; > >> > >> } __attribute__((aligned(8))); > > >This should be in include/linux/checkpoint_hdr.h *except* since it > >doesn't need anything besides the ckpt_hdr_file I don't see why you > >don't just use that struct instead. > > I kept seperate structure because there might have need to add few more > variable in this structure later on. I didnt move it to checkpoint_hdr.h > just because to avoid messing with large number of files. but once > everything is settled, I hope we can do that. > . > . > . > >> int fuse_file_checkpoint(struct ckpt_ctx *ctx, struct file *file) > >> { > >> int ret; > >> struct ckpt_hdr_file_fuse *h; > >> > >> if (d_unlinked(file->f_dentry)) { > >> ckpt_err(ctx, -EBADF, "%(T)%(P)Unlinked files > unsupported\n", > >> file); > >> return -EBADF; > > >Unlinked files are important too. Have you had a chance to review my > >recent patches for unlinked files? > > No. I worked with one single kernel source so that frequent changes wont > affect to this(fuse-cr). > > >> } > >> > >> h = ckpt_hdr_get_type(ctx, sizeof(*h), CKPT_HDR_FILE); > >> if (!h) > >> return -ENOMEM; > >> > >> h->common.f_type = CKPT_FILE_FUSE; > >> > >> ret = checkpoint_file_common(ctx, file, &h->common); > >> if (ret < 0) > >> goto out; > >> ret = ckpt_write_obj(ctx, &h->common.h); > >> if (ret < 0) > >> goto out; > >> ret = checkpoint_fname(ctx, &file->f_path, &ctx->root_fs_path); > >> > >> // ret = fuse_file_ckpt_send(file); > > >This looks like the only real difference from generic_file_checkpoint() > yet > >it's commented out. What's going on? Have you compiled this code? > >Tested it? > > > I compiled , tested with above mentioned test cases(fuse-zip and simple > fuse). It worked fine. I thought not to mess with userspace and I wanted to > know, whether it works fine or not. But it worked. yes, It is almost > completely similar to generic file checkpoint. I am looking for SUFFICIENT > USECASEs for that where it also require user space support. Even I tried > with non-commented code(fuse_file_ckpt_send()). then also it worked fine and > even at userspace(I have checkpoint handles in user space fuse library > similar to other handles). but I found there is nothing much to do with > UserSpace. so I just commented out. It worked. > > It works fine with uncommented code also. > > so, I will update with refine code. > > thanks, > > regards, > vishnumurthy prabhu >
diff --git a/fs/checkpoint.c b/fs/checkpoint.c index 87d7c6e..4b4b83d 100644 --- a/fs/checkpoint.c +++ b/fs/checkpoint.c @@ -711,6 +711,8 @@ struct restore_file_ops { struct ckpt_hdr_file *ptr); }; +extern struct file *fuse_file_restore(struct ckpt_ctx *ctx, struct ckpt_hdr_file *ptr); + static struct restore_file_ops restore_file_ops[] = { /* ignored file */ { @@ -760,6 +762,11 @@ static struct restore_file_ops restore_file_ops[] = { .file_type = CKPT_FILE_EVENTFD, .restore = eventfd_restore, }, + { + .file_name = "FUSE", + .file_type = CKPT_FILE_FUSE, + .restore = fuse_file_restore, + }, }; static void *restore_file(struct ckpt_ctx *ctx) diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile index e95eeb4..6a25407 100644 --- a/fs/fuse/Makefile +++ b/fs/fuse/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_FUSE_FS) += fuse.o obj-$(CONFIG_CUSE) += cuse.o -fuse-objs := dev.o dir.o file.o inode.o control.o +fuse-objs := dev.o dir.o file.o inode.o control.o fuse_kcr.o diff --git a/fs/fuse/file.c b/fs/fuse/file.c index a9f5e13..23716a4 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1974,6 +1974,7 @@ int fuse_notify_poll_wakeup(struct fuse_conn *fc, return 0; } +extern int fuse_file_checkpoint(struct ckpt_ctx *ctx, struct file *file); static const struct file_operations fuse_file_operations = { .llseek = fuse_file_llseek, .read = do_sync_read, @@ -1991,6 +1992,9 @@ static const struct file_operations fuse_file_operations = { .unlocked_ioctl = fuse_file_ioctl, .compat_ioctl = fuse_file_compat_ioctl, .poll = fuse_file_poll, +#ifdef CONFIG_CHECKPOINT + .checkpoint = fuse_file_checkpoint, +#endif }; static const struct file_operations fuse_direct_io_file_operations = { @@ -2007,6 +2011,9 @@ static const struct file_operations fuse_direct_io_file_operations = { .unlocked_ioctl = fuse_file_ioctl, .compat_ioctl = fuse_file_compat_ioctl, .poll = fuse_file_poll, +#ifdef CONFIG_CHECKPOINT + .checkpoint = fuse_file_checkpoint, +#endif /* no splice_read */ }; diff --git a/include/linux/checkpoint_hdr.h b/include/linux/checkpoint_hdr.h index f4f9577..0eace6e 100644 --- a/include/linux/checkpoint_hdr.h +++ b/include/linux/checkpoint_hdr.h @@ -561,6 +561,8 @@ enum file_type { #define CKPT_FILE_EPOLL CKPT_FILE_EPOLL CKPT_FILE_EVENTFD, #define CKPT_FILE_EVENTFD CKPT_FILE_EVENTFD + CKPT_FILE_FUSE, +#define CKPT_FILE_FUSE CKPT_FILE_FUSE CKPT_FILE_MAX #define CKPT_FILE_MAX CKPT_FILE_MAX }; @@ -581,6 +583,11 @@ struct ckpt_hdr_file_generic { struct ckpt_hdr_file common; } __attribute__((aligned(8))); +struct ckpt_hdr_file_fuse { + struct ckpt_hdr_file common; + +} __attribute__((aligned(8))); + struct ckpt_hdr_file_pipe { struct ckpt_hdr_file common; __s32 pipe_objref; diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 3e2925a..104c67d 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -249,6 +249,10 @@ enum fuse_opcode { FUSE_IOCTL = 39, FUSE_POLL = 40, +#ifdef CONFIG_CHECKPOINT + FUSE_CHECKPOINT = 1024, +#endif /*CONFIG_CHECKPOINT*/ + /* CUSE specific operations */ CUSE_INIT = 4096, }; @@ -565,4 +569,16 @@ struct fuse_notify_inval_entry_out { __u32 padding; }; +#ifdef CONFIG_CHECKPOINT + struct fuse_checkpoint_in{ + __u64 fh; + __u32 flags; + __u32 padding; + }; + + struct fuse_checkpoint_out{ + __u32 status; + }; +#endif /*CONFIG_CHECKPOINT*/ + #endif /* _LINUX_FUSE_H */
/* fuse_cr: Checkpoint-Restart implementation for FUSE filesystem kernel module. Authors: Manoj Kumar and Vishnumurthy Prabhu NITK Surathkal */ #include <linux/file.h> #include "fuse_kcr.h" int fuse_file_ckpt_send(struct file *file) { struct inode *inode = file->f_path.dentry->d_inode; struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_req *req; struct fuse_checkpoint_in inarg; struct fuse_checkpoint_out outarg; __u64 nodeid; int err; struct fuse_file *ff; ff = file->private_data; if (is_bad_inode(inode)) return -EIO; nodeid = get_node_id(inode); req = fuse_get_req(fc); memset(&inarg, 0, sizeof(inarg)); // inargs must be supplied. inarg.fh = ff->fh; inarg.flags &= ~(0); //inargs to be supplied req->in.h.opcode = FUSE_CHECKPOINT; req->in.h.nodeid = nodeid; req->in.numargs = 1; req->in.args[0].size = sizeof(inarg); req->in.args[0].value = &inarg; req->out.numargs = 1; req->out.args[0].size = sizeof(outarg); req->out.args[0].value = &outarg; //aboue is sample inargs need to be changed... fuse_request_send(fc, req); err = req->out.h.error; fuse_put_request(fc, req); if (err == -ENOSYS) { fc->no_flush = 1; err = 0; } return outarg.status; } int fuse_file_checkpoint(struct ckpt_ctx *ctx, struct file *file) { int ret; struct ckpt_hdr_file_fuse *h; if (d_unlinked(file->f_dentry)) { ckpt_err(ctx, -EBADF, "%(T)%(P)Unlinked files unsupported\n", file); return -EBADF; } h = ckpt_hdr_get_type(ctx, sizeof(*h), CKPT_HDR_FILE); if (!h) return -ENOMEM; h->common.f_type = CKPT_FILE_FUSE; ret = checkpoint_file_common(ctx, file, &h->common); if (ret < 0) goto out; ret = ckpt_write_obj(ctx, &h->common.h); if (ret < 0) goto out; ret = checkpoint_fname(ctx, &file->f_path, &ctx->root_fs_path); // ret = fuse_file_ckpt_send(file); out: ckpt_hdr_put(ctx, h); return ret; } EXPORT_SYMBOL(fuse_file_checkpoint); /****************************************************************************************************************************************************** Restart */ struct file *fuse_file_restore(struct ckpt_ctx *ctx, struct ckpt_hdr_file *ptr) { struct file *file; int ret; if (ptr->h.type != CKPT_HDR_FILE || ptr->h.len != sizeof(*ptr) || ptr->f_type != CKPT_FILE_FUSE) return ERR_PTR(-EINVAL); file = restore_open_fname(ctx, ptr->f_flags); if (IS_ERR(file)) return file; ret = restore_file_common(ctx, file, ptr); if (ret < 0) { fput(file); file = ERR_PTR(ret); } return file; }
_______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/containers