c/r support on FUSE filesystems.

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

 



hi,
I just worked with implementation of of CR support for FUSE filesystems. I
have attached two files here that support FUSE-cr. fuse_kcr.h/c belongs to
fs/fuse dir. What I found is that similar approach as that of generic file
checkpoint can be used in fuse also and it works fine. In fact I did
separate implementation just because if there is any need for extra
functionalities, we can add that in these, so I kept it separate.  I want
know any problems or issues in this implementation.


Thank you
regards,
Vishnumurthy P
Only in linux-cr: .config
Only in linux-cr/drivers/gpu/drm/radeon: r100_reg_safe.h
Only in linux-cr/drivers/gpu/drm/radeon: r200_reg_safe.h
Only in linux-cr/drivers/gpu/drm/radeon: r300_reg_safe.h
Only in linux-cr/drivers/gpu/drm/radeon: r420_reg_safe.h
Only in linux-cr/drivers/gpu/drm/radeon: r600_reg_safe.h
Only in linux-cr/drivers/gpu/drm/radeon: rn50_reg_safe.h
Only in linux-cr/drivers/gpu/drm/radeon: rs600_reg_safe.h
Only in linux-cr/drivers/gpu/drm/radeon: rv515_reg_safe.h
diff -crB linux-cr1/fs/checkpoint.c linux-cr/fs/checkpoint.c
*** linux-cr1/fs/checkpoint.c	2010-09-14 06:59:05.026511080 +0530
--- linux-cr/fs/checkpoint.c	2011-03-30 21:14:15.260306880 +0530
***************
*** 711,716 ****
--- 711,718 ----
  				  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,765 ****
--- 762,773 ----
  		.file_type = CKPT_FILE_EVENTFD,
  		.restore = eventfd_restore,
  	},
+ 	/*FUSE filesystem .It needs special handling*/
+ 	{
+ 		.file_name = "FUSE",
+ 		.file_type = CKPT_FILE_FUSE,
+ 		.restore = fuse_file_restore,
+ 	},	
  };
  
  static void *restore_file(struct ckpt_ctx *ctx)
diff -crB linux-cr1/fs/fuse/dev.c linux-cr/fs/fuse/dev.c
*** linux-cr1/fs/fuse/dev.c	2010-09-14 06:59:05.114511787 +0530
--- linux-cr/fs/fuse/dev.c	2011-03-28 21:59:53.786456000 +0530
***************
*** 35,41 ****
  	memset(req, 0, sizeof(*req));
  	INIT_LIST_HEAD(&req->list);
  	INIT_LIST_HEAD(&req->intr_entry);
! 	init_waitqueue_head(&req->waitq);
  	atomic_set(&req->count, 1);
  }
  
--- 34,41 ----
  	memset(req, 0, sizeof(*req));
  	INIT_LIST_HEAD(&req->list);
  	INIT_LIST_HEAD(&req->intr_entry);
! 	init_waitqueue_head(&req->waitq); //used to initialize a wait queue head variable that was allocated dynamically
! 
  	atomic_set(&req->count, 1);
  }
  
***************
*** 102,108 ****
  
  	atomic_inc(&fc->num_waiting);
  	block_sigs(&oldset);
! 	intr = wait_event_interruptible(fc->blocked_waitq, !fc->blocked);
  	restore_sigs(&oldset);
  	err = -EINTR;
  	if (intr)
--- 102,108 ----
  
  	atomic_inc(&fc->num_waiting);
  	block_sigs(&oldset);
! 	intr = wait_event_interruptible(fc->blocked_waitq, !fc->blocked);  //waits on fc->blocked_waitq until fc->blocked becomes 0.
  	restore_sigs(&oldset);
  	err = -EINTR;
  	if (intr)
