mirror of
https://git.proxmox.com/git/grub2
synced 2025-08-14 14:42:39 +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
|
||||
|
||||
[ 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
|
||||
+++ b/grub-core/kern/emu/getroot.c
|
||||
@@ -626,6 +626,28 @@
|
||||
return grub_find_device ("/dev/mapper", dev);
|
||||
}
|
||||
@@ -32,6 +32,9 @@
|
||||
#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. */
|
||||
+ if (!os_dev)
|
||||
@@ -238,7 +241,67 @@
|
||||
|
||||
#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;
|
||||
+ char *fs;
|
||||
+
|
||||
+ grub_find_zpool_from_dir (dir, &pool, &fs);
|
||||
+
|
||||
+ if (pool)
|
||||
+ line = NULL;
|
||||
+ ret = getline (&line, &len, fp);
|
||||
+ if (ret == -1)
|
||||
+ {
|
||||
+ os_dev = xasprintf ("zfs/%s", pool);
|
||||
+ free (pool);
|
||||
+ pclose (fp);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (fs)
|
||||
+ free (fs);
|
||||
+ if (sscanf (line, " %s %s %s %s %s %s", name, state, readlen, writelen, cksum, notes) >= 5)
|
||||
+ 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))
|
||||
+ /* This kind of abstraction doesn't provide device nodes. */
|
||||
+ return os_dev;
|
||||
+ asprintf (&device, "/dev/%s", name);
|
||||
+
|
||||
if (stat (dir, &st) < 0)
|
||||
grub_util_error ("cannot stat `%s'", dir);
|
||||
+ return device;
|
||||
+}
|
||||
+
|
||||
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
|
||||
@ -219,27 +158,6 @@
|
||||
{
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
/* 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
|
||||
+++ b/grub-core/kern/emu/misc.c
|
||||
@@ -287,7 +287,6 @@
|
||||
@ -307,54 +225,3 @@
|
||||
ret = buf3;
|
||||
|
||||
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