grub2/grub2-diskfilter-support-pv-without-metadatacopies.patch
Andrei Borzenkov b4cc930160 Accepting request 500506 from home:michael-chang:branches:Base:System
- Support LVM physical volume created without metadatacopies (bsc#1027526)
  * grub2-diskfilter-support-pv-without-metadatacopies.patch 
- Fix page fault exception when grub loads with Nvidia cards (bsc#1038533)
  * grub2-efi-uga-64bit-fb.patch
- Require 'kexec-tools' for System z. (bsc#944358)
  * modified grub2.spec

OBS-URL: https://build.opensuse.org/request/show/500506
OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=271
2017-06-03 21:22:46 +00:00

224 lines
6.5 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From a28bc19400b4e70725ce5532bc5e4c374c72d7a9 Mon Sep 17 00:00:00 2001
From: Lidong Zhong <lzhong@suse.com>
Date: Wed, 26 Apr 2017 15:52:40 +0800
Subject: [PATCH] diskfilter: implementation of processing no metadata recorded
in PV
If one PV underlying the root LV is created with no metadata, such as
pvcreate --metadatacopies 0 /dev/sda
then we could get a lot of error messages when generating a new
configuration file.
Generating grub configuration file ...
error: unknown LVM metadata header.
error: unknown LVM metadata header.
/usr/sbin/grub2-probe: warning: Couldn't find physical volume `pv1'.
Some modules may be missing from core image..
(For details, please refer to
https://bugzilla.suse.com/show_bug.cgi?id=1027526)
When one labelled PV which dose not have any metadata is found, we put
it into a global grub_detached_pv list. and we search all the PVs in the
current array list to check if it is a member of grub_detached_pv list.
So we can know if the PV is really missing or just without metadata.
Signed-off-by: Lidong Zhong <lzhong@suse.com>
---
grub-core/disk/diskfilter.c | 112 +++++++++++++++++++++++++++++++++++++++++++-
grub-core/disk/lvm.c | 15 ++++--
2 files changed, 121 insertions(+), 6 deletions(-)
Index: grub-2.02/grub-core/disk/diskfilter.c
===================================================================
--- grub-2.02.orig/grub-core/disk/diskfilter.c
+++ grub-2.02/grub-core/disk/diskfilter.c
@@ -28,6 +28,7 @@
#include <grub/i18n.h>
#include <grub/util/misc.h>
#endif
+#include <grub/lvm.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -43,7 +44,17 @@ static struct grub_diskfilter_lv *
find_lv (const char *name);
static int is_lv_readable (struct grub_diskfilter_lv *lv, int easily);
-
+struct grub_detached_pv {
+ struct grub_detached_pv *next;
+ struct grub_detached_pv **prev;
+ struct grub_diskfilter_pv_id id;
+ grub_disk_t disk;
+ grub_diskfilter_t diskfilter;
+} ;
+
+static struct grub_detached_pv *detached_pv_list;
+
+#define FOR_DETACHED_PVS(var) for (var = detached_pv_list; var; var = var->next)
static grub_err_t
is_node_readable (const struct grub_diskfilter_node *node, int easily)
@@ -132,6 +143,7 @@ scan_disk_partition_iter (grub_disk_t di
grub_disk_addr_t start_sector;
struct grub_diskfilter_pv_id id;
grub_diskfilter_t diskfilter;
+ struct grub_detached_pv *pv;
grub_dprintf ("diskfilter", "Scanning for DISKFILTER devices on disk %s\n",
name);
@@ -168,6 +180,28 @@ scan_disk_partition_iter (grub_disk_t di
grub_free (id.uuid);
return 0;
}
+ /*insert the special LVM PV into detached_pv_list*/
+ if (!arr && (id.uuidlen > 0) && (grub_strcmp(diskfilter->name, "lvm") == 0))
+ {
+ pv = grub_zalloc(sizeof(*pv));
+ if (!pv)
+ return 1;
+ pv->id.uuidlen = GRUB_LVM_ID_STRLEN;
+ pv->id.uuid = grub_malloc(GRUB_LVM_ID_STRLEN);
+ if (!pv->id.uuid)
+ goto fail_id;
+ grub_memcpy(pv->id.uuid, id.uuid, GRUB_LVM_ID_STRLEN);
+ /*It's safe to save disk into this standalone pv list*/
+ pv->disk = grub_disk_open(name);
+ if (!pv->disk)
+ goto fail_id;
+ pv->diskfilter = diskfilter;
+ grub_list_push (GRUB_AS_LIST_P (&detached_pv_list),
+ GRUB_AS_LIST(pv));
+#ifdef GRUB_UTIL
+ grub_util_info ("adding disk %s into detached pv list", name);
+#endif
+ }
if (arr && id.uuidlen)
grub_free (id.uuid);
@@ -180,6 +214,65 @@ scan_disk_partition_iter (grub_disk_t di
}
return 0;
+fail_id:
+ if (pv->id.uuidlen)
+ grub_free(pv->id.uuid);
+ grub_free(pv);
+ return 1;
+}
+
+static int
+process_detached_pv_list(void)
+{
+ struct grub_diskfilter_vg *arr;
+ struct grub_diskfilter_pv *pv1;
+ struct grub_detached_pv *pv2;
+ unsigned found = 0;
+
+ for (arr = array_list; arr != NULL; arr = arr->next)
+ {
+ for (pv1 = arr->pvs; pv1; pv1 = pv1->next)
+ {
+ if (pv1->disk)
+ continue;
+ FOR_DETACHED_PVS(pv2)
+ {
+ if (pv2->id.uuidlen == pv1->id.uuidlen &&
+ !grub_memcmp(pv2->id.uuid, pv1->id.uuid, pv1->id.uuidlen))
+ {
+ if (insert_array(pv2->disk, &(pv2->id), arr, -1, pv2->diskfilter))
+ return grub_errno;
+ else
+ {
+#ifdef GRUB_UTIL
+ grub_util_info ("found disk %s in detached pv list", pv1->disk->name);
+#endif
+ found = 1;
+ break;
+ }
+ }
+ }
+ /*remove pv2 from the list*/
+ if (found)
+ {
+#ifdef GRUB_UTIL
+ grub_util_info ("removing disk %s from detached pv list", pv1->disk->name);
+#endif
+ grub_list_remove(GRUB_AS_LIST (pv2));
+ if (pv2->id.uuidlen)
+ {
+ pv2->id.uuidlen = 0;
+ grub_free(pv2->id.uuid);
+ }
+ grub_disk_close(pv2->disk);
+ grub_free(pv2);
+ break;
+ }
+ }
+ if (found)
+ break;
+ }
+ return 0;
}
static int
@@ -206,6 +299,9 @@ scan_disk (const char *name, int accept_
grub_partition_iterate (disk, scan_disk_partition_iter, (void *) name);
grub_disk_close (disk);
scan_depth--;
+
+ /*process the detached_pv_list*/
+ process_detached_pv_list();
return 0;
}
@@ -1249,6 +1345,20 @@ insert_array (grub_disk_t disk, const st
static void
free_array (void)
{
+ while(detached_pv_list)
+ {
+ struct grub_detached_pv *pv;
+ pv = detached_pv_list;
+ detached_pv_list = detached_pv_list->next;
+#ifdef GRUB_UTIL
+ grub_util_warn (_("Couldn't find disk for physical volume `%s'."
+ "Some LVs may not work normally."),pv->disk->name);
+#endif
+ if (pv->id.uuidlen)
+ grub_free(pv->id.uuid);
+ grub_disk_close(pv->disk);
+ grub_free(pv);
+ }
while (array_list)
{
struct grub_diskfilter_vg *vg;
Index: grub-2.02/grub-core/disk/lvm.c
===================================================================
--- grub-2.02.orig/grub-core/disk/lvm.c
+++ grub-2.02/grub-core/disk/lvm.c
@@ -182,11 +182,16 @@ grub_lvm_detect (grub_disk_t disk,
sizeof (mdah->magic)))
|| (grub_le_to_cpu32 (mdah->version) != GRUB_LVM_FMTT_VERSION))
{
- grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
- "unknown LVM metadata header");
-#ifdef GRUB_UTIL
- grub_util_info ("unknown LVM metadata header");
-#endif
+ /*
+ * It's not necessarily an error. There is no metadata recorded when
+ * PV is created with pvmetadatacopies set to zero. We need to process
+ * this kind of PV seperately.
+ */
+ id->uuid = grub_malloc(GRUB_LVM_ID_STRLEN);
+ if (!id->uuid)
+ goto fail;
+ grub_memcpy(id->uuid, pv_id, GRUB_LVM_ID_STRLEN);
+ id->uuidlen = GRUB_LVM_ID_STRLEN;
goto fail;
}