Same patch with a bit of cleanup, and ChangeLog entry.

2010/7/29, Robert Millan <r...@gnu.org>:
> This patch is a proof of concept for solving the ZFS "(dev)/foo@/"
> pathname problem at the lowest possible level: a small change in
> grub_make_system_path_relative_to_its_root() propagates into
> all the places in grub-install and grub-mkconfig that are affected
> by the problem.
>
> It factors some of the code in my previous patch, so that it can be
> reused to extract the zpool filesystem names.
>
> (It still needs some polish like adding function prototypes)
>
> Comments?
>
2010-07-30  Robert Millan  <r...@gnu.org>

	* conf/common.rmk (grub_mkrelpath_SOURCES): Add kern/emu/getroot.c
	kern/emu/hostdisk.c kern/err.c kern/misc.c kern/emu/mm.c kern/env.c
	kern/term.c kern/disk.c kern/partition.c.

	* include/grub/emu/misc.h (grub_find_mount_point_from_dir)
	(grub_find_zpool_from_mount_point): New function prototypes.

	* kern/emu/getroot.c (find_mount_point_from_dir): Rename to ...
	(grub_find_mount_point_from_dir): ... this.  Remove `static' attribute.
	(find_root_device_from_libzfs): Split code for finding zpool from
	mount point into ...
	(grub_find_zpool_from_mount_point): ... this.

	* kern/emu/misc.c (grub_make_system_path_relative_to_its_root): When
	requested path is part of a ZFS pool, use
	grub_find_zpool_from_mount_point() to detect its filesystem name,
	and generate a path with `/fsn...@path' syntax.

=== modified file 'conf/common.rmk'
--- conf/common.rmk	2010-07-06 18:27:55 +0000
+++ conf/common.rmk	2010-07-30 21:11:07 +0000
@@ -78,7 +78,9 @@ endif
 
 # For grub-mkrelpath.
 bin_UTILITIES += grub-mkrelpath
-grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c kern/emu/misc.c
+grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c kern/emu/misc.c \
+	kern/emu/getroot.c kern/emu/hostdisk.c kern/err.c kern/misc.c kern/emu/mm.c \
+	kern/env.c kern/term.c kern/disk.c kern/partition.c
 
 bin_UTILITIES += grub-bin2h
 grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c

=== modified file 'include/grub/emu/misc.h'
--- include/grub/emu/misc.h	2010-07-30 20:01:10 +0000
+++ include/grub/emu/misc.h	2010-07-30 21:11:07 +0000
@@ -44,7 +44,14 @@ extern const char *program_name;
 void grub_init_all (void);
 void grub_fini_all (void);
 
-char *grub_make_system_path_relative_to_its_root (const char *path) __attribute__ ((warn_unused_result));
+char *grub_find_mount_point_from_dir (const char *dir)
+  __attribute__ ((warn_unused_result));
+char *grub_find_zpool_from_mount_point (const char *mnt_point,
+					char **poolname, char **poolfs)
+  __attribute__ ((warn_unused_result));
+
+char *grub_make_system_path_relative_to_its_root (const char *path)
+  __attribute__ ((warn_unused_result));
 
 void * EXPORT_FUNC(xmalloc) (grub_size_t size) __attribute__ ((warn_unused_result));
 void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) __attribute__ ((warn_unused_result));

=== modified file 'kern/emu/getroot.c'
--- kern/emu/getroot.c	2010-07-30 19:43:12 +0000
+++ kern/emu/getroot.c	2010-07-30 21:11:07 +0000
@@ -97,8 +97,8 @@ xgetcwd (void)
   return path;
 }
 
-static char *
-find_mount_point_from_dir (const char *dir)
+char *
+grub_find_mount_point_from_dir (const char *dir)
 {
   struct stat st;
   typeof (st.st_dev) fs;
@@ -236,16 +236,12 @@ find_root_device_from_mountinfo (const c
 #if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
 
 /* ZFS has similar problems to those of btrfs (see above).  */
-static char *
-find_root_device_from_libzfs (const char *dir)
+void
+grub_find_zpool_from_mount_point (const char *mnt_point, char **poolname, char **poolfs)
 {
-  char *device = NULL;
-  char *poolname = NULL;
-  char *poolfs = NULL;
-  char *mnt_point;
   char *slash;
 
-  mnt_point = find_mount_point_from_dir (dir);
+  *poolname = *poolfs = NULL;
 
 #ifdef HAVE_GETFSSTAT
   {
@@ -264,7 +260,7 @@ find_root_device_from_libzfs (const char
       if (!strcmp (mnt[i].f_fstypename, "zfs")
 	  && !strcmp (mnt[i].f_mntonname, mnt_point))
 	{
-	  poolname = xstrdup (mnt[i].f_mntfromname);
+	  *poolname = xstrdup (mnt[i].f_mntfromname);
 	  break;
 	}
 
@@ -272,14 +268,33 @@ find_root_device_from_libzfs (const char
   }
 #endif
 
-  if (! poolname)
-    return NULL;
+  if (! *poolname)
+    return;
 
-  slash = strchr (poolname, '/');
+  slash = strchr (*poolname, '/');
   if (slash)
     {
       *slash = '\0';
-      poolfs = slash + 1;
+      *poolfs = xstrdup (slash + 1);
+    }
+  else
+    *poolfs = xstrdup ("");
+}
+
+static char *
+find_root_device_from_libzfs (const char *dir)
+{
+  char *device;
+  char *poolname;
+  char *poolfs;
+  char *mnt_point;
+
+  mnt_point = grub_find_mount_point_from_dir (dir);
+  grub_find_zpool_from_mount_point (mnt_point, &poolname, &poolfs);
+  if (! poolname)
+    {
+      free (mnt_point);
+      return NULL;
     }
 
   {
@@ -310,6 +325,8 @@ find_root_device_from_libzfs (const char
   }
 
   free (poolname);
+  if (poolfs)
+    free (poolfs);
 
   return device;
 }

=== modified file 'kern/emu/misc.c'
--- kern/emu/misc.c	2010-06-07 21:41:55 +0000
+++ kern/emu/misc.c	2010-07-30 21:11:07 +0000
@@ -225,16 +225,24 @@ grub_make_system_path_relative_to_its_ro
 {
   struct stat st;
   char *p, *buf, *buf2, *buf3;
+  char *mnt_point, *poolname = NULL, *poolfs = NULL, *ret;
   uintptr_t offset = 0;
   dev_t num;
   size_t len;
 
   /* canonicalize.  */
   p = canonicalize_file_name (path);
-
   if (p == NULL)
     grub_util_error ("failed to get canonical path of %s", path);
 
+  /* For ZFS sub-pool filesystems, could be extended to others (btrfs?).  */
+  mnt_point = grub_find_mount_point_from_dir (p);
+  if (mnt_point)
+    {
+      grub_find_zpool_from_mount_point (mnt_point, &poolname, &poolfs);
+      free (mnt_point);
+    }
+
   len = strlen (p) + 1;
   buf = xstrdup (p);
   free (p);
@@ -313,7 +321,15 @@ grub_make_system_path_relative_to_its_ro
       len--;
     }
 
-  return buf3;
+  if (poolfs)
+    {
+      ret = xasprintf ("/%...@%s", poolfs, buf3);
+      free (buf3);
+    }
+  else
+    ret = buf3;
+
+  return ret;
 }
 
 #ifdef HAVE_DEVICE_MAPPER

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to