grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH]: IEEE1275 path name escaping...


From: David Miller
Subject: [PATCH]: IEEE1275 path name escaping...
Date: Mon, 04 May 2009 16:16:18 -0700 (PDT)

Ok, finally GRUB works also on my workstation.

These are the changes that allow GRUB to properly handle
"," characters in OF path names.

As we discussed about a month ago, when a "," appears in an
OF path name we escape it with "\".

So all of the real work is escaping OF paths as they are given
to GRUB, and then un-escaping them when ofdisk tries to open
them.

Committed.

PS: I plan to spend the next few days testing what we have now on
    a variety of sparc64 systems to make sure all of the most obvious
    problems get shaken out.

2009-05-04  David S. Miller  <address@hidden>

        * 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.

Index: disk/ieee1275/ofdisk.c
===================================================================
--- disk/ieee1275/ofdisk.c      (revision 2188)
+++ disk/ieee1275/ofdisk.c      (working copy)
@@ -115,6 +115,38 @@
   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 @@
   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);
Index: kern/disk.c
===================================================================
--- kern/disk.c (revision 2185)
+++ kern/disk.c (working copy)
@@ -215,10 +215,28 @@
   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 @@
   if (! disk->name)
     goto fail;
   
-  p = grub_strchr (name, ',');
+  p = find_part_sep (name);
   if (p)
     {
       grub_size_t len = p - name;
Index: util/sparc64/ieee1275/grub-install.in
===================================================================
--- util/sparc64/ieee1275/grub-install.in       (revision 2185)
+++ util/sparc64/ieee1275/grub-install.in       (working copy)
@@ -237,8 +237,8 @@
     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
Index: util/sparc64/ieee1275/grub-setup.c
===================================================================
--- util/sparc64/ieee1275/grub-setup.c  (revision 2185)
+++ util/sparc64/ieee1275/grub-setup.c  (working copy)
@@ -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 @@
   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 @@
   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 @@
       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 @@
                                           + 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 @@
 
   *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);
Index: util/ieee1275/devicemap.c
===================================================================
--- util/ieee1275/devicemap.c   (revision 2185)
+++ util/ieee1275/devicemap.c   (working copy)
@@ -1,13 +1,47 @@
 #include <stdio.h>
+#include <string.h>
 #include <grub/types.h>
 #include <grub/util/deviceiter.h>
 #include <grub/util/ofpath.h>
+#include <grub/util/misc.h>
 
+/* 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);
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]