public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Preserve hibenate-system-image on startup
@ 2005-07-17  6:26 Hiroyuki Machida
  2005-07-17 16:58 ` Nigel Cunningham
  2005-07-18 11:41 ` Pavel Machek
  0 siblings, 2 replies; 5+ messages in thread
From: Hiroyuki Machida @ 2005-07-17  6:26 UTC (permalink / raw)
  To: linux-kernel


We are now investigating fast startup/shutdown using
2.6 kernel PM functions.

An attached patch enables kernel to preserve system image
on startup, to implement "Snapshot boot".Majordomo@vger.kernel.org wrote:
Conventionally system image will be broken after startup.

Snapshot boot uses un-hibernate from a permanent system image for
startup. During shutdown, does a conventional shutdown without
saving a system image.

We'll explain concept and initial work at OLS. So if you have
interest, we can talk with you at Ottawa.

Thanks,
Hiroyuki Machida

---

This patch enables preserving swsuspend system image over boot cycle, 
against 2.6.12

Signed-off-by: Hiroyui Machida <machida@sony.co.jp> for CELF

-----------------
Index: alp-linux--dev-2-6-12--1.7/kernel/power/Kconfig
===================================================================
--- alp-linux--dev-2-6-12--1.7.orig/kernel/power/Kconfig	2005-07-15 14:59:20.000000000 -0400
+++ alp-linux--dev-2-6-12--1.7/kernel/power/Kconfig	2005-07-16 00:43:31.420000000 -0400
@@ -84,6 +84,20 @@
 	  suspended image to. It will simply pick the first available swap 
 	  device.
 
+config PRESERVE_SWSUSP_IMAGE
+	bool "Preserve swsuspend image"
+	depends on SOFTWARE_SUSPEND
+	default n
+	---help---
+	  Useally boot with swsup destories the swsusp image.
+	  This function enables to preserve swsup image over boot cycle. 
+	  Default behavior is not chaged even this configuration turned on.
+
+	  To preseve swsusp image, specify following option to command line;
+
+		prsv-img
+
+
 config DEFERRED_RESUME
 	bool "Deferred resume"
 	depends on PM
Index: alp-linux--dev-2-6-12--1.7/kernel/power/disk.c
===================================================================
--- alp-linux--dev-2-6-12--1.7.orig/kernel/power/disk.c	2005-07-16 00:43:02.990000000 -0400
+++ alp-linux--dev-2-6-12--1.7/kernel/power/disk.c	2005-07-16 01:01:42.220000000 -0400
@@ -29,10 +29,29 @@
 extern void swsusp_close(void);
 extern int swsusp_resume(void);
 extern int swsusp_free(void);
+extern void dump_pagedir_nosave(void);
 #ifdef	CONFIG_SAFE_SUSPEND
 extern int suspend_remount(void);
 extern int resume_remount(void);
 #endif
+#ifdef CONFIG_PRESERVE_SWSUSP_IMAGE
+extern int preserve_swsusp_image;
+extern dev_t swsusp_resume_device_nosave __nosavedata;
+extern int swsusp_swap_rdonly(dev_t);
+extern int swsusp_swap_off(dev_t);
+#else
+#define preserve_swsusp_image 0
+#define swsusp_resume_device_nosave 0
+static inline int swsusp_swap_rdonly(dev_t dev)
+{
+	return 0;
+}
+static inline int swsusp_swap_off(dev_t dev)
+{
+	return 0;
+}
+#endif
+
 
 
 static int noresume = 0;
@@ -135,6 +154,26 @@
 	pm_restore_console();
 }
 
+#ifdef CONFIG_PRESERVE_SWSUSP_IMAGE
+void finish_in_resume(void)
+{
+	device_resume();
+	platform_finish();
+	enable_nonboot_cpus();
+	thaw_processes();
+	if (preserve_swsusp_image) {
+		swsusp_swap_off(swsusp_resume_device_nosave);
+	}
+	pm_restore_console();
+}
+#else
+void finish_in_resume(void)
+{
+	finish();
+}
+#endif
+
+
 extern atomic_t on_suspend;   /* See refrigerator() */
 
 static int prepare_processes(void)
@@ -234,8 +273,15 @@
 		error = swsusp_write();
 		if (!error)
 			power_down(pm_disk_mode);
