diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2008-06-11 20:46:51 +0000 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2008-06-11 20:46:51 +0000 |
commit | 9457df86578d7884382a59218b72364635db4d3d (patch) | |
tree | 1bddc4e523bd2b0f0c34c048479a3df60cc9502d | |
parent | 5be998fab03075034ceb1fb29d6af206dea7c07f (diff) | |
download | suspend-utils-9457df86578d7884382a59218b72364635db4d3d.tar.gz |
Allow the user to reboot and try again if the freezing of tasks fails during
resume from hibernation.
-rw-r--r-- | resume.c | 123 |
1 files changed, 73 insertions, 50 deletions
@@ -218,63 +218,51 @@ static void pause_resume(int pause) splash.restore_abort(&savedtrm); } -static int read_image(int dev, int fd, struct swsusp_header *swsusp_header) +static void reboot_question(char *message) +{ + char c; + char full_message[SPLASH_GENERIC_MESSAGE_SIZE]; + char *warning = + "\n\tYou can now boot the system and lose the saved state\n" + "\tor reboot and try again.\n\n" + "\t[Notice that if you decide to reboot, you MUST NOT mount\n" + "\tany filesystems before a successful resume.\n" + "\tResuming after some filesystems have been mounted\n" + "\twill badly damage these filesystems.]\n\n" + "\tDo you want to continue booting (Y/n)?"; + + snprintf(full_message, SPLASH_GENERIC_MESSAGE_SIZE, "%s\n%s", + message, warning); + c = splash.dialog(full_message); + if (c == 'n' || c == 'N') { + reboot(); + fprintf(stderr, "%s: Reboot failed, please reboot manually.\n", + my_name); + while(1) + sleep(10); + } +} + +static int read_image(int dev, int fd, loff_t start) { - ssize_t size = sizeof(struct swsusp_header); - unsigned int shift = (resume_offset + 1) * page_size - size; struct image_header_info *header; int ret, error; char c; header = getmem(page_size); - error = read_or_verify_image(dev, fd, header, swsusp_header->image, 0); + error = read_or_verify_image(dev, fd, header, start, 0); if (error) { - c = splash.dialog( + reboot_question( "\nThe system snapshot image could not be read.\n\n" -#ifdef CONFIG_ENCRYPT - "\tThis might be a result of booting a wrong kernel\n" - "\tor typing in a wrong passphrase.\n\n" -#else - "\tThis might be a result of booting a wrong kernel.\n\n" -#endif - "\tYou can continue to boot the system and lose the saved state\n" - "\tor reboot and try again.\n\n" - "\t[Notice that you may not mount any filesystem between\n" - "\tnow and successful resume. That would badly damage\n" - "\taffected filesystems.]\n\n" - "\tDo you want to continue boot (Y/n)? "); - ret = (c == 'n' || c == 'N'); - if (ret) { - close(fd); - reboot(); - fprintf(stderr, "%s: Reboot failed, please reboot manually.\n", - my_name); - while(1) - sleep(1); - } + "\tThis might be a result of booting a wrong " + "kernel.\n" + ); } else { if (header->flags & PLATFORM_SUSPEND) use_platform_suspend = 1; } - /* Reset swap signature now */ - memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10); - if (lseek(fd, shift, SEEK_SET) != shift) { - error = -EIO; - } else { - ret = write(fd, swsusp_header, size); - if (ret != size) { - error = ret < 0 ? -errno : -EIO; - fprintf(stderr, - "%s: Could not restore the partition header\n", - my_name); - } - } - - fsync(fd); - close(fd); - if (error) { char message[SPLASH_GENERIC_MESSAGE_SIZE]; @@ -292,6 +280,33 @@ static int read_image(int dev, int fd, struct swsusp_header *swsusp_header) return error; } +static int reset_signature(int fd, struct swsusp_header *swsusp_header) +{ + ssize_t ret, size = sizeof(struct swsusp_header); + unsigned int shift = (resume_offset + 1) * page_size - size; + int error = 0; + + /* Reset swap signature now */ + memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10); + + if (lseek(fd, shift, SEEK_SET) != shift) { + fprintf(stderr, "%s: Could not lseek() to the swap header", + my_name); + return -EIO; + } + + ret = write(fd, swsusp_header, size); + if (ret == size) { + fsync(fd); + } else { + fprintf(stderr, "%s: Could not restore the swap header", + my_name); + error = -EIO; + } + + return error; +} + /* Parse the command line and/or configuration file */ static inline int get_config(int argc, char *argv[]) { @@ -488,18 +503,26 @@ int main(int argc, char *argv[]) splash_prepare(&splash, splash_param); splash.progress(5); - error = read_image(dev, resume_dev, &swsusp_header); + error = read_image(dev, resume_dev, swsusp_header.image); if (error) { - fprintf(stderr, "%s: Could not read the image\n", my_name); error = -error; - goto Close_splash; + fprintf(stderr, "%s: Could not read the image\n", my_name); + } else if (freeze(dev)) { + error = errno; + reboot_question("Processes could not be frozen, " + "cannot continue resuming.\n"); } - if (freeze(dev)) { - error = errno; - fprintf(stderr, "%s: Could not freeze processes\n", my_name); + if (reset_signature(resume_dev, &swsusp_header)) + fprintf(stderr, "%s: Swap signature has not been restored.\n" + "\tRun mkswap on the resume partition/file.\n", + my_name); + + close(resume_dev); + + if (error) goto Close_splash; - } + if (use_platform_suspend) { int err = platform_prepare(dev); |