mirror of
https://git.proxmox.com/git/grub2
synced 2025-08-14 18:24:27 +00:00
Rewrite no_libzfs.patch using a different approach. (Closes: #648539)
This commit is contained in:
parent
6e1ddd4b2e
commit
fdec2d595f
6
debian/changelog
vendored
6
debian/changelog
vendored
@ -1,3 +1,9 @@
|
|||||||
|
grub2 (1.99-14) unstable; urgency=low
|
||||||
|
|
||||||
|
* Rewrite no_libzfs.patch using a different approach. (Closes: #648539)
|
||||||
|
|
||||||
|
-- Robert Millan <rmh@debian.org> Sun, 13 Nov 2011 00:14:38 +0100
|
||||||
|
|
||||||
grub2 (1.99-13) unstable; urgency=low
|
grub2 (1.99-13) unstable; urgency=low
|
||||||
|
|
||||||
[ Debconf translations ]
|
[ Debconf translations ]
|
||||||
|
415
debian/patches/no_libzfs.patch
vendored
415
debian/patches/no_libzfs.patch
vendored
@ -1,216 +1,155 @@
|
|||||||
--- a/grub-core/fs/zfs/zfs.c
|
|
||||||
+++ b/grub-core/fs/zfs/zfs.c
|
|
||||||
@@ -53,6 +53,10 @@
|
|
||||||
#include <grub/zfs/dsl_dataset.h>
|
|
||||||
#include <grub/deflate.h>
|
|
||||||
|
|
||||||
+#ifdef GRUB_UTIL
|
|
||||||
+#include <grub/emu/misc.h>
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
#define ZPOOL_PROP_BOOTFS "bootfs"
|
|
||||||
@@ -3039,6 +3043,129 @@
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
+struct grub_zfs_vdev
|
|
||||||
+{
|
|
||||||
+ const char *name;
|
|
||||||
+ struct grub_zfs_vdev *next;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+struct grub_zfs_pool
|
|
||||||
+{
|
|
||||||
+ grub_uint64_t guid;
|
|
||||||
+ char *name;
|
|
||||||
+ struct grub_zfs_vdev *vdev_list;
|
|
||||||
+ struct grub_zfs_pool *next;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct grub_zfs_pool *zpool_list;
|
|
||||||
+
|
|
||||||
+static int
|
|
||||||
+zfs_scan_device (const char *name)
|
|
||||||
+{
|
|
||||||
+ grub_device_t device;
|
|
||||||
+ struct grub_zfs_data *data;
|
|
||||||
+ char *nvlist;
|
|
||||||
+ grub_uint64_t guid;
|
|
||||||
+ char *label;
|
|
||||||
+ struct grub_zfs_pool *zpool;
|
|
||||||
+ struct grub_zfs_vdev *vdev;
|
|
||||||
+
|
|
||||||
+#ifdef GRUB_UTIL
|
|
||||||
+ grub_util_info ("scanning %s for ZFS", name);
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ device = grub_device_open (name);
|
|
||||||
+ if (! device)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ data = zfs_mount (device);
|
|
||||||
+ if (! data)
|
|
||||||
+ goto end1;
|
|
||||||
+
|
|
||||||
+ if (zfs_fetch_nvlist (data->device_original, &nvlist))
|
|
||||||
+ goto end2;
|
|
||||||
+
|
|
||||||
+ if (! grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_GUID, &guid))
|
|
||||||
+ goto end3;
|
|
||||||
+
|
|
||||||
+ label = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME);
|
|
||||||
+ if (! label)
|
|
||||||
+ goto end3;
|
|
||||||
+
|
|
||||||
+ vdev = grub_zalloc (sizeof (*vdev));
|
|
||||||
+ vdev->name = grub_strdup (name);
|
|
||||||
+
|
|
||||||
+ struct grub_zfs_pool *i;
|
|
||||||
+ for (i = zpool_list; i; i = i->next)
|
|
||||||
+ {
|
|
||||||
+ if (guid == i->guid)
|
|
||||||
+ {
|
|
||||||
+ /* This vdev belongs to an already-registered pool. */
|
|
||||||
+ vdev->next = i->vdev_list;
|
|
||||||
+ i->vdev_list = vdev;
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Create a new ZFS pool with this vdev. */
|
|
||||||
+ zpool = grub_zalloc (sizeof (*zpool));
|
|
||||||
+ zpool->guid = guid;
|
|
||||||
+ zpool->name = grub_xasprintf ("zfs/%s", label);
|
|
||||||
+ zpool->vdev_list = vdev;
|
|
||||||
+
|
|
||||||
+ /* Insert it to ZFS pool list. */
|
|
||||||
+ zpool->next = zpool_list;
|
|
||||||
+ zpool_list = zpool;
|
|
||||||
+
|
|
||||||
+ end3:
|
|
||||||
+ grub_free (nvlist);
|
|
||||||
+ end2:
|
|
||||||
+ zfs_unmount (data);
|
|
||||||
+ end1:
|
|
||||||
+ grub_device_close (device);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int
|
|
||||||
+grub_zpool_iterate (int (*hook) (const char *name))
|
|
||||||
+{
|
|
||||||
+ struct grub_zfs_pool *i;
|
|
||||||
+ for (i = zpool_list; i; i = i->next)
|
|
||||||
+ {
|
|
||||||
+ if (hook (i->name))
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static grub_err_t
|
|
||||||
+grub_zpool_open (const char *name, grub_disk_t disk)
|
|
||||||
+{
|
|
||||||
+ struct grub_zfs_pool *i;
|
|
||||||
+ for (i = zpool_list; i; i = i->next)
|
|
||||||
+ {
|
|
||||||
+ if (! grub_strcmp (i->name, name))
|
|
||||||
+ {
|
|
||||||
+ /* For now just pick the first vdev as lower layer. */
|
|
||||||
+ grub_disk_t lower = grub_disk_open (i->vdev_list->name);
|
|
||||||
+ grub_memcpy (disk, lower, sizeof (*disk));
|
|
||||||
+ return GRUB_ERR_NONE;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a ZFS pool");
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct grub_disk_dev grub_zpool_dev =
|
|
||||||
+ {
|
|
||||||
+ .name = "zfs",
|
|
||||||
+ .id = GRUB_DISK_DEVICE_ZFS_ID,
|
|
||||||
+ .iterate = grub_zpool_iterate,
|
|
||||||
+ .open = grub_zpool_open,
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* zfs_open() locates a file in the rootpool by following the
|
|
||||||
* MOS and places the dnode of the file in the memory address DNODE.
|
|
||||||
@@ -3490,6 +3617,8 @@
|
|
||||||
GRUB_MOD_INIT (zfs)
|
|
||||||
{
|
|
||||||
COMPILE_TIME_ASSERT (sizeof (zap_leaf_chunk_t) == ZAP_LEAF_CHUNKSIZE);
|
|
||||||
+ grub_device_iterate (&zfs_scan_device);
|
|
||||||
+ grub_disk_dev_register (&grub_zpool_dev);
|
|
||||||
grub_fs_register (&grub_zfs_fs);
|
|
||||||
#ifndef GRUB_UTIL
|
|
||||||
my_mod = mod;
|
|
||||||
@@ -3498,5 +3627,9 @@
|
|
||||||
|
|
||||||
GRUB_MOD_FINI (zfs)
|
|
||||||
{
|
|
||||||
+ grub_disk_dev_unregister (&grub_zpool_dev);
|
|
||||||
+ zpool_list = NULL;
|
|
||||||
+ /* FIXME: free the zpool list. */
|
|
||||||
+
|
|
||||||
grub_fs_unregister (&grub_zfs_fs);
|
|
||||||
}
|
|
||||||
--- a/grub-core/kern/disk.c
|
|
||||||
+++ b/grub-core/kern/disk.c
|
|
||||||
@@ -269,6 +269,7 @@
|
|
||||||
|
|
||||||
for (dev = grub_disk_dev_list; dev; dev = dev->next)
|
|
||||||
{
|
|
||||||
+ disk->dev = dev;
|
|
||||||
if ((dev->open) (raw, disk) == GRUB_ERR_NONE)
|
|
||||||
break;
|
|
||||||
else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE)
|
|
||||||
@@ -283,8 +284,6 @@
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
- disk->dev = dev;
|
|
||||||
-
|
|
||||||
if (p)
|
|
||||||
{
|
|
||||||
disk->partition = grub_partition_probe (disk, p + 1);
|
|
||||||
--- a/grub-core/kern/emu/getroot.c
|
--- a/grub-core/kern/emu/getroot.c
|
||||||
+++ b/grub-core/kern/emu/getroot.c
|
+++ b/grub-core/kern/emu/getroot.c
|
||||||
@@ -626,6 +626,28 @@
|
@@ -32,6 +32,9 @@
|
||||||
return grub_find_device ("/dev/mapper", dev);
|
#include <stdio.h>
|
||||||
}
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
+#ifdef HAVE_LIMITS_H
|
||||||
|
+#include <limits.h>
|
||||||
|
+#endif
|
||||||
|
#include <grub/util/misc.h>
|
||||||
|
#include <grub/util/lvm.h>
|
||||||
|
|
||||||
+ /* Check for ZFS. */
|
@@ -238,7 +241,67 @@
|
||||||
+ if (!os_dev)
|
|
||||||
|
#endif /* __linux__ */
|
||||||
|
|
||||||
|
-#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
|
||||||
|
+static char *
|
||||||
|
+find_device_from_pool (const char *poolname)
|
||||||
|
+{
|
||||||
|
+ char *device;
|
||||||
|
+ char *cmd;
|
||||||
|
+ FILE *fp;
|
||||||
|
+ int ret;
|
||||||
|
+ char *line;
|
||||||
|
+ size_t len;
|
||||||
|
+ int st;
|
||||||
|
+
|
||||||
|
+ char name[PATH_MAX], state[256], readlen[256], writelen[256], cksum[256], notes[256];
|
||||||
|
+ unsigned int dummy;
|
||||||
|
+
|
||||||
|
+ asprintf (&cmd, "zpool status %s", poolname);
|
||||||
|
+ fp = popen (cmd, "r");
|
||||||
|
+ free (cmd);
|
||||||
|
+
|
||||||
|
+ st = 0;
|
||||||
|
+ while (st < 3)
|
||||||
+ {
|
+ {
|
||||||
+ char *pool;
|
+ line = NULL;
|
||||||
+ char *fs;
|
+ ret = getline (&line, &len, fp);
|
||||||
+
|
+ if (ret == -1)
|
||||||
+ grub_find_zpool_from_dir (dir, &pool, &fs);
|
|
||||||
+
|
|
||||||
+ if (pool)
|
|
||||||
+ {
|
+ {
|
||||||
+ os_dev = xasprintf ("zfs/%s", pool);
|
+ pclose (fp);
|
||||||
+ free (pool);
|
+ return NULL;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ if (fs)
|
+ if (sscanf (line, " %s %s %s %s %s %s", name, state, readlen, writelen, cksum, notes) >= 5)
|
||||||
+ free (fs);
|
+ switch (st)
|
||||||
|
+ {
|
||||||
|
+ case 0:
|
||||||
|
+ if (!strcmp (name, "NAME")
|
||||||
|
+ && !strcmp (state, "STATE")
|
||||||
|
+ && !strcmp (readlen, "READ")
|
||||||
|
+ && !strcmp (writelen, "WRITE")
|
||||||
|
+ && !strcmp (cksum, "CKSUM"))
|
||||||
|
+ st++;
|
||||||
|
+ break;
|
||||||
|
+ case 1:
|
||||||
|
+ if (!strcmp (name, poolname))
|
||||||
|
+ st++;
|
||||||
|
+ break;
|
||||||
|
+ case 2:
|
||||||
|
+ if (strcmp (name, "mirror") && !sscanf (name, "mirror-%u", &dummy)
|
||||||
|
+ && !sscanf (name, "raidz%u", &dummy)
|
||||||
|
+ && !strcmp (state, "ONLINE"))
|
||||||
|
+ st++;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ free (line);
|
||||||
+ }
|
+ }
|
||||||
|
+ pclose (fp);
|
||||||
+
|
+
|
||||||
+ if (! strncmp (os_dev, "zfs/", sizeof ("zfs/")-1))
|
+ asprintf (&device, "/dev/%s", name);
|
||||||
+ /* This kind of abstraction doesn't provide device nodes. */
|
|
||||||
+ return os_dev;
|
|
||||||
+
|
+
|
||||||
if (stat (dir, &st) < 0)
|
+ return device;
|
||||||
grub_util_error ("cannot stat `%s'", dir);
|
+}
|
||||||
|
+
|
||||||
|
static char *
|
||||||
|
find_root_device_from_libzfs (const char *dir)
|
||||||
|
{
|
||||||
|
@@ -250,49 +313,7 @@
|
||||||
|
if (! poolname)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
@@ -708,7 +730,7 @@
|
- {
|
||||||
|
- zpool_handle_t *zpool;
|
||||||
|
- libzfs_handle_t *libzfs;
|
||||||
|
- nvlist_t *config, *vdev_tree;
|
||||||
|
- nvlist_t **children, **path;
|
||||||
|
- unsigned int nvlist_count;
|
||||||
|
- unsigned int i;
|
||||||
|
-
|
||||||
|
- libzfs = grub_get_libzfs_handle ();
|
||||||
|
- if (! libzfs)
|
||||||
|
- return NULL;
|
||||||
|
-
|
||||||
|
- zpool = zpool_open (libzfs, poolname);
|
||||||
|
- config = zpool_get_config (zpool, NULL);
|
||||||
|
-
|
||||||
|
- if (nvlist_lookup_nvlist (config, "vdev_tree", &vdev_tree) != 0)
|
||||||
|
- error (1, errno, "nvlist_lookup_nvlist (\"vdev_tree\")");
|
||||||
|
-
|
||||||
|
- if (nvlist_lookup_nvlist_array (vdev_tree, "children", &children, &nvlist_count) != 0)
|
||||||
|
- error (1, errno, "nvlist_lookup_nvlist_array (\"children\")");
|
||||||
|
- assert (nvlist_count > 0);
|
||||||
|
-
|
||||||
|
- while (nvlist_lookup_nvlist_array (children[0], "children",
|
||||||
|
- &children, &nvlist_count) == 0)
|
||||||
|
- assert (nvlist_count > 0);
|
||||||
|
-
|
||||||
|
- for (i = 0; i < nvlist_count; i++)
|
||||||
|
- {
|
||||||
|
- if (nvlist_lookup_string (children[i], "path", &device) != 0)
|
||||||
|
- error (1, errno, "nvlist_lookup_string (\"path\")");
|
||||||
|
-
|
||||||
|
- struct stat st;
|
||||||
|
- if (stat (device, &st) == 0)
|
||||||
|
- {
|
||||||
|
- device = xstrdup (device);
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- device = NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- zpool_close (zpool);
|
||||||
|
- }
|
||||||
|
+ device = find_device_from_pool (poolname);
|
||||||
|
|
||||||
|
free (poolname);
|
||||||
|
if (poolfs)
|
||||||
|
@@ -300,7 +321,6 @@
|
||||||
|
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
|
||||||
|
@@ -603,10 +623,8 @@
|
||||||
|
os_dev = grub_find_root_device_from_mountinfo (dir, NULL);
|
||||||
|
#endif /* __linux__ */
|
||||||
|
|
||||||
|
-#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
|
||||||
|
if (!os_dev)
|
||||||
|
os_dev = find_root_device_from_libzfs (dir);
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
if (os_dev)
|
||||||
|
{
|
||||||
|
@@ -708,7 +726,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -219,27 +158,6 @@
|
|||||||
{
|
{
|
||||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||||
/* User explicitly claims that this drive is visible by BIOS. */
|
/* User explicitly claims that this drive is visible by BIOS. */
|
||||||
@@ -732,6 +754,9 @@
|
|
||||||
return GRUB_DEV_ABSTRACTION_LVM;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+ if (!strncmp (os_dev, "zfs/", sizeof ("zfs/")-1))
|
|
||||||
+ return GRUB_DEV_ABSTRACTION_ZFS;
|
|
||||||
+
|
|
||||||
/* No abstraction found. */
|
|
||||||
return GRUB_DEV_ABSTRACTION_NONE;
|
|
||||||
}
|
|
||||||
@@ -948,6 +973,10 @@
|
|
||||||
break;
|
|
||||||
#endif /* __linux__ */
|
|
||||||
|
|
||||||
+ case GRUB_DEV_ABSTRACTION_ZFS:
|
|
||||||
+ grub_dev = xstrdup (os_dev);
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
default: /* GRUB_DEV_ABSTRACTION_NONE */
|
|
||||||
grub_dev = grub_util_biosdisk_get_grub_dev (os_dev);
|
|
||||||
}
|
|
||||||
--- a/grub-core/kern/emu/misc.c
|
--- a/grub-core/kern/emu/misc.c
|
||||||
+++ b/grub-core/kern/emu/misc.c
|
+++ b/grub-core/kern/emu/misc.c
|
||||||
@@ -287,7 +287,6 @@
|
@@ -287,7 +287,6 @@
|
||||||
@ -307,54 +225,3 @@
|
|||||||
ret = buf3;
|
ret = buf3;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
--- a/include/grub/disk.h
|
|
||||||
+++ b/include/grub/disk.h
|
|
||||||
@@ -42,7 +42,8 @@
|
|
||||||
GRUB_DISK_DEVICE_PXE_ID,
|
|
||||||
GRUB_DISK_DEVICE_SCSI_ID,
|
|
||||||
GRUB_DISK_DEVICE_FILE_ID,
|
|
||||||
- GRUB_DISK_DEVICE_LUKS_ID
|
|
||||||
+ GRUB_DISK_DEVICE_LUKS_ID,
|
|
||||||
+ GRUB_DISK_DEVICE_ZFS_ID,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct grub_disk;
|
|
||||||
--- a/include/grub/emu/getroot.h
|
|
||||||
+++ b/include/grub/emu/getroot.h
|
|
||||||
@@ -25,6 +25,7 @@
|
|
||||||
GRUB_DEV_ABSTRACTION_NONE,
|
|
||||||
GRUB_DEV_ABSTRACTION_LVM,
|
|
||||||
GRUB_DEV_ABSTRACTION_RAID,
|
|
||||||
+ GRUB_DEV_ABSTRACTION_ZFS,
|
|
||||||
};
|
|
||||||
|
|
||||||
char *grub_find_device (const char *dir, dev_t dev);
|
|
||||||
--- a/util/grub-probe.c
|
|
||||||
+++ b/util/grub-probe.c
|
|
||||||
@@ -99,6 +99,8 @@
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
{
|
|
||||||
+ if (strncmp (device_name, "zfs/", sizeof ("zfs/")-1))
|
|
||||||
+ {
|
|
||||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
|
|
||||||
if (! grub_util_check_char_device (device_name))
|
|
||||||
grub_util_error ("%s is not a character device", device_name);
|
|
||||||
@@ -106,6 +108,7 @@
|
|
||||||
if (! grub_util_check_block_device (device_name))
|
|
||||||
grub_util_error ("%s is not a block device", device_name);
|
|
||||||
#endif
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
@@ -188,6 +191,9 @@
|
|
||||||
if (is_lvm)
|
|
||||||
printf ("lvm ");
|
|
||||||
|
|
||||||
+ if (dev->disk->dev->id == GRUB_DISK_DEVICE_ZFS_ID)
|
|
||||||
+ printf ("zfs ");
|
|
||||||
+
|
|
||||||
printf ("\n");
|
|
||||||
|
|
||||||
goto end;
|
|
||||||
|
Loading…
Reference in New Issue
Block a user