[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RESEND PATCH V3] Backup old boot sectors before installation
From: |
Zhu Yi |
Subject: |
[RESEND PATCH V3] Backup old boot sectors before installation |
Date: |
Thu, 25 Feb 2010 14:58:29 +0800 |
Make grub-setup backup the old boot sectors into a file
(bootsectors.bak) before overwriting it. The backup image starts from
the MBR to the end of core.img position (including embed regions).
This makes it possible for a user to later restore it.
A new option -o|--restore (with optional argument) is added for
grub-setup to restore the backup image into the install device.
A simple `dd` won't work when partitioning has been changed after
the backup. The --restore option only restores the MBR and the boot
sectors overwritten by core.img (embed region is excluded).
Signed-off-by: Zhu Yi <address@hidden>
---
Resend the patch after signed the FSF copyright document.
diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c
index c536be0..e8dc2b7 100644
--- a/util/i386/pc/grub-setup.c
+++ b/util/i386/pc/grub-setup.c
@@ -53,6 +53,7 @@ static const grub_gpt_part_type_t
grub_gpt_partition_type_bios_boot = GRUB_GPT_P
#define DEFAULT_BOOT_FILE "boot.img"
#define DEFAULT_CORE_FILE "core.img"
+#define DEFAULT_BACKUP_FILE "bootsectors.bak"
/* This is the blocklist used in the diskboot image. */
struct boot_blocklist
@@ -85,7 +86,7 @@ grub_refresh (void)
static void
setup (const char *dir,
- const char *boot_file, const char *core_file,
+ const char *boot_file, const char *core_file, const char *restore_file,
const char *root, const char *dest, int must_embed, int force, int
fs_probe)
{
char *boot_path, *core_path, *core_path_dev;
@@ -396,6 +397,59 @@ setup (const char *dir,
block->len = 0;
block->segment = 0;
+ int grub_disk_backup(grub_disk_t disk, const char *file)
+ {
+ char *path = grub_util_get_path (dir, file);
+ char *buf;
+ grub_size_t size;
+
+ grub_util_info ("opening backup file `%s'", path);
+ fp = fopen (path, "wb");
+ if (! fp) {
+ free (path);
+ return -1;
+ }
+
+ size = GRUB_DISK_SECTOR_SIZE * embed_region.start + core_size;
+ buf = xmalloc (size);
+ if (grub_disk_read (disk, 0, 0, size, buf) != GRUB_ERR_NONE) {
+ free (path);
+ fclose (fp);
+ return -1;
+ }
+
+ grub_util_write_image (buf, size, fp);
+
+ free (buf);
+ free (path);
+ fclose (fp);
+ return 0;
+ }
+
+ void grub_disk_restore(grub_disk_t disk, const char *path)
+ {
+ size_t size = grub_util_get_image_size (path);
+ char *img;
+
+ if (size != GRUB_DISK_SECTOR_SIZE * embed_region.start + core_size)
+ grub_util_error ("Invalid backup image `%s'", path);
+
+ img = grub_util_read_image (path);
+ grub_disk_write (disk, 0, 0, GRUB_DISK_SECTOR_SIZE, img);
+ grub_disk_write (disk, embed_region.start, 0, core_size,
+ img + GRUB_DISK_SECTOR_SIZE * embed_region.start);
+ free (img);
+ }
+
+ if (restore_file) {
+ grub_disk_restore (dest_dev->disk, restore_file);
+ goto finish;
+ }
+
+ /* Backup old boot sectors */
+ if (grub_disk_backup (dest_dev->disk, DEFAULT_BACKUP_FILE))
+ grub_util_error ("failed to backup previous boot sectors");
+
/* Write the core image onto the disk. */
if (grub_disk_write (dest_dev->disk, embed_region.start, 0, core_size,
core_img))
grub_util_error ("%s", grub_errmsg);
@@ -571,6 +625,7 @@ static struct option options[] =
{"directory", required_argument, 0, 'd'},
{"device-map", required_argument, 0, 'm'},
{"root-device", required_argument, 0, 'r'},
+ {"restore", optional_argument, 0, 'o'},
{"force", no_argument, 0, 'f'},
{"skip-fs-probe", no_argument, 0, 's'},
{"help", no_argument, 0, 'h'},
@@ -596,6 +651,7 @@ DEVICE must be a GRUB device (e.g. ``(hd0,1)'').\n\
-d, --directory=DIR use GRUB files in the directory DIR [default=%s]\n\
-m, --device-map=FILE use FILE as the device map [default=%s]\n\
-r, --root-device=DEV use DEV as the root device [default=guessed]\n\
+ -o, --restore[=FILE] restore boot sectors from backup image
[default=%s]\n\
-f, --force install even if problems are detected\n\
-s, --skip-fs-probe do not probe for filesystems in DEVICE\n\
-h, --help display this message and exit\n\
@@ -605,7 +661,8 @@ DEVICE must be a GRUB device (e.g. ``(hd0,1)'').\n\
Report bugs to <%s>.\n\
",
DEFAULT_BOOT_FILE, DEFAULT_CORE_FILE, DEFAULT_DIRECTORY,
- DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT);
+ DEFAULT_DEVICE_MAP, DEFAULT_DIRECTORY "/" DEFAULT_BACKUP_FILE,
+ PACKAGE_BUGREPORT);
exit (status);
}
@@ -627,6 +684,7 @@ main (int argc, char *argv[])
{
char *boot_file = 0;
char *core_file = 0;
+ char *restore_file = 0;
char *dir = 0;
char *dev_map = 0;
char *root_dev = 0;
@@ -638,7 +696,7 @@ main (int argc, char *argv[])
/* Check for options. */
while (1)
{
- int c = getopt_long (argc, argv, "b:c:d:m:r:hVvf", options, 0);
+ int c = getopt_long (argc, argv, "b:c:d:m:r:o::hVvfs", options, 0);
if (c == -1)
break;
@@ -680,6 +738,17 @@ main (int argc, char *argv[])
root_dev = xstrdup (optarg);
break;
+ case 'o':
+ if (restore_file)
+ free (restore_file);
+
+ if (optarg)
+ restore_file = xstrdup (optarg);
+ else
+ restore_file = grub_util_get_path (dir ? dir : DEFAULT_DIRECTORY,
+ DEFAULT_BACKUP_FILE);
+ break;
+
case 'f':
force = 1;
break;
@@ -788,7 +857,7 @@ main (int argc, char *argv[])
{
setup (dir ? : DEFAULT_DIRECTORY,
boot_file ? : DEFAULT_BOOT_FILE,
- core_file ? : DEFAULT_CORE_FILE,
+ core_file ? : DEFAULT_CORE_FILE, restore_file,
root_dev, grub_util_get_grub_dev (devicelist[i]), 1, force,
fs_probe);
}
}
@@ -797,7 +866,7 @@ main (int argc, char *argv[])
/* Do the real work. */
setup (dir ? : DEFAULT_DIRECTORY,
boot_file ? : DEFAULT_BOOT_FILE,
- core_file ? : DEFAULT_CORE_FILE,
+ core_file ? : DEFAULT_CORE_FILE, restore_file,
root_dev, dest_dev, must_embed, force, fs_probe);
/* Free resources. */
@@ -806,6 +875,7 @@ main (int argc, char *argv[])
free (boot_file);
free (core_file);
+ free (restore_file);
free (dir);
free (dev_map);
free (root_dev);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [RESEND PATCH V3] Backup old boot sectors before installation,
Zhu Yi <=