diff -crB linux-cr1/fs/fuse/dir.c linux-cr/fs/fuse/dir.c
*** linux-cr1/fs/fuse/dir.c	2010-09-14 06:59:05.114511787 +0530
--- linux-cr/fs/fuse/dir.c	2011-03-28 21:59:53.802473000 +0530
***************
*** 1576,1581 ****
--- 1576,1584 ----
  	.open		= fuse_dir_open,
  	.release	= fuse_dir_release,
  	.fsync		= fuse_dir_fsync,
+  //#ifdef CONFIG_CHECKPOINT
+ 	//.checkpoint	= fuse_dir_checkpoint,
+  //#endif
  };
  
  static const struct inode_operations fuse_common_inode_operations = {
diff -crB linux-cr1/fs/fuse/file.c linux-cr/fs/fuse/file.c
*** linux-cr1/fs/fuse/file.c	2010-09-14 06:59:05.114511787 +0530
--- linux-cr/fs/fuse/file.c	2011-03-28 21:59:53.737442000 +0530
***************
*** 7,12 ****
--- 7,13 ----
  */
  
  #include "fuse_i.h"
+ #include "fuse_kcr.h"
  
  #include <linux/pagemap.h>
  #include <linux/slab.h>
***************
*** 1991,1996 ****
--- 1992,2000 ----
  	.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,2012 ****
--- 2011,2019 ----
  	.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 */
  };
  
Only in linux-cr/fs/fuse: fuse_kcr.c
Only in linux-cr/fs/fuse: fuse_kcr.h
diff -crB linux-cr1/fs/fuse/inode.c linux-cr/fs/fuse/inode.c
*** linux-cr1/fs/fuse/inode.c	2010-09-14 06:59:05.118512015 +0530
--- linux-cr/fs/fuse/inode.c	2011-03-28 21:59:53.805496000 +0530
***************
*** 1200,1206 ****
  
  	printk(KERN_INFO "fuse init (API version %i.%i)\n",
  	       FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
! 
  	INIT_LIST_HEAD(&fuse_conn_list);
  	res = fuse_fs_init();
  	if (res)
--- 1200,1208 ----
  
  	printk(KERN_INFO "fuse init (API version %i.%i)\n",
  	       FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
!     printk("#######################################\n");
!     printk("#FUSE kernel module is initializing...#\n");
!     printk("#######################################\n");
  	INIT_LIST_HEAD(&fuse_conn_list);
  	res = fuse_fs_init();
  	if (res)
***************
*** 1235,1240 ****
--- 1237,1245 ----
  
  static void __exit fuse_exit(void)
  {
+     printk("##################################\n");
+     printk("#FUSE kernel module is exiting...#\n");
+     printk("##################################\n");
  	printk(KERN_DEBUG "fuse exit\n");
  
  	fuse_ctl_cleanup();
diff -crB linux-cr1/fs/fuse/Makefile linux-cr/fs/fuse/Makefile
*** linux-cr1/fs/fuse/Makefile	2010-09-14 06:59:05.114511787 +0530
--- linux-cr/fs/fuse/Makefile	2011-03-22 20:23:18.427370000 +0530
***************
*** 5,8 ****
  obj-$(CONFIG_FUSE_FS) += fuse.o
  obj-$(CONFIG_CUSE) += cuse.o
  
! fuse-objs := dev.o dir.o file.o inode.o control.o
--- 5,8 ----
  obj-$(CONFIG_FUSE_FS) += fuse.o
  obj-$(CONFIG_CUSE) += cuse.o
  
! fuse-objs := dev.o dir.o file.o inode.o control.o fuse_kcr.o
Only in linux-cr/include: config
Only in linux-cr/include: generated
diff -crB linux-cr1/include/linux/checkpoint_hdr.h linux-cr/include/linux/checkpoint_hdr.h
*** linux-cr1/include/linux/checkpoint_hdr.h	2010-09-14 06:59:05.515511078 +0530
--- linux-cr/include/linux/checkpoint_hdr.h	2011-03-28 21:59:53.913441000 +0530
***************
*** 561,567 ****
  #define CKPT_FILE_EPOLL CKPT_FILE_EPOLL
  	CKPT_FILE_EVENTFD,
  #define CKPT_FILE_EVENTFD CKPT_FILE_EVENTFD
! 	CKPT_FILE_MAX
  #define CKPT_FILE_MAX CKPT_FILE_MAX
  };
  
--- 561,569 ----
  #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
  };
  
diff -crB linux-cr1/include/linux/fuse.h linux-cr/include/linux/fuse.h
*** linux-cr1/include/linux/fuse.h	2010-09-14 06:59:05.543512193 +0530
--- linux-cr/include/linux/fuse.h	2011-03-28 21:59:53.846445000 +0530
***************
*** 249,254 ****
--- 249,258 ----
  	FUSE_IOCTL         = 39,
  	FUSE_POLL          = 40,
  
+ #ifdef CONFIG_CHECKPOINT
+ 	FUSE_CHECKPOINT    = 1024,
+ #endif                                  /*CONFIG_CHECKPOINT*/
+ 
  	/* CUSE specific operations */
  	CUSE_INIT          = 4096,
  };
