From: Vladimir 'phcoder' Serbinenko Date: Thu, 21 Apr 2011 23:21:26 +0000 (+0200) Subject: merge devmapper into lazy X-Git-Tag: 2.00~1165^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c0c837c10b3f04e19fbbb582cd6fea88b6831d44;p=thirdparty%2Fgrub.git merge devmapper into lazy --- c0c837c10b3f04e19fbbb582cd6fea88b6831d44 diff --cc grub-core/kern/emu/hostdisk.c index 3ee6174d0,ea42d945e..9b65d417e --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@@ -343,71 -338,12 +347,73 @@@ grub_util_device_is_mapped (const char return 0; return dm_is_dm_major (major (st.st_rdev)); - } + #else + return 0; #endif /* HAVE_DEVICE_MAPPER */ + } -#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) +#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) +/* FIXME: geom actually gives us the whole container hierarchy. + It can be used more efficiently than this. */ +static void +follow_geom_up (const char *name, grub_disk_addr_t *off_out, char **name_out) +{ + struct gmesh mesh; + struct gclass *class; + int error; + struct ggeom *geom; + + grub_util_info ("following geom '%s'", name); + + error = geom_gettree (&mesh); + if (error != 0) + grub_util_error ("couldn't open geom"); + + LIST_FOREACH (class, &mesh.lg_class, lg_class) + if (strcasecmp (class->lg_name, "part") == 0) + break; + if (!class) + grub_util_error ("couldn't open geom part"); + + LIST_FOREACH (geom, &class->lg_geom, lg_geom) + { + struct gprovider *provider; + LIST_FOREACH (provider, &geom->lg_provider, lg_provider) + if (strcmp (provider->lg_name, name) == 0) + { + char *name_tmp = xstrdup (geom->lg_name); + grub_disk_addr_t off = 0; + struct gconfig *config; + grub_util_info ("geom '%s' has parent '%s'", name, geom->lg_name); + + follow_geom_up (name_tmp, &off, name_out); + free (name_tmp); + LIST_FOREACH (config, &provider->lg_config, lg_config) + if (strcasecmp (config->lg_name, "start") == 0) + off += strtoull (config->lg_val, 0, 10); + if (off_out) + *off_out = off; + return; + } + } + grub_util_info ("geom '%s' has no parent", name); + if (name_out) + *name_out = xstrdup (name); + if (off_out) + *off_out = 0; +} + +static grub_disk_addr_t +find_partition_start (const char *dev) +{ + grub_disk_addr_t out; + if (strncmp (dev, "/dev/", sizeof ("/dev/") - 1) != 0) + return 0; + follow_geom_up (dev + sizeof ("/dev/") - 1, &out, NULL); + + return out; +} +#elif defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) static grub_disk_addr_t find_partition_start (const char *dev) {