diff --git a/.gitignore b/.gitignore index 618dc68..0342d81 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ SOURCES/grub-2.02~beta2.tar.xz SOURCES/theme.tar.bz2 SOURCES/unifont-5.1.20080820.pcf.gz -SOURCES/centos.cer diff --git a/.grub2.metadata b/.grub2.metadata index a5c2c6a..261f908 100644 --- a/.grub2.metadata +++ b/.grub2.metadata @@ -1,4 +1,3 @@ 1bf580f1e8bce4909a7ac7ca485cee02b00ed383 SOURCES/grub-2.02~beta2.tar.xz cf0b7763c528902da7e8b05cfa248f20c8825ce5 SOURCES/theme.tar.bz2 87f8600ba24e521b5d20bdf6c4b71af8ae861e3a SOURCES/unifont-5.1.20080820.pcf.gz -6e9105eb51e55a46761838f289a917611cad8091 SOURCES/centos.cer diff --git a/SOURCES/0001-Try-to-make-sure-configure.ac-and-grub-rpm-sort-play.patch b/SOURCES/0001-Try-to-make-sure-configure.ac-and-grub-rpm-sort-play.patch deleted file mode 100644 index 47e99ce..0000000 --- a/SOURCES/0001-Try-to-make-sure-configure.ac-and-grub-rpm-sort-play.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 0576c43a727f095caac0b04b551ebdb66adf616a Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 3 Aug 2015 11:46:42 -0400 -Subject: [PATCH] Try to make sure configure.ac and grub-rpm-sort play nice. - -Apparently the test for whether to use grub-rpm-sort and also the -renaming of it to grub2-rpm-sort on the runtime side weren't right. - -Related: rhbz#1124074 - -Signed-off-by: Peter Jones ---- - configure.ac | 2 +- - util/grub-mkconfig_lib.in | 9 ++++++--- - 2 files changed, 7 insertions(+), 4 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 273da6c..04c052d 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1549,7 +1549,7 @@ AC_SUBST([LIBDEVMAPPER]) - AC_ARG_ENABLE([rpm-sort], - [AS_HELP_STRING([--enable-rpm-sort], - [enable native rpm sorting of kernels in grub (default=guessed)])]) --if test x"$enable_rpm-sort" = xno ; then -+if test x"$enable_rpm_sort" = xno ; then - rpm_sort_excuse="explicitly disabled" - fi - -diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in -index e85b60c..c67a319 100644 ---- a/util/grub-mkconfig_lib.in -+++ b/util/grub-mkconfig_lib.in -@@ -33,6 +33,9 @@ fi - if test "x$grub_mkrelpath" = x; then - grub_mkrelpath="${bindir}/@grub_mkrelpath@" - fi -+if test "x$grub_rpm_sort" = x; then -+ grub_rpm_sort="${sbindir}/@grub_rpm_sort@" -+fi - - if which gettext >/dev/null 2>/dev/null; then - : -@@ -213,10 +216,10 @@ version_sort () - esac - } - --if [ "x$RPMLIB" = x ]; then -- kernel_sort=version_sort -+if [ "x$grub_rpm_sort" != x -a -x "$grub_rpm_sort" ]; then -+ kernel_sort="$grub_rpm_sort" - else -- kernel_sort="${sbindir}/grub-rpm-sort" -+ kernel_sort=version_sort - fi - - version_test_numeric () --- -2.4.3 - diff --git a/SOURCES/0001-Update-info-with-grub.cfg-netboot-selection-order-11.patch b/SOURCES/0001-Update-info-with-grub.cfg-netboot-selection-order-11.patch new file mode 100644 index 0000000..538f9f9 --- /dev/null +++ b/SOURCES/0001-Update-info-with-grub.cfg-netboot-selection-order-11.patch @@ -0,0 +1,70 @@ +From 24f034631df06b2f33d0721b8cd5126906aa7b34 Mon Sep 17 00:00:00 2001 +From: Robert Marshall +Date: Mon, 16 Mar 2015 16:34:51 -0400 +Subject: [PATCH 1/2] Update info with grub.cfg netboot selection order + (#1148650) + +Added documentation to the grub info page that specifies the order +netboot clients will use to select a grub configuration file. + +Resolves rhbz#1148650 +--- + docs/grub.texi | 42 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +diff --git a/docs/grub.texi b/docs/grub.texi +index 6b112c1..ef09c83 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -2414,6 +2414,48 @@ grub-mknetdir --net-directory=/srv/tftp --subdir=/boot/grub -d /usr/lib/grub/i38 + Then follow instructions printed out by grub-mknetdir on configuring your DHCP + server. + ++The grub.cfg file is placed in the same directory as the path output by ++grub-mknetdir hereafter referred to as FWPATH. GRUB will search for its ++configuration files in order using the following rules where the appended ++value corresponds to a value on the client machine. ++ ++@example ++@group ++@samp{(FWPATH)}/grub.cfg-@samp{(UUID OF NIC)} ++@samp{(FWPATH)}/grub.cfg-@samp{(MAC ADDRESS OF NIC)} ++@samp{(FWPATH)}/grub.cfg-@samp{(IPv4 OR IPv6 ADDRESS)} ++@samp{(FWPATH)}/grub.cfg ++@end group ++@end example ++ ++The client will only attempt to look up an IPv6 address config once, however, ++it will try the IPv4 multiple times. The concrete example below shows what ++would happen under the IPv4 case. ++ ++@example ++@group ++UUID: 7726a678-7fc0-4853-a4f6-c85ac36a120a ++MAC: 52:54:00:ec:33:81 ++IPV4: 10.0.0.130 (0A000082) ++@end group ++@end example ++ ++@example ++@group ++@samp{(FWPATH)}/grub.cfg-7726a678-7fc0-4853-a4f6-c85ac36a120a ++@samp{(FWPATH)}/grub.cfg-52-54-00-ec-33-81 ++@samp{(FWPATH)}/grub.cfg-0A000082 ++@samp{(FWPATH)}/grub.cfg-0A00008 ++@samp{(FWPATH)}/grub.cfg-0A0000 ++@samp{(FWPATH)}/grub.cfg-0A000 ++@samp{(FWPATH)}/grub.cfg-0A00 ++@samp{(FWPATH)}/grub.cfg-0A0 ++@samp{(FWPATH)}/grub.cfg-0A ++@samp{(FWPATH)}/grub.cfg-0 ++@samp{(FWPATH)}/grub.cfg ++@end group ++@end example ++ + After GRUB has started, files on the TFTP server will be accessible via the + @samp{(tftp)} device. + +-- +2.4.3 + diff --git a/SOURCES/0001-efidisk-move-device-path-helpers-in-core-for-efinet.patch b/SOURCES/0001-efidisk-move-device-path-helpers-in-core-for-efinet.patch new file mode 100644 index 0000000..90de69d --- /dev/null +++ b/SOURCES/0001-efidisk-move-device-path-helpers-in-core-for-efinet.patch @@ -0,0 +1,207 @@ +From 559b04c2e29643b73f238cf95add8cef9a192a00 Mon Sep 17 00:00:00 2001 +From: Andrei Borzenkov +Date: Thu, 7 May 2015 20:37:16 +0300 +Subject: [PATCH 01/17] efidisk: move device path helpers in core for efinet + +--- + grub-core/disk/efi/efidisk.c | 61 ++++++++------------------------------------ + grub-core/kern/efi/efi.c | 41 +++++++++++++++++++++++++++++ + include/grub/efi/efi.h | 4 +++ + 3 files changed, 55 insertions(+), 51 deletions(-) + +diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c +index 3b12c34..845c66f 100644 +--- a/grub-core/disk/efi/efidisk.c ++++ b/grub-core/disk/efi/efidisk.c +@@ -43,47 +43,6 @@ static struct grub_efidisk_data *fd_devices; + static struct grub_efidisk_data *hd_devices; + static struct grub_efidisk_data *cd_devices; + +-/* Duplicate a device path. */ +-static grub_efi_device_path_t * +-duplicate_device_path (const grub_efi_device_path_t *dp) +-{ +- grub_efi_device_path_t *p; +- grub_size_t total_size = 0; +- +- for (p = (grub_efi_device_path_t *) dp; +- ; +- p = GRUB_EFI_NEXT_DEVICE_PATH (p)) +- { +- total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p); +- if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p)) +- break; +- } +- +- p = grub_malloc (total_size); +- if (! p) +- return 0; +- +- grub_memcpy (p, dp, total_size); +- return p; +-} +- +-/* Return the device path node right before the end node. */ +-static grub_efi_device_path_t * +-find_last_device_path (const grub_efi_device_path_t *dp) +-{ +- grub_efi_device_path_t *next, *p; +- +- if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) +- return 0; +- +- for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p); +- ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next); +- p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next)) +- ; +- +- return p; +-} +- + static struct grub_efidisk_data * + make_devices (void) + { +@@ -110,7 +69,7 @@ make_devices (void) + if (! dp) + continue; + +- ldp = find_last_device_path (dp); ++ ldp = grub_efi_find_last_device_path (dp); + if (! ldp) + /* This is empty. Why? */ + continue; +@@ -150,11 +109,11 @@ find_parent_device (struct grub_efidisk_data *devices, + grub_efi_device_path_t *dp, *ldp; + struct grub_efidisk_data *parent; + +- dp = duplicate_device_path (d->device_path); ++ dp = grub_efi_duplicate_device_path (d->device_path); + if (! dp) + return 0; + +- ldp = find_last_device_path (dp); ++ ldp = grub_efi_find_last_device_path (dp); + ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; + ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; + ldp->length = sizeof (*ldp); +@@ -180,11 +139,11 @@ is_child (struct grub_efidisk_data *child, + grub_efi_device_path_t *dp, *ldp; + int ret; + +- dp = duplicate_device_path (child->device_path); ++ dp = grub_efi_duplicate_device_path (child->device_path); + if (! dp) + return 0; + +- ldp = find_last_device_path (dp); ++ ldp = grub_efi_find_last_device_path (dp); + ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; + ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; + ldp->length = sizeof (*ldp); +@@ -207,8 +166,8 @@ add_device (struct grub_efidisk_data **devices, struct grub_efidisk_data *d) + { + int ret; + +- ret = grub_efi_compare_device_paths (find_last_device_path ((*p)->device_path), +- find_last_device_path (d->device_path)); ++ ret = grub_efi_compare_device_paths (grub_efi_find_last_device_path ((*p)->device_path), ++ grub_efi_find_last_device_path (d->device_path)); + if (ret == 0) + ret = grub_efi_compare_device_paths ((*p)->device_path, + d->device_path); +@@ -795,7 +754,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) + if (! dp) + return 0; + +- ldp = find_last_device_path (dp); ++ ldp = grub_efi_find_last_device_path (dp); + if (! ldp) + return 0; + +@@ -811,14 +770,14 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) + + /* It is necessary to duplicate the device path so that GRUB + can overwrite it. */ +- dup_dp = duplicate_device_path (dp); ++ dup_dp = grub_efi_duplicate_device_path (dp); + if (! dup_dp) + return 0; + + while (1) + { + grub_efi_device_path_t *dup_ldp; +- dup_ldp = find_last_device_path (dup_dp); ++ dup_ldp = grub_efi_find_last_device_path (dup_dp); + if (!(GRUB_EFI_DEVICE_PATH_TYPE (dup_ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE + && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE + || GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE))) +diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c +index d99a6fb..c80d85b 100644 +--- a/grub-core/kern/efi/efi.c ++++ b/grub-core/kern/efi/efi.c +@@ -423,6 +423,47 @@ grub_efi_get_device_path (grub_efi_handle_t handle) + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); + } + ++/* Return the device path node right before the end node. */ ++grub_efi_device_path_t * ++grub_efi_find_last_device_path (const grub_efi_device_path_t *dp) ++{ ++ grub_efi_device_path_t *next, *p; ++ ++ if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) ++ return 0; ++ ++ for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p); ++ ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next); ++ p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next)) ++ ; ++ ++ return p; ++} ++ ++/* Duplicate a device path. */ ++grub_efi_device_path_t * ++grub_efi_duplicate_device_path (const grub_efi_device_path_t *dp) ++{ ++ grub_efi_device_path_t *p; ++ grub_size_t total_size = 0; ++ ++ for (p = (grub_efi_device_path_t *) dp; ++ ; ++ p = GRUB_EFI_NEXT_DEVICE_PATH (p)) ++ { ++ total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p); ++ if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p)) ++ break; ++ } ++ ++ p = grub_malloc (total_size); ++ if (! p) ++ return 0; ++ ++ grub_memcpy (p, dp, total_size); ++ return p; ++} ++ + static void + dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor) + { +diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h +index a000c38..2245632 100644 +--- a/include/grub/efi/efi.h ++++ b/include/grub/efi/efi.h +@@ -56,6 +56,10 @@ void EXPORT_FUNC(grub_efi_print_device_path) (grub_efi_device_path_t *dp); + char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp); + grub_efi_device_path_t * + EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle); ++grub_efi_device_path_t * ++EXPORT_FUNC(grub_efi_find_last_device_path) (const grub_efi_device_path_t *dp); ++grub_efi_device_path_t * ++EXPORT_FUNC(grub_efi_duplicate_device_path) (const grub_efi_device_path_t *dp); + grub_err_t EXPORT_FUNC (grub_efi_finish_boot_services) (grub_efi_uintn_t *outbuf_size, void *outbuf, + grub_efi_uintn_t *map_key, + grub_efi_uintn_t *efi_desc_size, +-- +2.4.3 + diff --git a/SOURCES/0158-efinet-Check-for-immediate-completition.patch b/SOURCES/0158-efinet-Check-for-immediate-completition.patch new file mode 100644 index 0000000..cfd04c1 --- /dev/null +++ b/SOURCES/0158-efinet-Check-for-immediate-completition.patch @@ -0,0 +1,51 @@ +From 763eff26748ca3d2ae8b178aef15da54a70527a5 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 27 Mar 2015 14:27:56 +0100 +Subject: [PATCH 01/23] efinet: Check for immediate completition. + +This both speeds GRUB up and workarounds unexpected EFI behaviour. +--- + grub-core/net/drivers/efi/efinet.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c +index a6e4c79..78df215 100644 +--- a/grub-core/net/drivers/efi/efinet.c ++++ b/grub-core/net/drivers/efi/efinet.c +@@ -37,11 +37,12 @@ send_card_buffer (struct grub_net_card *dev, + grub_efi_status_t st; + grub_efi_simple_network_t *net = dev->efi_net; + grub_uint64_t limit_time = grub_get_time_ms () + 4000; ++ void *txbuf; + + if (dev->txbusy) + while (1) + { +- void *txbuf = NULL; ++ txbuf = NULL; + st = efi_call_3 (net->get_status, net, 0, &txbuf); + if (st != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_IO, +@@ -74,7 +75,18 @@ send_card_buffer (struct grub_net_card *dev, + dev->txbuf, NULL, NULL, NULL); + if (st != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_IO, N_("couldn't send network packet")); +- dev->txbusy = 1; ++ ++ /* ++ The card may have sent out the packet immediately - set txbusy ++ to 0 in this case. ++ Cases were observed where checking txbuf at the next call ++ of send_card_buffer() is too late: 0 is returned in txbuf and ++ we run in the GRUB_ERR_TIMEOUT case above. ++ Perhaps a timeout in the FW has discarded the recycle buffer. ++ */ ++ st = efi_call_3 (net->get_status, net, 0, &txbuf); ++ dev->txbusy = !(st == GRUB_EFI_SUCCESS && txbuf == dev->txbuf); ++ + return GRUB_ERR_NONE; + } + +-- +2.4.3 + diff --git a/SOURCES/0159-efinet-memory-leak-on-module-removal.patch b/SOURCES/0159-efinet-memory-leak-on-module-removal.patch new file mode 100644 index 0000000..7eec92a --- /dev/null +++ b/SOURCES/0159-efinet-memory-leak-on-module-removal.patch @@ -0,0 +1,30 @@ +From 8471c374d9379ba80e4b3bbcacb4813a2d04f008 Mon Sep 17 00:00:00 2001 +From: Andrei Borzenkov +Date: Mon, 4 May 2015 08:08:57 +0300 +Subject: [PATCH 02/23] efinet: memory leak on module removal + +--- + grub-core/net/drivers/efi/efinet.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c +index 78df215..810adf3 100644 +--- a/grub-core/net/drivers/efi/efinet.c ++++ b/grub-core/net/drivers/efi/efinet.c +@@ -294,6 +294,12 @@ GRUB_MOD_FINI(efinet) + + FOR_NET_CARDS_SAFE (card, next) + if (card->driver == &efidriver) +- grub_net_card_unregister (card); ++ { ++ grub_net_card_unregister (card); ++ grub_free (card->txbuf); ++ grub_free (card->rcvbuf); ++ grub_free (card->name); ++ grub_free (card); ++ } + } + +-- +2.4.3 + diff --git a/SOURCES/0160-efinet-cannot-free-const-char-pointer.patch b/SOURCES/0160-efinet-cannot-free-const-char-pointer.patch new file mode 100644 index 0000000..cdc8b49 --- /dev/null +++ b/SOURCES/0160-efinet-cannot-free-const-char-pointer.patch @@ -0,0 +1,25 @@ +From fe8c0ca495c7225682e2af47d0d77b4ad0077f34 Mon Sep 17 00:00:00 2001 +From: Andrei Borzenkov +Date: Mon, 4 May 2015 08:39:29 +0300 +Subject: [PATCH 03/23] efinet: cannot free const char * pointer + +--- + grub-core/net/drivers/efi/efinet.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c +index 810adf3..bb863e6 100644 +--- a/grub-core/net/drivers/efi/efinet.c ++++ b/grub-core/net/drivers/efi/efinet.c +@@ -298,7 +298,7 @@ GRUB_MOD_FINI(efinet) + grub_net_card_unregister (card); + grub_free (card->txbuf); + grub_free (card->rcvbuf); +- grub_free (card->name); ++ grub_free ((char *)card->name); + grub_free (card); + } + } +-- +2.4.3 + diff --git a/SOURCES/0161-Revert-efinet-memory-leak-on-module-removal.patch b/SOURCES/0161-Revert-efinet-memory-leak-on-module-removal.patch new file mode 100644 index 0000000..284c4b5 --- /dev/null +++ b/SOURCES/0161-Revert-efinet-memory-leak-on-module-removal.patch @@ -0,0 +1,34 @@ +From 41772bb7633fab5e38f0dac90e1e04538a066a3d Mon Sep 17 00:00:00 2001 +From: Andrei Borzenkov +Date: Mon, 4 May 2015 09:13:53 +0300 +Subject: [PATCH 04/23] Revert "efinet: memory leak on module removal" + +This reverts commits 47b2bee3ef0ea60fc3f5bfc37f3784e559385297 +and 8d3c4544ffdd0289a4b0bdeb0cdc6355f801a4b3. It is not safe +to free allocated cards, dangling pointers main remain. Such +cleanup requires more changes in net core. +--- + grub-core/net/drivers/efi/efinet.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c +index bb863e6..78df215 100644 +--- a/grub-core/net/drivers/efi/efinet.c ++++ b/grub-core/net/drivers/efi/efinet.c +@@ -294,12 +294,6 @@ GRUB_MOD_FINI(efinet) + + FOR_NET_CARDS_SAFE (card, next) + if (card->driver == &efidriver) +- { +- grub_net_card_unregister (card); +- grub_free (card->txbuf); +- grub_free (card->rcvbuf); +- grub_free ((char *)card->name); +- grub_free (card); +- } ++ grub_net_card_unregister (card); + } + +-- +2.4.3 + diff --git a/SOURCES/0162-efinet-skip-virtual-IPv4-and-IPv6-devices-when-enume.patch b/SOURCES/0162-efinet-skip-virtual-IPv4-and-IPv6-devices-when-enume.patch new file mode 100644 index 0000000..f280428 --- /dev/null +++ b/SOURCES/0162-efinet-skip-virtual-IPv4-and-IPv6-devices-when-enume.patch @@ -0,0 +1,97 @@ +From 0faa80b06bc1e9956d7ee6aa3b23574b7c4c18c8 Mon Sep 17 00:00:00 2001 +From: Andrei Borzenkov +Date: Thu, 7 May 2015 20:37:17 +0300 +Subject: [PATCH 05/23] efinet: skip virtual IPv4 and IPv6 devices when + enumerating cards + +EDK2 PXE driver creates two child devices - IPv4 and IPv6 - with +bound SNP instance. This means we get three cards for every physical +adapter when enumerating. Not only is this confusing, this may result +in grub ignoring packets that come in via the "wrong" card. + +Example of device hierarchy is + + Ctrl[91] PciRoot(0x0)/Pci(0x3,0x0) + Ctrl[95] PciRoot(0x0)/Pci(0x3,0x0)/MAC(525400123456,0x1) + Ctrl[B4] PciRoot(0x0)/Pci(0x3,0x0)/MAC(525400123456,0x1)/IPv4(0.0.0.0) + Ctrl[BC] PciRoot(0x0)/Pci(0x3,0x0)/MAC(525400123456,0x1)/IPv6(0000:0000:0000:0000:0000:0000:0000:0000) + +Skip PXE created virtual devices when enumerating cards. Make sure to +find real card when applying initial autoconfiguration during PXE boot, +this information is associated with one of child devices. +--- + grub-core/net/drivers/efi/efinet.c | 51 +++++++++++++++++++++++++++++++++++++- + 1 file changed, 50 insertions(+), 1 deletion(-) + +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c +index 78df215..caa7b50 100644 +--- a/grub-core/net/drivers/efi/efinet.c ++++ b/grub-core/net/drivers/efi/efinet.c +@@ -174,6 +174,29 @@ grub_efinet_findcards (void) + { + grub_efi_simple_network_t *net; + struct grub_net_card *card; ++ grub_efi_device_path_t *dp, *parent = NULL, *child = NULL; ++ ++ /* EDK2 UEFI PXE driver creates IPv4 and IPv6 messaging devices as ++ children of main MAC messaging device. We only need one device with ++ bound SNP per physical card, otherwise they compete with each other ++ when polling for incoming packets. ++ */ ++ dp = grub_efi_get_device_path (*handle); ++ if (!dp) ++ continue; ++ for (; ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp); dp = GRUB_EFI_NEXT_DEVICE_PATH (dp)) ++ { ++ parent = child; ++ child = dp; ++ } ++ if (child ++ && GRUB_EFI_DEVICE_PATH_TYPE (child) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE ++ && (GRUB_EFI_DEVICE_PATH_SUBTYPE (child) == GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE ++ || GRUB_EFI_DEVICE_PATH_SUBTYPE (child) == GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE) ++ && parent ++ && GRUB_EFI_DEVICE_PATH_TYPE (parent) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE ++ && GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE) ++ continue; + + net = grub_efi_open_protocol (*handle, &net_io_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); +@@ -252,7 +275,33 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, + if (! cdp) + continue; + if (grub_efi_compare_device_paths (dp, cdp) != 0) +- continue; ++ { ++ grub_efi_device_path_t *ldp, *dup_dp, *dup_ldp; ++ int match; ++ ++ /* EDK2 UEFI PXE driver creates pseudo devices with type IPv4/IPv6 ++ as children of Ethernet card and binds PXE and Load File protocols ++ to it. Loaded Image Device Path protocol will point to these pseudo ++ devices. We skip them when enumerating cards, so here we need to ++ find matching MAC device. ++ */ ++ ldp = grub_efi_find_last_device_path (dp); ++ if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE ++ || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE ++ && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)) ++ continue; ++ dup_dp = grub_efi_duplicate_device_path (dp); ++ if (!dup_dp) ++ continue; ++ dup_ldp = grub_efi_find_last_device_path (dup_dp); ++ dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; ++ dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; ++ dup_ldp->length = sizeof (*dup_ldp); ++ match = grub_efi_compare_device_paths (dup_dp, cdp) == 0; ++ grub_free (dup_dp); ++ if (!match) ++ continue; ++ } + pxe = grub_efi_open_protocol (hnd, &pxe_io_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (! pxe) +-- +2.4.3 + diff --git a/SOURCES/0163-efinet-open-Simple-Network-Protocol-exclusively.patch b/SOURCES/0163-efinet-open-Simple-Network-Protocol-exclusively.patch new file mode 100644 index 0000000..608f8cb --- /dev/null +++ b/SOURCES/0163-efinet-open-Simple-Network-Protocol-exclusively.patch @@ -0,0 +1,89 @@ +From 0a84c5c3f0a50115372a61c68cc752367d669b07 Mon Sep 17 00:00:00 2001 +From: Andrei Borzenkov +Date: Thu, 7 May 2015 20:37:17 +0300 +Subject: [PATCH 06/23] efinet: open Simple Network Protocol exclusively + +EDK2 network stack is based on Managed Network Protocol which is layered +on top of Simple Management Protocol and does background polling. This +polling races with grub for received (and probably trasmitted) packets +which causes either serious slowdown or complete failure to load files. + +Open SNP device exclusively. This destroys all child MNP instances and +stops background polling. + +Exclusive open cannot be done when enumerating cards, as it would destroy +PXE information we need to autoconfigure interface; and it cannot be done +during autoconfiguration as we need to do it for non-PXE boot as well. So +move SNP open to card ->open method and add matching ->close to clean up. + +Based on patch from Mark Salter + +Also-By: Mark Salter +Closes: 41731 +--- + grub-core/net/drivers/efi/efinet.c | 46 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 46 insertions(+) + +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c +index caa7b50..6a1dd1f 100644 +--- a/grub-core/net/drivers/efi/efinet.c ++++ b/grub-core/net/drivers/efi/efinet.c +@@ -142,9 +142,55 @@ get_card_packet (struct grub_net_card *dev) + return nb; + } + ++static grub_err_t ++open_card (struct grub_net_card *dev) ++{ ++ grub_efi_simple_network_t *net; ++ ++ /* Try to reopen SNP exlusively to close any active MNP protocol instance ++ that may compete for packet polling ++ */ ++ net = grub_efi_open_protocol (dev->efi_handle, &net_io_guid, ++ GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE); ++ if (net) ++ { ++ if (net->mode->state == GRUB_EFI_NETWORK_STOPPED ++ && efi_call_1 (net->start, net) != GRUB_EFI_SUCCESS) ++ return grub_error (GRUB_ERR_NET_NO_CARD, "%s: net start failed", ++ dev->name); ++ ++ if (net->mode->state == GRUB_EFI_NETWORK_STOPPED) ++ return grub_error (GRUB_ERR_NET_NO_CARD, "%s: card stopped", ++ dev->name); ++ ++ if (net->mode->state == GRUB_EFI_NETWORK_STARTED ++ && efi_call_3 (net->initialize, net, 0, 0) != GRUB_EFI_SUCCESS) ++ return grub_error (GRUB_ERR_NET_NO_CARD, "%s: net initialize failed", ++ dev->name); ++ ++ efi_call_4 (grub_efi_system_table->boot_services->close_protocol, ++ dev->efi_net, &net_io_guid, ++ grub_efi_image_handle, dev->efi_handle); ++ dev->efi_net = net; ++ } ++ ++ /* If it failed we just try to run as best as we can */ ++ return GRUB_ERR_NONE; ++} ++ ++static void ++close_card (struct grub_net_card *dev) ++{ ++ efi_call_4 (grub_efi_system_table->boot_services->close_protocol, ++ dev->efi_net, &net_io_guid, ++ grub_efi_image_handle, dev->efi_handle); ++} ++ + static struct grub_net_card_driver efidriver = + { + .name = "efinet", ++ .open = open_card, ++ .close = close_card, + .send = send_card_buffer, + .recv = get_card_packet + }; +-- +2.4.3 + diff --git a/SOURCES/0164-efinet-enable-hardware-filters-when-opening-interfac.patch b/SOURCES/0164-efinet-enable-hardware-filters-when-opening-interfac.patch new file mode 100644 index 0000000..4c91618 --- /dev/null +++ b/SOURCES/0164-efinet-enable-hardware-filters-when-opening-interfac.patch @@ -0,0 +1,107 @@ +From 2c38daa48daebd9b5ebfbb94a9c451b00c9f251c Mon Sep 17 00:00:00 2001 +From: Andrei Borzenkov +Date: Tue, 16 Jun 2015 19:52:45 +0300 +Subject: [PATCH 07/23] efinet: enable hardware filters when opening interface + +Exclusive open on SNP will close all existing protocol instances which +may disable all receive filters on interface. Reinstall them after we +opened protocol exclusively. + +Also follow UEFI specification recommendation and stop interfaces when +closing them: + +Unexpected system errors, reboots and hangs can occur if an OS is loaded +and the network devices are not Shutdown() and Stopped(). + +Also by: Mark Salter +Closes: 45204 +--- + grub-core/net/drivers/efi/efinet.c | 25 +++++++++++++++++++++++++ + include/grub/efi/api.h | 20 +++++++++++++++++--- + 2 files changed, 42 insertions(+), 3 deletions(-) + +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c +index 6a1dd1f..7b8c4a5 100644 +--- a/grub-core/net/drivers/efi/efinet.c ++++ b/grub-core/net/drivers/efi/efinet.c +@@ -168,6 +168,29 @@ open_card (struct grub_net_card *dev) + return grub_error (GRUB_ERR_NET_NO_CARD, "%s: net initialize failed", + dev->name); + ++ /* Enable hardware receive filters if driver declares support for it. ++ We need unicast and broadcast and additionaly all nodes and ++ solicited multicast for IPv6. Solicited multicast is per-IPv6 ++ address and we currently do not have API to do it so simply ++ try to enable receive of all multicast packets or evertyhing in ++ the worst case (i386 PXE driver always enables promiscuous too). ++ ++ This does trust firmware to do what it claims to do. ++ */ ++ if (net->mode->receive_filter_mask) ++ { ++ grub_uint32_t filters = GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST | ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST | ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST; ++ ++ filters &= net->mode->receive_filter_mask; ++ if (!(filters & GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST)) ++ filters |= (net->mode->receive_filter_mask & ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS); ++ ++ efi_call_6 (net->receive_filters, net, filters, 0, 0, 0, NULL); ++ } ++ + efi_call_4 (grub_efi_system_table->boot_services->close_protocol, + dev->efi_net, &net_io_guid, + grub_efi_image_handle, dev->efi_handle); +@@ -181,6 +204,8 @@ open_card (struct grub_net_card *dev) + static void + close_card (struct grub_net_card *dev) + { ++ efi_call_1 (dev->efi_net->shutdown, dev->efi_net); ++ efi_call_1 (dev->efi_net->stop, dev->efi_net); + efi_call_4 (grub_efi_system_table->boot_services->close_protocol, + dev->efi_net, &net_io_guid, + grub_efi_image_handle, dev->efi_handle); +diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h +index 1423403..029ee92 100644 +--- a/include/grub/efi/api.h ++++ b/include/grub/efi/api.h +@@ -1564,17 +1564,31 @@ enum + GRUB_EFI_NETWORK_INITIALIZED, + }; + ++enum ++ { ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST = 0x01, ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST = 0x02, ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST = 0x04, ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS = 0x08, ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST = 0x10, ++ }; ++ + struct grub_efi_simple_network + { + grub_uint64_t revision; + grub_efi_status_t (*start) (struct grub_efi_simple_network *this); +- void (*stop) (void); ++ grub_efi_status_t (*stop) (struct grub_efi_simple_network *this); + grub_efi_status_t (*initialize) (struct grub_efi_simple_network *this, + grub_efi_uintn_t extra_rx, + grub_efi_uintn_t extra_tx); + void (*reset) (void); +- void (*shutdown) (void); +- void (*receive_filters) (void); ++ grub_efi_status_t (*shutdown) (struct grub_efi_simple_network *this); ++ grub_efi_status_t (*receive_filters) (struct grub_efi_simple_network *this, ++ grub_uint32_t enable, ++ grub_uint32_t disable, ++ grub_efi_boolean_t reset_mcast_filter, ++ grub_efi_uintn_t mcast_filter_count, ++ grub_efi_mac_address_t *mcast_filter); + void (*station_address) (void); + void (*statistics) (void); + void (*mcastiptomac) (void); +-- +2.4.3 + diff --git a/SOURCES/0165-efinet-handle-get_status-on-buggy-firmware-properly.patch b/SOURCES/0165-efinet-handle-get_status-on-buggy-firmware-properly.patch new file mode 100644 index 0000000..803a5ab --- /dev/null +++ b/SOURCES/0165-efinet-handle-get_status-on-buggy-firmware-properly.patch @@ -0,0 +1,66 @@ +From 17bd27e298d2b27859c8c6ee2e654d8f03988c42 Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Thu, 6 Aug 2015 10:49:46 -0700 +Subject: [PATCH 08/23] efinet: handle get_status() on buggy firmware properly + +The EFI spec indicates that get_status() should return the address of the buffer +we passed into transmit to indicate the the buffer was transmitted. However we +have boxes where the firmware returns some arbitrary address instead, which +makes grub think that we've not sent anything. So since we have the SNP stuff +opened in exclusive mode just assume any non-NULL txbuf means that our transmit +occurred properly. This makes grub able to do its networking stuff properly on +our broken firmware. Thanks, + +cc: Peter Jones +Signed-off-by: Josef Bacik +--- + grub-core/net/drivers/efi/efinet.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c +index 7b8c4a5..ea0e0ca 100644 +--- a/grub-core/net/drivers/efi/efinet.c ++++ b/grub-core/net/drivers/efi/efinet.c +@@ -47,19 +47,19 @@ send_card_buffer (struct grub_net_card *dev, + if (st != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_IO, + N_("couldn't send network packet")); +- if (txbuf == dev->txbuf) ++ /* ++ Some buggy firmware could return an arbitrary address instead of the ++ txbuf address we trasmitted, so just check that txbuf is non NULL ++ for success. This is ok because we open the SNP protocol in ++ exclusive mode so we know we're the only ones transmitting on this ++ box and since we only transmit one packet at a time we know our ++ transmit was successfull. ++ */ ++ if (txbuf) + { + dev->txbusy = 0; + break; + } +- if (txbuf) +- { +- st = efi_call_7 (net->transmit, net, 0, dev->last_pkt_size, +- dev->txbuf, NULL, NULL, NULL); +- if (st != GRUB_EFI_SUCCESS) +- return grub_error (GRUB_ERR_IO, +- N_("couldn't send network packet")); +- } + if (limit_time < grub_get_time_ms ()) + return grub_error (GRUB_ERR_TIMEOUT, + N_("couldn't send network packet")); +@@ -84,8 +84,9 @@ send_card_buffer (struct grub_net_card *dev, + we run in the GRUB_ERR_TIMEOUT case above. + Perhaps a timeout in the FW has discarded the recycle buffer. + */ ++ txbuf = NULL; + st = efi_call_3 (net->get_status, net, 0, &txbuf); +- dev->txbusy = !(st == GRUB_EFI_SUCCESS && txbuf == dev->txbuf); ++ dev->txbusy = !(st == GRUB_EFI_SUCCESS && txbuf); + + return GRUB_ERR_NONE; + } +-- +2.4.3 + diff --git a/SOURCES/0166-Handle-rssd-storage-devices.patch b/SOURCES/0166-Handle-rssd-storage-devices.patch new file mode 100644 index 0000000..14754c7 --- /dev/null +++ b/SOURCES/0166-Handle-rssd-storage-devices.patch @@ -0,0 +1,39 @@ +From 1ab087435c259702c62fdfe85e28f3e3f2459266 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 30 Jun 2015 15:50:41 -0400 +Subject: [PATCH 09/23] Handle rssd storage devices. + +Resolves: rhbz#1087962 + +Signed-off-by: Peter Jones +--- + grub-core/osdep/linux/getroot.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c +index 7007193..5987d07 100644 +--- a/grub-core/osdep/linux/getroot.c ++++ b/grub-core/osdep/linux/getroot.c +@@ -884,6 +884,19 @@ grub_util_part_to_disk (const char *os_dev, struct stat *st, + return path; + } + ++ /* If this is an rssd device. */ ++ if ((strncmp ("rssd", p, 4) == 0) && p[4] >= 'a' && p[4] <= 'z') ++ { ++ char *pp = p + 4; ++ while (*pp >= 'a' && *pp <= 'z') ++ pp++; ++ if (*pp) ++ *is_part = 1; ++ /* /dev/rssd[a-z]+[0-9]* */ ++ *pp = '\0'; ++ return path; ++ } ++ + /* If this is a loop device */ + if ((strncmp ("loop", p, 4) == 0) && p[4] >= '0' && p[4] <= '9') + { +-- +2.4.3 + diff --git a/SOURCES/0167-xfs-Fix-termination-loop-for-directory-iteration.patch b/SOURCES/0167-xfs-Fix-termination-loop-for-directory-iteration.patch new file mode 100644 index 0000000..6f4521b --- /dev/null +++ b/SOURCES/0167-xfs-Fix-termination-loop-for-directory-iteration.patch @@ -0,0 +1,32 @@ +From 6afb93f24d48ff10d4266396b079b79033e05b0a Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 14 Jul 2014 17:21:29 +0200 +Subject: [PATCH 10/23] xfs: Fix termination loop for directory iteration + +Directory iteration used wrong position (sizeof wrong structure) for +termination of iteration inside a directory block. Luckily the position +ended up being wrong by just 1 byte and directory entries are larger so +things worked out fine in practice. But fix the problem anyway. + +Signed-off-by: Jan Kara +--- + grub-core/fs/xfs.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c +index 16ffd3f..4bd52d1 100644 +--- a/grub-core/fs/xfs.c ++++ b/grub-core/fs/xfs.c +@@ -603,8 +603,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + - grub_be_to_cpu32 (tail->leaf_stale)); + + /* Iterate over all entries within this block. */ +- while (pos < (dirblk_size +- - (int) sizeof (struct grub_xfs_dir2_entry))) ++ while (pos < tail_start) + { + struct grub_xfs_dir2_entry *direntry; + grub_uint8_t *freetag; +-- +2.4.3 + diff --git a/SOURCES/0168-xfs-Convert-inode-numbers-to-cpu-endianity-immediate.patch b/SOURCES/0168-xfs-Convert-inode-numbers-to-cpu-endianity-immediate.patch new file mode 100644 index 0000000..01dbad0 --- /dev/null +++ b/SOURCES/0168-xfs-Convert-inode-numbers-to-cpu-endianity-immediate.patch @@ -0,0 +1,82 @@ +From 54a4f53f9ecae2378195e4e66a8410d3862a0be2 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 14 Jul 2014 17:21:30 +0200 +Subject: [PATCH 11/23] xfs: Convert inode numbers to cpu endianity immediately + after reading + +Currently XFS driver converted inode numbers to native endianity only +when using them to compute inode position. Although this works, it is +somewhat confusing. So convert inode numbers when reading them from disk +structures as every other field. + +Signed-off-by: Jan Kara +--- + grub-core/fs/xfs.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c +index 4bd52d1..0d704e9 100644 +--- a/grub-core/fs/xfs.c ++++ b/grub-core/fs/xfs.c +@@ -180,14 +180,14 @@ static inline grub_uint64_t + GRUB_XFS_INO_INOINAG (struct grub_xfs_data *data, + grub_uint64_t ino) + { +- return (grub_be_to_cpu64 (ino) & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1)); ++ return (ino & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1)); + } + + static inline grub_uint64_t + GRUB_XFS_INO_AG (struct grub_xfs_data *data, + grub_uint64_t ino) + { +- return (grub_be_to_cpu64 (ino) >> GRUB_XFS_INO_AGBITS (data)); ++ return (ino >> GRUB_XFS_INO_AGBITS (data)); + } + + static inline grub_disk_addr_t +@@ -506,13 +506,12 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + if (smallino) + { + parent = grub_be_to_cpu32 (diro->inode.data.dir.dirhead.parent.i4); +- parent = grub_cpu_to_be64 (parent); + /* The header is a bit smaller than usual. */ + de = (struct grub_xfs_dir_entry *) ((char *) de - 4); + } + else + { +- parent = diro->inode.data.dir.dirhead.parent.i8; ++ parent = grub_be_to_cpu64(diro->inode.data.dir.dirhead.parent.i8); + } + + /* Synthesize the direntries for `.' and `..'. */ +@@ -545,7 +544,6 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + | (((grub_uint64_t) inopos[5]) << 16) + | (((grub_uint64_t) inopos[6]) << 8) + | (((grub_uint64_t) inopos[7]) << 0); +- ino = grub_cpu_to_be64 (ino); + + c = de->name[de->len]; + de->name[de->len] = '\0'; +@@ -627,7 +625,8 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + is not used by GRUB. So it can be overwritten. */ + filename[direntry->len] = '\0'; + +- if (iterate_dir_call_hook (direntry->inode, filename, &ctx)) ++ if (iterate_dir_call_hook (grub_be_to_cpu64(direntry->inode), ++ filename, &ctx)) + { + grub_free (dirblock); + return 1; +@@ -689,7 +688,7 @@ grub_xfs_mount (grub_disk_t disk) + goto fail; + + data->diropen.data = data; +- data->diropen.ino = data->sblock.rootino; ++ data->diropen.ino = grub_be_to_cpu64(data->sblock.rootino); + data->diropen.inode_read = 1; + data->bsize = grub_be_to_cpu32 (data->sblock.bsize); + data->agsize = grub_be_to_cpu32 (data->sblock.agsize); +-- +2.4.3 + diff --git a/SOURCES/0169-xfs-Add-helpers-for-inode-size.patch b/SOURCES/0169-xfs-Add-helpers-for-inode-size.patch new file mode 100644 index 0000000..89b1257 --- /dev/null +++ b/SOURCES/0169-xfs-Add-helpers-for-inode-size.patch @@ -0,0 +1,97 @@ +From bc7e3f1e508c91b9ad7d3459998c5cd31d1caca0 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 1 Jun 2015 14:28:45 +0200 +Subject: [PATCH 12/23] xfs: Add helpers for inode size + +Add helpers to return size of XFS inode on disk and when loaded in +memory. + +Signed-off-by: Jan Kara +--- + grub-core/fs/xfs.c | 35 ++++++++++++++++++++++++----------- + 1 file changed, 24 insertions(+), 11 deletions(-) + +diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c +index 0d704e9..26d8147 100644 +--- a/grub-core/fs/xfs.c ++++ b/grub-core/fs/xfs.c +@@ -255,6 +255,24 @@ grub_xfs_inode_offset (struct grub_xfs_data *data, + data->sblock.log2_inode); + } + ++static inline grub_size_t ++grub_xfs_inode_size(struct grub_xfs_data *data) ++{ ++ return 1 << data->sblock.log2_inode; ++} ++ ++/* ++ * Returns size occupied by XFS inode stored in memory - we store struct ++ * grub_fshelp_node there but on disk inode size may be actually larger than ++ * struct grub_xfs_inode so we need to account for that so that we can read ++ * from disk directly into in-memory structure. ++ */ ++static inline grub_size_t ++grub_xfs_fshelp_size(struct grub_xfs_data *data) ++{ ++ return sizeof (struct grub_fshelp_node) - sizeof (struct grub_xfs_inode) ++ + grub_xfs_inode_size(data); ++} + + static grub_err_t + grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino, +@@ -264,8 +282,8 @@ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino, + int offset = grub_xfs_inode_offset (data, ino); + + /* Read the inode. */ +- if (grub_disk_read (data->disk, block, offset, +- 1 << data->sblock.log2_inode, inode)) ++ if (grub_disk_read (data->disk, block, offset, grub_xfs_inode_size(data), ++ inode)) + return grub_errno; + + if (grub_strncmp ((char *) inode->magic, "IN", 2)) +@@ -297,7 +315,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + if (node->inode.fork_offset) + recoffset = (node->inode.fork_offset - 1) / 2; + else +- recoffset = ((1 << node->data->sblock.log2_inode) ++ recoffset = (grub_xfs_inode_size(node->data) + - ((char *) &node->inode.data.btree.keys + - (char *) &node->inode)) + / (2 * sizeof (grub_uint64_t)); +@@ -456,9 +474,7 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename, + struct grub_fshelp_node *fdiro; + grub_err_t err; + +- fdiro = grub_malloc (sizeof (struct grub_fshelp_node) +- - sizeof (struct grub_xfs_inode) +- + (1 << ctx->diro->data->sblock.log2_inode) + 1); ++ fdiro = grub_malloc (grub_xfs_fshelp_size(ctx->diro->data) + 1); + if (!fdiro) + { + grub_print_error (); +@@ -682,7 +698,7 @@ grub_xfs_mount (grub_disk_t disk) + data = grub_realloc (data, + sizeof (struct grub_xfs_data) + - sizeof (struct grub_xfs_inode) +- + (1 << data->sblock.log2_inode) + 1); ++ + grub_xfs_inode_size(data) + 1); + + if (! data) + goto fail; +@@ -797,10 +813,7 @@ grub_xfs_open (struct grub_file *file, const char *name) + + if (fdiro != &data->diropen) + { +- grub_memcpy (&data->diropen, fdiro, +- sizeof (struct grub_fshelp_node) +- - sizeof (struct grub_xfs_inode) +- + (1 << data->sblock.log2_inode)); ++ grub_memcpy (&data->diropen, fdiro, grub_xfs_fshelp_size(data)); + grub_free (fdiro); + } + +-- +2.4.3 + diff --git a/SOURCES/0170-xfs-V5-filesystem-format-support.patch b/SOURCES/0170-xfs-V5-filesystem-format-support.patch new file mode 100644 index 0000000..36d6a39 --- /dev/null +++ b/SOURCES/0170-xfs-V5-filesystem-format-support.patch @@ -0,0 +1,579 @@ +From f9187f5eef9776ba51dca88e347bfd6675787cb6 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 1 Jun 2015 14:28:46 +0200 +Subject: [PATCH 13/23] xfs: V5 filesystem format support + +Add support for new XFS on disk format. We have to handle optional +filetype fields in directory entries, additional CRC, LSN, UUID entries +in some structures, etc. + +Signed-off-by: Jan Kara +--- + grub-core/fs/xfs.c | 332 ++++++++++++++++++++++++++++++++++++++++------------- + 1 file changed, 252 insertions(+), 80 deletions(-) + +diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c +index 26d8147..f00e43e 100644 +--- a/grub-core/fs/xfs.c ++++ b/grub-core/fs/xfs.c +@@ -34,6 +34,50 @@ GRUB_MOD_LICENSE ("GPLv3+"); + #define XFS_INODE_FORMAT_EXT 2 + #define XFS_INODE_FORMAT_BTREE 3 + ++/* Superblock version field flags */ ++#define XFS_SB_VERSION_NUMBITS 0x000f ++#define XFS_SB_VERSION_ATTRBIT 0x0010 ++#define XFS_SB_VERSION_NLINKBIT 0x0020 ++#define XFS_SB_VERSION_QUOTABIT 0x0040 ++#define XFS_SB_VERSION_ALIGNBIT 0x0080 ++#define XFS_SB_VERSION_DALIGNBIT 0x0100 ++#define XFS_SB_VERSION_LOGV2BIT 0x0400 ++#define XFS_SB_VERSION_SECTORBIT 0x0800 ++#define XFS_SB_VERSION_EXTFLGBIT 0x1000 ++#define XFS_SB_VERSION_DIRV2BIT 0x2000 ++#define XFS_SB_VERSION_MOREBITSBIT 0x8000 ++#define XFS_SB_VERSION_BITS_SUPPORTED \ ++ (XFS_SB_VERSION_NUMBITS | \ ++ XFS_SB_VERSION_ATTRBIT | \ ++ XFS_SB_VERSION_NLINKBIT | \ ++ XFS_SB_VERSION_QUOTABIT | \ ++ XFS_SB_VERSION_ALIGNBIT | \ ++ XFS_SB_VERSION_DALIGNBIT | \ ++ XFS_SB_VERSION_LOGV2BIT | \ ++ XFS_SB_VERSION_SECTORBIT | \ ++ XFS_SB_VERSION_EXTFLGBIT | \ ++ XFS_SB_VERSION_DIRV2BIT | \ ++ XFS_SB_VERSION_MOREBITSBIT) ++ ++/* Recognized xfs format versions */ ++#define XFS_SB_VERSION_4 4 /* Good old XFS filesystem */ ++#define XFS_SB_VERSION_5 5 /* CRC enabled filesystem */ ++ ++/* features2 field flags */ ++#define XFS_SB_VERSION2_LAZYSBCOUNTBIT 0x00000002 /* Superblk counters */ ++#define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ ++#define XFS_SB_VERSION2_PROJID32BIT 0x00000080 /* 32-bit project ids */ ++#define XFS_SB_VERSION2_FTYPE 0x00000200 /* inode type in dir */ ++#define XFS_SB_VERSION2_BITS_SUPPORTED \ ++ (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \ ++ XFS_SB_VERSION2_ATTR2BIT | \ ++ XFS_SB_VERSION2_PROJID32BIT | \ ++ XFS_SB_VERSION2_FTYPE) ++ ++/* incompat feature flags */ ++#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ ++#define XFS_SB_FEAT_INCOMPAT_SUPPORTED \ ++ (XFS_SB_FEAT_INCOMPAT_FTYPE) + + struct grub_xfs_sblock + { +@@ -45,7 +89,9 @@ struct grub_xfs_sblock + grub_uint64_t rootino; + grub_uint8_t unused3[20]; + grub_uint32_t agsize; +- grub_uint8_t unused4[20]; ++ grub_uint8_t unused4[12]; ++ grub_uint16_t version; ++ grub_uint8_t unused5[6]; + grub_uint8_t label[12]; + grub_uint8_t log2_bsize; + grub_uint8_t log2_sect; +@@ -54,12 +100,19 @@ struct grub_xfs_sblock + grub_uint8_t log2_agblk; + grub_uint8_t unused6[67]; + grub_uint8_t log2_dirblk; ++ grub_uint8_t unused7[7]; ++ grub_uint32_t features2; ++ grub_uint8_t unused8[4]; ++ grub_uint32_t sb_features_compat; ++ grub_uint32_t sb_features_ro_compat; ++ grub_uint32_t sb_features_incompat; ++ grub_uint32_t sb_features_log_incompat; + } GRUB_PACKED; + + struct grub_xfs_dir_header + { + grub_uint8_t count; +- grub_uint8_t smallino; ++ grub_uint8_t largeino; + union + { + grub_uint32_t i4; +@@ -67,14 +120,16 @@ struct grub_xfs_dir_header + } GRUB_PACKED parent; + } GRUB_PACKED; + ++/* Structure for directory entry inlined in the inode */ + struct grub_xfs_dir_entry + { + grub_uint8_t len; + grub_uint16_t offset; + char name[1]; +- /* Inode number follows, 32 bits. */ ++ /* Inode number follows, 32 / 64 bits. */ + } GRUB_PACKED; + ++/* Structure for directory entry in a block */ + struct grub_xfs_dir2_entry + { + grub_uint64_t inode; +@@ -90,7 +145,8 @@ struct grub_xfs_btree_node + grub_uint16_t numrecs; + grub_uint64_t left; + grub_uint64_t right; +- grub_uint64_t keys[1]; ++ /* In V5 here follow crc, uuid, etc. */ ++ /* Then follow keys and block pointers */ + } GRUB_PACKED; + + struct grub_xfs_btree_root +@@ -123,19 +179,11 @@ struct grub_xfs_inode + grub_uint16_t unused3; + grub_uint8_t fork_offset; + grub_uint8_t unused4[17]; +- union +- { +- char raw[156]; +- struct dir +- { +- struct grub_xfs_dir_header dirhead; +- struct grub_xfs_dir_entry direntry[1]; +- } dir; +- grub_xfs_extent extents[XFS_INODE_EXTENTS]; +- struct grub_xfs_btree_root btree; +- } GRUB_PACKED data; + } GRUB_PACKED; + ++#define XFS_V2_INODE_SIZE sizeof(struct grub_xfs_inode) ++#define XFS_V3_INODE_SIZE (XFS_V2_INODE_SIZE + 76) ++ + struct grub_xfs_dirblock_tail + { + grub_uint32_t leaf_count; +@@ -157,6 +205,8 @@ struct grub_xfs_data + int pos; + int bsize; + grub_uint32_t agsize; ++ unsigned int hasftype:1; ++ unsigned int hascrc:1; + struct grub_fshelp_node diropen; + }; + +@@ -164,6 +214,71 @@ static grub_dl_t my_mod; + + + ++static int grub_xfs_sb_hascrc(struct grub_xfs_data *data) ++{ ++ return (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) == ++ grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5); ++} ++ ++static int grub_xfs_sb_hasftype(struct grub_xfs_data *data) ++{ ++ if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) == ++ grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5) && ++ data->sblock.sb_features_incompat & grub_cpu_to_be32_compile_time(XFS_SB_FEAT_INCOMPAT_FTYPE)) ++ return 1; ++ if (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_MOREBITSBIT) && ++ data->sblock.features2 & grub_cpu_to_be32_compile_time(XFS_SB_VERSION2_FTYPE)) ++ return 1; ++ return 0; ++} ++ ++static int grub_xfs_sb_valid(struct grub_xfs_data *data) ++{ ++ grub_dprintf("xfs", "Validating superblock\n"); ++ if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4) ++ || data->sblock.log2_bsize < GRUB_DISK_SECTOR_BITS ++ || ((int) data->sblock.log2_bsize ++ + (int) data->sblock.log2_dirblk) >= 27) ++ { ++ grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem"); ++ return 0; ++ } ++ if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) == ++ grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5)) ++ { ++ grub_dprintf("xfs", "XFS v5 superblock detected\n"); ++ if (data->sblock.sb_features_incompat & ++ grub_cpu_to_be32_compile_time(~XFS_SB_FEAT_INCOMPAT_SUPPORTED)) ++ { ++ grub_error (GRUB_ERR_BAD_FS, "XFS filesystem has unsupported " ++ "incompatible features"); ++ return 0; ++ } ++ return 1; ++ } ++ else if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) == ++ grub_cpu_to_be16_compile_time(XFS_SB_VERSION_4)) ++ { ++ grub_dprintf("xfs", "XFS v4 superblock detected\n"); ++ if (!(data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_DIRV2BIT))) ++ { ++ grub_error (GRUB_ERR_BAD_FS, "XFS filesystem without V2 directories " ++ "is unsupported"); ++ return 0; ++ } ++ if (data->sblock.version & grub_cpu_to_be16_compile_time(~XFS_SB_VERSION_BITS_SUPPORTED) || ++ (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_MOREBITSBIT) && ++ data->sblock.features2 & grub_cpu_to_be16_compile_time(~XFS_SB_VERSION2_BITS_SUPPORTED))) ++ { ++ grub_error (GRUB_ERR_BAD_FS, "XFS filesystem has unsupported version " ++ "bits"); ++ return 0; ++ } ++ return 1; ++ } ++ return 0; ++} ++ + /* Filetype information as used in inodes. */ + #define FILETYPE_INO_MASK 0170000 + #define FILETYPE_INO_REG 0100000 +@@ -219,18 +334,6 @@ GRUB_XFS_EXTENT_SIZE (grub_xfs_extent *exts, int ex) + return (grub_be_to_cpu32 (exts[ex][3]) & ((1 << 21) - 1)); + } + +-static inline int +-GRUB_XFS_ROUND_TO_DIRENT (int pos) +-{ +- return ((((pos) + 8 - 1) / 8) * 8); +-} +- +-static inline int +-GRUB_XFS_NEXT_DIRENT (int pos, int len) +-{ +- return (pos) + GRUB_XFS_ROUND_TO_DIRENT (8 + 1 + len + 2); +-} +- + + static inline grub_uint64_t + grub_xfs_inode_block (struct grub_xfs_data *data, +@@ -274,6 +377,85 @@ grub_xfs_fshelp_size(struct grub_xfs_data *data) + + grub_xfs_inode_size(data); + } + ++static void * ++grub_xfs_inode_data(struct grub_xfs_inode *inode) ++{ ++ if (inode->version <= 2) ++ return ((char *)inode) + XFS_V2_INODE_SIZE; ++ return ((char *)inode) + XFS_V3_INODE_SIZE; ++} ++ ++static struct grub_xfs_dir_entry * ++grub_xfs_inline_de(struct grub_xfs_dir_header *head) ++{ ++ /* ++ * With small inode numbers the header is 4 bytes smaller because of ++ * smaller parent pointer ++ */ ++ return (void *)(((char *)head) + sizeof(struct grub_xfs_dir_header) - ++ (head->largeino ? 0 : sizeof(grub_uint32_t))); ++} ++ ++static grub_uint8_t * ++grub_xfs_inline_de_inopos(struct grub_xfs_data *data, ++ struct grub_xfs_dir_entry *de) ++{ ++ return ((grub_uint8_t *)(de + 1)) + de->len - 1 + ++ (data->hasftype ? 1 : 0); ++} ++ ++static struct grub_xfs_dir_entry * ++grub_xfs_inline_next_de(struct grub_xfs_data *data, ++ struct grub_xfs_dir_header *head, ++ struct grub_xfs_dir_entry *de) ++{ ++ char *p = (char *)de + sizeof(struct grub_xfs_dir_entry) - 1 + de->len; ++ ++ p += head->largeino ? sizeof(grub_uint64_t) : sizeof(grub_uint32_t); ++ if (data->hasftype) ++ p++; ++ ++ return (struct grub_xfs_dir_entry *)p; ++} ++ ++static struct grub_xfs_dirblock_tail * ++grub_xfs_dir_tail(struct grub_xfs_data *data, void *dirblock) ++{ ++ int dirblksize = 1 << (data->sblock.log2_bsize + data->sblock.log2_dirblk); ++ ++ return (struct grub_xfs_dirblock_tail *) ++ ((char *)dirblock + dirblksize - sizeof (struct grub_xfs_dirblock_tail)); ++} ++ ++static struct grub_xfs_dir2_entry * ++grub_xfs_first_de(struct grub_xfs_data *data, void *dirblock) ++{ ++ if (data->hascrc) ++ return (struct grub_xfs_dir2_entry *)((char *)dirblock + 64); ++ return (struct grub_xfs_dir2_entry *)((char *)dirblock + 16); ++} ++ ++static struct grub_xfs_dir2_entry * ++grub_xfs_next_de(struct grub_xfs_data *data, struct grub_xfs_dir2_entry *de) ++{ ++ int size = sizeof (struct grub_xfs_dir2_entry) + de->len + 2 /* Tag */; ++ ++ if (data->hasftype) ++ size++; /* File type */ ++ return (struct grub_xfs_dir2_entry *)(((char *)de) + ALIGN_UP(size, 8)); ++} ++ ++static grub_uint64_t * ++grub_xfs_btree_keys(struct grub_xfs_data *data, ++ struct grub_xfs_btree_node *leaf) ++{ ++ grub_uint64_t *keys = (grub_uint64_t *)(leaf + 1); ++ ++ if (data->hascrc) ++ keys += 6; /* skip crc, uuid, ... */ ++ return keys; ++} ++ + static grub_err_t + grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino, + struct grub_xfs_inode *inode) +@@ -281,6 +463,8 @@ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino, + grub_uint64_t block = grub_xfs_inode_block (data, ino); + int offset = grub_xfs_inode_offset (data, ino); + ++ grub_dprintf("xfs", "Reading inode (%"PRIuGRUB_UINT64_T") - %"PRIuGRUB_UINT64_T", %d\n", ++ ino, block, offset); + /* Read the inode. */ + if (grub_disk_read (data->disk, block, offset, grub_xfs_inode_size(data), + inode)) +@@ -303,6 +487,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + + if (node->inode.format == XFS_INODE_FORMAT_BTREE) + { ++ struct grub_xfs_btree_root *root; + const grub_uint64_t *keys; + int recoffset; + +@@ -310,15 +495,15 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + if (leaf == 0) + return 0; + +- nrec = grub_be_to_cpu16 (node->inode.data.btree.numrecs); +- keys = &node->inode.data.btree.keys[0]; ++ root = grub_xfs_inode_data(&node->inode); ++ nrec = grub_be_to_cpu16 (root->numrecs); ++ keys = &root->keys[0]; + if (node->inode.fork_offset) + recoffset = (node->inode.fork_offset - 1) / 2; + else + recoffset = (grub_xfs_inode_size(node->data) +- - ((char *) &node->inode.data.btree.keys +- - (char *) &node->inode)) +- / (2 * sizeof (grub_uint64_t)); ++ - ((char *) keys - (char *) &node->inode)) ++ / (2 * sizeof (grub_uint64_t)); + do + { + int i; +@@ -340,7 +525,10 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + 0, node->data->bsize, leaf)) + return 0; + +- if (grub_strncmp ((char *) leaf->magic, "BMAP", 4)) ++ if ((!node->data->hascrc && ++ grub_strncmp ((char *) leaf->magic, "BMAP", 4)) || ++ (node->data->hascrc && ++ grub_strncmp ((char *) leaf->magic, "BMA3", 4))) + { + grub_free (leaf); + grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node"); +@@ -348,8 +536,8 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + } + + nrec = grub_be_to_cpu16 (leaf->numrecs); +- keys = &leaf->keys[0]; +- recoffset = ((node->data->bsize - ((char *) &leaf->keys ++ keys = grub_xfs_btree_keys(node->data, leaf); ++ recoffset = ((node->data->bsize - ((char *) keys + - (char *) leaf)) + / (2 * sizeof (grub_uint64_t))); + } +@@ -359,7 +547,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + else if (node->inode.format == XFS_INODE_FORMAT_EXT) + { + nrec = grub_be_to_cpu32 (node->inode.nextents); +- exts = &node->inode.data.extents[0]; ++ exts = grub_xfs_inode_data(&node->inode); + } + else + { +@@ -417,7 +605,7 @@ grub_xfs_read_symlink (grub_fshelp_node_t node) + switch (node->inode.format) + { + case XFS_INODE_FORMAT_INO: +- return grub_strndup (node->inode.data.raw, size); ++ return grub_strndup (grub_xfs_inode_data(&node->inode), size); + + case XFS_INODE_FORMAT_EXT: + { +@@ -512,23 +700,18 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + { + case XFS_INODE_FORMAT_INO: + { +- struct grub_xfs_dir_entry *de = &diro->inode.data.dir.direntry[0]; +- int smallino = !diro->inode.data.dir.dirhead.smallino; ++ struct grub_xfs_dir_header *head = grub_xfs_inode_data(&diro->inode); ++ struct grub_xfs_dir_entry *de = grub_xfs_inline_de(head); ++ int smallino = !head->largeino; + int i; + grub_uint64_t parent; + + /* If small inode numbers are used to pack the direntry, the + parent inode number is small too. */ + if (smallino) +- { +- parent = grub_be_to_cpu32 (diro->inode.data.dir.dirhead.parent.i4); +- /* The header is a bit smaller than usual. */ +- de = (struct grub_xfs_dir_entry *) ((char *) de - 4); +- } ++ parent = grub_be_to_cpu32 (head->parent.i4); + else +- { +- parent = grub_be_to_cpu64(diro->inode.data.dir.dirhead.parent.i8); +- } ++ parent = grub_be_to_cpu64 (head->parent.i8); + + /* Synthesize the direntries for `.' and `..'. */ + if (iterate_dir_call_hook (diro->ino, ".", &ctx)) +@@ -537,12 +720,10 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + if (iterate_dir_call_hook (parent, "..", &ctx)) + return 1; + +- for (i = 0; i < diro->inode.data.dir.dirhead.count; i++) ++ for (i = 0; i < head->count; i++) + { + grub_uint64_t ino; +- grub_uint8_t *inopos = (((grub_uint8_t *) de) +- + sizeof (struct grub_xfs_dir_entry) +- + de->len - 1); ++ grub_uint8_t *inopos = grub_xfs_inline_de_inopos(dir->data, de); + grub_uint8_t c; + + /* inopos might be unaligned. */ +@@ -567,10 +748,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + return 1; + de->name[de->len] = c; + +- de = ((struct grub_xfs_dir_entry *) +- (((char *) de)+ sizeof (struct grub_xfs_dir_entry) + de->len +- + ((smallino ? sizeof (grub_uint32_t) +- : sizeof (grub_uint64_t))) - 1)); ++ de = grub_xfs_inline_next_de(dir->data, head, de); + } + break; + } +@@ -597,15 +775,11 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + >> dirblk_log2); + blk++) + { +- /* The header is skipped, the first direntry is stored +- from byte 16. */ +- int pos = 16; ++ struct grub_xfs_dir2_entry *direntry = ++ grub_xfs_first_de(dir->data, dirblock); + int entries; +- int tail_start = (dirblk_size +- - sizeof (struct grub_xfs_dirblock_tail)); +- +- struct grub_xfs_dirblock_tail *tail; +- tail = (struct grub_xfs_dirblock_tail *) &dirblock[tail_start]; ++ struct grub_xfs_dirblock_tail *tail = ++ grub_xfs_dir_tail(dir->data, dirblock); + + numread = grub_xfs_read_file (dir, 0, 0, + blk << dirblk_log2, +@@ -617,13 +791,11 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + - grub_be_to_cpu32 (tail->leaf_stale)); + + /* Iterate over all entries within this block. */ +- while (pos < tail_start) ++ while ((char *)direntry < (char *)tail) + { +- struct grub_xfs_dir2_entry *direntry; + grub_uint8_t *freetag; + char *filename; + +- direntry = (struct grub_xfs_dir2_entry *) &dirblock[pos]; + freetag = (grub_uint8_t *) direntry; + + if (grub_get_unaligned16 (freetag) == 0XFFFF) +@@ -631,14 +803,16 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + grub_uint8_t *skip = (freetag + sizeof (grub_uint16_t)); + + /* This entry is not used, go to the next one. */ +- pos += grub_be_to_cpu16 (grub_get_unaligned16 (skip)); ++ direntry = (struct grub_xfs_dir2_entry *) ++ (((char *)direntry) + ++ grub_be_to_cpu16 (grub_get_unaligned16 (skip))); + + continue; + } + +- filename = &dirblock[pos + sizeof (*direntry)]; +- /* The byte after the filename is for the tag, which +- is not used by GRUB. So it can be overwritten. */ ++ filename = (char *)(direntry + 1); ++ /* The byte after the filename is for the filetype, padding, or ++ tag, which is not used by GRUB. So it can be overwritten. */ + filename[direntry->len] = '\0'; + + if (iterate_dir_call_hook (grub_be_to_cpu64(direntry->inode), +@@ -655,8 +829,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + break; + + /* Select the next directory entry. */ +- pos = GRUB_XFS_NEXT_DIRENT (pos, direntry->len); +- pos = GRUB_XFS_ROUND_TO_DIRENT (pos); ++ direntry = grub_xfs_next_de(dir->data, direntry); + } + } + grub_free (dirblock); +@@ -681,19 +854,14 @@ grub_xfs_mount (grub_disk_t disk) + if (!data) + return 0; + ++ grub_dprintf("xfs", "Reading sb\n"); + /* Read the superblock. */ + if (grub_disk_read (disk, 0, 0, + sizeof (struct grub_xfs_sblock), &data->sblock)) + goto fail; + +- if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4) +- || data->sblock.log2_bsize < GRUB_DISK_SECTOR_BITS +- || ((int) data->sblock.log2_bsize +- + (int) data->sblock.log2_dirblk) >= 27) +- { +- grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem"); +- goto fail; +- } ++ if (!grub_xfs_sb_valid(data)) ++ goto fail; + + data = grub_realloc (data, + sizeof (struct grub_xfs_data) +@@ -708,9 +876,13 @@ grub_xfs_mount (grub_disk_t disk) + data->diropen.inode_read = 1; + data->bsize = grub_be_to_cpu32 (data->sblock.bsize); + data->agsize = grub_be_to_cpu32 (data->sblock.agsize); ++ data->hasftype = grub_xfs_sb_hasftype(data); ++ data->hascrc = grub_xfs_sb_hascrc(data); + + data->disk = disk; + data->pos = 0; ++ grub_dprintf("xfs", "Reading root ino %"PRIuGRUB_UINT64_T"\n", ++ grub_cpu_to_be64(data->sblock.rootino)); + + grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode); + +-- +2.4.3 + diff --git a/SOURCES/0171-xfs-silence-Coverity-overflow-warning.patch b/SOURCES/0171-xfs-silence-Coverity-overflow-warning.patch new file mode 100644 index 0000000..5f5ae3e --- /dev/null +++ b/SOURCES/0171-xfs-silence-Coverity-overflow-warning.patch @@ -0,0 +1,27 @@ +From 4ac2b84fea9a90d68970c0729a02895d47a8b40c Mon Sep 17 00:00:00 2001 +From: Andrei Borzenkov +Date: Fri, 19 Jun 2015 18:38:25 +0300 +Subject: [PATCH 14/23] xfs: silence Coverity overflow warning + +inode size cannot really overflow integer, but Coverity does not know it. +CID: 96602 +--- + grub-core/fs/xfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c +index f00e43e..7249291 100644 +--- a/grub-core/fs/xfs.c ++++ b/grub-core/fs/xfs.c +@@ -361,7 +361,7 @@ grub_xfs_inode_offset (struct grub_xfs_data *data, + static inline grub_size_t + grub_xfs_inode_size(struct grub_xfs_data *data) + { +- return 1 << data->sblock.log2_inode; ++ return (grub_size_t)1 << data->sblock.log2_inode; + } + + /* +-- +2.4.3 + diff --git a/SOURCES/0172-send-router-solicitation-for-ipv6-address-autoconf-v.patch b/SOURCES/0172-send-router-solicitation-for-ipv6-address-autoconf-v.patch new file mode 100644 index 0000000..c2d3385 --- /dev/null +++ b/SOURCES/0172-send-router-solicitation-for-ipv6-address-autoconf-v.patch @@ -0,0 +1,163 @@ +From a1f8402056e13cadab252dd64d7dc28ccdf6fda0 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Tue, 18 Nov 2014 16:03:08 +0800 +Subject: [PATCH 15/23] send router solicitation for ipv6 address autoconf v2 + +Many routers have long router advertisment interval configured by +default. The Neighbor Discovery protocol (RFC4861) has defined default +MaxRtrAdvInterval value as 600 seconds and +MinRtrAdvInterval as 0.33*MaxRtrAdvInterval. This makes +net_ipv6_autoconf fails more often than not as currently it passively +listens the RA message to perfom address autoconfiguration. + +This patch tries to send router solicitation to overcome the problem of +long RA interval. + +v2: +use cpu_to_be macro for network byte order conversion +add missing error handling +--- + grub-core/net/icmp6.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++ + grub-core/net/net.c | 4 ++- + include/grub/net/ip.h | 2 ++ + 3 files changed, 88 insertions(+), 1 deletion(-) + +diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c +index bbc9020..0843a15 100644 +--- a/grub-core/net/icmp6.c ++++ b/grub-core/net/icmp6.c +@@ -72,6 +72,11 @@ struct neighbour_advertise + grub_uint64_t target[2]; + } GRUB_PACKED; + ++struct router_solicit ++{ ++ grub_uint32_t reserved; ++} GRUB_PACKED; ++ + enum + { + FLAG_SLAAC = 0x40 +@@ -81,6 +86,7 @@ enum + { + ICMP6_ECHO = 128, + ICMP6_ECHO_REPLY = 129, ++ ICMP6_ROUTER_SOLICIT = 133, + ICMP6_ROUTER_ADVERTISE = 134, + ICMP6_NEIGHBOUR_SOLICIT = 135, + ICMP6_NEIGHBOUR_ADVERTISE = 136, +@@ -533,3 +539,80 @@ grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf, + grub_netbuff_free (nb); + return err; + } ++ ++grub_err_t ++grub_net_icmp6_send_router_solicit (struct grub_net_network_level_interface *inf) ++{ ++ struct grub_net_buff *nb; ++ grub_err_t err = GRUB_ERR_NONE; ++ grub_net_network_level_address_t multicast; ++ grub_net_link_level_address_t ll_multicast; ++ struct option_header *ohdr; ++ struct router_solicit *sol; ++ struct icmp_header *icmphr; ++ ++ multicast.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; ++ multicast.ipv6[0] = grub_cpu_to_be64 (0xff02ULL << 48); ++ multicast.ipv6[1] = grub_cpu_to_be64 (0x02ULL); ++ ++ err = grub_net_link_layer_resolve (inf, &multicast, &ll_multicast); ++ if (err) ++ return err; ++ ++ nb = grub_netbuff_alloc (sizeof (struct router_solicit) ++ + sizeof (struct option_header) ++ + 6 ++ + sizeof (struct icmp_header) ++ + GRUB_NET_OUR_IPV6_HEADER_SIZE ++ + GRUB_NET_MAX_LINK_HEADER_SIZE); ++ if (!nb) ++ return grub_errno; ++ err = grub_netbuff_reserve (nb, ++ sizeof (struct router_solicit) ++ + sizeof (struct option_header) ++ + 6 ++ + sizeof (struct icmp_header) ++ + GRUB_NET_OUR_IPV6_HEADER_SIZE ++ + GRUB_NET_MAX_LINK_HEADER_SIZE); ++ if (err) ++ goto fail; ++ ++ err = grub_netbuff_push (nb, 6); ++ if (err) ++ goto fail; ++ ++ grub_memcpy (nb->data, inf->hwaddress.mac, 6); ++ ++ err = grub_netbuff_push (nb, sizeof (*ohdr)); ++ if (err) ++ goto fail; ++ ++ ohdr = (struct option_header *) nb->data; ++ ohdr->type = OPTION_SOURCE_LINK_LAYER_ADDRESS; ++ ohdr->len = 1; ++ ++ err = grub_netbuff_push (nb, sizeof (*sol)); ++ if (err) ++ goto fail; ++ ++ sol = (struct router_solicit *) nb->data; ++ sol->reserved = 0; ++ ++ err = grub_netbuff_push (nb, sizeof (*icmphr)); ++ if (err) ++ goto fail; ++ ++ icmphr = (struct icmp_header *) nb->data; ++ icmphr->type = ICMP6_ROUTER_SOLICIT; ++ icmphr->code = 0; ++ icmphr->checksum = 0; ++ icmphr->checksum = grub_net_ip_transport_checksum (nb, ++ GRUB_NET_IP_ICMPV6, ++ &inf->address, ++ &multicast); ++ err = grub_net_send_ip_packet (inf, &multicast, &ll_multicast, nb, ++ GRUB_NET_IP_ICMPV6); ++ fail: ++ grub_netbuff_free (nb); ++ return err; ++} +diff --git a/grub-core/net/net.c b/grub-core/net/net.c +index 10bfed3..b10addb 100644 +--- a/grub-core/net/net.c ++++ b/grub-core/net/net.c +@@ -380,12 +380,14 @@ grub_cmd_ipv6_autoconf (struct grub_command *cmd __attribute__ ((unused)), + + for (interval = 200; interval < 10000; interval *= 2) + { +- /* FIXME: send router solicitation. */ + int done = 1; + for (j = 0; j < ncards; j++) + { + if (slaacs[j]->slaac_counter) + continue; ++ err = grub_net_icmp6_send_router_solicit (ifaces[j]); ++ if (err) ++ err = GRUB_ERR_NONE; + done = 0; + } + if (done) +diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h +index 7a8e614..dcceaa5 100644 +--- a/include/grub/net/ip.h ++++ b/include/grub/net/ip.h +@@ -92,4 +92,6 @@ grub_err_t + grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf, + const grub_net_network_level_address_t *proto_addr); + ++grub_err_t ++grub_net_icmp6_send_router_solicit (struct grub_net_network_level_interface *inf); + #endif +-- +2.4.3 + diff --git a/SOURCES/0173-icmp6-fix-no-respond-to-neighbor-solicit-message.patch b/SOURCES/0173-icmp6-fix-no-respond-to-neighbor-solicit-message.patch new file mode 100644 index 0000000..b8be36e --- /dev/null +++ b/SOURCES/0173-icmp6-fix-no-respond-to-neighbor-solicit-message.patch @@ -0,0 +1,29 @@ +From 70717c72f114860c25908eabc4cb18a15ed2680e Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Mon, 3 Nov 2014 16:27:45 +0800 +Subject: [PATCH 16/23] icmp6 fix no respond to neighbor solicit message + +The structure size used in grub_netbuff_pull to get the pointer to +option header is apparently wrong, which leads to subsequent range check +failed and therefore not responding to any neighbor solicit message in my +testing. +--- + grub-core/net/icmp6.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c +index 0843a15..7822394 100644 +--- a/grub-core/net/icmp6.c ++++ b/grub-core/net/icmp6.c +@@ -211,7 +211,7 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, + if (ttl != 0xff) + break; + nbh = (struct neighbour_solicit *) nb->data; +- err = grub_netbuff_pull (nb, sizeof (struct router_adv)); ++ err = grub_netbuff_pull (nb, sizeof (*nbh)); + if (err) + { + grub_netbuff_free (nb); +-- +2.4.3 + diff --git a/SOURCES/0174-calibrate_tsc-use-the-Stall-EFI-boot-service-on-GRUB.patch b/SOURCES/0174-calibrate_tsc-use-the-Stall-EFI-boot-service-on-GRUB.patch new file mode 100644 index 0000000..94346e9 --- /dev/null +++ b/SOURCES/0174-calibrate_tsc-use-the-Stall-EFI-boot-service-on-GRUB.patch @@ -0,0 +1,73 @@ +From af355a7fe160c6c798e416f8f14e059aaf16ea13 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek +Date: Fri, 10 Oct 2014 11:11:09 +0200 +Subject: [PATCH 17/23] calibrate_tsc(): use the Stall() EFI boot service on + GRUB_MACHINE_EFI + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1150698 + +HyperV Gen2 virtual machines have no PIT; guest code should rely on UEFI +services instead. + +Signed-off-by: RHEL Ninjas +--- + grub-core/kern/i386/tsc.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/grub-core/kern/i386/tsc.c b/grub-core/kern/i386/tsc.c +index 3a4cae6..e499648 100644 +--- a/grub-core/kern/i386/tsc.c ++++ b/grub-core/kern/i386/tsc.c +@@ -26,9 +26,14 @@ + #include + #include + #ifdef GRUB_MACHINE_XEN +-#include ++# include + #else +-#include ++# ifdef GRUB_MACHINE_EFI ++# include ++# include ++# else ++# include ++# endif + #endif + #include + +@@ -72,8 +77,14 @@ grub_cpu_is_tsc_supported (void) + #ifndef GRUB_MACHINE_XEN + + static void +-grub_pit_wait (grub_uint16_t tics) ++grub_stall (grub_uint16_t tics) + { ++# ifdef GRUB_MACHINE_EFI ++ grub_uint64_t microseconds; ++ ++ microseconds = (grub_uint64_t)tics * 1000 * 1000 * 3 / 3579545; ++ efi_call_1 (grub_efi_system_table->boot_services->stall, microseconds); ++# else + /* Disable timer2 gate and speaker. */ + grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT) + & ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2), +@@ -97,6 +108,7 @@ grub_pit_wait (grub_uint16_t tics) + grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT) + & ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2), + GRUB_PIT_SPEAKER_PORT); ++# endif + } + #endif + +@@ -119,7 +131,7 @@ calibrate_tsc (void) + grub_uint64_t end_tsc; + + tsc_boot_time = grub_get_tsc (); +- grub_pit_wait (0xffff); ++ grub_stall (0xffff); + end_tsc = grub_get_tsc (); + + grub_tsc_rate = grub_divmod64 ((55ULL << 32), end_tsc - tsc_boot_time, 0); +-- +2.4.3 + diff --git a/SOURCES/0175-fix-memory-corruption-in-pubkey-filter-over-network.patch b/SOURCES/0175-fix-memory-corruption-in-pubkey-filter-over-network.patch new file mode 100644 index 0000000..2774ff0 --- /dev/null +++ b/SOURCES/0175-fix-memory-corruption-in-pubkey-filter-over-network.patch @@ -0,0 +1,167 @@ +From 27d2434ea9aed09b6cefdcc8600e191fa6d1c2fb Mon Sep 17 00:00:00 2001 +From: Andrei Borzenkov +Date: Fri, 5 Dec 2014 21:17:08 +0300 +Subject: [PATCH 18/23] fix memory corruption in pubkey filter over network + +grub_pubkey_open closed original file after it was read; it set +io->device to NULL to prevent grub_file_close from trying to close device. +But network device itself is stacked (net -> bufio); and bufio preserved +original netfs file which hold reference to device. grub_file_close(io) +called grub_bufio_close which called grub_file_close for original file. +grub_file_close(netfs-file) now also called grub_device_close which +freed file->device->net. So file structure returned by grub_pubkey_open +now had device->net pointed to freed memory. When later file was closed, +it was attempted to be freed again. + +Change grub_pubkey_open to behave like other filters - preserve original +parent file and pass grub_file_close down to parent. In this way only the +original file will close device. We really need to move this logic into +core instead. + +Also plug memory leaks in error paths on the way. + +Reported-By: Robert Kliewer +Closes: bug #43601 +--- + grub-core/commands/verify.c | 72 +++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 60 insertions(+), 12 deletions(-) + +diff --git a/grub-core/commands/verify.c b/grub-core/commands/verify.c +index 525bdd1..d599576 100644 +--- a/grub-core/commands/verify.c ++++ b/grub-core/commands/verify.c +@@ -33,6 +33,13 @@ + + GRUB_MOD_LICENSE ("GPLv3+"); + ++struct grub_verified ++{ ++ grub_file_t file; ++ void *buf; ++}; ++typedef struct grub_verified *grub_verified_t; ++ + enum + { + OPTION_SKIP_SIG = 0 +@@ -802,19 +809,39 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt, + + static int sec = 0; + ++static void ++verified_free (grub_verified_t verified) ++{ ++ if (verified) ++ { ++ grub_free (verified->buf); ++ grub_free (verified); ++ } ++} ++ + static grub_ssize_t + verified_read (struct grub_file *file, char *buf, grub_size_t len) + { +- grub_memcpy (buf, (char *) file->data + file->offset, len); ++ grub_verified_t verified = file->data; ++ ++ grub_memcpy (buf, (char *) verified->buf + file->offset, len); + return len; + } + + static grub_err_t + verified_close (struct grub_file *file) + { +- grub_free (file->data); ++ grub_verified_t verified = file->data; ++ ++ grub_file_close (verified->file); ++ verified_free (verified); + file->data = 0; +- return GRUB_ERR_NONE; ++ ++ /* device and name are freed by parent */ ++ file->device = 0; ++ file->name = 0; ++ ++ return grub_errno; + } + + struct grub_fs verified_fs = +@@ -832,6 +859,7 @@ grub_pubkey_open (grub_file_t io, const char *filename) + grub_err_t err; + grub_file_filter_t curfilt[GRUB_FILE_FILTER_MAX]; + grub_file_t ret; ++ grub_verified_t verified; + + if (!sec) + return io; +@@ -857,7 +885,10 @@ grub_pubkey_open (grub_file_t io, const char *filename) + + ret = grub_malloc (sizeof (*ret)); + if (!ret) +- return NULL; ++ { ++ grub_file_close (sig); ++ return NULL; ++ } + *ret = *io; + + ret->fs = &verified_fs; +@@ -866,29 +897,46 @@ grub_pubkey_open (grub_file_t io, const char *filename) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "big file signature isn't implemented yet"); ++ grub_file_close (sig); ++ grub_free (ret); ++ return NULL; ++ } ++ verified = grub_malloc (sizeof (*verified)); ++ if (!verified) ++ { ++ grub_file_close (sig); ++ grub_free (ret); + return NULL; + } +- ret->data = grub_malloc (ret->size); +- if (!ret->data) ++ verified->buf = grub_malloc (ret->size); ++ if (!verified->buf) + { ++ grub_file_close (sig); ++ grub_free (verified); + grub_free (ret); + return NULL; + } +- if (grub_file_read (io, ret->data, ret->size) != (grub_ssize_t) ret->size) ++ if (grub_file_read (io, verified->buf, ret->size) != (grub_ssize_t) ret->size) + { + if (!grub_errno) + grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), + filename); ++ grub_file_close (sig); ++ verified_free (verified); ++ grub_free (ret); + return NULL; + } + +- err = grub_verify_signature_real (ret->data, ret->size, 0, sig, NULL); ++ err = grub_verify_signature_real (verified->buf, ret->size, 0, sig, NULL); + grub_file_close (sig); + if (err) +- return NULL; +- io->device = 0; +- io->name = 0; +- grub_file_close (io); ++ { ++ verified_free (verified); ++ grub_free (ret); ++ return NULL; ++ } ++ verified->file = io; ++ ret->data = verified; + return ret; + } + +-- +2.4.3 + diff --git a/SOURCES/0176-Make-grub2-mkconfig-construct-titles-that-look-like-.patch b/SOURCES/0176-Make-grub2-mkconfig-construct-titles-that-look-like-.patch new file mode 100644 index 0000000..bca5e11 --- /dev/null +++ b/SOURCES/0176-Make-grub2-mkconfig-construct-titles-that-look-like-.patch @@ -0,0 +1,72 @@ +From 204d0616ba497656d21e65f1b26561c539ea1a21 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 28 Apr 2015 11:15:03 -0400 +Subject: [PATCH 19/23] Make grub2-mkconfig construct titles that look like the + ones we want elsewhere. + +Resolves: rhbz#1215839 + +Signed-off-by: Peter Jones +--- + util/grub.d/10_linux.in | 34 +++++++++++++++++++++++++++------- + 1 file changed, 27 insertions(+), 7 deletions(-) + +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index e8088a1..b3c460c 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -66,6 +66,32 @@ case x"$GRUB_FS" in + ;; + esac + ++mktitle () ++{ ++ local title_type ++ local version ++ local OS_NAME ++ local OS_VERS ++ ++ title_type=$1 && shift ++ version=$1 && shift ++ ++ OS_NAME="$(eval $(grep ^NAME= /etc/os-release) ; echo ${NAME})" ++ OS_VERS="$(eval $(grep ^VERSION= /etc/os-release) ; echo ${VERSION})" ++ ++ case $title_type in ++ recovery) ++ title=$(printf '%s (%s) %s (recovery mode)' \ ++ "${OS_NAME}" "${version}" "${OS_VERS}") ++ ;; ++ *) ++ title=$(printf '%s (%s) %s' \ ++ "${OS_NAME}" "${version}" "${OS_VERS}") ++ ;; ++ esac ++ echo -n ${title} ++} ++ + title_correction_code= + + linux_entry () +@@ -94,17 +120,11 @@ linux_entry () + boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" + fi + if [ x$type != xsimple ] ; then +- case $type in +- recovery) +- title="$(gettext_printf "%s, with Linux %s (recovery mode)" "${os}" "${version}")" ;; +- *) +- title="$(gettext_printf "%s, with Linux %s" "${os}" "${version}")" ;; +- esac ++ title=$(mktitle "$type" "$version") + if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then + replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')" + quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)" + title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;" +- grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")" + fi + echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/" + else +-- +2.4.3 + diff --git a/SOURCES/0177-don-t-strip-fw_path-twice-for-EFI-network-boot.patch b/SOURCES/0177-don-t-strip-fw_path-twice-for-EFI-network-boot.patch new file mode 100644 index 0000000..d95749f --- /dev/null +++ b/SOURCES/0177-don-t-strip-fw_path-twice-for-EFI-network-boot.patch @@ -0,0 +1,30 @@ +From 224bdbee2e9cc9a9aaa198cec9b984bb1fa0ee73 Mon Sep 17 00:00:00 2001 +From: RHEL Ninjas +Date: Mon, 13 Apr 2015 12:42:53 +1000 +Subject: [PATCH 20/23] don't strip fw_path twice for EFI network boot + +--- + grub-core/kern/efi/init.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c +index 942ab02..c391df4 100644 +--- a/grub-core/kern/efi/init.c ++++ b/grub-core/kern/efi/init.c +@@ -61,7 +61,12 @@ grub_machine_get_bootlocation (char **device, char **path) + *device = grub_efidisk_get_device_name (image->device_handle); + *path = grub_efi_get_filename (image->file_path); + if (!*device && grub_efi_net_config) +- grub_efi_net_config (image->device_handle, device, path); ++ { ++ grub_efi_net_config (image->device_handle, device, path); ++ /* grub_efi_net_config returns the directory path, not the boot filename, ++ so don't strip any further. */ ++ return; ++ } + + /* Get the directory. */ + p = grub_strrchr (*path, '/'); +-- +2.4.3 + diff --git a/SOURCES/0178-Add-friendly-grub2-password-config-tool-985962.patch b/SOURCES/0178-Add-friendly-grub2-password-config-tool-985962.patch new file mode 100644 index 0000000..a4d289e --- /dev/null +++ b/SOURCES/0178-Add-friendly-grub2-password-config-tool-985962.patch @@ -0,0 +1,282 @@ +From bde7036b706857aff32a025e82da5bc32473e439 Mon Sep 17 00:00:00 2001 +From: Robert Marshall +Date: Thu, 25 Jun 2015 11:13:11 -0400 +Subject: [PATCH 21/23] Add friendly grub2 password config tool (#985962) + +Provided a tool for users to reset the grub2 root user password +without having to alter the grub.cfg. The hashed password now +lives in a root-only-readable configuration file. + +Resolves: rhbz#985962 +--- + .gitignore | 12 ++--- + Makefile.util.def | 13 +++++ + configure.ac | 1 + + util/grub-mkconfig.in | 2 + + util/grub-setpassword.8 | 28 +++++++++++ + util/grub-setpassword.in | 123 +++++++++++++++++++++++++++++++++++++++++++++++ + util/grub.d/01_users.in | 11 +++++ + 7 files changed, 182 insertions(+), 8 deletions(-) + create mode 100644 util/grub-setpassword.8 + create mode 100755 util/grub-setpassword.in + create mode 100644 util/grub.d/01_users.in + +diff --git a/.gitignore b/.gitignore +index b6c4577..e49f76b 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -1,11 +1,7 @@ +-00_header +-10_* +-20_linux_xen +-30_os-prober +-40_custom +-41_custom +-*.1 +-*.8 ++[[:digit:]][[:digit:]]_* ++!util/[[:digit:]][[:digit:]]_*.in ++*.[[:digit:]] ++!util/*.[[:digit:]] + aclocal.m4 + ahci_test + ascii.bitmaps +diff --git a/Makefile.util.def b/Makefile.util.def +index 3ac7572..e2821a2 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -438,6 +438,12 @@ script = { + }; + + script = { ++ name = '01_users'; ++ common = util/grub.d/01_users.in; ++ installdir = grubconf; ++}; ++ ++script = { + name = '10_windows'; + common = util/grub.d/10_windows.in; + installdir = grubconf; +@@ -713,6 +719,13 @@ script = { + }; + + script = { ++ name = grub-setpassword; ++ common = util/grub-setpassword.in; ++ mansection = 8; ++ installdir = sbin; ++}; ++ ++script = { + name = grub-mkconfig_lib; + common = util/grub-mkconfig_lib.in; + installdir = noinst; +diff --git a/configure.ac b/configure.ac +index de17e65..273da6c 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -65,6 +65,7 @@ grub_TRANSFORM([grub-mkrelpath]) + grub_TRANSFORM([grub-mkrescue]) + grub_TRANSFORM([grub-probe]) + grub_TRANSFORM([grub-reboot]) ++grub_TRANSFORM([grub-setpassword]) + grub_TRANSFORM([grub-rpm-sort]) + grub_TRANSFORM([grub-script-check]) + grub_TRANSFORM([grub-set-default]) +diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in +index bc26e7c..e029d0d 100644 +--- a/util/grub-mkconfig.in ++++ b/util/grub-mkconfig.in +@@ -260,6 +260,8 @@ for i in "${grub_mkconfig_dir}"/* ; do + *~) ;; + # emacsen autosave files. FIXME: support other editors + */\#*\#) ;; ++ # rpm config files of yore. ++ *.rpmsave|*.rpmnew|*.rpmorig) ;; + *) + if grub_file_is_not_garbage "$i" && test -x "$i" ; then + echo +diff --git a/util/grub-setpassword.8 b/util/grub-setpassword.8 +new file mode 100644 +index 0000000..5973abe +--- /dev/null ++++ b/util/grub-setpassword.8 +@@ -0,0 +1,28 @@ ++.TH GRUB-SETPASSWORD 3 "Thu Jun 25 2015" ++.SH NAME ++\fBgrub-setpassword\fR \(em Generate the user.cfg file containing the hashed grub bootloader password. ++ ++.SH SYNOPSIS ++\fBgrub-setpassword\fR [OPTION] ++ ++.SH DESCRIPTION ++\fBgrub-setpassword\fR outputs the user.cfg file which contains the hashed GRUB bootloader password. This utility only supports configurations where there is a single root user. ++ ++The file has the format: ++GRUB_2PASSWORD=<\fIhashed password\fR>. ++ ++.SH OPTIONS ++.TP ++-h, --help ++Display program usage and exit. ++.TP ++-v, --version ++Display the current version. ++.TP ++-o, --output[=\fIDIRECTORY PATH\fR] ++Choose the file path to which user.cfg will be written. ++ ++.SH SEE ALSO ++.BR "info grub" ++ ++.BR "info grub2-mkpasswd-pbkdf2" +diff --git a/util/grub-setpassword.in b/util/grub-setpassword.in +new file mode 100755 +index 0000000..dd76f00 +--- /dev/null ++++ b/util/grub-setpassword.in +@@ -0,0 +1,123 @@ ++#!/bin/sh -e ++ ++if [ -d /sys/firmware/efi/efivars/ ]; then ++ grubdir=`echo "/@bootdirname@/efi/EFI/redhat/" | sed 's,//*,/,g'` ++else ++ grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` ++fi ++ ++PACKAGE_VERSION="@PACKAGE_VERSION@" ++PACKAGE_NAME="@PACKAGE_NAME@" ++self=`basename $0` ++bindir="@bindir@" ++grub_mkpasswd="${bindir}/@grub_mkpasswd_pbkdf2@" ++ ++# Usage: usage ++# Print the usage. ++usage () { ++ cat <&2 ++ exit 1 ++ fi ++ echo $1 ++} ++ ++# Ensure that it's the root user running this script ++if [ "${EUID}" -ne 0 ]; then ++ echo "The grub bootloader password may only be set by root." ++ usage ++ exit 2 ++fi ++ ++# Check the arguments. ++while test $# -gt 0 ++do ++ option=$1 ++ shift ++ ++ case "$option" in ++ -h | --help) ++ usage ++ exit 0 ;; ++ -v | --version) ++ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" ++ exit 0 ;; ++ -o | --output) ++ OUTPUT_PATH=`argument $option "$@"`; shift ;; ++ --output=*) ++ OUTPUT_PATH=`echo "$option" | sed 's/--output=//'` ;; ++ -o=*) ++ OUTPUT_PATH=`echo "$option" | sed 's/-o=//'` ;; ++ esac ++done ++ ++# set user input or default path for user.cfg file ++if [ -z "${OUTPUT_PATH}" ]; then ++ OUTPUT_PATH="${grubdir}" ++fi ++ ++if [ ! -d "${OUTPUT_PATH}" ]; then ++ echo "${OUTPUT_PATH} does not exist." ++ usage ++ exit 2; ++fi ++ ++ttyopt=$(stty -g) ++fixtty() { ++ stty ${ttyopt} ++} ++ ++trap fixtty EXIT ++stty -echo ++ ++# prompt & confirm new grub2 root user password ++echo -n "Enter password: " ++read PASSWORD ++echo ++echo -n "Confirm password: " ++read PASSWORD_CONFIRM ++echo ++stty ${ttyopt} ++ ++getpass() { ++ local P0 ++ local P1 ++ P0="$1" && shift ++ P1="$1" && shift ++ ++ ( echo ${P0} ; echo ${P1} ) | \ ++ ${grub_mkpasswd} | \ ++ grep -v '[eE]nter password:' | \ ++ sed -e "s/PBKDF2 hash of your password is //" ++} ++ ++MYPASS="$(getpass "${PASSWORD}" "${PASSWORD_CONFIRM}")" ++if [ -z "${MYPASS}" ]; then ++ echo "${self}: error: empty password" 1>&2 ++ exit 1 ++fi ++ ++# on the ESP, these will fail to set the permissions, but it's okay because ++# the directory is protected. ++install -m 0600 /dev/null "${grubdir}/user.cfg" 2>/dev/null || : ++chmod 0600 "${grubdir}/user.cfg" 2>/dev/null || : ++echo "GRUB2_PASSWORD=${MYPASS}" > "${grubdir}/user.cfg" +diff --git a/util/grub.d/01_users.in b/util/grub.d/01_users.in +new file mode 100644 +index 0000000..facd409 +--- /dev/null ++++ b/util/grub.d/01_users.in +@@ -0,0 +1,11 @@ ++#!/bin/sh -e ++cat << EOF ++if [ -f \${prefix}/user.cfg ]; then ++ source \${prefix}/user.cfg ++ if [ -n \${GRUB2_PASSWORD} ]; then ++ set superusers="root" ++ export superusers ++ password_pbkdf2 root \${GRUB2_PASSWORD} ++ fi ++fi ++EOF +-- +2.4.3 + diff --git a/SOURCES/0179-Try-to-make-sure-configure.ac-and-grub-rpm-sort-play.patch b/SOURCES/0179-Try-to-make-sure-configure.ac-and-grub-rpm-sort-play.patch new file mode 100644 index 0000000..05bc86a --- /dev/null +++ b/SOURCES/0179-Try-to-make-sure-configure.ac-and-grub-rpm-sort-play.patch @@ -0,0 +1,61 @@ +From f742724d51dc84b32a1298cd6bab62f12d887052 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 3 Aug 2015 11:46:42 -0400 +Subject: [PATCH 22/23] Try to make sure configure.ac and grub-rpm-sort play + nice. + +Apparently the test for whether to use grub-rpm-sort and also the +renaming of it to grub2-rpm-sort on the runtime side weren't right. + +Related: rhbz#1124074 + +Signed-off-by: Peter Jones +--- + configure.ac | 2 +- + util/grub-mkconfig_lib.in | 9 ++++++--- + 2 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 273da6c..04c052d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1549,7 +1549,7 @@ AC_SUBST([LIBDEVMAPPER]) + AC_ARG_ENABLE([rpm-sort], + [AS_HELP_STRING([--enable-rpm-sort], + [enable native rpm sorting of kernels in grub (default=guessed)])]) +-if test x"$enable_rpm-sort" = xno ; then ++if test x"$enable_rpm_sort" = xno ; then + rpm_sort_excuse="explicitly disabled" + fi + +diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in +index e85b60c..c67a319 100644 +--- a/util/grub-mkconfig_lib.in ++++ b/util/grub-mkconfig_lib.in +@@ -33,6 +33,9 @@ fi + if test "x$grub_mkrelpath" = x; then + grub_mkrelpath="${bindir}/@grub_mkrelpath@" + fi ++if test "x$grub_rpm_sort" = x; then ++ grub_rpm_sort="${sbindir}/@grub_rpm_sort@" ++fi + + if which gettext >/dev/null 2>/dev/null; then + : +@@ -213,10 +216,10 @@ version_sort () + esac + } + +-if [ "x$RPMLIB" = x ]; then +- kernel_sort=version_sort ++if [ "x$grub_rpm_sort" != x -a -x "$grub_rpm_sort" ]; then ++ kernel_sort="$grub_rpm_sort" + else +- kernel_sort="${sbindir}/grub-rpm-sort" ++ kernel_sort=version_sort + fi + + version_test_numeric () +-- +2.4.3 + diff --git a/SOURCES/0180-ppc64le-sync-mkconfig-to-disk-1212114.patch b/SOURCES/0180-ppc64le-sync-mkconfig-to-disk-1212114.patch new file mode 100644 index 0000000..e1fcab3 --- /dev/null +++ b/SOURCES/0180-ppc64le-sync-mkconfig-to-disk-1212114.patch @@ -0,0 +1,42 @@ +From f1edaeeeffdfc291e0b17d87f8727baaecbfaf63 Mon Sep 17 00:00:00 2001 +From: Don Zickus +Date: Wed, 22 Jul 2015 13:59:55 -0400 +Subject: [PATCH 23/23] ppc64le sync mkconfig to disk (#1212114) + +If creating a new grub2 entry using grub2-mkconfig, the entry is not +immediately sync'd to disk. If a crash happens before the writeback, +the subsequent reboot fails because the grub2.cfg is corrupted. + +Address this by forcing all the changes (mainly the fs meta data) to disk +before finishing the grub2 conf changes. + +Tested by 'grub2-mkconfig -o /etc/grub22.cfg; echo c > /proc/sysrq-trigger'. + +Before, the machine would panic and on reboot be stuck without a grub.cfg +to read. After, works as expected. + +Resolves: rhbz#1212114 +--- + util/grub-mkconfig.in | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in +index e029d0d..cf315e2 100644 +--- a/util/grub-mkconfig.in ++++ b/util/grub-mkconfig.in +@@ -290,3 +290,12 @@ fi + + gettext "done" >&2 + echo >&2 ++ ++# make sure changes make it to the disk. ++# if /boot is a mountpoint, force the meta data on disk ++# to by-pass writeback delay. ++# PPC64LE-only to deal with Petitboot issues ++ARCH=$(uname -m) ++if [ "${ARCH}" = "ppc64le" ]; then ++ sync && mountpoint -q /boot &&fsfreeze -f /boot && fsfreeze -u /boot ++fi +-- +2.4.3 + diff --git a/SOURCES/0181-tcp-ack-when-we-get-an-OOO-lost-packet.patch b/SOURCES/0181-tcp-ack-when-we-get-an-OOO-lost-packet.patch new file mode 100644 index 0000000..dbde843 --- /dev/null +++ b/SOURCES/0181-tcp-ack-when-we-get-an-OOO-lost-packet.patch @@ -0,0 +1,37 @@ +From 66804a1e21978713902da654ec890574efe25e7d Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Wed, 12 Aug 2015 08:16:22 -0700 +Subject: [PATCH 1/3] tcp: ack when we get an OOO/lost packet + +While adding tcp window scaling support I was finding that I'd get some packet +loss or reordering when transferring from large distances and grub would just +timeout. This is because we weren't ack'ing when we got our OOO packet, so the +sender didn't know it needed to retransmit anything, so eventually it would fill +the window and stop transmitting, and we'd time out. Fix this by ACK'ing when +we don't find our next sequence numbered packet. With this fix I no longer time +out. Thanks, + +Signed-off-by: Josef Bacik +--- + grub-core/net/tcp.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/grub-core/net/tcp.c b/grub-core/net/tcp.c +index 2077f55..fa29a2a 100644 +--- a/grub-core/net/tcp.c ++++ b/grub-core/net/tcp.c +@@ -882,7 +882,10 @@ grub_net_recv_tcp_packet (struct grub_net_buff *nb, + grub_priority_queue_pop (sock->pq); + } + if (grub_be_to_cpu32 (tcph->seqnr) != sock->their_cur_seq) +- return GRUB_ERR_NONE; ++ { ++ ack (sock); ++ return GRUB_ERR_NONE; ++ } + while (1) + { + nb_top_p = grub_priority_queue_top (sock->pq); +-- +2.4.3 + diff --git a/SOURCES/0182-tcp-add-window-scaling-support.patch b/SOURCES/0182-tcp-add-window-scaling-support.patch new file mode 100644 index 0000000..b91ce62 --- /dev/null +++ b/SOURCES/0182-tcp-add-window-scaling-support.patch @@ -0,0 +1,90 @@ +From 8e86a32160008b34796f597016cc335680bb3486 Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Wed, 12 Aug 2015 08:57:55 -0700 +Subject: [PATCH 2/3] tcp: add window scaling support + +Sometimes we have to provision boxes across regions, such as California to +Sweden. The http server has a 10 minute timeout, so if we can't get our 250mb +image transferred fast enough our provisioning fails, which is not ideal. So +add tcp window scaling on open connections and set the window size to 1mb. With +this change we're able to get higher sustained transfers between regions and can +transfer our image in well below 10 minutes. Without this patch we'd time out +every time halfway through the transfer. Thanks, + +Signed-off-by: Josef Bacik +--- + grub-core/net/tcp.c | 42 +++++++++++++++++++++++++++++------------- + 1 file changed, 29 insertions(+), 13 deletions(-) + +diff --git a/grub-core/net/tcp.c b/grub-core/net/tcp.c +index fa29a2a..c22ef03 100644 +--- a/grub-core/net/tcp.c ++++ b/grub-core/net/tcp.c +@@ -106,6 +106,18 @@ struct tcphdr + grub_uint16_t urgent; + } GRUB_PACKED; + ++struct tcp_scale_opt { ++ grub_uint8_t kind; ++ grub_uint8_t length; ++ grub_uint8_t scale; ++} GRUB_PACKED; ++ ++struct tcp_synhdr { ++ struct tcphdr tcphdr; ++ struct tcp_scale_opt scale_opt; ++ grub_uint8_t padding; ++}; ++ + struct tcp_pseudohdr + { + grub_uint32_t src; +@@ -555,7 +567,7 @@ grub_net_tcp_open (char *server, + grub_net_tcp_socket_t socket; + static grub_uint16_t in_port = 21550; + struct grub_net_buff *nb; +- struct tcphdr *tcph; ++ struct tcp_synhdr *tcph; + int i; + grub_uint8_t *nbd; + grub_net_link_level_address_t ll_target_addr; +@@ -617,20 +629,24 @@ grub_net_tcp_open (char *server, + } + + tcph = (void *) nb->data; ++ grub_memset(tcph, 0, sizeof (*tcph)); + socket->my_start_seq = grub_get_time_ms (); + socket->my_cur_seq = socket->my_start_seq + 1; +- socket->my_window = 8192; +- tcph->seqnr = grub_cpu_to_be32 (socket->my_start_seq); +- tcph->ack = grub_cpu_to_be32_compile_time (0); +- tcph->flags = grub_cpu_to_be16_compile_time ((5 << 12) | TCP_SYN); +- tcph->window = grub_cpu_to_be16 (socket->my_window); +- tcph->urgent = 0; +- tcph->src = grub_cpu_to_be16 (socket->in_port); +- tcph->dst = grub_cpu_to_be16 (socket->out_port); +- tcph->checksum = 0; +- tcph->checksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_TCP, +- &socket->inf->address, +- &socket->out_nla); ++ socket->my_window = 32768; ++ tcph->tcphdr.seqnr = grub_cpu_to_be32 (socket->my_start_seq); ++ tcph->tcphdr.ack = grub_cpu_to_be32_compile_time (0); ++ tcph->tcphdr.flags = grub_cpu_to_be16_compile_time ((6 << 12) | TCP_SYN); ++ tcph->tcphdr.window = grub_cpu_to_be16 (socket->my_window); ++ tcph->tcphdr.urgent = 0; ++ tcph->tcphdr.src = grub_cpu_to_be16 (socket->in_port); ++ tcph->tcphdr.dst = grub_cpu_to_be16 (socket->out_port); ++ tcph->tcphdr.checksum = 0; ++ tcph->scale_opt.kind = 3; ++ tcph->scale_opt.length = 3; ++ tcph->scale_opt.scale = 5; ++ tcph->tcphdr.checksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_TCP, ++ &socket->inf->address, ++ &socket->out_nla); + + tcp_socket_register (socket); + +-- +2.4.3 + diff --git a/SOURCES/0183-efinet-retransmit-if-our-device-is-busy.patch b/SOURCES/0183-efinet-retransmit-if-our-device-is-busy.patch new file mode 100644 index 0000000..7fbddc2 --- /dev/null +++ b/SOURCES/0183-efinet-retransmit-if-our-device-is-busy.patch @@ -0,0 +1,48 @@ +From 1b9767c1360827639927ab9bd337d1344d3b2d68 Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Mon, 31 Aug 2015 13:34:35 -0400 +Subject: [PATCH 3/3] efinet: retransmit if our device is busy + +When I fixed the txbuf handling I ripped out the retransmission code since it +was flooding our network when we had the buggy behavior. Turns out this was too +heavy handed as we can still have transient tx timeouts. So instead make sure +we retry our transmission once per timeout. This way we can deal with transient +transmission problems without flooding the box. This fixes an issue we were +seeing in production. Thanks, + +Signed-off-by: Josef Bacik +--- + grub-core/net/drivers/efi/efinet.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c +index ea0e0ca..c3a128c 100644 +--- a/grub-core/net/drivers/efi/efinet.c ++++ b/grub-core/net/drivers/efi/efinet.c +@@ -38,6 +38,7 @@ send_card_buffer (struct grub_net_card *dev, + grub_efi_simple_network_t *net = dev->efi_net; + grub_uint64_t limit_time = grub_get_time_ms () + 4000; + void *txbuf; ++ int retry = 0; + + if (dev->txbusy) + while (1) +@@ -60,6 +61,15 @@ send_card_buffer (struct grub_net_card *dev, + dev->txbusy = 0; + break; + } ++ if (!retry) ++ { ++ st = efi_call_7 (net->transmit, net, 0, dev->last_pkt_size, ++ dev->txbuf, NULL, NULL, NULL); ++ if (st != GRUB_EFI_SUCCESS) ++ return grub_error (GRUB_ERR_IO, ++ N_("couldn't send network packet")); ++ retry = 1; ++ } + if (limit_time < grub_get_time_ms ()) + return grub_error (GRUB_ERR_TIMEOUT, + N_("couldn't send network packet")); +-- +2.4.3 + diff --git a/SOURCES/0184-Be-more-aggro-about-actually-using-the-configured-ne.patch b/SOURCES/0184-Be-more-aggro-about-actually-using-the-configured-ne.patch new file mode 100644 index 0000000..ee62a3c --- /dev/null +++ b/SOURCES/0184-Be-more-aggro-about-actually-using-the-configured-ne.patch @@ -0,0 +1,224 @@ +From 46d5b1ccce248a275b1dcf15824fb3501a32d9dc Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 11 Sep 2015 17:30:49 -0400 +Subject: [PATCH] Be more aggro about actually using the *configured* network + device. + +Right now we use any SNP device with the same mac+IP block, but when +it's discovered there will be more than one of them. We need to pick +the same one we were loaded with, so that it'll be configured the same +way as it was before, and won't be re-used by the system firmware later. + +Resolves: rhbz#1257475 + +Signed-off-by: Peter Jones +--- + grub-core/net/drivers/efi/efinet.c | 124 +++++++++++++++++++++++++++++-------- + include/grub/efi/api.h | 4 ++ + 2 files changed, 102 insertions(+), 26 deletions(-) + +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c +index c3a128c..fd47b8a 100644 +--- a/grub-core/net/drivers/efi/efinet.c ++++ b/grub-core/net/drivers/efi/efinet.c +@@ -239,46 +239,85 @@ grub_efinet_get_device_handle (struct grub_net_card *card) + return card->efi_handle; + } + +-static void +-grub_efinet_findcards (void) ++static int ++grub_efinet_find_snp_cards (int preferred_only, grub_efi_handle_t preferred, ++ int *i) + { +- grub_efi_uintn_t num_handles; +- grub_efi_handle_t *handles; ++ grub_efi_uintn_t num_handles = 0; ++ grub_efi_handle_t *handles = NULL; + grub_efi_handle_t *handle; +- int i = 0; ++ grub_efi_device_path_t *pdp = NULL, *pp = NULL, *pc = NULL; ++ int ret = 0; ++ ++ if (preferred) ++ { ++ grub_efi_device_path_t *pdpc; ++ pdpc = pdp = grub_efi_get_device_path (preferred); ++ if (pdp == NULL) ++ { ++ grub_print_error (); ++ return -1; ++ } + +- /* Find handles which support the disk io interface. */ ++ for (; ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (pdpc); ++ pdpc = GRUB_EFI_NEXT_DEVICE_PATH (pdpc)) ++ { ++ pp = pc; ++ pc = pdpc; ++ } ++ } ++ ++ /* Find handles which support the SNP interface. */ + handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &net_io_guid, + 0, &num_handles); +- if (! handles) +- return; +- for (handle = handles; num_handles--; handle++) ++ ++ for (handle = handles; handle && num_handles--; handle++) + { + grub_efi_simple_network_t *net; + struct grub_net_card *card; + grub_efi_device_path_t *dp, *parent = NULL, *child = NULL; + +- /* EDK2 UEFI PXE driver creates IPv4 and IPv6 messaging devices as +- children of main MAC messaging device. We only need one device with +- bound SNP per physical card, otherwise they compete with each other +- when polling for incoming packets. +- */ ++ /* if we're looking for only the preferred handle, skip anything that ++ isn't it. */ ++ if (preferred_only && preferred != NULL && *handle != preferred) ++ continue; ++ ++ /* if we're not looking for the preferred handle, skip it if it's ++ found. */ ++ if (!preferred_only && *handle == preferred) ++ continue; ++ + dp = grub_efi_get_device_path (*handle); + if (!dp) + continue; +- for (; ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp); dp = GRUB_EFI_NEXT_DEVICE_PATH (dp)) ++ ++ for (; ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp); ++ dp = GRUB_EFI_NEXT_DEVICE_PATH (dp)) + { + parent = child; + child = dp; + } +- if (child +- && GRUB_EFI_DEVICE_PATH_TYPE (child) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE +- && (GRUB_EFI_DEVICE_PATH_SUBTYPE (child) == GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE +- || GRUB_EFI_DEVICE_PATH_SUBTYPE (child) == GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE) +- && parent +- && GRUB_EFI_DEVICE_PATH_TYPE (parent) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE +- && GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE) +- continue; ++ ++ if (!preferred_only) ++ { ++ if (pp && pc ++ && grub_efi_compare_device_paths (pp, parent) == 0 ++ && grub_efi_compare_device_paths (pc, child) == 0) ++ continue; ++ ++ if (child ++ && (GRUB_EFI_DEVICE_PATH_IS_TYPE(child, ++ GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE, ++ GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE) || ++ GRUB_EFI_DEVICE_PATH_IS_TYPE(child, ++ GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE, ++ GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE)) ++ && parent ++ && (GRUB_EFI_DEVICE_PATH_IS_TYPE(parent, ++ GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE, ++ GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE))) ++ continue; ++ } + + net = grub_efi_open_protocol (*handle, &net_io_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); +@@ -302,7 +341,7 @@ grub_efinet_findcards (void) + { + grub_print_error (); + grub_free (handles); +- return; ++ return -1; + } + + card->mtu = net->mode->max_packet_size; +@@ -313,13 +352,14 @@ grub_efinet_findcards (void) + grub_print_error (); + grub_free (handles); + grub_free (card); +- return; ++ return -1; + } + card->txbusy = 0; + + card->rcvbufsize = ALIGN_UP (card->mtu, 64) + 256; + +- card->name = grub_xasprintf ("efinet%d", i++); ++ card->name = grub_xasprintf ("efinet%d", *i); ++ *i = (*i)+1; + card->driver = &efidriver; + card->flags = 0; + card->default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; +@@ -330,8 +370,38 @@ grub_efinet_findcards (void) + card->efi_handle = *handle; + + grub_net_card_register (card); ++ ret++; + } + grub_free (handles); ++ ++ return ret; ++} ++ ++static void ++grub_efinet_findcards (void) ++{ ++ grub_efi_loaded_image_t *image = NULL; ++ int rc; ++ int efinet_number = 0; ++ ++ image = grub_efi_get_loaded_image (grub_efi_image_handle); ++ ++ if (image && image->device_handle) ++ { ++ rc = grub_efinet_find_snp_cards (1, image->device_handle, &efinet_number); ++ if (rc < 0) ++ return; ++ ++ rc = grub_efinet_find_snp_cards (0, image->device_handle, &efinet_number); ++ if (rc < 0) ++ return; ++ } ++ else ++ { ++ rc = grub_efinet_find_snp_cards (0, NULL, &efinet_number); ++ if (rc < 0) ++ return; ++ } + } + + static void +@@ -353,6 +423,8 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, + struct grub_efi_pxe_mode *pxe_mode; + if (card->driver != &efidriver) + continue; ++ if (hnd != card->efi_handle) ++ continue; + cdp = grub_efi_get_device_path (card->efi_handle); + if (! cdp) + continue; +diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h +index 029ee92..f0640c2 100644 +--- a/include/grub/efi/api.h ++++ b/include/grub/efi/api.h +@@ -573,6 +573,10 @@ typedef struct grub_efi_device_path grub_efi_device_path_t; + It seems to be identical to EFI_DEVICE_PATH. */ + typedef struct grub_efi_device_path grub_efi_device_path_protocol_t; + ++#define GRUB_EFI_DEVICE_PATH_IS_TYPE(dp, type, subtype) \ ++ ((GRUB_EFI_DEVICE_PATH_TYPE(dp) == (type)) && \ ++ (GRUB_EFI_DEVICE_PATH_SUBTYPE(dp) == (subtype))) ++ + #define GRUB_EFI_DEVICE_PATH_TYPE(dp) ((dp)->type & 0x7f) + #define GRUB_EFI_DEVICE_PATH_SUBTYPE(dp) ((dp)->subtype) + #define GRUB_EFI_DEVICE_PATH_LENGTH(dp) ((dp)->length) +-- +2.4.3 + diff --git a/SOURCES/0185-efinet-add-filter-for-the-first-exclusive-reopen-of-.patch b/SOURCES/0185-efinet-add-filter-for-the-first-exclusive-reopen-of-.patch new file mode 100644 index 0000000..aeb5543 --- /dev/null +++ b/SOURCES/0185-efinet-add-filter-for-the-first-exclusive-reopen-of-.patch @@ -0,0 +1,47 @@ +From 2cdea5ad6c34d04e0a2a833fc010618d3e6bddac Mon Sep 17 00:00:00 2001 +From: RHEL Ninjas +Date: Fri, 25 Sep 2015 16:24:23 +0900 +Subject: [PATCH] efinet: add filter for the first exclusive reopen of SNP + +--- + grub-core/net/drivers/efi/efinet.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c +index fd47b8a..b6b5187 100644 +--- a/grub-core/net/drivers/efi/efinet.c ++++ b/grub-core/net/drivers/efi/efinet.c +@@ -479,6 +479,30 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, + if (net->mode->state == GRUB_EFI_NETWORK_STARTED + && efi_call_3 (net->initialize, net, 0, 0) != GRUB_EFI_SUCCESS) + continue; ++ ++ /* Enable hardware receive filters if driver declares support for it. ++ We need unicast and broadcast and additionaly all nodes and ++ solicited multicast for IPv6. Solicited multicast is per-IPv6 ++ address and we currently do not have API to do it so simply ++ try to enable receive of all multicast packets or evertyhing in ++ the worst case (i386 PXE driver always enables promiscuous too). ++ ++ This does trust firmware to do what it claims to do. ++ */ ++ if (net->mode->receive_filter_mask) ++ { ++ grub_uint32_t filters = GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST | ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST | ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST; ++ ++ filters &= net->mode->receive_filter_mask; ++ if (!(filters & GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST)) ++ filters |= (net->mode->receive_filter_mask & ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS); ++ ++ efi_call_6 (net->receive_filters, net, filters, 0, 0, 0, NULL); ++ } ++ + card->efi_net = net; + } + return; +-- +2.5.0 + diff --git a/SOURCES/gitignore b/SOURCES/gitignore index c21ee5f..f318bf1 100644 --- a/SOURCES/gitignore +++ b/SOURCES/gitignore @@ -1,12 +1,11 @@ 00_header 10_* -!10_*.in 20_linux_xen 30_os-prober 40_custom 41_custom -*.[[:digit:]] -!util/*.[[:digit:]] +*.1 +*.8 aclocal.m4 ahci_test ascii.bitmaps @@ -240,3 +239,5 @@ build-aux/test-driver /garbage-gen /garbage-gen.exe /grub-fs-tester +!util/grub.d/[[:digit:]][[:digit:]]*.in +!util/*.[[:digit:]] diff --git a/SPECS/grub2.spec b/SPECS/grub2.spec index 5f3de40..aafba13 100644 --- a/SPECS/grub2.spec +++ b/SPECS/grub2.spec @@ -33,9 +33,6 @@ %if 0%{?fedora} %global efidir fedora %endif -%if 0%{?centos} -%global efidir centos -%endif %endif @@ -45,7 +42,7 @@ Name: grub2 Epoch: 1 Version: 2.02 -Release: 0.17%{?dist}.4 +Release: 0.29%{?dist} Summary: Bootloader with support for Linux, Multiboot and more Group: System Environment/Base @@ -54,8 +51,8 @@ URL: http://www.gnu.org/software/grub/ Obsoletes: grub < 1:0.98 Source0: ftp://alpha.gnu.org/gnu/grub/grub-%{tarversion}.tar.xz #Source0: ftp://ftp.gnu.org/gnu/grub/grub-%{tarversion}.tar.xz -Source1: centos.cer -#(source removed) +Source1: securebootca.cer +Source2: secureboot.cer Source4: http://unifoundry.com/unifont-5.1.20080820.pcf.gz Source5: theme.tar.bz2 Source6: gitignore @@ -215,8 +212,39 @@ Patch0151: 0001-Initialized-initrd_ctx-so-we-don-t-free-a-random-poi.patch Patch0152: 0002-Load-arm-with-SB-enabled.patch Patch0153: 0001-Fix-up-some-man-pages-rpmdiff-noticed.patch Patch0154: 0001-Try-prefix-if-fw_path-doesn-t-work.patch -Patch0155: 0002-Use-Distribution-Package-Sort-for-grub2-mkconfig-112.patch -Patch0156: 0001-Try-to-make-sure-configure.ac-and-grub-rpm-sort-play.patch +Patch0155: 0001-Update-info-with-grub.cfg-netboot-selection-order-11.patch +Patch0156: 0002-Use-Distribution-Package-Sort-for-grub2-mkconfig-112.patch +Patch0157: 0001-efidisk-move-device-path-helpers-in-core-for-efinet.patch +Patch0158: 0158-efinet-Check-for-immediate-completition.patch +Patch0159: 0159-efinet-memory-leak-on-module-removal.patch +Patch0160: 0160-efinet-cannot-free-const-char-pointer.patch +Patch0161: 0161-Revert-efinet-memory-leak-on-module-removal.patch +Patch0162: 0162-efinet-skip-virtual-IPv4-and-IPv6-devices-when-enume.patch +Patch0163: 0163-efinet-open-Simple-Network-Protocol-exclusively.patch +Patch0164: 0164-efinet-enable-hardware-filters-when-opening-interfac.patch +Patch0165: 0165-efinet-handle-get_status-on-buggy-firmware-properly.patch +Patch0166: 0166-Handle-rssd-storage-devices.patch +Patch0167: 0167-xfs-Fix-termination-loop-for-directory-iteration.patch +Patch0168: 0168-xfs-Convert-inode-numbers-to-cpu-endianity-immediate.patch +Patch0169: 0169-xfs-Add-helpers-for-inode-size.patch +Patch0170: 0170-xfs-V5-filesystem-format-support.patch +Patch0171: 0171-xfs-silence-Coverity-overflow-warning.patch +Patch0172: 0172-send-router-solicitation-for-ipv6-address-autoconf-v.patch +Patch0173: 0173-icmp6-fix-no-respond-to-neighbor-solicit-message.patch +Patch0174: 0174-calibrate_tsc-use-the-Stall-EFI-boot-service-on-GRUB.patch +Patch0175: 0175-fix-memory-corruption-in-pubkey-filter-over-network.patch +Patch0176: 0176-Make-grub2-mkconfig-construct-titles-that-look-like-.patch +Patch0177: 0177-don-t-strip-fw_path-twice-for-EFI-network-boot.patch +Patch0178: 0178-Add-friendly-grub2-password-config-tool-985962.patch +Patch0179: 0179-Try-to-make-sure-configure.ac-and-grub-rpm-sort-play.patch +Patch0180: 0180-ppc64le-sync-mkconfig-to-disk-1212114.patch +Patch0181: 0181-tcp-ack-when-we-get-an-OOO-lost-packet.patch +Patch0182: 0182-tcp-add-window-scaling-support.patch +Patch0183: 0183-efinet-retransmit-if-our-device-is-busy.patch +Patch0184: 0184-Be-more-aggro-about-actually-using-the-configured-ne.patch +Patch0185: 0185-efinet-add-filter-for-the-first-exclusive-reopen-of-.patch + + BuildRequires: flex bison binutils python BuildRequires: ncurses-devel xz-devel bzip2-devel @@ -284,6 +312,7 @@ provides support for rebuilding your own grub.efi on EFI systems. Summary: Support tools for GRUB. Group: System Environment/Base Requires: gettext os-prober which file system-logos +Requires(pre): sed grep coreutils %description tools The GRand Unified Bootloader (GRUB) is a highly configurable and customizable @@ -337,7 +366,7 @@ cd grub-efi-%{tarversion} -e 's/-mregparm=3/-mregparm=4/g' \ -e 's/-fexceptions//g' \ -e 's/-fasynchronous-unwind-tables//g' \ - -e 's/^/ -fno-strict-aliasing /' )" \ + -e 's/^/ -fno-strict-aliasing -std=gnu99 /' )" \ TARGET_LDFLAGS=-static \ --with-platform=efi \ --with-grubdir=%{name} \ @@ -355,7 +384,7 @@ GRUB_MODULES=" all_video boot btrfs cat chain configfile echo efifwsetup \ %ifarch aarch64 GRUB_MODULES="${GRUB_MODULES} linux" %else -GRUB_MODULES="${GRUB_MODULES} linuxefi multiboot2 multiboot" +GRUB_MODULES="${GRUB_MODULES} linuxefi" %endif ./grub-mkimage -O %{grubefiarch} -o %{grubefiname}.orig -p /EFI/%{efidir} \ -d grub-core ${GRUB_MODULES} @@ -365,8 +394,8 @@ GRUB_MODULES="${GRUB_MODULES} linuxefi multiboot2 multiboot" mv %{grubefiname}.orig %{grubefiname} mv %{grubeficdname}.orig %{grubeficdname} %else -%pesign -s -i %{grubefiname}.orig -o %{grubefiname} -a %{SOURCE1} -c %{SOURCE1} -n redhatsecureboot301 -%pesign -s -i %{grubeficdname}.orig -o %{grubeficdname} -a %{SOURCE1} -c %{SOURCE1} -n redhatsecureboot301 +%pesign -s -i %{grubefiname}.orig -o %{grubefiname} -a %{SOURCE1} -c %{SOURCE2} -n redhatsecureboot301 +%pesign -s -i %{grubeficdname}.orig -o %{grubeficdname} -a %{SOURCE1} -c %{SOURCE2} -n redhatsecureboot301 %endif cd .. %endif @@ -391,7 +420,7 @@ cd grub-%{tarversion} -e 's/-m64//g' \ -e 's/-fasynchronous-unwind-tables//g' \ -e 's/-mcpu=power7/-mcpu=power6/g' \ - -e 's/^/ -fno-strict-aliasing /' )" \ + -e 's/^/ -fno-strict-aliasing -std=gnu99 /' )" \ TARGET_LDFLAGS=-static \ --with-platform=%{platform} \ --with-grubdir=%{name} \ @@ -516,7 +545,28 @@ ln -s /boot/efi/EFI/%{efidir}/grubenv boot/grub2/grubenv %clean rm -rf $RPM_BUILD_ROOT -%post +%pre tools +if [ $1 -gt 1 ]; then + if [ -f /etc/grub.d/01_users ] && \ + grep -c -q '^password_pbkdf2 root' /etc/grub.d/01_users ; then + if [ -f /boot/efi/EFI/%{efidir}/grub.cfg ]; then + # on EFI we don't get permissions on the file, but + # the directory is protected. + grep '^password_pbkdf2 root' /etc/grub.d/01_users | \ + sed 's/^password_pbkdf2 root \(.*\)$/GRUB_PASSWORD=\1/' \ + > /boot/efi/EFI/%{efidir}/user.cfg + fi + if [ -f /boot/grub2/grub.cfg ]; then + install -m 0600 /dev/null /boot/grub2/user.cfg + chmod 0600 /boot/grub2/user.cfg + grep '^password_pbkdf2 root' /etc/grub.d/01_users | \ + sed 's/^password_pbkdf2 root \(.*\)$/GRUB_PASSWORD=\1/' \ + > /boot/grub2/user.cfg + fi + fi +fi + +%post tools if [ "$1" = 1 ]; then /sbin/install-info --info-dir=%{_infodir} %{_infodir}/%{name}.info.gz || : /sbin/install-info --info-dir=%{_infodir} %{_infodir}/%{name}-dev.info.gz || : @@ -547,7 +597,7 @@ mv -f /boot/grub2.tmp/*.mod \ /boot/grub2/ && rm -r /boot/grub2.tmp/ || : -%preun +%preun tools if [ "$1" = 0 ]; then /sbin/install-info --delete --info-dir=%{_infodir} %{_infodir}/%{name}.info.gz || : /sbin/install-info --delete --info-dir=%{_infodir} %{_infodir}/%{name}-dev.info.gz || : @@ -596,6 +646,7 @@ fi %{_sbindir}/%{name}-reboot %{_sbindir}/%{name}-rpm-sort %{_sbindir}/%{name}-set-default +%{_sbindir}/%{name}-setpassword %{_sbindir}/%{name}-sparc64-setup %{_bindir}/%{name}-editenv %{_bindir}/%{name}-file @@ -623,7 +674,7 @@ fi %{_sysconfdir}/grub.d/README %attr(0644,root,root) %ghost %config(noreplace) %{_sysconfdir}/default/grub %{_sysconfdir}/sysconfig/grub -%dir /boot/%{name} +%attr(0700,root,root) %dir /boot/%{name} %dir /boot/%{name}/themes/ %dir /boot/%{name}/themes/system %exclude /boot/%{name}/themes/system/* @@ -641,29 +692,83 @@ fi %exclude %{_datarootdir}/grub/themes/starfield %changelog -* Tue Sep 15 2015 CentOS Sources - 2.02-0.17.el7.centos.4 -- Roll in CentOS Secureboot keys -- Move the edidir to be CentOS, so people can co-install fedora, rhel and centos - -* Mon Aug 03 2015 Robert Marshall - 2.02-0.17.4 -- Reversed .17.2 and changed how rpm-sort availability is verified. - Resolves: rhbz#1229329 - -* Fri Jul 31 2015 Robert Marshall = 2.02.0.17.3 -- Built again with proper build target and updates rhbz# to be zstream. - Resolves: rhbz#1229329 - -* Thu Jul 30 2015 Robert Marshall - 2.02.0.17.2 -- Reversed order of kernel sorting. - Resolves: rhbz#1229329 - -* Tue Jul 14 2015 Robert Marshall - 2.02-0.17.1 -- Fixed rpmdiff issues. - Resolves: rhbz#1229329 - -* Mon Jul 13 2015 Robert Marshall - 2.02.0.17 +* Fri Oct 09 2015 Peter Jones - 2.02-0.29 +- Fix DHCP6 timeouts due to failed network stack once more. + Resolves: rhbz#1267139 + +* Thu Sep 17 2015 Peter Jones - 2.02-0.28 +- Once again, rebuild for the right build target. + Resolves: CVE-2015-5281 + +* Thu Sep 17 2015 Peter Jones - 2.02-0.27 +- Remove multiboot and multiboot2 modules from the .efi builds; they + should never have been there. + Resolves: CVE-2015-5281 + +* Mon Sep 14 2015 Peter Jones - 2.02-0.26 +- Be more aggressive about trying to make sure we use the configured SNP + device in UEFI. + Resolves: rhbz#1257475 + +* Wed Aug 05 2015 Robert Marshall - 2.02-0.25 +- Force file sync to disk on ppc64le machines. + Resolves: rhbz#1212114 + +* Mon Aug 03 2015 Peter Jones - 2.02-0.24 +- Undo 0.23 and fix it a different way. + Resolves: rhbz#1124074 + +* Thu Jul 30 2015 Peter Jones - 2.02-0.23 +- Reverse kernel sort order so they're displayed correctly. + Resolves: rhbz#1124074 + +* Wed Jul 08 2015 Peter Jones - 2.02-0.22 +- Make upgrades work reasonably well with grub2-setpassword . + Related: rhbz#985962 + +* Tue Jul 07 2015 Peter Jones - 2.02-0.21 +- Add a simpler grub2 password config tool + Related: rhbz#985962 +- Some more coverity nits. + +* Mon Jul 06 2015 Peter Jones - 2.02-0.20 +- Deal with some coverity nits. + Related: rhbz#1215839 + Related: rhbz#1124074 + +* Mon Jul 06 2015 Peter Jones - 2.02-0.19 +- Rebuild for Aarch64 +- Deal with some coverity nits. + Related: rhbz#1215839 + Related: rhbz#1124074 + +* Thu Jul 02 2015 Peter Jones - 2.02-0.18 +- Update for an rpmdiff problem with one of the man pages. + Related: rhbz#1124074 + +* Tue Jun 30 2015 Peter Jones - 2.02-0.17 +- Handle ipv6 better + Resolves: rhbz#1154226 +- On UEFI, use SIMPLE_NETWORK_PROTOCOL when we can. + Resolves: rhbz#1233378 +- Handle rssd disk drives in grub2 utilities. + Resolves: rhbz#1087962 +- Handle xfs CRC disk format. + Resolves: rhbz#1001279 +- Calibrate TCS using the EFI Stall service + Resolves: rhbz#1150698 +- Fix built-in gpg verification when using TFTP + Resolves: rhbz#1167977 +- Generate better stanza titles so grubby can find them easier. + Resolves: rhbz#1177003 +- Don't strip the fw_path variable twice when we're using EFI networking. + Resolves: rhbz#1211101 + +* Mon May 11 2015 Peter Jones - 2.02-0.17 +- Document network boot paths better + Resolves: rhbz#1148650 - Use an rpm-based version sorted in grub2-mkconfig - Resolves: rhbz#1229329 + Resolves: rhbz#1124074 * Thu Oct 09 2014 Peter Jones - 2.02-0.16 - ... and build it on the right target.