-	} else
+	} else  {
 		pr_debug("PM: Image restored successfully.\n");
+		if (preserve_swsusp_image) {
+			swsusp_swap_rdonly(swsusp_resume_device_nosave);
+		}
+		swsusp_free();
+		finish_in_resume();
+		return 0;
+	}
 	swsusp_free();
  Done:
 	finish();
Index: alp-linux--dev-2-6-12--1.7/kernel/power/swsusp.c
===================================================================
--- alp-linux--dev-2-6-12--1.7.orig/kernel/power/swsusp.c	2005-07-16 00:43:03.000000000 -0400
+++ alp-linux--dev-2-6-12--1.7/kernel/power/swsusp.c	2005-07-16 00:56:22.170000000 -0400
@@ -128,6 +128,11 @@
 
 static struct swsusp_info swsusp_info;
 
+#ifdef CONFIG_PRESERVE_SWSUSP_IMAGE
+dev_t swsusp_resume_device_nosave __nosavedata;
+struct swsusp_header swsusp_header_nosave __nosavedata ;
+#endif
+
 /*
  * XXX: We try to keep some more pages free so that I/O operations succeed
  * without paging. Might this be more?
@@ -139,6 +144,24 @@
 #define PAGES_FOR_IO	512
 #endif
 
+#ifdef CONFIG_PRESERVE_SWSUSP_IMAGE
+int preserve_swsusp_image=0;
+static  int __init preserve_swsusp_image_setup(char *str)
+{
+	if (*str)
+		return 0;
+	preserve_swsusp_image = 1;
+	return 1;
+}
+#else
+static  int __init preserve_swsusp_image_setup(char *str)
+{
+	return 0;
+}
+#endif
+
+__setup("prsv-img", preserve_swsusp_image_setup);
+
 /*
  * Saving part...
  */
@@ -1250,6 +1273,53 @@
 	return error;
 }
 
