=== modified file 'conf/common.rmk' --- conf/common.rmk 2010-07-06 18:27:55 +0000 +++ conf/common.rmk 2010-07-29 16:06:55 +0000 @@ -78,7 +78,9 @@ # 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 'kern/emu/getroot.c' --- kern/emu/getroot.c 2010-07-29 15:49:20 +0000 +++ kern/emu/getroot.c 2010-07-29 16:15:27 +0000 @@ -97,7 +97,7 @@ return path; } -static char * +char * find_mount_point_from_dir (const char *dir) { struct stat st; @@ -236,16 +236,12 @@ #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 +find_zpool_from_mount_point (const char *mnt_point, char **poolname, char **poolfs) { - char *device; - 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 @@ 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 @@ } #endif + if (! *poolname) + return; + + slash = strchr (*poolname, '/'); + if (slash) + { + *slash = '\0'; + *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 = find_mount_point_from_dir (dir); + find_zpool_from_mount_point (mnt_point, &poolname, &poolfs); if (! poolname) - return NULL; - - slash = strchr (poolname, '/'); - if (slash) { - *slash = '\0'; - poolfs = slash + 1; + free (mnt_point); + return NULL; } { @@ -300,6 +315,8 @@ } 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-29 16:14:02 +0000 @@ -225,16 +225,24 @@ { 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 = find_mount_point_from_dir (p); + if (mnt_point) + { + 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 @@ len--; } - return buf3; + if (poolfs) + { + ret = xasprintf ("/address@hidden", poolfs, buf3); + free (buf3); + } + else + ret = buf3; + + return ret; } #ifdef HAVE_DEVICE_MAPPER