mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Nigel Cunningham <nigel@suspend2.net>
To: linux-kernel@vger.kernel.org
Subject: [Suspend2][ 15/19] [Suspend2] Core of code for reading pageset1.
Date: Tue, 27 Jun 2006 08:36:49 +1000	[thread overview]
Message-ID: <20060626223648.4219.80371.stgit@nigel.suspend2.net> (raw)
In-Reply-To: <20060626223557.4219.53030.stgit@nigel.suspend2.net>

Core code for reading pageset1, which checks that an image exists, that we
haven't been told not to resume (noresume2) and that the user wants to try
again if we've tried before. Once these tests are passed, we start to read
the image header, checking that the sanity checks are passed, and then the
image proper.

Signed-off-by: Nigel Cunningham <nigel@suspend2.net>

 kernel/power/io.c |  183 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 183 insertions(+), 0 deletions(-)

diff --git a/kernel/power/io.c b/kernel/power/io.c
index 8c9c284..35fb081 100644
--- a/kernel/power/io.c
+++ b/kernel/power/io.c
@@ -715,3 +715,186 @@ static char *sanity_check(struct suspend
 	return 0;
 }
 
+/* __read_pageset1
+ *
+ * Description:	Test for the existence of an image and attempt to load it.
+ * Returns:	Int. Zero if image found and pageset1 successfully loaded.
+ * 		Error if no image found or loaded.
+ */
+static int __read_pageset1(void)
+{			
+	int i, result = 0;
+	char *header_buffer = (char *) get_zeroed_page(GFP_ATOMIC),
+	     *sanity_error = NULL;
+	struct suspend_header *suspend_header;
+
+	if (!header_buffer)
+		return -ENOMEM;
+	
+	/* Check for an image */
+	if (!(result = suspend_active_writer->image_exists())) {
+		result = -ENODATA;
+		noresume_reset_modules();
+		goto out;
+	}
+
+	/* Check for noresume command line option */
+	if (test_suspend_state(SUSPEND_NORESUME_SPECIFIED)) {
+		suspend_active_writer->invalidate_image();
+		result = -EINVAL;
+		noresume_reset_modules();
+		goto out;
+	}
+
+	/* Check whether we've resumed before */
+	if (test_suspend_state(SUSPEND_RESUMED_BEFORE)) {
+		int resumed_before_default = 0;
+		if (test_suspend_state(SUSPEND_RETRY_RESUME))
+			resumed_before_default = SUSPEND_CONTINUE_REQ;
+		suspend_early_boot_message(1, resumed_before_default, NULL);
+		clear_suspend_state(SUSPEND_RETRY_RESUME);
+		if (!(test_suspend_state(SUSPEND_CONTINUE_REQ))) {
+			suspend_active_writer->invalidate_image();
+			result = -EINVAL;
+			noresume_reset_modules();
+			goto out;
+		}
+	}
+
+	clear_suspend_state(SUSPEND_CONTINUE_REQ);
+
+	/* 
+	 * Prepare the active writer for reading the image header. The
+	 * activate writer might read its own configuration.
+	 * 
+	 * NB: This call may never return because there might be a signature
+	 * for a different image such that we warn the user and they choose
+	 * to reboot. (If the device ids look erroneous (2.4 vs 2.6) or the
+	 * location of the image might be unavailable if it was stored on a
+	 * network connection.
+	 */
+
+	if ((result = suspend_active_writer->read_header_init())) {
+		noresume_reset_modules();
+		goto out;
+	}
+	
+	/* Read suspend header */
+	if ((result = suspend_active_writer->rw_header_chunk(READ, NULL,
+			header_buffer, sizeof(struct suspend_header))) < 0) {
+		noresume_reset_modules();
+		goto out;
+	}
+	
+	suspend_header = (struct suspend_header *) header_buffer;
+
+	/*
+	 * NB: This call may also result in a reboot rather than returning.
+	 */
+
+	if ((sanity_error = sanity_check(suspend_header)) &&
+	    suspend_early_boot_message(1, SUSPEND_CONTINUE_REQ, sanity_error)) {
+		suspend_active_writer->invalidate_image();
+		result = -EINVAL;
+		noresume_reset_modules();
+		goto out;
+	}
+
+	/*
+	 * We have an image and it looks like it will load okay.
+	 */
+
+	/* Get metadata from header. Don't override commandline parameters.
+	 *
+	 * We don't need to save the image size limit because it's not used
+	 * during resume and will be restored with the image anyway.
+	 */
+	
+	suspend_orig_mem_free = suspend_header->orig_mem_free;
+	memcpy((char *) &pagedir1,
+		(char *) &suspend_header->pagedir, sizeof(pagedir1));
+	suspend_result = suspend_header->param0;
+	suspend_action = suspend_header->param1;
+	suspend_debug_state = suspend_header->param2;
+	console_loglevel = suspend_header->param3;
+	clear_suspend_state(SUSPEND_IGNORE_LOGLEVEL);
+	pagedir2.pageset_size = suspend_header->pageset_2_size;
+	for (i = 0; i < 4; i++)
+		suspend_io_time[i/2][i%2] =
+			suspend_header->io_time[i/2][i%2];
+
+	/* Read module configurations */
+	if ((result = read_module_configs())) {
+		noresume_reset_modules();
+		pagedir1.pageset_size =
+			pagedir2.pageset_size = 0;
+		goto out;
+	}
+
+	suspend_prepare_console();
+
+	suspend_cond_pause(1, "About to read original pageset1 locations.");
+
+	/*
+	 * Read original pageset1 locations. These are the addresses we can't
+	 * use for the data to be restored.
+	 */
+
+	allocate_dyn_pageflags(&pageset1_map);
+	load_dyn_pageflags(pageset1_map);
+
+	set_suspend_state(SUSPEND_NOW_RESUMING);
+
+	/* Relocate it so that it's not overwritten while we're using it to
+	 * copy the original contents back */
+	relocate_dyn_pageflags(&pageset1_map);
+	
+	allocate_dyn_pageflags(&pageset1_copy_map);
+	relocate_dyn_pageflags(&pageset1_copy_map);
+
+	/* Clean up after reading the header */
+	if ((result = suspend_active_writer->read_header_cleanup())) {
+		noresume_reset_modules();
+		goto out_reset_console;
+	}
+
+	suspend_cond_pause(1, "About to read pagedir.");
+
+	/* 
+	 * Get the addresses of pages into which we will load the kernel to
+	 * be copied back
+	 */
+	if (suspend_get_pageset1_load_addresses()) {
+		result = -ENOMEM;
+		noresume_reset_modules();
+		goto out_reset_console;
+	}
+
+	/* Read the original kernel back */
+	suspend_cond_pause(1, "About to read pageset 1.");
+
+	if (read_pageset(&pagedir1, 1, 0)) {
+		suspend_prepare_status(CLEAR_BAR, "Failed to read pageset 1.");
+		result = -EPERM;
+		noresume_reset_modules();
+		goto out_reset_console;
+	}
+
+	suspend_cond_pause(1, "About to restore original kernel.");
+	result = 0;
+
+	if (!test_action_state(SUSPEND_KEEP_IMAGE) &&
+	    suspend_active_writer->mark_resume_attempted)
+		suspend_active_writer->mark_resume_attempted();
+
+out:
+	free_page((unsigned long) header_buffer);
+	return result;
+
+out_reset_console:
+	free_dyn_pageflags(&pageset1_map);
+	free_dyn_pageflags(&pageset1_copy_map);
+	suspend_cleanup_console();
+	goto out;
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

  parent reply	other threads:[~2006-06-26 23:22 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-06-26 22:35 [Suspend2][ 00/19] Highlevel I/O routines Nigel Cunningham
2006-06-26 22:36 ` [Suspend2][ 01/19] [Suspend2] Core io.c header Nigel Cunningham
2006-06-26 22:36 ` [Suspend2][ 02/19] [Suspend2] Attempt to parse resume device Nigel Cunningham
2006-06-26 22:36 ` [Suspend2][ 03/19] [Suspend2] Attempt to parse resume device (wrapped) Nigel Cunningham
2006-06-26 22:36 ` [Suspend2][ 04/19] [Suspend2] Reset modules after invalidating an image Nigel Cunningham
2006-06-26 22:36 ` [Suspend2][ 05/19] [Suspend2] Fill the suspend header fields Nigel Cunningham
2006-06-26 22:36 ` [Suspend2][ 06/19] [Suspend2] Initialise modules before doing I/O Nigel Cunningham
2006-06-26 22:36 ` [Suspend2][ 07/19] [Suspend2] Cleanup modules after doing I/O on a portion of the image Nigel Cunningham
2006-06-26 22:36 ` [Suspend2][ 08/19] [Suspend2] I/O main loop Nigel Cunningham
2006-06-26 22:36 ` [Suspend2][ 09/19] [Suspend2] Write a pageset Nigel Cunningham
2006-06-26 22:36 ` [Suspend2][ 10/19] [Suspend2] Read a portion of the image from storage Nigel Cunningham
2006-06-26 22:36 ` [Suspend2][ 11/19] [Suspend2] Write module configurations in an image header Nigel Cunningham
2006-06-26 22:36 ` [Suspend2][ 12/19] [Suspend2] Read module configs from " Nigel Cunningham
2006-06-26 22:36 ` [Suspend2][ 13/19] [Suspend2] Write " Nigel Cunningham
2006-06-26 22:36 ` [Suspend2][ 14/19] [Suspend2] Sanity check " Nigel Cunningham
2006-06-26 22:36 ` Nigel Cunningham [this message]
2006-06-26 22:36 ` [Suspend2][ 16/19] [Suspend2] Read pageset1 Nigel Cunningham
2006-06-26 22:36 ` [Suspend2][ 17/19] [Suspend2] Get image_exists data Nigel Cunningham
2006-06-26 22:36 ` [Suspend2][ 18/19] [Suspend2] Read pageset2 Nigel Cunningham
2006-06-26 22:37 ` [Suspend2][ 19/19] [Suspend2] I/O header file Nigel Cunningham

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20060626223648.4219.80371.stgit@nigel.suspend2.net \
    --to=nigel@suspend2.net \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome