From 67e23c9004af980502b997b876da7ff3cb109cc7 Mon Sep 17 00:00:00 2001 From: davem Date: Mon, 4 May 2009 23:13:53 +0000 Subject: [PATCH] * disk/ieee1275/ofdisk.c (compute_dev_path): New. (grub_ofdisk_open): Use it to un-escape "," characters. * kern/disk.c (find_part_sep): New. (grub_disk_open): Use it to find the first non-escaped ',' character in the disk name. * util/ieee1275/devicemap.c (escape_of_path): New. (grub_util_emit_devicemap_entry): Use it. * util/sparc64/ieee1275/grub-install.in: Update script to strip partition specifiers properly by not triggering on '\' escaped ',' characters. --- ChangeLog | 11 ++++++++ disk/ieee1275/ofdisk.c | 38 +++++++++++++++++++++++---- kern/disk.c | 22 ++++++++++++++-- util/ieee1275/devicemap.c | 36 ++++++++++++++++++++++++- util/sparc64/ieee1275/grub-install.in | 4 +-- util/sparc64/ieee1275/grub-setup.c | 33 ++++++++++++++++++++--- 6 files changed, 130 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 26616ab3b..3b3ebd5ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,17 @@ * disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Bypass cdrom devices, and do not traverse down under controller nodes. + * disk/ieee1275/ofdisk.c (compute_dev_path): New. + (grub_ofdisk_open): Use it to un-escape "," characters. + * kern/disk.c (find_part_sep): New. + (grub_disk_open): Use it to find the first non-escaped ',' + character in the disk name. + * util/ieee1275/devicemap.c (escape_of_path): New. + (grub_util_emit_devicemap_entry): Use it. + * util/sparc64/ieee1275/grub-install.in: Update script to + strip partition specifiers properly by not triggering on + '\' escaped ',' characters. + 2009-05-04 Robert Millan * include/grub/i386/linux.h (GRUB_LINUX_VID_MODE_VESA_START): Set diff --git a/disk/ieee1275/ofdisk.c b/disk/ieee1275/ofdisk.c index 1620fee83..7904cc0c0 100644 --- a/disk/ieee1275/ofdisk.c +++ b/disk/ieee1275/ofdisk.c @@ -115,6 +115,38 @@ grub_ofdisk_iterate (int (*hook) (const char *name)) return grub_devalias_iterate (dev_iterate); } +static char * +compute_dev_path (const char *name) +{ + char *devpath = grub_malloc (grub_strlen (name) + 2); + char *p, c; + + if (!devpath) + return NULL; + + /* Un-escape commas. */ + p = devpath; + while ((c = *name++) != '\0') + { + if (c == '\\' && *name == ',') + { + *p++ = ','; + name++; + } + else + *p++ = c; + } + + if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0)) + { + *p++ = ':'; + *p++ = '0'; + } + *p++ = '\0'; + + return devpath; +} + static grub_err_t grub_ofdisk_open (const char *name, grub_disk_t disk) { @@ -126,14 +158,10 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) char prop[64]; grub_ssize_t actual; - devpath = grub_strndup (name, grub_strlen (name) + 2); + devpath = compute_dev_path (name); if (! devpath) return grub_errno; - /* To access the complete disk add `:0'. */ - if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0)) - grub_strcat (devpath, ":0"); - op = ofdisk_hash_find (devpath); if (!op) op = ofdisk_hash_add (devpath); diff --git a/kern/disk.c b/kern/disk.c index 8a92989ad..4db3f30cd 100644 --- a/kern/disk.c +++ b/kern/disk.c @@ -215,10 +215,28 @@ grub_disk_dev_iterate (int (*hook) (const char *name)) return 0; } +/* Return the location of the first ',', if any, which is not + escaped by a '\'. */ +static const char * +find_part_sep (const char *name) +{ + const char *p = name; + char c; + + while ((c = *p++) != '\0') + { + if (c == '\\' && *p == ',') + p++; + else if (c == ',') + return p - 1; + } + return NULL; +} + grub_disk_t grub_disk_open (const char *name) { - char *p; + const char *p; grub_disk_t disk; grub_disk_dev_t dev; char *raw = (char *) name; @@ -238,7 +256,7 @@ grub_disk_open (const char *name) if (! disk->name) goto fail; - p = grub_strchr (name, ','); + p = find_part_sep (name); if (p) { grub_size_t len = p - name; diff --git a/util/ieee1275/devicemap.c b/util/ieee1275/devicemap.c index 8e6eb39c4..bddfc17e7 100644 --- a/util/ieee1275/devicemap.c +++ b/util/ieee1275/devicemap.c @@ -1,13 +1,47 @@ #include +#include #include #include #include +#include + +/* Since OF path names can have "," characters in them, and GRUB + internally uses "," to indicate partitions (unlike OF which uses + ":" for this purpose) we escape such commas. */ + +static char * +escape_of_path (const char *orig_path) +{ + char *new_path, *d, c; + const char *p; + + if (!strchr (orig_path, ',')) + return (char *) orig_path; + + new_path = xmalloc (strlen (orig_path) * 2); + + p = orig_path; + d = new_path; + while ((c = *p++) != '\0') + { + if (c == ',') + *d++ = '\\'; + *d++ = c; + } + + free ((char *) orig_path); + + return new_path; +} void grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy UNUSED, int *num_fd UNUSED, int *num_hd UNUSED) { - const char *ofpath = grub_util_devname_to_ofpath (name); + const char *orig_path = grub_util_devname_to_ofpath (name); + char *ofpath = escape_of_path (orig_path); fprintf(fp, "(%s)\t%s\n", ofpath, name); + + free (ofpath); } diff --git a/util/sparc64/ieee1275/grub-install.in b/util/sparc64/ieee1275/grub-install.in index e2af5e8d9..a174050b4 100644 --- a/util/sparc64/ieee1275/grub-install.in +++ b/util/sparc64/ieee1275/grub-install.in @@ -237,8 +237,8 @@ if [ "x${devabstraction_module}" = "x" ] ; then grub_drive="`$grub_probe --target=drive --device ${grub_device}`" # Strip partition number - install_drive="`echo ${install_drive} | sed -e s/,[0-9]*//g`" - grub_drive="`echo ${grub_drive} | sed -e s/,[0-9]*//g`" + install_drive="`echo ${install_drive} | sed -e s/\([^\]\),[0-9]*/\1/g`" + grub_drive="`echo ${grub_drive} | sed -e s/\([^\]\),[0-9]*/\1/g`" if [ "x${grub_drive}" != "x${install_drive}" ] ; then uuid="`$grub_probe --target=fs_uuid --device ${grub_device}`" if [ "x${uuid}" = "x" ] ; then diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index 6ca3a7aa1..9509eb30b 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -56,7 +56,7 @@ * device. It also needs to know the initial block number of * 'core' (which is 'diskboot' concatenated with 'kernel' and * all the modules, this is created by grub-mkimage). This resulting - * 'boot' image is 512 bytes in size and is placed in the first block + * 'boot' image is 512 bytes in size and is placed in the second block * of a partition. * * The initial 'diskboot' block acts as a loader for the actual GRUB @@ -100,6 +100,28 @@ grub_refresh (void) fflush (stdout); } +static char *compute_dest_ofpath (const char *dest) +{ + int len = strlen (dest); + char *res, *p, c; + + res = xmalloc (len); + p = res; + while ((c = *dest++) != '\0') + { + if (c == '\\' && *dest == ',') + { + *p++ = ','; + dest++; + } + else + *p++ = c; + } + *p++ = '\0'; + + return res; +} + static void setup (const char *prefix, const char *dir, const char *boot_file, const char *core_file, @@ -110,7 +132,7 @@ setup (const char *prefix, const char *dir, size_t boot_size, core_size; grub_uint16_t core_sectors; grub_device_t root_dev, dest_dev; - char *boot_devpath; + char *boot_devpath, *dest_ofpath; grub_disk_addr_t *kernel_sector; struct boot_blocklist *first_block, *block; char *tmp_img; @@ -170,6 +192,8 @@ setup (const char *prefix, const char *dir, last_length = length; } + dest_ofpath = compute_dest_ofpath (dest); + /* Read the boot image by the OS service. */ boot_path = grub_util_get_path (dir, boot_file); boot_size = grub_util_get_image_size (boot_path); @@ -202,7 +226,8 @@ setup (const char *prefix, const char *dir, + GRUB_DISK_SECTOR_SIZE - sizeof (*block)); - grub_util_info ("root is '%s' and dest is '%s'", root, dest); + grub_util_info ("root is '%s', dest is '%s', and dest_ofpath is '%s'", + root, dest, dest_ofpath); /* Open the root device and the destination device. */ grub_util_info ("Opening root"); @@ -330,7 +355,7 @@ setup (const char *prefix, const char *dir, *kernel_sector = grub_cpu_to_be64 (first_sector); - strcpy(boot_devpath, dest); + strcpy(boot_devpath, dest_ofpath); grub_util_info ("boot device path %s, prefix is %s, dest is %s", boot_devpath, prefix, dest);