***************
*** 565,568 ****
--- 568,583 ----
  	__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 */
Only in linux-cr/include/linux: version.h
Only in linux-cr/scripts/basic: docproc
Only in linux-cr/scripts/basic: fixdep
Only in linux-cr/scripts/basic: hash
Only in linux-cr/scripts: conmakehash
Only in linux-cr/scripts/genksyms: genksyms
Only in linux-cr/scripts/genksyms: keywords.c
Only in linux-cr/scripts/genksyms: lex.c
Only in linux-cr/scripts/genksyms: parse.c
Only in linux-cr/scripts/genksyms: parse.h
Only in linux-cr/scripts: kallsyms
Only in linux-cr/scripts/kconfig: conf
Only in linux-cr/scripts/kconfig: lex.zconf.c
Only in linux-cr/scripts/kconfig: mconf
Only in linux-cr/scripts/kconfig: zconf.hash.c
Only in linux-cr/scripts/kconfig: zconf.tab.c
Only in linux-cr/scripts/mod: elfconfig.h
Only in linux-cr/scripts/mod: mk_elfconfig
Only in linux-cr/scripts/mod: modpost
Only in linux-cr/scripts/selinux/genheaders: genheaders
Only in linux-cr/scripts/selinux/mdp: mdp
Only in linux-cr/security/selinux: av_permissions.h
Only in linux-cr: .version
/*
fuse_cr: Checkpoint-Restart implementation for FUSE filesystem kernel module.

Authors: Manoj Kumar and Vishnumurthy Prabhu 
         NITK Surathkal

*/

#include "fuse_kcr.h"
#include <linux/file.h>
/*
	FUSE filesystem .It needs special handling
	{
		.file_name = "FUSE",
		.file_type = CKPT_FILE_FUSE,
		.restore = fuse_file_restore,
	},	
*/

struct ckpt_hdr_file_fuse {
	struct ckpt_hdr_file common;
	
} __attribute__((aligned(8)));

//extern int generic_file_checkpoint(struct ckpt_ctx *ctx, struct file *file);

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_file *ff = file->private_data;
	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);
    printk("**************************fuse_file_checkpoint is working fine\n");
	  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);
	}
    printk("**************************fuse_file_restore is working fine\n");
	return file;
}

#ifdef CONFIG_CHECKPOINT
#ifndef _FUSE_KCR_H_
#define _FUSE_KCR_H_

#include <linux/fuse.h>
#include <linux/checkpoint.h>
#include "fuse_i.h"

int fuse_file_checkpoint(struct ckpt_ctx *ctx, struct file *file);
struct file *fuse_file_restore(struct ckpt_ctx *ctx, struct ckpt_hdr_file *ptr);
#endif
#endif
_______________________________________________
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