Re: c/r support on FUSE filesystems.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Cgroups]     [Netdev]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux