From 32175386182f86942dfaf9488d473af7977ba5f0a873d8421337855407b73ebb Mon Sep 17 00:00:00 2001 From: Marcus Meissner Date: Tue, 8 Jan 2013 13:33:26 +0000 Subject: [PATCH] Accepting request 147484 from home:arvidjaar:bnc:796919 - add os-prober-1.49-fix-grub2.cfg-parsing.patch (bnc#796919) OBS-URL: https://build.opensuse.org/request/show/147484 OBS-URL: https://build.opensuse.org/package/show/Base:System/os-prober?expand=0&rev=11 --- os-prober-1.49-fix-grub2.cfg-parsing.patch | 132 +++++++++++++++++++++ os-prober.changes | 5 + os-prober.spec | 3 + 3 files changed, 140 insertions(+) create mode 100644 os-prober-1.49-fix-grub2.cfg-parsing.patch diff --git a/os-prober-1.49-fix-grub2.cfg-parsing.patch b/os-prober-1.49-fix-grub2.cfg-parsing.patch new file mode 100644 index 0000000..f144cca --- /dev/null +++ b/os-prober-1.49-fix-grub2.cfg-parsing.patch @@ -0,0 +1,132 @@ +From: Andrey Borzenkov +Subject: fix parsing GRUB2 grub.cfg +References: bnc#796919 + +Fix several problems in parsing of grub.cfg by +linux-boot-probes/mounted/40grub2 + +1. It looked for /boot/grub/grub.cfg only. Make it check for +/boot/grub2-efi/grub.cfg, /boot/grub2/grub.cfg, /boot/grub/grub.cfg in +that order + +2. Parsing of menuentry was completely broken. It is (near to) impossible +to parse full fledged shell quoted strings with a couple of sed expressions. +Replace it with ``eval "set -- $line"'', which should handle quoting +automatically. It still may fail for manually created grub.cfg though. + +3. It checked for literal "(on /dev/.*)" to filter out menu entries +added by another os-prober on target system. But grub.cfg now includes +TRANSLATED strings, so this check will fail if grub.cfg was created in +non-English locale. Relax check and make it '(.* /dev/.*)'. It should +work as long as grub.cfg was created by grub-mkconfig. +Index: os-prober/linux-boot-probes/mounted/common/40grub2 +=================================================================== +--- os-prober.orig/linux-boot-probes/mounted/common/40grub2 ++++ os-prober/linux-boot-probes/mounted/common/40grub2 +@@ -34,33 +34,43 @@ parse_grub_menu () { + title="" + ignore_item=0 + +- while read line; do ++ # grub.cfg is written in shell like language that can contain ++ # arbitrary quoting. We need to extract second word according to ++ # normal quoting rules. Unfortunately, sticking ``eval $line'' for ++ # every line will try to interpret it according to shell ++ # grammar and error out for something as simple as "xxx; then". ++ # So the following is using it only on known cases. ++ # FIXME: it will fail if ``menuentry'' is not the first word on line. ++ # case patterns below include SPACE and TAB. ++ while read -r line; do + debug "parsing: $line" +- set -f +- set -- $line +- set +f +- case "$1" in +- menuentry) ++ line="$(printf "%s" "$line" | sed -e 's/^[[:space:]]*//')" ++ case "$line" in ++ menuentry[" "]*) + entry_result +- shift 1 +- # The double-quoted string is the title. +- title="$(echo "$@" | sed -n 's/[^"]*"\(.*\)".*/\1/p' | sed 's/://g')" +- if [ -z "$title" ]; then +- # ... or single-quoted? The +- # unescaping here is odd because the +- # 'set' above has already eaten +- # backslash-escapes. +- title="$(echo "$@" | sed -n "s/[^']*'\(.*\)'.*/\1/p" | sed "s/'''/'/; s/://g")" +- fi ++ set -f ++ eval "set -- $line" ++ set +f ++ title="$2" + if [ -z "$title" ]; then + ignore_item=1 +- elif echo "$title" | grep -q '(on /dev/[^)]*)$'; then ++ # Currently GRUB2 puts translated strings ++ # in grub.cfg, so checking for verbatim ++ # (on /dev/.*) will fail if target grub.cfg ++ # was created in non-English locale ++ elif echo "$title" | grep -q '(.* /dev/[^)]*)$'; then + log "Skipping entry '$title':" + log "appears to be an automatic reference taken from another menu.lst" + ignore_item=1 + fi + ;; +- linux) ++ linux[" "]*) ++ # And here we do NOT want to strip off ++ # existing quting, which will be transferred ++ # verbatim in new grub.cfg ++ set -f ++ set -- $line ++ set +f + # Hack alert: sed off any (hdn,n) but + # assume the kernel is on the same + # partition. +@@ -73,14 +83,17 @@ parse_grub_menu () { + kernel="/boot$kernel" + fi + ;; +- initrd) ++ initrd[" "]*) ++ # And here we do NOT want to strip off ++ # existing quting, which will be transferred ++ # verbatim in new grub.cfg + initrd="$(echo "$2" | sed 's/(.*)//')" + # Initrd same. + if [ "$partition" != "$bootpart" ]; then + initrd="/boot$initrd" + fi + ;; +- "}") ++ "}*") + entry_result + ;; + esac +@@ -89,11 +102,20 @@ parse_grub_menu () { + entry_result + } + +-if [ -e "$mpoint/boot/grub/grub.cfg" ] && \ ++grubcfg= ++if [ -e "$mpoint/boot/grub2-efi/grub.cfg" ]; then ++ grubcfg="$mpoint/boot/grub2-efi/grub.cfg" ++elif [ -e "$mpoint/boot/grub2/grub.cfg" ]; then ++ grubcfg="$mpoint/boot/grub2/grub.cfg" ++elif [ -e "$mpoint/boot/grub/grub.cfg" ]; then ++ grubcfg="$mpoint/boot/grub/grub.cfg" ++fi ++ ++if [ -n "$grubcfg" ] && \ + ([ ! -e "$mpoint/boot/grub/menu.lst" ] || \ +- [ "$mpoint/boot/grub/grub.cfg" -nt "$mpoint/boot/grub/menu.lst" ]); then +- debug "parsing grub.cfg" +- parse_grub_menu "$mpoint" "$partition" "$bootpart" < "$mpoint/boot/grub/grub.cfg" ++ [ "$grubcfg" -nt "$mpoint/boot/grub/menu.lst" ]); then ++ debug "parsing $grubcfg" ++ parse_grub_menu "$mpoint" "$partition" "$bootpart" < "$grubcfg" + fi + + if [ "$found_item" = 0 ]; then diff --git a/os-prober.changes b/os-prober.changes index 0b65402..9d52002 100644 --- a/os-prober.changes +++ b/os-prober.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Tue Jan 8 07:14:53 UTC 2013 - arvidjaar@gmail.com + +- add os-prober-1.49-fix-grub2.cfg-parsing.patch (bnc#796919) + ------------------------------------------------------------------- Fri Jan 4 11:18:01 UTC 2013 - arvidjaar@gmail.com diff --git a/os-prober.spec b/os-prober.spec index 2074480..af6490a 100644 --- a/os-prober.spec +++ b/os-prober.spec @@ -36,6 +36,8 @@ Patch0: os-prober-newnsdirfix.patch Patch1: os-prober-SUSE.patch # PATCH-FIX-OPENSUSE: Skip legacy Microsoft bootloader on UEFI [bnc#775610] Patch2: os-prober-skip-MS-legacy-on-UEFI.patch +# PATCH-FIX-OPENSUSE: Fix parsing of grub.cfg [bnc#796919] +Patch3: os-prober-1.49-fix-grub2.cfg-parsing.patch Requires: /bin/grep Requires: /bin/sed @@ -57,6 +59,7 @@ cp %SOURCE1 . %patch0 -p1 %patch1 -p1 %patch2 -p1 +%patch3 -p1 %build make %{?_smp_mflags} CC="%__cc" CFLAGS="%{optflags}"