+#ifdef CONFIG_PRESERVE_SWSUSP_IMAGE
+/**
+ *	mark_swapfiles - Revert swap signature
+ *	
+ *	Assumed that swsusp_header holds correct data 
+ *	and rw_swap_page_sync() works
+ */
+int mark_swsusp(dev_t dev)
+{
+	int	error;
+
+	resume_bdev = open_by_devnum(dev, FMODE_WRITE);
+	if (!IS_ERR(resume_bdev)) {
+		set_blocksize(resume_bdev, PAGE_SIZE);
+		error = bio_write_page(0, &swsusp_header_nosave);
+		blkdev_put(resume_bdev);
+	} else
+		error = PTR_ERR(resume_bdev);
+
+	if (!error)
+		pr_debug("swsusp: Mark swsusp again\n");
+	else
+		pr_debug("swsusp: Error %d marking swsusp\n", error);
+	return error;
+}
+
+inline static void update_swsusp_header(void)
+{
+	swsusp_header_nosave=swsusp_header;
+}
+
+inline static void update_swsusp_device(void)
+{
+	swsusp_resume_device_nosave = swsusp_resume_device;
+}
+#else
+inline static void update_swsusp_header(void)
+{
+	;
+}
+
+inline static void update_swsusp_device(void)
+{
+	;
+}
+#endif
+
 static int check_sig(void)
 {
 	int error;
@@ -1258,6 +1328,7 @@
 	if ((error = bio_read_page(0, &swsusp_header)))
 		return error;
 	if (!memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) {
+		update_swsusp_header();
 		memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10);
 
 		/*
@@ -1412,6 +1483,7 @@
 		pr_debug("swsusp: Resume From Partition %d:%d\n",
 			 MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device));
 	}
+	update_swsusp_device();
 
 	resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ);
 	if (!IS_ERR(resume_bdev)) {
Index: alp-linux--dev-2-6-12--1.7/mm/swapfile.c
===================================================================
--- alp-linux--dev-2-6-12--1.7.orig/mm/swapfile.c	2005-07-15 10:34:54.000000000 -0400
+++ alp-linux--dev-2-6-12--1.7/mm/swapfile.c	2005-07-16 00:43:31.000000000 -0400
@@ -1065,6 +1065,186 @@
 }
 #endif
 
+#ifdef CONFIG_PRESERVE_SWSUSP_IMAGE
+extern int mark_swsusp(dev_t);
+
+#ifdef DEBUG
+extern void cons_write(char *);
+
+#undef pr_debug
+#define pr_debug(fmt,arg...) \
+        do {    \
+		char __cw_buf[64]; \
+		__cw_buf[63]='\0'; \
+                snprintf(__cw_buf, 63, fmt,##arg);   \
+                cons_write(__cw_buf);   \
+        } while (0)
+#endif	/*DEBUG*/
+
+/**
+ *  find_swapdev_info - Find swap block device info, currently used
+ *
+ */
+
+static struct swap_info_struct *find_swapdev_info(dev_t dev,
+					int *p_prev, int *p_type)
+{
+	int prev, type;
+	struct inode *inode;
+	struct swap_info_struct * si = NULL;
+
+	prev = -1;
+	for (type = swap_list.head; type >= 0; type = swap_info[type].next) {
+		si = swap_info + type;
+		pr_debug("P:0x%8.8x, TYPE:0x%8.8x\n", (int)si, type);
+		if (si->flags & SWP_USED) {
+			inode = si->swap_file->f_mapping->host;
+			if (S_ISBLK(inode->i_mode)) {
+				pr_debug("INODE: 0x%8.8x:0x%8.8x\n", 
+					dev, 
+					MKDEV(imajor(inode), iminor(inode)));
+				if (dev == MKDEV(imajor(inode), iminor(inode)))
+					break;
+			}
+		}
+		prev = type;
+	}
+
+	if (type<0) {
+		si = 0;
+	}
+	*p_type = type;
+	*p_prev = prev;
+	return si;
+}
+
+/**
+ * swsusp_swap_rdonly - Find Swap device for swsusp and mark ReadOnly
+ *
+ */
+int swsusp_swap_rdonly(dev_t resume_dev)
+{
+	struct swap_info_struct * si = NULL;
+	int prev;
+	int type;
+	int found=0;
+
+	swap_list_lock();
+
+	si = find_swapdev_info(resume_dev, &prev, &type);
+	if (si) {
+		si->flags &= ~SWP_WRITEOK;
+		found = 1;
+	}
+	swap_list_unlock();
+	return found;
+
+}
+
+/**
+ * swsusp_swpoff -  Turn off swap and set signature for swsusp image
+ *
+ */
+int swsusp_swap_off(dev_t resume_dev)
+{
+	struct swap_info_struct * si = NULL;
+	unsigned short *swap_map;
+	int i;
+	int type, prev;
+	struct block_device *bdev;
+	int err = 0;
+
+	swap_list_lock();
+
+	si = find_swapdev_info(resume_dev, &prev, &type);
+
+	/* swap area for swsusp image is not writable */
+	if ((!si) || (si->flags & SWP_WRITEOK)) {
+		err = -EINVAL;
+		swap_list_unlock();
+		goto out;
+	}
+
+	if (!security_vm_enough_memory(si->pages)) {
+		vm_unacct_memory(si->pages);
+	} else {
+		err = -ENOMEM;
+		si->flags |= SWP_WRITEOK;
+		swap_list_unlock();
+		goto out;
+	}
+
+	pr_debug("swsusp_swapoff:inuse_pages:%ld\n", si->inuse_pages);
+	pr_debug("swsusp_swapoff:pages:%d\n", si->pages);
+	if (prev < 0) {
+		swap_list.head = si->next;
+	} else {
+		swap_info[prev].next = si->next;
+	}
+	if (type == swap_list.next) {
+		/* just pick something that's safe... */
+		swap_list.next = swap_list.head;
+	}
+	nr_swap_pages -= si->pages;
+	total_swap_pages -= si->pages;
+	bdev = I_BDEV(si->swap_file->f_mapping->host);
+	swap_list_unlock();
+
+	current->flags |= PF_SWAPOFF;
+	err = try_to_unuse(type);
+	current->flags &= ~PF_SWAPOFF;
+
+	/* wait for any unplug function to finish */
+	down_write(&swap_unplug_sem);
+	up_write(&swap_unplug_sem);
+
+	if (err) {
+		pr_debug("swsusp_swapoff:err:%d\n", err);
+		/* re-insert swap space back into swap_list */
+		swap_list_lock();
+		for (prev = -1, i = swap_list.head; i >= 0; prev = i, i = swap_info[i].next)
+			if (si->prio >= swap_info[i].prio)
+				break;
+		si->next = i;
+		if (prev < 0)
+			swap_list.head = swap_list.next = si - swap_info;
+		else
+			swap_info[prev].next = si - swap_info;
+		nr_swap_pages += si->pages;
+		total_swap_pages += si->pages;
+		si->flags |= SWP_WRITEOK;
+		swap_list_unlock();
+		goto out;
+	}
+
+	down(&swapon_sem);
+	swap_list_lock();
+	drain_mmlist();
+	swap_device_lock(si);
+	si->swap_file = NULL;
+	si->max = 0;
+	swap_map = si->swap_map;
+	si->swap_map = NULL;
+	si->flags = 0;
+	destroy_swap_extents(si);
+	swap_device_unlock(si);
+	swap_list_unlock();
+	up(&swapon_sem);
+	vfree(swap_map);
+
+	/* set SWSUSP signature, again */
+	mark_swsusp(resume_dev);
+
+	/* release device */
+	set_blocksize(bdev, si->old_block_size);
+	bd_release(bdev);
+	err = 0;
+
+out:
+	return err;
+}
+#endif /*CONFIG_PRESERVE_SWSUSP_IMAGE*/
+
 asmlinkage long sys_swapoff(const char __user * specialfile)
 {
 	struct swap_info_struct * p = NULL;
---





^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Preserve hibenate-system-image on startup
  2005-07-17  6:26 [PATCH] Preserve hibenate-system-image on startup Hiroyuki Machida
@ 2005-07-17 16:58 ` Nigel Cunningham
  2005-07-20 10:54   ` Hiroyuki Machida
  2005-07-18 11:41 ` Pavel Machek
  1 sibling, 1 reply; 5+ messages in thread
From: Nigel Cunningham @ 2005-07-17 16:58 UTC (permalink / raw)
  To: Hiroyuki Machida; +Cc: Linux Kernel Mailing List

Hi.

We've had this feature in Suspend2 for a couple of years and I can
confirm that the approach works, provided that the on-disk filesystem
remains unchanged throughout this. (Useful mainly for kiosks etc).

This is not to say that I've reviewed the code below for correctness.

Regards,

Nigel

On Sun, 2005-07-17 at 16:26, Hiroyuki Machida wrote:
> We are now investigating fast startup/shutdown using
> 2.6 kernel PM functions.
> 
> An attached patch enables kernel to preserve system image
> on startup, to implement "Snapshot boot".Majordomo@vger.kernel.org wrote:
> Conventionally system image will be broken after startup.
> 
> Snapshot boot uses un-hibernate from a permanent system image for
> startup. During shutdown, does a conventional shutdown without
> saving a system image.
> 
> We'll explain concept and initial work at OLS. So if you have
> interest, we can talk with you at Ottawa.
> 
> Thanks,
> Hiroyuki Machida
> 
> ---
> 
> This patch enables preserving swsuspend system image over boot cycle, 
> against 2.6.12
> 
> Signed-off-by: Hiroyui Machida <machida@sony.co.jp> for CELF
> 
> -----------------
> Index: alp-linux--dev-2-6-12--1.7/kernel/power/Kconfig
> ===================================================================
> --- alp-linux--dev-2-6-12--1.7.orig/kernel/power/Kconfig	2005-07-15 14:59:20.000000000 -0400
> +++ alp-linux--dev-2-6-12--1.7/kernel/power/Kconfig	2005-07-16 00:43:31.420000000 -0400
> @@ -84,6 +84,20 @@
>  	  suspended image to. It will simply pick the first available swap 
>  	  device.
>  
> +config PRESERVE_SWSUSP_IMAGE
> +	bool "Preserve swsuspend image"
> +	depends on SOFTWARE_SUSPEND
> +	default n
> +	---help---
> +	  Useally boot with swsup destories the swsusp image.
> +	  This function enables to preserve swsup image over boot cycle. 
> +	  Default behavior is not chaged even this configuration turned on.
> +
> +	  To preseve swsusp image, specify following option to command line;
> +
> +		prsv-img
> +
> +
>  config DEFERRED_RESUME
>  	bool "Deferred resume"
>  	depends on PM
> Index: alp-linux--dev-2-6-12--1.7/kernel/power/disk.c
> ===================================================================
> --- alp-linux--dev-2-6-12--1.7.orig/kernel/power/disk.c	2005-07-16 00:43:02.990000000 -0400
> +++ alp-linux--dev-2-6-12--1.7/kernel/power/disk.c	2005-07-16 01:01:42.220000000 -0400
> @@ -29,10 +29,29 @@
>  extern void swsusp_close(void);
>  extern int swsusp_resume(void);
>  extern int swsusp_free(void);
> +extern void dump_pagedir_nosave(void);
>  #ifdef	CONFIG_SAFE_SUSPEND
>  extern int suspend_remount(void);
>  extern int resume_remount(void);
>  #endif
> +#ifdef CONFIG_PRESERVE_SWSUSP_IMAGE
> +extern int preserve_swsusp_image;
> +extern dev_t swsusp_resume_device_nosave __nosavedata;
> +extern int swsusp_swap_rdonly(dev_t);
> +extern int swsusp_swap_off(dev_t);
> +#else
> +#define preserve_swsusp_image 0
> +#define swsusp_resume_device_nosave 0
> +static inline int swsusp_swap_rdonly(dev_t dev)
> +{
> +	return 0;
> +}
> +static inline int swsusp_swap_off(dev_t dev)
> +{
> +	return 0;
> +}
> +#endif
> +
>  
> 
>  static int noresume = 0;
> @@ -135,6 +154,26 @@
>  	pm_restore_console();
>  }
>  
> +#ifdef CONFIG_PRESERVE_SWSUSP_IMAGE
> +void finish_in_resume(void)
> +{
> +	device_resume();
> +	platform_finish();
> +	enable_nonboot_cpus();
> +	thaw_processes();
> +	if (preserve_swsusp_image) {
> +		swsusp_swap_off(swsusp_resume_device_nosave);
> +	}
> +	pm_restore_console();
> +}
> +#else
> +void finish_in_resume(void)
> +{
> +	finish();
> +}
> +#endif
> +
> +
>  extern atomic_t on_suspend;   /* See refrigerator() */
>  
>  static int prepare_processes(void)
> @@ -234,8 +273,15 @@
>  		error = swsusp_write();
>  		if (!error)
>  			power_down(pm_disk_mode);
> -	} else
> +	} else  {
>  		pr_debug("PM: Image restored successfully.\n");
> +		if (preserve_swsusp_image) {
> +			swsusp_swap_rdonly(swsusp_resume_device_nosave);
> +		}
> +		swsusp_free();
> +		finish_in_resume();
> +		return 0;
> +	}
>  	swsusp_free();
>   Done:
>  	finish();
> Index: alp-linux--dev-2-6-12--1.7/kernel/power/swsusp.c
> ===================================================================
> --- alp-linux--dev-2-6-12--1.7.orig/kernel/power/swsusp.c	2005-07-16 00:43:03.000000000 -0400
> +++ alp-linux--dev-2-6-12--1.7/kernel/power/swsusp.c	2005-07-16 00:56:22.170000000 -0400
> @@ -128,6 +128,11 @@
>  
>  static struct swsusp_info swsusp_info;
>  
> +#ifdef CONFIG_PRESERVE_SWSUSP_IMAGE
> +dev_t swsusp_resume_device_nosave __nosavedata;
> +struct swsusp_header swsusp_header_nosave __nosavedata ;
> +#endif
> +
>  /*
>   * XXX: We try to keep some more pages free so that I/O operations succeed
>   * without paging. Might this be more?
> @@ -139,6 +144,24 @@
>  #define PAGES_FOR_IO	512
>  #endif
>  
> +#ifdef CONFIG_PRESERVE_SWSUSP_IMAGE
> +int preserve_swsusp_image=0;
> +static  int __init preserve_swsusp_image_setup(char *str)
> +{
> +	if (*str)
> +		return 0;
> +	preserve_swsusp_image = 1;
> +	return 1;
> +}
> +#else
> +static  int __init preserve_swsusp_image_setup(char *str)
> +{
> +	return 0;
> +}
> +#endif
> +
> +__setup("prsv-img", preserve_swsusp_image_setup);
> +
>  /*
>   * Saving part...
>   */
> @@ -1250,6 +1273,53 @@
>  	return error;
>  }
>  
> +#ifdef CONFIG_PRESERVE_SWSUSP_IMAGE
> +/**
> + *	mark_swapfiles - Revert swap signature
> + *	
> + *	Assumed that swsusp_header holds correct data 
> + *	and rw_swap_page_sync() works
> + */
> +int mark_swsusp(dev_t dev)
> +{
> +	int	error;
> +
> +	resume_bdev = open_by_devnum(dev, FMODE_WRITE);
> +	if (!IS_ERR(resume_bdev)) {
> +		set_blocksize(resume_bdev, PAGE_SIZE);
> +		error = bio_write_page(0, &swsusp_header_nosave);
> +		blkdev_put(resume_bdev);
> +	} else
> +		error = PTR_ERR(resume_bdev);
> +
> +	if (!error)
> +		pr_debug("swsusp: Mark swsusp again\n");
> +	else
> +		pr_debug("swsusp: Error %d marking swsusp\n", error);
> +	return error;
> +}
> +
> +inline static void update_swsusp_header(void)
> +{
> +	swsusp_header_nosave=swsusp_header;
> +}
> +
> +inline static void update_swsusp_device(void)
> +{
> +	swsusp_resume_device_nosave = swsusp_resume_device;
> +}
> +#else
> +inline static void update_swsusp_header(void)
> +{
> +	;
> +}
> +
> +inline static void update_swsusp_device(void)
> +{
> +	;
> +}
> +#endif
> +
>  static int check_sig(void)
>  {
>  	int error;
> @@ -1258,6 +1328,7 @@
>  	if ((error = bio_read_page(0, &swsusp_header)))
>  		return error;
>  	if (!memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) {
> +		update_swsusp_header();
>  		memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10);
>  
>  		/*
> @@ -1412,6 +1483,7 @@
>  		pr_debug("swsusp: Resume From Partition %d:%d\n",
>  			 MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device));
>  	}
> +	update_swsusp_device();
>  
>  	resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ);
>  	if (!IS_ERR(resume_bdev)) {
> Index: alp-linux--dev-2-6-12--1.7/mm/swapfile.c
> ===================================================================
> --- alp-linux--dev-2-6-12--1.7.orig/mm/swapfile.c	2005-07-15 10:34:54.000000000 -0400
> +++ alp-linux--dev-2-6-12--1.7/mm/swapfile.c	2005-07-16 00:43:31.000000000 -0400
> @@ -1065,6 +1065,186 @@
>  }
>  #endif
>  
> +#ifdef CONFIG_PRESERVE_SWSUSP_IMAGE
> +extern int mark_swsusp(dev_t);
> +
> +#ifdef DEBUG
> +extern void cons_write(char *);
> +
> +#undef pr_debug
> +#define pr_debug(fmt,arg...) \
> +        do {    \
> +		char __cw_buf[64]; \
> +		__cw_buf[63]='\0'; \
> +                snprintf(__cw_buf, 63, fmt,##arg);   \
> +                cons_write(__cw_buf);   \
> +        } while (0)
> +#endif	/*DEBUG*/
> +
> +/**
> + *  find_swapdev_info - Find swap block device info, currently used
> + *
> + */
> +
> +static struct swap_info_struct *find_swapdev_info(dev_t dev,
> +					int *p_prev, int *p_type)
> +{
> +	int prev, type;
> +	struct inode *inode;
> +	struct swap_info_struct * si = NULL;
> +
> +	prev = -1;
> +	for (type = swap_list.head; type >= 0; type = swap_info[type].next) {
> +		si = swap_info + type;
> +		pr_debug("P:0x%8.8x, TYPE:0x%8.8x\n", (int)si, type);
> +		if (si->flags & SWP_USED) {
> +			inode = si->swap_file->f_mapping->host;
> +			if (S_ISBLK(inode->i_mode)) {
> +				pr_debug("INODE: 0x%8.8x:0x%8.8x\n", 
> +					dev, 
> +					MKDEV(imajor(inode), iminor(inode)));
> +				if (dev == MKDEV(imajor(inode), iminor(inode)))
> +					break;
> +			}
> +		}
> +		prev = type;
> +	}
> +
> +	if (type<0) {
> +		si = 0;
> +	}
> +	*p_type = type;
> +	*p_prev = prev;
> +	return si;
> +}
> +
> +/**
> + * swsusp_swap_rdonly - Find Swap device for swsusp and mark ReadOnly
> + *
> + */
> +int swsusp_swap_rdonly(dev_t resume_dev)
> +{
> +	struct swap_info_struct * si = NULL;
> +	int prev;
> +	int type;
> +	int found=0;
> +
> +	swap_list_lock();
> +
> +	si = find_swapdev_info(resume_dev, &prev, &type);
> +	if (si) {
> +		si->flags &= ~SWP_WRITEOK;
> +		found = 1;
> +	}
> +	swap_list_unlock();
> +	return found;
> +
> +}
> +
> +/**
> + * swsusp_swpoff -  Turn off swap and set signature for swsusp image
> + *
> + */
> +int swsusp_swap_off(dev_t resume_dev)
> +{
> +	struct swap_info_struct * si = NULL;
> +	unsigned short *swap_map;
> +	int i;
> +	int type, prev;
> +	struct block_device *bdev;
> +	int err = 0;
> +
> +	swap_list_lock();
> +
> +	si = find_swapdev_info(resume_dev, &prev, &type);
> +
> +	/* swap area for swsusp image is not writable */
> +	if ((!si) || (si->flags & SWP_WRITEOK)) {
> +		err = -EINVAL;
> +		swap_list_unlock();
> +		goto out;
> +	}
> +
> +	if (!security_vm_enough_memory(si->pages)) {
> +		vm_unacct_memory(si->pages);
> +	} else {
> +		err = -ENOMEM;
> +		si->flags |= SWP_WRITEOK;
> +		swap_list_unlock();
> +		goto out;
> +	}
> +
> +	pr_debug("swsusp_swapoff:inuse_pages:%ld\n", si->inuse_pages);
> +	pr_debug("swsusp_swapoff:pages:%d\n", si->pages);
> +	if (prev < 0) {
> +		swap_list.head = si->next;
> +	} else {
> +		swap_info[prev].next = si->next;
> +	}
> +	if (type == swap_list.next) {
> +		/* just pick something that's safe... */
> +		swap_list.next = swap_list.head;
> +	}
> +	nr_swap_pages -= si->pages;
> +	total_swap_pages -= si->pages;
> +	bdev = I_BDEV(si->swap_file->f_mapping->host);
> +	swap_list_unlock();
> +
> +	current->flags |= PF_SWAPOFF;
> +	err = try_to_unuse(type);
> +	current->flags &= ~PF_SWAPOFF;
> +
> +	/* wait for any unplug function to finish */
> +	down_write(&swap_unplug_sem);
> +	up_write(&swap_unplug_sem);
> +
> +	if (err) {
> +		pr_debug("swsusp_swapoff:err:%d\n", err);
> +		/* re-insert swap space back into swap_list */
> +		swap_list_lock();
> +		for (prev = -1, i = swap_list.head; i >= 0; prev = i, i = swap_info[i].next)
> +			if (si->prio >= swap_info[i].prio)
> +				break;
> +		si->next = i;
> +		if (prev < 0)
> +			swap_list.head = swap_list.next = si - swap_info;
> +		else
> +			swap_info[prev].next = si - swap_info;
> +		nr_swap_pages += si->pages;
> +		total_swap_pages += si->pages;
> +		si->flags |= SWP_WRITEOK;
> +		swap_list_unlock();
> +		goto out;
> +	}
> +
> +	down(&swapon_sem);
> +	swap_list_lock();
> +	drain_mmlist();
> +	swap_device_lock(si);
> +	si->swap_file = NULL;
> +	si->max = 0;
> +	swap_map = si->swap_map;
> +	si->swap_map = NULL;
> +	si->flags = 0;
> +	destroy_swap_extents(si);
> +	swap_device_unlock(si);
> +	swap_list_unlock();
> +	up(&swapon_sem);
> +	vfree(swap_map);
> +
> +	/* set SWSUSP signature, again */
> +	mark_swsusp(resume_dev);
> +
> +	/* release device */
> +	set_blocksize(bdev, si->old_block_size);
> +	bd_release(bdev);
> +	err = 0;
> +
> +out:
> +	return err;
> +}
> +#endif /*CONFIG_PRESERVE_SWSUSP_IMAGE*/
> +
>  asmlinkage long sys_swapoff(const char __user * specialfile)
>  {
>  	struct swap_info_struct * p = NULL;
> ---
> 
> 
> 
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
-- 
Evolution.
Enumerate the requirements.
Consider the interdependencies.
Calculate the probabilities.
Be amazed that people believe it happened. 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Preserve hibenate-system-image on startup
  2005-07-17  6:26 [PATCH] Preserve hibenate-system-image on startup Hiroyuki Machida
  2005-07-17 16:58 ` Nigel Cunningham
@ 2005-07-18 11:41 ` Pavel Machek
  1 sibling, 0 replies; 5+ messages in thread
From: Pavel Machek @ 2005-07-18 11:41 UTC (permalink / raw)
  To: Hiroyuki Machida; +Cc: linux-kernel

Hi!

> We are now investigating fast startup/shutdown using
> 2.6 kernel PM functions.
> 
> An attached patch enables kernel to preserve system image
> on startup, to implement "Snapshot boot".Majordomo@vger.kernel.org wrote:
> Conventionally system image will be broken after startup.
> 
> Snapshot boot uses un-hibernate from a permanent system image for
> startup. During shutdown, does a conventional shutdown without
> saving a system image.
> 
> We'll explain concept and initial work at OLS. So if you have
> interest, we can talk with you at Ottawa.

Interesting....

> +config PRESERVE_SWSUSP_IMAGE
> +	bool "Preserve swsuspend image"
> +	depends on SOFTWARE_SUSPEND
> +	default n
> +	---help---
> +	  Useally boot with swsup destories the swsusp image.
> +	  This function enables to preserve swsup image over boot cycle. 
> +	  Default behavior is not chaged even this configuration turned on.
> +
> +	  To preseve swsusp image, specify following option to command line;
> +
> +		prsv-img

You are missing "eeeae" here.

> +}
> +
> +/**
> + * swsusp_swpoff -  Turn off swap and set signature for swsusp image
             ~~~~~~
		missing "a".

In general, the patch looks a bit too long, given it only needs to
comment out one write...
								Pavel

-- 
teflon -- maybe it is a trademark, but it should not be.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Preserve hibenate-system-image on startup
  2005-07-17 16:58 ` Nigel Cunningham
@ 2005-07-20 10:54   ` Hiroyuki Machida
  2005-07-20 15:25     ` Nigel Cunningham
  0 siblings, 1 reply; 5+ messages in thread
From: Hiroyuki Machida @ 2005-07-20 10:54 UTC (permalink / raw)
  To: ncunningham; +Cc: Linux Kernel Mailing List

Hi,


With this function, system needs to mount read-write file systems on
every boot cycle, due to avoid inconsistency between FS and memory.
How did you address this problem? Did kernel check RW FS remained as
mounted on boot up or hibernate time ?


I think I need to discuss with you at San Jose at the beginning of 
this year.


Regards,
Hiroyuki Machida

Nigel Cunningham wrote:
> Hi.
> 
> We've had this feature in Suspend2 for a couple of years and I can
> confirm that the approach works, provided that the on-disk filesystem
> remains unchanged throughout this. (Useful mainly for kiosks etc).
> 
> This is not to say that I've reviewed the code below for correctness.
> 
> Regards,


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Preserve hibenate-system-image on startup
  2005-07-20 10:54   ` Hiroyuki Machida
@ 2005-07-20 15:25     ` Nigel Cunningham
  0 siblings, 0 replies; 5+ messages in thread
From: Nigel Cunningham @ 2005-07-20 15:25 UTC (permalink / raw)
  To: Hiroyuki Machida; +Cc: Linux Kernel Mailing List

Hi.

On Wed, 2005-07-20 at 20:54, Hiroyuki Machida wrote:
> Hi,
> 
> 
> With this function, system needs to mount read-write file systems on
> every boot cycle, due to avoid inconsistency between FS and memory.
> How did you address this problem? Did kernel check RW FS remained as
> mounted on boot up or hibernate time ?

You're right. We don't seek to address this problem, just document
clearly that filesystems in use when creating the image need to be
mounted readonly. You can of course mount another filesystem read/write
while the system is up.

> I think I need to discuss with you at San Jose at the beginning of 
> this year.

Yes, I think we did meet. Nice to talk to you again.

Regards,

Nigel

> 
> Regards,
> Hiroyuki Machida
> 
> Nigel Cunningham wrote:
> > Hi.
> > 
> > We've had this feature in Suspend2 for a couple of years and I can
> > confirm that the approach works, provided that the on-disk filesystem
> > remains unchanged throughout this. (Useful mainly for kiosks etc).
> > 
> > This is not to say that I've reviewed the code below for correctness.
> > 
> > Regards,
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
-- 
Evolution.
Enumerate the requirements.
Consider the interdependencies.
Calculate the probabilities.


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-07-21  2:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-07-17  6:26 [PATCH] Preserve hibenate-system-image on startup Hiroyuki Machida
2005-07-17 16:58 ` Nigel Cunningham
2005-07-20 10:54   ` Hiroyuki Machida
2005-07-20 15:25     ` Nigel Cunningham
2005-07-18 11:41 ` Pavel Machek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox