diff --git a/.gitignore b/.gitignore index 7050abc..5148984 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ grubby-*.tar.bz2 clog *.rpm /8.40-1.tar.gz +grubby-*/ +.build*.log +.*sw? diff --git a/0001-Change-return-type-in-getRootSpecifier.patch b/0001-Change-return-type-in-getRootSpecifier.patch new file mode 100644 index 0000000..0a6808b --- /dev/null +++ b/0001-Change-return-type-in-getRootSpecifier.patch @@ -0,0 +1,143 @@ +From c1c46d21182974181f5b4c2ed0a02288b4bfd880 Mon Sep 17 00:00:00 2001 +From: Nathaniel McCallum +Date: Fri, 2 Mar 2018 14:59:32 -0500 +Subject: [PATCH 1/3] Change return type in getRootSpecifier() + +Rather than returning a new allocation of the prefix, just return the +length of the prefix. This change accomplishes a couple things. First, +it reduces some memory leaks since the return value was often never +freed. Second, it simplifies the caller who is usually only interested +in the length of the prefix. +--- + grubby.c | 54 +++++++++++++++++++++++++++--------------------------- + 1 file changed, 27 insertions(+), 27 deletions(-) + +diff --git a/grubby.c b/grubby.c +index d4ebb86..a062ef8 100644 +--- a/grubby.c ++++ b/grubby.c +@@ -675,7 +675,7 @@ static int lineWrite(FILE * out, struct singleLine * line, + struct configFileInfo * cfi); + static int getNextLine(char ** bufPtr, struct singleLine * line, + struct configFileInfo * cfi); +-static char * getRootSpecifier(char * str); ++static size_t getRootSpecifier(const char *str); + static void requote(struct singleLine *line, struct configFileInfo * cfi); + static void insertElement(struct singleLine * line, + const char * item, int insertHere, +@@ -1840,7 +1840,7 @@ int suitableImage(struct singleEntry * entry, const char * bootPrefix, + char * fullName; + int i; + char * dev; +- char * rootspec; ++ size_t rs; + char * rootdev; + + if (skipRemoved && entry->skip) { +@@ -1866,12 +1866,11 @@ int suitableImage(struct singleEntry * entry, const char * bootPrefix, + + fullName = alloca(strlen(bootPrefix) + + strlen(line->elements[1].item) + 1); +- rootspec = getRootSpecifier(line->elements[1].item); +- int rootspec_offset = rootspec ? strlen(rootspec) : 0; ++ rs = getRootSpecifier(line->elements[1].item); + int hasslash = endswith(bootPrefix, '/') || +- beginswith(line->elements[1].item + rootspec_offset, '/'); ++ beginswith(line->elements[1].item + rs, '/'); + sprintf(fullName, "%s%s%s", bootPrefix, hasslash ? "" : "/", +- line->elements[1].item + rootspec_offset); ++ line->elements[1].item + rs); + if (access(fullName, R_OK)) { + notSuitablePrintf(entry, 0, "access to %s failed\n", fullName); + return 0; +@@ -1952,7 +1951,6 @@ struct singleEntry * findEntryByPath(struct grubConfig * config, + struct singleLine * line; + int i; + char * chptr; +- char * rootspec = NULL; + enum lineType_e checkType = LT_KERNEL; + + if (isdigit(*kernel)) { +@@ -2044,11 +2042,10 @@ struct singleEntry * findEntryByPath(struct grubConfig * config, + + if (line && line->type != LT_MENUENTRY && + line->numElements >= 2) { +- rootspec = getRootSpecifier(line->elements[1].item); +- if (!strcmp(line->elements[1].item + +- ((rootspec != NULL) ? strlen(rootspec) : 0), +- kernel + strlen(prefix))) +- break; ++ if (!strcmp(line->elements[1].item + ++ getRootSpecifier(line->elements[1].item), ++ kernel + strlen(prefix))) ++ break; + } + if(line->type == LT_MENUENTRY && + !strcmp(line->elements[1].item, kernel)) +@@ -2797,11 +2794,11 @@ struct singleLine * addLineTmpl(struct singleEntry * entry, + + /* but try to keep the rootspec from the template... sigh */ + if (tmplLine->type & (LT_HYPER|LT_KERNEL|LT_MBMODULE|LT_INITRD|LT_KERNEL_EFI|LT_INITRD_EFI|LT_KERNEL_16|LT_INITRD_16)) { +- char * rootspec = getRootSpecifier(tmplLine->elements[1].item); +- if (rootspec != NULL) { +- free(newLine->elements[1].item); +- newLine->elements[1].item = +- sdupprintf("%s%s", rootspec, val); ++ size_t rs = getRootSpecifier(tmplLine->elements[1].item); ++ if (rs > 0) { ++ free(newLine->elements[1].item); ++ newLine->elements[1].item = sdupprintf("%.*s%s", (int) rs, ++ tmplLine->elements[1].item, val); + } + } + } +@@ -3729,15 +3726,19 @@ int checkForElilo(struct grubConfig * config) { + return 1; + } + +-static char * getRootSpecifier(char * str) { +- char * idx, * rootspec = NULL; ++static size_t getRootSpecifier(const char *str) ++{ ++ size_t rs = 0; + + if (*str == '(') { +- idx = rootspec = strdup(str); +- while(*idx && (*idx != ')') && (!isspace(*idx))) idx++; +- *(++idx) = '\0'; ++ for (; str[rs] != ')' && !isspace(str[rs]); rs++) { ++ if (!str[rs]) ++ return rs; ++ } ++ rs++; + } +- return rootspec; ++ ++ return rs; + } + + static char * getInitrdVal(struct grubConfig * config, +@@ -4616,7 +4617,7 @@ int main(int argc, const char ** argv) { + if (displayDefault) { + struct singleLine * line; + struct singleEntry * entry; +- char * rootspec; ++ size_t rs; + + if (config->defaultImage == -1) return 0; + if (config->defaultImage == DEFAULT_SAVED_GRUB2 && +@@ -4629,9 +4630,8 @@ int main(int argc, const char ** argv) { + line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines); + if (!line) return 0; + +- rootspec = getRootSpecifier(line->elements[1].item); +- printf("%s%s\n", bootPrefix, line->elements[1].item + +- ((rootspec != NULL) ? strlen(rootspec) : 0)); ++ rs = getRootSpecifier(line->elements[1].item); ++ printf("%s%s\n", bootPrefix, line->elements[1].item + rs); + + return 0; + +-- +2.14.3 + diff --git a/0002-Add-btrfs-subvolume-support-for-grub2.patch b/0002-Add-btrfs-subvolume-support-for-grub2.patch new file mode 100644 index 0000000..d460c5d --- /dev/null +++ b/0002-Add-btrfs-subvolume-support-for-grub2.patch @@ -0,0 +1,209 @@ +From 5dec033b19bb5b07a0a136a7357e16c8ca9f5dd6 Mon Sep 17 00:00:00 2001 +From: Nathaniel McCallum +Date: Fri, 2 Mar 2018 08:40:18 -0500 +Subject: [PATCH 2/3] Add btrfs subvolume support for grub2 + +In order to find the subvolume prefix from a given path, we parse +/proc/mounts. In cases where /proc/mounts doesn't contain the +filesystem, the caller can use the --mounts option to specify his own +mounts file. + +Btrfs subvolumes are already supported by grub2 and by grub2-mkconfig. + +Fixes #22 +--- + grubby.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 143 insertions(+), 5 deletions(-) + +diff --git a/grubby.c b/grubby.c +index a062ef8..96d252a 100644 +--- a/grubby.c ++++ b/grubby.c +@@ -68,6 +68,8 @@ int isEfi = 0; + + char *saved_command_line = NULL; + ++const char *mounts = "/proc/mounts"; ++ + /* comments get lumped in with indention */ + struct lineElement { + char * item; +@@ -1834,6 +1836,129 @@ static int endswith(const char *s, char c) + return s[slen] == c; + } + ++typedef struct { ++ const char *start; ++ size_t chars; ++} field; ++ ++static int iscomma(int c) ++{ ++ return c == ','; ++} ++ ++static int isequal(int c) ++{ ++ return c == '='; ++} ++ ++static field findField(const field *in, typeof(isspace) *isdelim, field *out) ++{ ++ field nxt = {}; ++ size_t off = 0; ++ ++ while (off < in->chars && isdelim(in->start[off])) ++ off++; ++ ++ if (off == in->chars) ++ return nxt; ++ ++ out->start = &in->start[off]; ++ out->chars = 0; ++ ++ while (off + out->chars < in->chars && !isdelim(out->start[out->chars])) ++ out->chars++; ++ ++ nxt.start = out->start + out->chars; ++ nxt.chars = in->chars - off - out->chars; ++ return nxt; ++} ++ ++static int fieldEquals(const field *in, const char *str) ++{ ++ return in->chars == strlen(str) && ++ strncmp(in->start, str, in->chars) == 0; ++} ++ ++/* Parse /proc/mounts to determine the subvolume prefix. */ ++static size_t subvolPrefix(const char *str) ++{ ++ FILE *file = NULL; ++ char *line = NULL; ++ size_t prfx = 0; ++ size_t size = 0; ++ ++ file = fopen(mounts, "r"); ++ if (!file) ++ return 0; ++ ++ for (ssize_t s; (s = getline(&line, &size, file)) >= 0; ) { ++ field nxt = { line, s }; ++ field dev = {}; ++ field path = {}; ++ field type = {}; ++ field opts = {}; ++ field opt = {}; ++ ++ nxt = findField(&nxt, isspace, &dev); ++ if (!nxt.start) ++ continue; ++ ++ nxt = findField(&nxt, isspace, &path); ++ if (!nxt.start) ++ continue; ++ ++ nxt = findField(&nxt, isspace, &type); ++ if (!nxt.start) ++ continue; ++ ++ nxt = findField(&nxt, isspace, &opts); ++ if (!nxt.start) ++ continue; ++ ++ if (!fieldEquals(&type, "btrfs")) ++ continue; ++ ++ /* We have found a btrfs mount point. */ ++ ++ nxt = opts; ++ while ((nxt = findField(&nxt, iscomma, &opt)).start) { ++ field key = {}; ++ field val = {}; ++ ++ opt = findField(&opt, isequal, &key); ++ if (!opt.start) ++ continue; ++ ++ opt = findField(&opt, isequal, &val); ++ if (!opt.start) ++ continue; ++ ++ if (!fieldEquals(&key, "subvol")) ++ continue; ++ ++ /* We have found a btrfs subvolume mount point. */ ++ ++ if (strncmp(val.start, str, val.chars)) ++ continue; ++ ++ if (val.start[val.chars - 1] != '/' && ++ str[val.chars] != '/') ++ continue; ++ ++ /* The subvolume mount point matches our input. */ ++ ++ if (prfx < val.chars) ++ prfx = val.chars; ++ } ++ } ++ ++ dbgPrintf("%s(): str: '%s', prfx: '%s'\n", __FUNCTION__, str, prfx); ++ ++ fclose(file); ++ free(line); ++ return prfx; ++} ++ + int suitableImage(struct singleEntry * entry, const char * bootPrefix, + int skipRemoved, int flags) { + struct singleLine * line; +@@ -2794,12 +2919,22 @@ struct singleLine * addLineTmpl(struct singleEntry * entry, + + /* but try to keep the rootspec from the template... sigh */ + if (tmplLine->type & (LT_HYPER|LT_KERNEL|LT_MBMODULE|LT_INITRD|LT_KERNEL_EFI|LT_INITRD_EFI|LT_KERNEL_16|LT_INITRD_16)) { +- size_t rs = getRootSpecifier(tmplLine->elements[1].item); ++ const char *prfx = tmplLine->elements[1].item; ++ size_t rs = getRootSpecifier(prfx); ++ if (isinitrd(tmplLine->type)) { ++ for (struct singleLine *l = entry->lines; ++ rs == 0 && l; l = l->next) { ++ if (iskernel(l->type)) { ++ prfx = l->elements[1].item; ++ rs = getRootSpecifier(prfx); ++ } ++ } ++ } + if (rs > 0) { + free(newLine->elements[1].item); +- newLine->elements[1].item = sdupprintf("%.*s%s", (int) rs, +- tmplLine->elements[1].item, val); +- } ++ newLine->elements[1].item = sdupprintf("%.*s%s", ++ (int) rs, prfx, val); ++ } + } + } + +@@ -3738,7 +3873,7 @@ static size_t getRootSpecifier(const char *str) + rs++; + } + +- return rs; ++ return rs + subvolPrefix(str + rs); + } + + static char * getInitrdVal(struct grubConfig * config, +@@ -4253,6 +4388,9 @@ int main(int argc, const char ** argv) { + { "mbargs", 0, POPT_ARG_STRING, &newMBKernelArgs, 0, + _("default arguments for the new multiboot kernel or " + "new arguments for multiboot kernel being updated"), NULL }, ++ { "mounts", 0, POPT_ARG_STRING, &mounts, 0, ++ _("path to fake /proc/mounts file (for testing only)"), ++ _("mounts") }, + { "bad-image-okay", 0, 0, &badImageOkay, 0, + _("don't sanity check images in boot entries (for testing only)"), + NULL }, +-- +2.14.3 + diff --git a/0003-Add-tests-for-btrfs-support.patch b/0003-Add-tests-for-btrfs-support.patch new file mode 100644 index 0000000..d274bb9 --- /dev/null +++ b/0003-Add-tests-for-btrfs-support.patch @@ -0,0 +1,1871 @@ +From 20d92194d03750d5d839c501d0539f9258614aae Mon Sep 17 00:00:00 2001 +From: Gene Czarcinski +Date: Mon, 9 Jun 2014 21:11:37 -0400 +Subject: [PATCH 3/3] Add tests for btrfs support + +The tests performed are: +- add kernel with /boot on btrfs subvol (20) +- update kernel/add initrd with /boot on btrfs subvol (21) +- add kernel with rootfs on btrfs subvol and /boot a directory (22) +- update kernel/add initrd with rootfs on btrfs subvol and + /boot a directory (23) +- add kernel and initrd with /boot on btrfs subvol (24) +- add kernel and initrd with rootfs on btrfs subvol and /boot + a directory (25) +--- + test.sh | 40 ++++++++++ + test/grub2-support_files/g2.20-mounts | 2 + + test/grub2-support_files/g2.21-mounts | 1 + + test/grub2-support_files/g2.22-mounts | 1 + + test/grub2-support_files/g2.23-mounts | 1 + + test/grub2-support_files/g2.24-mounts | 1 + + test/grub2-support_files/g2.25-mounts | 1 + + test/grub2.20 | 126 +++++++++++++++++++++++++++++ + test/grub2.21 | 140 +++++++++++++++++++++++++++++++++ + test/grub2.22 | 128 ++++++++++++++++++++++++++++++ + test/grub2.23 | 143 +++++++++++++++++++++++++++++++++ + test/grub2.24 | 126 +++++++++++++++++++++++++++++ + test/grub2.25 | 128 ++++++++++++++++++++++++++++++ + test/results/add/g2-1.20 | 140 +++++++++++++++++++++++++++++++++ + test/results/add/g2-1.21 | 141 +++++++++++++++++++++++++++++++++ + test/results/add/g2-1.22 | 143 +++++++++++++++++++++++++++++++++ + test/results/add/g2-1.23 | 144 ++++++++++++++++++++++++++++++++++ + test/results/add/g2-1.24 | 141 +++++++++++++++++++++++++++++++++ + test/results/add/g2-1.25 | 144 ++++++++++++++++++++++++++++++++++ + 19 files changed, 1691 insertions(+) + create mode 100644 test/grub2-support_files/g2.20-mounts + create mode 120000 test/grub2-support_files/g2.21-mounts + create mode 100644 test/grub2-support_files/g2.22-mounts + create mode 120000 test/grub2-support_files/g2.23-mounts + create mode 120000 test/grub2-support_files/g2.24-mounts + create mode 120000 test/grub2-support_files/g2.25-mounts + create mode 100644 test/grub2.20 + create mode 100644 test/grub2.21 + create mode 100644 test/grub2.22 + create mode 100644 test/grub2.23 + create mode 100644 test/grub2.24 + create mode 100644 test/grub2.25 + create mode 100644 test/results/add/g2-1.20 + create mode 100644 test/results/add/g2-1.21 + create mode 100644 test/results/add/g2-1.22 + create mode 100644 test/results/add/g2-1.23 + create mode 100644 test/results/add/g2-1.24 + create mode 100644 test/results/add/g2-1.25 + +diff --git a/test.sh b/test.sh +index 6379698..c35bfca 100755 +--- a/test.sh ++++ b/test.sh +@@ -629,6 +629,46 @@ if [ "$testgrub2" == "y" ]; then + --initrd /boot/initramfs-0-rescue-5a94251776a14678911d4ae0949500f5.img \ + --copy-default --title "Fedora 21 Rescue" --args=root=/fooooo \ + --remove-kernel=wtf --boot-filesystem=/boot/ ++ ++ testing="GRUB2 add kernel with boot on btrfs subvol" ++ grub2Test grub2.20 add/g2-1.20 --add-kernel=/boot/new-kernel.img \ ++ --title='title' \ ++ --boot-filesystem=/boot/ \ ++ --copy-default \ ++ --mounts='test/grub2-support_files/g2.20-mounts' ++ ++ testing="GRUB2 add initrd with boot on btrfs subvol" ++ grub2Test grub2.21 add/g2-1.21 --update-kernel=/boot/new-kernel.img \ ++ --initrd=/boot/new-initrd --boot-filesystem=/boot/ \ ++ --mounts='test/grub2-support_files/g2.21-mounts' ++ ++ testing="GRUB2 add kernel with rootfs on btrfs subvol and boot directory" ++ grub2Test grub2.22 add/g2-1.22 --add-kernel=/boot/new-kernel.img \ ++ --title='title' \ ++ --boot-filesystem= \ ++ --copy-default \ ++ --mounts='test/grub2-support_files/g2.22-mounts' ++ ++ testing="GRUB2 add initrd with rootfs on btrfs subvol and boot directory" ++ grub2Test grub2.23 add/g2-1.23 --update-kernel=/boot/new-kernel.img \ ++ --initrd=/boot/new-initrd --boot-filesystem= \ ++ --mounts='test/grub2-support_files/g2.23-mounts' ++ ++ testing="GRUB2 add kernel and initrd with boot on btrfs subvol" ++ grub2Test grub2.24 add/g2-1.24 --add-kernel=/boot/new-kernel.img \ ++ --title='title' \ ++ --initrd=/boot/new-initrd \ ++ --boot-filesystem=/boot/ \ ++ --copy-default \ ++ --mounts='test/grub2-support_files/g2.24-mounts' ++ ++ testing="GRUB2 add kernel and initrd with rootfs on btrfs subvol and boot directory" ++ grub2Test grub2.25 add/g2-1.25 --add-kernel=/boot/new-kernel.img \ ++ --title='title' \ ++ --initrd=/boot/new-initrd \ ++ --boot-filesystem= \ ++ --copy-default \ ++ --mounts='test/grub2-support_files/g2.25-mounts' + fi + fi + +diff --git a/test/grub2-support_files/g2.20-mounts b/test/grub2-support_files/g2.20-mounts +new file mode 100644 +index 0000000..00bdb48 +--- /dev/null ++++ b/test/grub2-support_files/g2.20-mounts +@@ -0,0 +1,2 @@ ++/dev/sda / btrfs subvol=/root6,defaults 0 0 ++/dev/sda /boot btrfs subvol=/boot6,defaults 0 0 +diff --git a/test/grub2-support_files/g2.21-mounts b/test/grub2-support_files/g2.21-mounts +new file mode 120000 +index 0000000..42ef3fd +--- /dev/null ++++ b/test/grub2-support_files/g2.21-mounts +@@ -0,0 +1 @@ ++g2.20-mounts +\ No newline at end of file +diff --git a/test/grub2-support_files/g2.22-mounts b/test/grub2-support_files/g2.22-mounts +new file mode 100644 +index 0000000..5b664e7 +--- /dev/null ++++ b/test/grub2-support_files/g2.22-mounts +@@ -0,0 +1 @@ ++/dev/sda / btrfs defaults,subvol=/root4,ro 0 0 +diff --git a/test/grub2-support_files/g2.23-mounts b/test/grub2-support_files/g2.23-mounts +new file mode 120000 +index 0000000..74f036f +--- /dev/null ++++ b/test/grub2-support_files/g2.23-mounts +@@ -0,0 +1 @@ ++g2.22-mounts +\ No newline at end of file +diff --git a/test/grub2-support_files/g2.24-mounts b/test/grub2-support_files/g2.24-mounts +new file mode 120000 +index 0000000..42ef3fd +--- /dev/null ++++ b/test/grub2-support_files/g2.24-mounts +@@ -0,0 +1 @@ ++g2.20-mounts +\ No newline at end of file +diff --git a/test/grub2-support_files/g2.25-mounts b/test/grub2-support_files/g2.25-mounts +new file mode 120000 +index 0000000..74f036f +--- /dev/null ++++ b/test/grub2-support_files/g2.25-mounts +@@ -0,0 +1 @@ ++g2.22-mounts +\ No newline at end of file +diff --git a/test/grub2.20 b/test/grub2.20 +new file mode 100644 +index 0000000..23b75fa +--- /dev/null ++++ b/test/grub2.20 +@@ -0,0 +1,126 @@ ++# ++# DO NOT EDIT THIS FILE ++# ++# It is automatically generated by grub2-mkconfig using templates ++# from /etc/grub.d and settings from /etc/default/grub ++# ++ ++### BEGIN /etc/grub.d/00_header ### ++set pager=1 ++ ++if [ -s $prefix/grubenv ]; then ++ load_env ++fi ++if [ "${next_entry}" ] ; then ++ set default="${next_entry}" ++ set next_entry= ++ save_env next_entry ++ set boot_once=true ++else ++ set default="${saved_entry}" ++fi ++ ++if [ x"${feature_menuentry_id}" = xy ]; then ++ menuentry_id_option="--id" ++else ++ menuentry_id_option="" ++fi ++ ++export menuentry_id_option ++ ++if [ "${prev_saved_entry}" ]; then ++ set saved_entry="${prev_saved_entry}" ++ save_env saved_entry ++ set prev_saved_entry= ++ save_env prev_saved_entry ++ set boot_once=true ++fi ++ ++function savedefault { ++ if [ -z "${boot_once}" ]; then ++ saved_entry="${chosen}" ++ save_env saved_entry ++ fi ++} ++ ++function load_video { ++ if [ x$feature_all_video_module = xy ]; then ++ insmod all_video ++ else ++ insmod efi_gop ++ insmod efi_uga ++ insmod ieee1275_fb ++ insmod vbe ++ insmod vga ++ insmod video_bochs ++ insmod video_cirrus ++ fi ++} ++ ++terminal_output console ++if [ x$feature_timeout_style = xy ] ; then ++ set timeout_style=menu ++ set timeout=15 ++# Fallback normal timeout code in case the timeout_style feature is ++# unavailable. ++else ++ set timeout=15 ++fi ++### END /etc/grub.d/00_header ### ++ ++### BEGIN /etc/grub.d/10_linux ### ++menuentry 'Fedora, with Linux 3.15.0-0.rc7.git2.1.fc21.x86_64' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ else ++ search --no-floppy --fs-uuid --set=root 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ fi ++ linux16 /boot6/vmlinuz-3.15.0-0.rc7.git2.1.fc21.x86_64 root=UUID=1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ro rootflags=subvol=root6 rhgb quiet ++ initrd16 /boot6/initramfs-3.15.0-0.rc7.git2.1.fc21.x86_64.img ++} ++menuentry 'Fedora, with Linux 0-rescue-81378818f7a24478b496ebef90e1dd69' --class gnu-linux --class gnu --class os { ++ load_video ++ insmod gzio ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ else ++ search --no-floppy --fs-uuid --set=root 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ fi ++ linux16 /boot6/vmlinuz-0-rescue-81378818f7a24478b496ebef90e1dd69 root=UUID=1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ro rootflags=subvol=root6 rhgb quiet ++ initrd16 /boot6/initramfs-0-rescue-81378818f7a24478b496ebef90e1dd69.img ++} ++ ++### END /etc/grub.d/10_linux ### ++ ++### BEGIN /etc/grub.d/20_linux_xen ### ++ ++### END /etc/grub.d/20_linux_xen ### ++ ++### BEGIN /etc/grub.d/20_ppc_terminfo ### ++### END /etc/grub.d/20_ppc_terminfo ### ++ ++### BEGIN /etc/grub.d/30_os-prober ### ++### END /etc/grub.d/30_os-prober ### ++ ++### BEGIN /etc/grub.d/40_custom ### ++# This file provides an easy way to add custom menu entries. Simply type the ++# menu entries you want to add after this comment. Be careful not to change ++# the 'exec tail' line above. ++### END /etc/grub.d/40_custom ### ++ ++### BEGIN /etc/grub.d/41_custom ### ++if [ -f ${config_directory}/custom.cfg ]; then ++ source ${config_directory}/custom.cfg ++elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then ++ source $prefix/custom.cfg; ++fi ++### END /etc/grub.d/41_custom ### +diff --git a/test/grub2.21 b/test/grub2.21 +new file mode 100644 +index 0000000..579c2f6 +--- /dev/null ++++ b/test/grub2.21 +@@ -0,0 +1,140 @@ ++# ++# DO NOT EDIT THIS FILE ++# ++# It is automatically generated by grub2-mkconfig using templates ++# from /etc/grub.d and settings from /etc/default/grub ++# ++ ++### BEGIN /etc/grub.d/00_header ### ++set pager=1 ++ ++if [ -s $prefix/grubenv ]; then ++ load_env ++fi ++if [ "${next_entry}" ] ; then ++ set default="${next_entry}" ++ set next_entry= ++ save_env next_entry ++ set boot_once=true ++else ++ set default="${saved_entry}" ++fi ++ ++if [ x"${feature_menuentry_id}" = xy ]; then ++ menuentry_id_option="--id" ++else ++ menuentry_id_option="" ++fi ++ ++export menuentry_id_option ++ ++if [ "${prev_saved_entry}" ]; then ++ set saved_entry="${prev_saved_entry}" ++ save_env saved_entry ++ set prev_saved_entry= ++ save_env prev_saved_entry ++ set boot_once=true ++fi ++ ++function savedefault { ++ if [ -z "${boot_once}" ]; then ++ saved_entry="${chosen}" ++ save_env saved_entry ++ fi ++} ++ ++function load_video { ++ if [ x$feature_all_video_module = xy ]; then ++ insmod all_video ++ else ++ insmod efi_gop ++ insmod efi_uga ++ insmod ieee1275_fb ++ insmod vbe ++ insmod vga ++ insmod video_bochs ++ insmod video_cirrus ++ fi ++} ++ ++terminal_output console ++if [ x$feature_timeout_style = xy ] ; then ++ set timeout_style=menu ++ set timeout=15 ++# Fallback normal timeout code in case the timeout_style feature is ++# unavailable. ++else ++ set timeout=15 ++fi ++### END /etc/grub.d/00_header ### ++ ++### BEGIN /etc/grub.d/10_linux ### ++menuentry 'title' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ else ++ search --no-floppy --fs-uuid --set=root 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ fi ++ linux16 /boot6/new-kernel.img root=UUID=1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ro rootflags=subvol=root6 rhgb quiet ++} ++menuentry 'Fedora, with Linux 3.15.0-0.rc7.git2.1.fc21.x86_64' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ else ++ search --no-floppy --fs-uuid --set=root 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ fi ++ linux16 /boot6/vmlinuz-3.15.0-0.rc7.git2.1.fc21.x86_64 root=UUID=1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ro rootflags=subvol=root6 rhgb quiet ++ initrd16 /boot6/initramfs-3.15.0-0.rc7.git2.1.fc21.x86_64.img ++} ++menuentry 'Fedora, with Linux 0-rescue-81378818f7a24478b496ebef90e1dd69' --class gnu-linux --class gnu --class os { ++ load_video ++ insmod gzio ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ else ++ search --no-floppy --fs-uuid --set=root 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ fi ++ linux16 /boot6/vmlinuz-0-rescue-81378818f7a24478b496ebef90e1dd69 root=UUID=1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ro rootflags=subvol=root6 rhgb quiet ++ initrd16 /boot6/initramfs-0-rescue-81378818f7a24478b496ebef90e1dd69.img ++} ++ ++### END /etc/grub.d/10_linux ### ++ ++### BEGIN /etc/grub.d/20_linux_xen ### ++ ++### END /etc/grub.d/20_linux_xen ### ++ ++### BEGIN /etc/grub.d/20_ppc_terminfo ### ++### END /etc/grub.d/20_ppc_terminfo ### ++ ++### BEGIN /etc/grub.d/30_os-prober ### ++### END /etc/grub.d/30_os-prober ### ++ ++### BEGIN /etc/grub.d/40_custom ### ++# This file provides an easy way to add custom menu entries. Simply type the ++# menu entries you want to add after this comment. Be careful not to change ++# the 'exec tail' line above. ++### END /etc/grub.d/40_custom ### ++ ++### BEGIN /etc/grub.d/41_custom ### ++if [ -f ${config_directory}/custom.cfg ]; then ++ source ${config_directory}/custom.cfg ++elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then ++ source $prefix/custom.cfg; ++fi ++### END /etc/grub.d/41_custom ### +diff --git a/test/grub2.22 b/test/grub2.22 +new file mode 100644 +index 0000000..9466bc3 +--- /dev/null ++++ b/test/grub2.22 +@@ -0,0 +1,128 @@ ++# ++# DO NOT EDIT THIS FILE ++# ++# It is automatically generated by grub2-mkconfig using templates ++# from /etc/grub.d and settings from /etc/default/grub ++# ++ ++### BEGIN /etc/grub.d/00_header ### ++set pager=1 ++ ++if [ -s $prefix/grubenv ]; then ++ load_env ++fi ++if [ "${next_entry}" ] ; then ++ set default="${next_entry}" ++ set next_entry= ++ save_env next_entry ++ set boot_once=true ++else ++ set default="${saved_entry}" ++fi ++ ++if [ x"${feature_menuentry_id}" = xy ]; then ++ menuentry_id_option="--id" ++else ++ menuentry_id_option="" ++fi ++ ++export menuentry_id_option ++ ++if [ "${prev_saved_entry}" ]; then ++ set saved_entry="${prev_saved_entry}" ++ save_env saved_entry ++ set prev_saved_entry= ++ save_env prev_saved_entry ++ set boot_once=true ++fi ++ ++function savedefault { ++ if [ -z "${boot_once}" ]; then ++ saved_entry="${chosen}" ++ save_env saved_entry ++ fi ++} ++ ++function load_video { ++ if [ x$feature_all_video_module = xy ]; then ++ insmod all_video ++ else ++ insmod efi_gop ++ insmod efi_uga ++ insmod ieee1275_fb ++ insmod vbe ++ insmod vga ++ insmod video_bochs ++ insmod video_cirrus ++ fi ++} ++ ++terminal_output console ++if [ x$feature_timeout_style = xy ] ; then ++ set timeout_style=menu ++ set timeout=15 ++# Fallback normal timeout code in case the timeout_style feature is ++# unavailable. ++else ++ set timeout=15 ++fi ++### END /etc/grub.d/00_header ### ++ ++### BEGIN /etc/grub.d/10_linux ### ++menuentry 'Fedora, with Linux 3.15.0-0.rc7.git2.1.fc21.x86_64' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' --hint='hd1,msdos3' 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ else ++ search --no-floppy --fs-uuid --set=root 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ fi ++ linux16 /root4/boot/vmlinuz-3.15.0-0.rc7.git2.1.fc21.x86_64 root=UUID=54c6abc2-b1e7-4987-aa73-c79927be69eb ro rootflags=subvol=root4 rhgb quiet ++ initrd16 /root4/boot/initramfs-3.15.0-0.rc7.git2.1.fc21.x86_64.img ++} ++menuentry 'Fedora, with Linux 0-rescue-20e7024f4e9c4b70b1042b91acd434c6' --class gnu-linux --class gnu --class os { ++ load_video ++ insmod gzio ++ insmod part_msdos ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' --hint='hd1,msdos3' 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ else ++ search --no-floppy --fs-uuid --set=root 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ fi ++ linux16 /root4/boot/vmlinuz-0-rescue-20e7024f4e9c4b70b1042b91acd434c6 root=UUID=54c6abc2-b1e7-4987-aa73-c79927be69eb ro rootflags=subvol=root4 rhgb quiet ++ initrd16 /root4/boot/initramfs-0-rescue-20e7024f4e9c4b70b1042b91acd434c6.img ++} ++ ++### END /etc/grub.d/10_linux ### ++ ++### BEGIN /etc/grub.d/20_linux_xen ### ++ ++### END /etc/grub.d/20_linux_xen ### ++ ++### BEGIN /etc/grub.d/20_ppc_terminfo ### ++### END /etc/grub.d/20_ppc_terminfo ### ++ ++### BEGIN /etc/grub.d/30_os-prober ### ++### ++ ++### BEGIN /etc/grub.d/40_custom ### ++# This file provides an easy way to add custom menu entries. Simply type the ++# menu entries you want to add after this comment. Be careful not to change ++# the 'exec tail' line above. ++### END /etc/grub.d/40_custom ### ++ ++### BEGIN /etc/grub.d/41_custom ### ++if [ -f ${config_directory}/custom.cfg ]; then ++ source ${config_directory}/custom.cfg ++elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then ++ source $prefix/custom.cfg; ++fi ++### END /etc/grub.d/41_custom ### +diff --git a/test/grub2.23 b/test/grub2.23 +new file mode 100644 +index 0000000..5cb240f +--- /dev/null ++++ b/test/grub2.23 +@@ -0,0 +1,143 @@ ++# ++# DO NOT EDIT THIS FILE ++# ++# It is automatically generated by grub2-mkconfig using templates ++# from /etc/grub.d and settings from /etc/default/grub ++# ++ ++### BEGIN /etc/grub.d/00_header ### ++set pager=1 ++ ++if [ -s $prefix/grubenv ]; then ++ load_env ++fi ++if [ "${next_entry}" ] ; then ++ set default="${next_entry}" ++ set next_entry= ++ save_env next_entry ++ set boot_once=true ++else ++ set default="${saved_entry}" ++fi ++ ++if [ x"${feature_menuentry_id}" = xy ]; then ++ menuentry_id_option="--id" ++else ++ menuentry_id_option="" ++fi ++ ++export menuentry_id_option ++ ++if [ "${prev_saved_entry}" ]; then ++ set saved_entry="${prev_saved_entry}" ++ save_env saved_entry ++ set prev_saved_entry= ++ save_env prev_saved_entry ++ set boot_once=true ++fi ++ ++function savedefault { ++ if [ -z "${boot_once}" ]; then ++ saved_entry="${chosen}" ++ save_env saved_entry ++ fi ++} ++ ++function load_video { ++ if [ x$feature_all_video_module = xy ]; then ++ insmod all_video ++ else ++ insmod efi_gop ++ insmod efi_uga ++ insmod ieee1275_fb ++ insmod vbe ++ insmod vga ++ insmod video_bochs ++ insmod video_cirrus ++ fi ++} ++ ++terminal_output console ++if [ x$feature_timeout_style = xy ] ; then ++ set timeout_style=menu ++ set timeout=15 ++# Fallback normal timeout code in case the timeout_style feature is ++# unavailable. ++else ++ set timeout=15 ++fi ++### END /etc/grub.d/00_header ### ++ ++### BEGIN /etc/grub.d/10_linux ### ++menuentry 'title' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' --hint='hd1,msdos3' 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ else ++ search --no-floppy --fs-uuid --set=root 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ fi ++ linux16 /root4/boot/new-kernel.img root=UUID=54c6abc2-b1e7-4987-aa73-c79927be69eb ro rootflags=subvol=root4 rhgb quiet ++} ++menuentry 'Fedora, with Linux 3.15.0-0.rc7.git2.1.fc21.x86_64' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' --hint='hd1,msdos3' 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ else ++ search --no-floppy --fs-uuid --set=root 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ fi ++ linux16 /root4/boot/vmlinuz-3.15.0-0.rc7.git2.1.fc21.x86_64 root=UUID=54c6abc2-b1e7-4987-aa73-c79927be69eb ro rootflags=subvol=root4 rhgb quiet ++ initrd16 /root4/boot/initramfs-3.15.0-0.rc7.git2.1.fc21.x86_64.img ++} ++menuentry 'Fedora, with Linux 0-rescue-20e7024f4e9c4b70b1042b91acd434c6' --class gnu-linux --class gnu --class os { ++ load_video ++ insmod gzio ++ insmod part_msdos ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' --hint='hd1,msdos3' 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ else ++ search --no-floppy --fs-uuid --set=root 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ fi ++ linux16 /root4/boot/vmlinuz-0-rescue-20e7024f4e9c4b70b1042b91acd434c6 root=UUID=54c6abc2-b1e7-4987-aa73-c79927be69eb ro rootflags=subvol=root4 rhgb quiet ++ initrd16 /root4/boot/initramfs-0-rescue-20e7024f4e9c4b70b1042b91acd434c6.img ++} ++ ++### END /etc/grub.d/10_linux ### ++ ++### BEGIN /etc/grub.d/20_linux_xen ### ++ ++### END /etc/grub.d/20_linux_xen ### ++ ++### BEGIN /etc/grub.d/20_ppc_terminfo ### ++### END /etc/grub.d/20_ppc_terminfo ### ++ ++### BEGIN /etc/grub.d/30_os-prober ### ++### ++ ++### BEGIN /etc/grub.d/40_custom ### ++# This file provides an easy way to add custom menu entries. Simply type the ++# menu entries you want to add after this comment. Be careful not to change ++# the 'exec tail' line above. ++### END /etc/grub.d/40_custom ### ++ ++### BEGIN /etc/grub.d/41_custom ### ++if [ -f ${config_directory}/custom.cfg ]; then ++ source ${config_directory}/custom.cfg ++elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then ++ source $prefix/custom.cfg; ++fi ++### END /etc/grub.d/41_custom ### +diff --git a/test/grub2.24 b/test/grub2.24 +new file mode 100644 +index 0000000..23b75fa +--- /dev/null ++++ b/test/grub2.24 +@@ -0,0 +1,126 @@ ++# ++# DO NOT EDIT THIS FILE ++# ++# It is automatically generated by grub2-mkconfig using templates ++# from /etc/grub.d and settings from /etc/default/grub ++# ++ ++### BEGIN /etc/grub.d/00_header ### ++set pager=1 ++ ++if [ -s $prefix/grubenv ]; then ++ load_env ++fi ++if [ "${next_entry}" ] ; then ++ set default="${next_entry}" ++ set next_entry= ++ save_env next_entry ++ set boot_once=true ++else ++ set default="${saved_entry}" ++fi ++ ++if [ x"${feature_menuentry_id}" = xy ]; then ++ menuentry_id_option="--id" ++else ++ menuentry_id_option="" ++fi ++ ++export menuentry_id_option ++ ++if [ "${prev_saved_entry}" ]; then ++ set saved_entry="${prev_saved_entry}" ++ save_env saved_entry ++ set prev_saved_entry= ++ save_env prev_saved_entry ++ set boot_once=true ++fi ++ ++function savedefault { ++ if [ -z "${boot_once}" ]; then ++ saved_entry="${chosen}" ++ save_env saved_entry ++ fi ++} ++ ++function load_video { ++ if [ x$feature_all_video_module = xy ]; then ++ insmod all_video ++ else ++ insmod efi_gop ++ insmod efi_uga ++ insmod ieee1275_fb ++ insmod vbe ++ insmod vga ++ insmod video_bochs ++ insmod video_cirrus ++ fi ++} ++ ++terminal_output console ++if [ x$feature_timeout_style = xy ] ; then ++ set timeout_style=menu ++ set timeout=15 ++# Fallback normal timeout code in case the timeout_style feature is ++# unavailable. ++else ++ set timeout=15 ++fi ++### END /etc/grub.d/00_header ### ++ ++### BEGIN /etc/grub.d/10_linux ### ++menuentry 'Fedora, with Linux 3.15.0-0.rc7.git2.1.fc21.x86_64' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ else ++ search --no-floppy --fs-uuid --set=root 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ fi ++ linux16 /boot6/vmlinuz-3.15.0-0.rc7.git2.1.fc21.x86_64 root=UUID=1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ro rootflags=subvol=root6 rhgb quiet ++ initrd16 /boot6/initramfs-3.15.0-0.rc7.git2.1.fc21.x86_64.img ++} ++menuentry 'Fedora, with Linux 0-rescue-81378818f7a24478b496ebef90e1dd69' --class gnu-linux --class gnu --class os { ++ load_video ++ insmod gzio ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ else ++ search --no-floppy --fs-uuid --set=root 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ fi ++ linux16 /boot6/vmlinuz-0-rescue-81378818f7a24478b496ebef90e1dd69 root=UUID=1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ro rootflags=subvol=root6 rhgb quiet ++ initrd16 /boot6/initramfs-0-rescue-81378818f7a24478b496ebef90e1dd69.img ++} ++ ++### END /etc/grub.d/10_linux ### ++ ++### BEGIN /etc/grub.d/20_linux_xen ### ++ ++### END /etc/grub.d/20_linux_xen ### ++ ++### BEGIN /etc/grub.d/20_ppc_terminfo ### ++### END /etc/grub.d/20_ppc_terminfo ### ++ ++### BEGIN /etc/grub.d/30_os-prober ### ++### END /etc/grub.d/30_os-prober ### ++ ++### BEGIN /etc/grub.d/40_custom ### ++# This file provides an easy way to add custom menu entries. Simply type the ++# menu entries you want to add after this comment. Be careful not to change ++# the 'exec tail' line above. ++### END /etc/grub.d/40_custom ### ++ ++### BEGIN /etc/grub.d/41_custom ### ++if [ -f ${config_directory}/custom.cfg ]; then ++ source ${config_directory}/custom.cfg ++elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then ++ source $prefix/custom.cfg; ++fi ++### END /etc/grub.d/41_custom ### +diff --git a/test/grub2.25 b/test/grub2.25 +new file mode 100644 +index 0000000..9466bc3 +--- /dev/null ++++ b/test/grub2.25 +@@ -0,0 +1,128 @@ ++# ++# DO NOT EDIT THIS FILE ++# ++# It is automatically generated by grub2-mkconfig using templates ++# from /etc/grub.d and settings from /etc/default/grub ++# ++ ++### BEGIN /etc/grub.d/00_header ### ++set pager=1 ++ ++if [ -s $prefix/grubenv ]; then ++ load_env ++fi ++if [ "${next_entry}" ] ; then ++ set default="${next_entry}" ++ set next_entry= ++ save_env next_entry ++ set boot_once=true ++else ++ set default="${saved_entry}" ++fi ++ ++if [ x"${feature_menuentry_id}" = xy ]; then ++ menuentry_id_option="--id" ++else ++ menuentry_id_option="" ++fi ++ ++export menuentry_id_option ++ ++if [ "${prev_saved_entry}" ]; then ++ set saved_entry="${prev_saved_entry}" ++ save_env saved_entry ++ set prev_saved_entry= ++ save_env prev_saved_entry ++ set boot_once=true ++fi ++ ++function savedefault { ++ if [ -z "${boot_once}" ]; then ++ saved_entry="${chosen}" ++ save_env saved_entry ++ fi ++} ++ ++function load_video { ++ if [ x$feature_all_video_module = xy ]; then ++ insmod all_video ++ else ++ insmod efi_gop ++ insmod efi_uga ++ insmod ieee1275_fb ++ insmod vbe ++ insmod vga ++ insmod video_bochs ++ insmod video_cirrus ++ fi ++} ++ ++terminal_output console ++if [ x$feature_timeout_style = xy ] ; then ++ set timeout_style=menu ++ set timeout=15 ++# Fallback normal timeout code in case the timeout_style feature is ++# unavailable. ++else ++ set timeout=15 ++fi ++### END /etc/grub.d/00_header ### ++ ++### BEGIN /etc/grub.d/10_linux ### ++menuentry 'Fedora, with Linux 3.15.0-0.rc7.git2.1.fc21.x86_64' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' --hint='hd1,msdos3' 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ else ++ search --no-floppy --fs-uuid --set=root 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ fi ++ linux16 /root4/boot/vmlinuz-3.15.0-0.rc7.git2.1.fc21.x86_64 root=UUID=54c6abc2-b1e7-4987-aa73-c79927be69eb ro rootflags=subvol=root4 rhgb quiet ++ initrd16 /root4/boot/initramfs-3.15.0-0.rc7.git2.1.fc21.x86_64.img ++} ++menuentry 'Fedora, with Linux 0-rescue-20e7024f4e9c4b70b1042b91acd434c6' --class gnu-linux --class gnu --class os { ++ load_video ++ insmod gzio ++ insmod part_msdos ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' --hint='hd1,msdos3' 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ else ++ search --no-floppy --fs-uuid --set=root 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ fi ++ linux16 /root4/boot/vmlinuz-0-rescue-20e7024f4e9c4b70b1042b91acd434c6 root=UUID=54c6abc2-b1e7-4987-aa73-c79927be69eb ro rootflags=subvol=root4 rhgb quiet ++ initrd16 /root4/boot/initramfs-0-rescue-20e7024f4e9c4b70b1042b91acd434c6.img ++} ++ ++### END /etc/grub.d/10_linux ### ++ ++### BEGIN /etc/grub.d/20_linux_xen ### ++ ++### END /etc/grub.d/20_linux_xen ### ++ ++### BEGIN /etc/grub.d/20_ppc_terminfo ### ++### END /etc/grub.d/20_ppc_terminfo ### ++ ++### BEGIN /etc/grub.d/30_os-prober ### ++### ++ ++### BEGIN /etc/grub.d/40_custom ### ++# This file provides an easy way to add custom menu entries. Simply type the ++# menu entries you want to add after this comment. Be careful not to change ++# the 'exec tail' line above. ++### END /etc/grub.d/40_custom ### ++ ++### BEGIN /etc/grub.d/41_custom ### ++if [ -f ${config_directory}/custom.cfg ]; then ++ source ${config_directory}/custom.cfg ++elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then ++ source $prefix/custom.cfg; ++fi ++### END /etc/grub.d/41_custom ### +diff --git a/test/results/add/g2-1.20 b/test/results/add/g2-1.20 +new file mode 100644 +index 0000000..579c2f6 +--- /dev/null ++++ b/test/results/add/g2-1.20 +@@ -0,0 +1,140 @@ ++# ++# DO NOT EDIT THIS FILE ++# ++# It is automatically generated by grub2-mkconfig using templates ++# from /etc/grub.d and settings from /etc/default/grub ++# ++ ++### BEGIN /etc/grub.d/00_header ### ++set pager=1 ++ ++if [ -s $prefix/grubenv ]; then ++ load_env ++fi ++if [ "${next_entry}" ] ; then ++ set default="${next_entry}" ++ set next_entry= ++ save_env next_entry ++ set boot_once=true ++else ++ set default="${saved_entry}" ++fi ++ ++if [ x"${feature_menuentry_id}" = xy ]; then ++ menuentry_id_option="--id" ++else ++ menuentry_id_option="" ++fi ++ ++export menuentry_id_option ++ ++if [ "${prev_saved_entry}" ]; then ++ set saved_entry="${prev_saved_entry}" ++ save_env saved_entry ++ set prev_saved_entry= ++ save_env prev_saved_entry ++ set boot_once=true ++fi ++ ++function savedefault { ++ if [ -z "${boot_once}" ]; then ++ saved_entry="${chosen}" ++ save_env saved_entry ++ fi ++} ++ ++function load_video { ++ if [ x$feature_all_video_module = xy ]; then ++ insmod all_video ++ else ++ insmod efi_gop ++ insmod efi_uga ++ insmod ieee1275_fb ++ insmod vbe ++ insmod vga ++ insmod video_bochs ++ insmod video_cirrus ++ fi ++} ++ ++terminal_output console ++if [ x$feature_timeout_style = xy ] ; then ++ set timeout_style=menu ++ set timeout=15 ++# Fallback normal timeout code in case the timeout_style feature is ++# unavailable. ++else ++ set timeout=15 ++fi ++### END /etc/grub.d/00_header ### ++ ++### BEGIN /etc/grub.d/10_linux ### ++menuentry 'title' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ else ++ search --no-floppy --fs-uuid --set=root 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ fi ++ linux16 /boot6/new-kernel.img root=UUID=1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ro rootflags=subvol=root6 rhgb quiet ++} ++menuentry 'Fedora, with Linux 3.15.0-0.rc7.git2.1.fc21.x86_64' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ else ++ search --no-floppy --fs-uuid --set=root 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ fi ++ linux16 /boot6/vmlinuz-3.15.0-0.rc7.git2.1.fc21.x86_64 root=UUID=1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ro rootflags=subvol=root6 rhgb quiet ++ initrd16 /boot6/initramfs-3.15.0-0.rc7.git2.1.fc21.x86_64.img ++} ++menuentry 'Fedora, with Linux 0-rescue-81378818f7a24478b496ebef90e1dd69' --class gnu-linux --class gnu --class os { ++ load_video ++ insmod gzio ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ else ++ search --no-floppy --fs-uuid --set=root 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ fi ++ linux16 /boot6/vmlinuz-0-rescue-81378818f7a24478b496ebef90e1dd69 root=UUID=1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ro rootflags=subvol=root6 rhgb quiet ++ initrd16 /boot6/initramfs-0-rescue-81378818f7a24478b496ebef90e1dd69.img ++} ++ ++### END /etc/grub.d/10_linux ### ++ ++### BEGIN /etc/grub.d/20_linux_xen ### ++ ++### END /etc/grub.d/20_linux_xen ### ++ ++### BEGIN /etc/grub.d/20_ppc_terminfo ### ++### END /etc/grub.d/20_ppc_terminfo ### ++ ++### BEGIN /etc/grub.d/30_os-prober ### ++### END /etc/grub.d/30_os-prober ### ++ ++### BEGIN /etc/grub.d/40_custom ### ++# This file provides an easy way to add custom menu entries. Simply type the ++# menu entries you want to add after this comment. Be careful not to change ++# the 'exec tail' line above. ++### END /etc/grub.d/40_custom ### ++ ++### BEGIN /etc/grub.d/41_custom ### ++if [ -f ${config_directory}/custom.cfg ]; then ++ source ${config_directory}/custom.cfg ++elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then ++ source $prefix/custom.cfg; ++fi ++### END /etc/grub.d/41_custom ### +diff --git a/test/results/add/g2-1.21 b/test/results/add/g2-1.21 +new file mode 100644 +index 0000000..c0dded9 +--- /dev/null ++++ b/test/results/add/g2-1.21 +@@ -0,0 +1,141 @@ ++# ++# DO NOT EDIT THIS FILE ++# ++# It is automatically generated by grub2-mkconfig using templates ++# from /etc/grub.d and settings from /etc/default/grub ++# ++ ++### BEGIN /etc/grub.d/00_header ### ++set pager=1 ++ ++if [ -s $prefix/grubenv ]; then ++ load_env ++fi ++if [ "${next_entry}" ] ; then ++ set default="${next_entry}" ++ set next_entry= ++ save_env next_entry ++ set boot_once=true ++else ++ set default="${saved_entry}" ++fi ++ ++if [ x"${feature_menuentry_id}" = xy ]; then ++ menuentry_id_option="--id" ++else ++ menuentry_id_option="" ++fi ++ ++export menuentry_id_option ++ ++if [ "${prev_saved_entry}" ]; then ++ set saved_entry="${prev_saved_entry}" ++ save_env saved_entry ++ set prev_saved_entry= ++ save_env prev_saved_entry ++ set boot_once=true ++fi ++ ++function savedefault { ++ if [ -z "${boot_once}" ]; then ++ saved_entry="${chosen}" ++ save_env saved_entry ++ fi ++} ++ ++function load_video { ++ if [ x$feature_all_video_module = xy ]; then ++ insmod all_video ++ else ++ insmod efi_gop ++ insmod efi_uga ++ insmod ieee1275_fb ++ insmod vbe ++ insmod vga ++ insmod video_bochs ++ insmod video_cirrus ++ fi ++} ++ ++terminal_output console ++if [ x$feature_timeout_style = xy ] ; then ++ set timeout_style=menu ++ set timeout=15 ++# Fallback normal timeout code in case the timeout_style feature is ++# unavailable. ++else ++ set timeout=15 ++fi ++### END /etc/grub.d/00_header ### ++ ++### BEGIN /etc/grub.d/10_linux ### ++menuentry 'title' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ else ++ search --no-floppy --fs-uuid --set=root 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ fi ++ linux16 /boot6/new-kernel.img root=UUID=1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ro rootflags=subvol=root6 rhgb quiet ++ initrd16 /boot6/new-initrd ++} ++menuentry 'Fedora, with Linux 3.15.0-0.rc7.git2.1.fc21.x86_64' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ else ++ search --no-floppy --fs-uuid --set=root 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ fi ++ linux16 /boot6/vmlinuz-3.15.0-0.rc7.git2.1.fc21.x86_64 root=UUID=1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ro rootflags=subvol=root6 rhgb quiet ++ initrd16 /boot6/initramfs-3.15.0-0.rc7.git2.1.fc21.x86_64.img ++} ++menuentry 'Fedora, with Linux 0-rescue-81378818f7a24478b496ebef90e1dd69' --class gnu-linux --class gnu --class os { ++ load_video ++ insmod gzio ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ else ++ search --no-floppy --fs-uuid --set=root 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ fi ++ linux16 /boot6/vmlinuz-0-rescue-81378818f7a24478b496ebef90e1dd69 root=UUID=1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ro rootflags=subvol=root6 rhgb quiet ++ initrd16 /boot6/initramfs-0-rescue-81378818f7a24478b496ebef90e1dd69.img ++} ++ ++### END /etc/grub.d/10_linux ### ++ ++### BEGIN /etc/grub.d/20_linux_xen ### ++ ++### END /etc/grub.d/20_linux_xen ### ++ ++### BEGIN /etc/grub.d/20_ppc_terminfo ### ++### END /etc/grub.d/20_ppc_terminfo ### ++ ++### BEGIN /etc/grub.d/30_os-prober ### ++### END /etc/grub.d/30_os-prober ### ++ ++### BEGIN /etc/grub.d/40_custom ### ++# This file provides an easy way to add custom menu entries. Simply type the ++# menu entries you want to add after this comment. Be careful not to change ++# the 'exec tail' line above. ++### END /etc/grub.d/40_custom ### ++ ++### BEGIN /etc/grub.d/41_custom ### ++if [ -f ${config_directory}/custom.cfg ]; then ++ source ${config_directory}/custom.cfg ++elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then ++ source $prefix/custom.cfg; ++fi ++### END /etc/grub.d/41_custom ### +diff --git a/test/results/add/g2-1.22 b/test/results/add/g2-1.22 +new file mode 100644 +index 0000000..5cb240f +--- /dev/null ++++ b/test/results/add/g2-1.22 +@@ -0,0 +1,143 @@ ++# ++# DO NOT EDIT THIS FILE ++# ++# It is automatically generated by grub2-mkconfig using templates ++# from /etc/grub.d and settings from /etc/default/grub ++# ++ ++### BEGIN /etc/grub.d/00_header ### ++set pager=1 ++ ++if [ -s $prefix/grubenv ]; then ++ load_env ++fi ++if [ "${next_entry}" ] ; then ++ set default="${next_entry}" ++ set next_entry= ++ save_env next_entry ++ set boot_once=true ++else ++ set default="${saved_entry}" ++fi ++ ++if [ x"${feature_menuentry_id}" = xy ]; then ++ menuentry_id_option="--id" ++else ++ menuentry_id_option="" ++fi ++ ++export menuentry_id_option ++ ++if [ "${prev_saved_entry}" ]; then ++ set saved_entry="${prev_saved_entry}" ++ save_env saved_entry ++ set prev_saved_entry= ++ save_env prev_saved_entry ++ set boot_once=true ++fi ++ ++function savedefault { ++ if [ -z "${boot_once}" ]; then ++ saved_entry="${chosen}" ++ save_env saved_entry ++ fi ++} ++ ++function load_video { ++ if [ x$feature_all_video_module = xy ]; then ++ insmod all_video ++ else ++ insmod efi_gop ++ insmod efi_uga ++ insmod ieee1275_fb ++ insmod vbe ++ insmod vga ++ insmod video_bochs ++ insmod video_cirrus ++ fi ++} ++ ++terminal_output console ++if [ x$feature_timeout_style = xy ] ; then ++ set timeout_style=menu ++ set timeout=15 ++# Fallback normal timeout code in case the timeout_style feature is ++# unavailable. ++else ++ set timeout=15 ++fi ++### END /etc/grub.d/00_header ### ++ ++### BEGIN /etc/grub.d/10_linux ### ++menuentry 'title' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' --hint='hd1,msdos3' 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ else ++ search --no-floppy --fs-uuid --set=root 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ fi ++ linux16 /root4/boot/new-kernel.img root=UUID=54c6abc2-b1e7-4987-aa73-c79927be69eb ro rootflags=subvol=root4 rhgb quiet ++} ++menuentry 'Fedora, with Linux 3.15.0-0.rc7.git2.1.fc21.x86_64' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' --hint='hd1,msdos3' 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ else ++ search --no-floppy --fs-uuid --set=root 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ fi ++ linux16 /root4/boot/vmlinuz-3.15.0-0.rc7.git2.1.fc21.x86_64 root=UUID=54c6abc2-b1e7-4987-aa73-c79927be69eb ro rootflags=subvol=root4 rhgb quiet ++ initrd16 /root4/boot/initramfs-3.15.0-0.rc7.git2.1.fc21.x86_64.img ++} ++menuentry 'Fedora, with Linux 0-rescue-20e7024f4e9c4b70b1042b91acd434c6' --class gnu-linux --class gnu --class os { ++ load_video ++ insmod gzio ++ insmod part_msdos ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' --hint='hd1,msdos3' 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ else ++ search --no-floppy --fs-uuid --set=root 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ fi ++ linux16 /root4/boot/vmlinuz-0-rescue-20e7024f4e9c4b70b1042b91acd434c6 root=UUID=54c6abc2-b1e7-4987-aa73-c79927be69eb ro rootflags=subvol=root4 rhgb quiet ++ initrd16 /root4/boot/initramfs-0-rescue-20e7024f4e9c4b70b1042b91acd434c6.img ++} ++ ++### END /etc/grub.d/10_linux ### ++ ++### BEGIN /etc/grub.d/20_linux_xen ### ++ ++### END /etc/grub.d/20_linux_xen ### ++ ++### BEGIN /etc/grub.d/20_ppc_terminfo ### ++### END /etc/grub.d/20_ppc_terminfo ### ++ ++### BEGIN /etc/grub.d/30_os-prober ### ++### ++ ++### BEGIN /etc/grub.d/40_custom ### ++# This file provides an easy way to add custom menu entries. Simply type the ++# menu entries you want to add after this comment. Be careful not to change ++# the 'exec tail' line above. ++### END /etc/grub.d/40_custom ### ++ ++### BEGIN /etc/grub.d/41_custom ### ++if [ -f ${config_directory}/custom.cfg ]; then ++ source ${config_directory}/custom.cfg ++elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then ++ source $prefix/custom.cfg; ++fi ++### END /etc/grub.d/41_custom ### +diff --git a/test/results/add/g2-1.23 b/test/results/add/g2-1.23 +new file mode 100644 +index 0000000..c3e87cf +--- /dev/null ++++ b/test/results/add/g2-1.23 +@@ -0,0 +1,144 @@ ++# ++# DO NOT EDIT THIS FILE ++# ++# It is automatically generated by grub2-mkconfig using templates ++# from /etc/grub.d and settings from /etc/default/grub ++# ++ ++### BEGIN /etc/grub.d/00_header ### ++set pager=1 ++ ++if [ -s $prefix/grubenv ]; then ++ load_env ++fi ++if [ "${next_entry}" ] ; then ++ set default="${next_entry}" ++ set next_entry= ++ save_env next_entry ++ set boot_once=true ++else ++ set default="${saved_entry}" ++fi ++ ++if [ x"${feature_menuentry_id}" = xy ]; then ++ menuentry_id_option="--id" ++else ++ menuentry_id_option="" ++fi ++ ++export menuentry_id_option ++ ++if [ "${prev_saved_entry}" ]; then ++ set saved_entry="${prev_saved_entry}" ++ save_env saved_entry ++ set prev_saved_entry= ++ save_env prev_saved_entry ++ set boot_once=true ++fi ++ ++function savedefault { ++ if [ -z "${boot_once}" ]; then ++ saved_entry="${chosen}" ++ save_env saved_entry ++ fi ++} ++ ++function load_video { ++ if [ x$feature_all_video_module = xy ]; then ++ insmod all_video ++ else ++ insmod efi_gop ++ insmod efi_uga ++ insmod ieee1275_fb ++ insmod vbe ++ insmod vga ++ insmod video_bochs ++ insmod video_cirrus ++ fi ++} ++ ++terminal_output console ++if [ x$feature_timeout_style = xy ] ; then ++ set timeout_style=menu ++ set timeout=15 ++# Fallback normal timeout code in case the timeout_style feature is ++# unavailable. ++else ++ set timeout=15 ++fi ++### END /etc/grub.d/00_header ### ++ ++### BEGIN /etc/grub.d/10_linux ### ++menuentry 'title' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' --hint='hd1,msdos3' 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ else ++ search --no-floppy --fs-uuid --set=root 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ fi ++ linux16 /root4/boot/new-kernel.img root=UUID=54c6abc2-b1e7-4987-aa73-c79927be69eb ro rootflags=subvol=root4 rhgb quiet ++ initrd16 /root4/boot/new-initrd ++} ++menuentry 'Fedora, with Linux 3.15.0-0.rc7.git2.1.fc21.x86_64' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' --hint='hd1,msdos3' 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ else ++ search --no-floppy --fs-uuid --set=root 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ fi ++ linux16 /root4/boot/vmlinuz-3.15.0-0.rc7.git2.1.fc21.x86_64 root=UUID=54c6abc2-b1e7-4987-aa73-c79927be69eb ro rootflags=subvol=root4 rhgb quiet ++ initrd16 /root4/boot/initramfs-3.15.0-0.rc7.git2.1.fc21.x86_64.img ++} ++menuentry 'Fedora, with Linux 0-rescue-20e7024f4e9c4b70b1042b91acd434c6' --class gnu-linux --class gnu --class os { ++ load_video ++ insmod gzio ++ insmod part_msdos ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' --hint='hd1,msdos3' 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ else ++ search --no-floppy --fs-uuid --set=root 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ fi ++ linux16 /root4/boot/vmlinuz-0-rescue-20e7024f4e9c4b70b1042b91acd434c6 root=UUID=54c6abc2-b1e7-4987-aa73-c79927be69eb ro rootflags=subvol=root4 rhgb quiet ++ initrd16 /root4/boot/initramfs-0-rescue-20e7024f4e9c4b70b1042b91acd434c6.img ++} ++ ++### END /etc/grub.d/10_linux ### ++ ++### BEGIN /etc/grub.d/20_linux_xen ### ++ ++### END /etc/grub.d/20_linux_xen ### ++ ++### BEGIN /etc/grub.d/20_ppc_terminfo ### ++### END /etc/grub.d/20_ppc_terminfo ### ++ ++### BEGIN /etc/grub.d/30_os-prober ### ++### ++ ++### BEGIN /etc/grub.d/40_custom ### ++# This file provides an easy way to add custom menu entries. Simply type the ++# menu entries you want to add after this comment. Be careful not to change ++# the 'exec tail' line above. ++### END /etc/grub.d/40_custom ### ++ ++### BEGIN /etc/grub.d/41_custom ### ++if [ -f ${config_directory}/custom.cfg ]; then ++ source ${config_directory}/custom.cfg ++elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then ++ source $prefix/custom.cfg; ++fi ++### END /etc/grub.d/41_custom ### +diff --git a/test/results/add/g2-1.24 b/test/results/add/g2-1.24 +new file mode 100644 +index 0000000..c0dded9 +--- /dev/null ++++ b/test/results/add/g2-1.24 +@@ -0,0 +1,141 @@ ++# ++# DO NOT EDIT THIS FILE ++# ++# It is automatically generated by grub2-mkconfig using templates ++# from /etc/grub.d and settings from /etc/default/grub ++# ++ ++### BEGIN /etc/grub.d/00_header ### ++set pager=1 ++ ++if [ -s $prefix/grubenv ]; then ++ load_env ++fi ++if [ "${next_entry}" ] ; then ++ set default="${next_entry}" ++ set next_entry= ++ save_env next_entry ++ set boot_once=true ++else ++ set default="${saved_entry}" ++fi ++ ++if [ x"${feature_menuentry_id}" = xy ]; then ++ menuentry_id_option="--id" ++else ++ menuentry_id_option="" ++fi ++ ++export menuentry_id_option ++ ++if [ "${prev_saved_entry}" ]; then ++ set saved_entry="${prev_saved_entry}" ++ save_env saved_entry ++ set prev_saved_entry= ++ save_env prev_saved_entry ++ set boot_once=true ++fi ++ ++function savedefault { ++ if [ -z "${boot_once}" ]; then ++ saved_entry="${chosen}" ++ save_env saved_entry ++ fi ++} ++ ++function load_video { ++ if [ x$feature_all_video_module = xy ]; then ++ insmod all_video ++ else ++ insmod efi_gop ++ insmod efi_uga ++ insmod ieee1275_fb ++ insmod vbe ++ insmod vga ++ insmod video_bochs ++ insmod video_cirrus ++ fi ++} ++ ++terminal_output console ++if [ x$feature_timeout_style = xy ] ; then ++ set timeout_style=menu ++ set timeout=15 ++# Fallback normal timeout code in case the timeout_style feature is ++# unavailable. ++else ++ set timeout=15 ++fi ++### END /etc/grub.d/00_header ### ++ ++### BEGIN /etc/grub.d/10_linux ### ++menuentry 'title' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ else ++ search --no-floppy --fs-uuid --set=root 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ fi ++ linux16 /boot6/new-kernel.img root=UUID=1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ro rootflags=subvol=root6 rhgb quiet ++ initrd16 /boot6/new-initrd ++} ++menuentry 'Fedora, with Linux 3.15.0-0.rc7.git2.1.fc21.x86_64' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ else ++ search --no-floppy --fs-uuid --set=root 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ fi ++ linux16 /boot6/vmlinuz-3.15.0-0.rc7.git2.1.fc21.x86_64 root=UUID=1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ro rootflags=subvol=root6 rhgb quiet ++ initrd16 /boot6/initramfs-3.15.0-0.rc7.git2.1.fc21.x86_64.img ++} ++menuentry 'Fedora, with Linux 0-rescue-81378818f7a24478b496ebef90e1dd69' --class gnu-linux --class gnu --class os { ++ load_video ++ insmod gzio ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ else ++ search --no-floppy --fs-uuid --set=root 1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ++ fi ++ linux16 /boot6/vmlinuz-0-rescue-81378818f7a24478b496ebef90e1dd69 root=UUID=1bab15a4-93ce-4373-8d7d-b77f907fd0c6 ro rootflags=subvol=root6 rhgb quiet ++ initrd16 /boot6/initramfs-0-rescue-81378818f7a24478b496ebef90e1dd69.img ++} ++ ++### END /etc/grub.d/10_linux ### ++ ++### BEGIN /etc/grub.d/20_linux_xen ### ++ ++### END /etc/grub.d/20_linux_xen ### ++ ++### BEGIN /etc/grub.d/20_ppc_terminfo ### ++### END /etc/grub.d/20_ppc_terminfo ### ++ ++### BEGIN /etc/grub.d/30_os-prober ### ++### END /etc/grub.d/30_os-prober ### ++ ++### BEGIN /etc/grub.d/40_custom ### ++# This file provides an easy way to add custom menu entries. Simply type the ++# menu entries you want to add after this comment. Be careful not to change ++# the 'exec tail' line above. ++### END /etc/grub.d/40_custom ### ++ ++### BEGIN /etc/grub.d/41_custom ### ++if [ -f ${config_directory}/custom.cfg ]; then ++ source ${config_directory}/custom.cfg ++elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then ++ source $prefix/custom.cfg; ++fi ++### END /etc/grub.d/41_custom ### +diff --git a/test/results/add/g2-1.25 b/test/results/add/g2-1.25 +new file mode 100644 +index 0000000..c3e87cf +--- /dev/null ++++ b/test/results/add/g2-1.25 +@@ -0,0 +1,144 @@ ++# ++# DO NOT EDIT THIS FILE ++# ++# It is automatically generated by grub2-mkconfig using templates ++# from /etc/grub.d and settings from /etc/default/grub ++# ++ ++### BEGIN /etc/grub.d/00_header ### ++set pager=1 ++ ++if [ -s $prefix/grubenv ]; then ++ load_env ++fi ++if [ "${next_entry}" ] ; then ++ set default="${next_entry}" ++ set next_entry= ++ save_env next_entry ++ set boot_once=true ++else ++ set default="${saved_entry}" ++fi ++ ++if [ x"${feature_menuentry_id}" = xy ]; then ++ menuentry_id_option="--id" ++else ++ menuentry_id_option="" ++fi ++ ++export menuentry_id_option ++ ++if [ "${prev_saved_entry}" ]; then ++ set saved_entry="${prev_saved_entry}" ++ save_env saved_entry ++ set prev_saved_entry= ++ save_env prev_saved_entry ++ set boot_once=true ++fi ++ ++function savedefault { ++ if [ -z "${boot_once}" ]; then ++ saved_entry="${chosen}" ++ save_env saved_entry ++ fi ++} ++ ++function load_video { ++ if [ x$feature_all_video_module = xy ]; then ++ insmod all_video ++ else ++ insmod efi_gop ++ insmod efi_uga ++ insmod ieee1275_fb ++ insmod vbe ++ insmod vga ++ insmod video_bochs ++ insmod video_cirrus ++ fi ++} ++ ++terminal_output console ++if [ x$feature_timeout_style = xy ] ; then ++ set timeout_style=menu ++ set timeout=15 ++# Fallback normal timeout code in case the timeout_style feature is ++# unavailable. ++else ++ set timeout=15 ++fi ++### END /etc/grub.d/00_header ### ++ ++### BEGIN /etc/grub.d/10_linux ### ++menuentry 'title' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' --hint='hd1,msdos3' 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ else ++ search --no-floppy --fs-uuid --set=root 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ fi ++ linux16 /root4/boot/new-kernel.img root=UUID=54c6abc2-b1e7-4987-aa73-c79927be69eb ro rootflags=subvol=root4 rhgb quiet ++ initrd16 /root4/boot/new-initrd ++} ++menuentry 'Fedora, with Linux 3.15.0-0.rc7.git2.1.fc21.x86_64' --class gnu-linux --class gnu --class os { ++ load_video ++ set gfxpayload=keep ++ insmod gzio ++ insmod part_msdos ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' --hint='hd1,msdos3' 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ else ++ search --no-floppy --fs-uuid --set=root 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ fi ++ linux16 /root4/boot/vmlinuz-3.15.0-0.rc7.git2.1.fc21.x86_64 root=UUID=54c6abc2-b1e7-4987-aa73-c79927be69eb ro rootflags=subvol=root4 rhgb quiet ++ initrd16 /root4/boot/initramfs-3.15.0-0.rc7.git2.1.fc21.x86_64.img ++} ++menuentry 'Fedora, with Linux 0-rescue-20e7024f4e9c4b70b1042b91acd434c6' --class gnu-linux --class gnu --class os { ++ load_video ++ insmod gzio ++ insmod part_msdos ++ insmod part_msdos ++ insmod btrfs ++ set root='hd0,msdos1' ++ if [ x$feature_platform_search_hint = xy ]; then ++ search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' --hint='hd1,msdos3' 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ else ++ search --no-floppy --fs-uuid --set=root 54c6abc2-b1e7-4987-aa73-c79927be69eb ++ fi ++ linux16 /root4/boot/vmlinuz-0-rescue-20e7024f4e9c4b70b1042b91acd434c6 root=UUID=54c6abc2-b1e7-4987-aa73-c79927be69eb ro rootflags=subvol=root4 rhgb quiet ++ initrd16 /root4/boot/initramfs-0-rescue-20e7024f4e9c4b70b1042b91acd434c6.img ++} ++ ++### END /etc/grub.d/10_linux ### ++ ++### BEGIN /etc/grub.d/20_linux_xen ### ++ ++### END /etc/grub.d/20_linux_xen ### ++ ++### BEGIN /etc/grub.d/20_ppc_terminfo ### ++### END /etc/grub.d/20_ppc_terminfo ### ++ ++### BEGIN /etc/grub.d/30_os-prober ### ++### ++ ++### BEGIN /etc/grub.d/40_custom ### ++# This file provides an easy way to add custom menu entries. Simply type the ++# menu entries you want to add after this comment. Be careful not to change ++# the 'exec tail' line above. ++### END /etc/grub.d/40_custom ### ++ ++### BEGIN /etc/grub.d/41_custom ### ++if [ -f ${config_directory}/custom.cfg ]; then ++ source ${config_directory}/custom.cfg ++elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then ++ source $prefix/custom.cfg; ++fi ++### END /etc/grub.d/41_custom ### +-- +2.14.3 + diff --git a/0004-Honor-sbindir.patch b/0004-Honor-sbindir.patch new file mode 100644 index 0000000..5a2c5cf --- /dev/null +++ b/0004-Honor-sbindir.patch @@ -0,0 +1,36 @@ +From a56df998177574ef2db332220c15f11bccd98f7e Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Wed, 18 Jul 2018 13:41:02 -0400 +Subject: [PATCH] Honor sbindir + +Signed-off-by: Peter Jones +--- + Makefile | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/Makefile b/Makefile +index ac144046133..2b18dd6404b 100644 +--- a/Makefile ++++ b/Makefile +@@ -42,14 +42,14 @@ test: all + @./test.sh + + install: all +- mkdir -p $(DESTDIR)$(PREFIX)/sbin ++ mkdir -p $(DESTDIR)$(PREFIX)$(sbindir) + mkdir -p $(DESTDIR)/$(mandir)/man8 +- install -m 755 new-kernel-pkg $(DESTDIR)$(PREFIX)/sbin ++ install -m 755 new-kernel-pkg $(DESTDIR)$(PREFIX)$(sbindir) + install -m 644 new-kernel-pkg.8 $(DESTDIR)/$(mandir)/man8 +- install -m 755 installkernel $(DESTDIR)$(PREFIX)/sbin ++ install -m 755 installkernel $(DESTDIR)$(PREFIX)$(sbindir) + install -m 644 installkernel.8 $(DESTDIR)/$(mandir)/man8 + if [ -f grubby ]; then \ +- install -m 755 grubby $(DESTDIR)$(PREFIX)/sbin ; \ ++ install -m 755 grubby $(DESTDIR)$(PREFIX)$(sbindir) ; \ + install -m 644 grubby.8 $(DESTDIR)/$(mandir)/man8 ; \ + fi + +-- +2.17.1 + diff --git a/0005-installkernel-use-kernel-install.patch b/0005-installkernel-use-kernel-install.patch new file mode 100644 index 0000000..2ec577d --- /dev/null +++ b/0005-installkernel-use-kernel-install.patch @@ -0,0 +1,48 @@ +From f93a35be5bdec17044dd2a17980689d3cbf73d58 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Tue, 31 Jul 2018 17:43:53 +0200 +Subject: [PATCH] Make installkernel to use kernel-install scripts on BLS + configuration + +The kernel make install target executes the arch/$ARCH/boot/install.sh +that in turns executes the distro specific installkernel script. This +script always uses new-kernel-pkg to install the kernel images. + +But on a BootLoaderSpec setup, the kernel-install scripts must be used +instead. Check if the system uses a BLS setup, and call kernel-install +add in that case instead of new-kernel-pkg. + +Reported-by: Hans de Goede +Signed-off-by: Javier Martinez Canillas +--- + installkernel | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/installkernel b/installkernel +index b887929c179..68dcfac16d2 100755 +--- a/installkernel ++++ b/installkernel +@@ -20,6 +20,8 @@ + # Author(s): tyson@rwii.com + # + ++[[ -f /etc/default/grub ]] && . /etc/default/grub ++ + usage() { + echo "Usage: `basename $0` " >&2 + exit 1 +@@ -77,6 +79,11 @@ cp $MAPFILE $INSTALL_PATH/System.map-$KERNEL_VERSION + ln -fs ${RELATIVE_PATH}$INSTALL_PATH/$KERNEL_NAME-$KERNEL_VERSION $LINK_PATH/$KERNEL_NAME + ln -fs ${RELATIVE_PATH}$INSTALL_PATH/System.map-$KERNEL_VERSION $LINK_PATH/System.map + ++if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ] || [ ! -f /sbin/new-kernel-pkg ]; then ++ kernel-install add $KERNEL_VERSION $INSTALL_PATH/$KERNEL_NAME-$KERNEL_VERSION ++ exit $? ++fi ++ + if [ -n "$cfgLoader" ] && [ -x /sbin/new-kernel-pkg ]; then + if [ -n "$(which dracut 2>/dev/null)" ]; then + new-kernel-pkg --mkinitrd --dracut --host-only --depmod --install --kernel-name $KERNEL_NAME $KERNEL_VERSION +-- +2.17.1 + diff --git a/grubby-bls b/grubby-bls new file mode 100755 index 0000000..d94415f --- /dev/null +++ b/grubby-bls @@ -0,0 +1,616 @@ +#!/bin/bash +# +# grubby wrapper to manage BootLoaderSpec files +# +# +# Copyright 2018 Red Hat, Inc. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +readonly SCRIPTNAME="${0##*/}" + +CMDLINE_LINUX_DEBUG=" systemd.log_level=debug systemd.log_target=kmsg" +LINUX_DEBUG_VERSION_POSTFIX="_with_debugging" +LINUX_DEBUG_TITLE_POSTFIX=" with debugging" + +declare -a bls_file +declare -a bls_title +declare -a bls_version +declare -a bls_linux +declare -a bls_initrd +declare -a bls_options +declare -a bls_id + +[[ -f /etc/sysconfig/kernel ]] && . /etc/sysconfig/kernel +[[ -f /etc/os-release ]] && . /etc/os-release +read MACHINE_ID < /etc/machine-id +arch=$(uname -m) + +if [[ $arch = 's390' || $arch = 's390x' ]]; then + bootloader="zipl" +else + bootloader="grub2" +fi + +print_error() { + echo "$1" >&2 + exit 1 +} + +if [[ ${#} = 0 ]]; then + print_error "no action specified" +fi + +get_bls_value() { + local bls="$1" && shift + local key="$1" && shift + + echo "$(grep "^${key}[ \t]" "${bls}" | sed -e "s,^${key}[ \t]*,,")" +} + +set_bls_value() { + local bls="$1" && shift + local key="$1" && shift + local value="$1" && shift + + sed -i -e "s,^${key}.*,${key} ${value}," "${bls}" +} + +append_bls_value() { + local bls="$1" && shift + local key="$1" && shift + local value="$1" && shift + + old_value="$(get_bls_value ${bls} ${key})" + set_bls_value "${bls}" "${key}" "${old_value}${value}" +} + +get_bls_values() { + count=0 + for bls in $(ls -vr ${blsdir}/*.conf 2> /dev/null); do + bls_file[$count]="${bls}" + bls_title[$count]="$(get_bls_value ${bls} title)" + bls_version[$count]="$(get_bls_value ${bls} version)" + bls_linux[$count]="$(get_bls_value ${bls} linux)" + bls_initrd[$count]="$(get_bls_value ${bls} initrd)" + bls_options[$count]="$(get_bls_value ${bls} options)" + bls_id[$count]="$(get_bls_value ${bls} id)" + + count=$((count+1)) + done +} + +get_default_index() { + local default="" + local index="-1" + local title="" + local version="" + if [[ $bootloader = "grub2" ]]; then + default="$(grep '^saved_entry=' ${env} | sed -e 's/^saved_entry=//')" + else + default="$(grep '^default=' ${zipl_config} | sed -e 's/^default=//')" + fi + + if [[ -z $default ]]; then + index=0 + elif [[ $default =~ ^[0-9]+$ ]]; then + index="$default" + fi + + # GRUB2 and zipl use different fields to set the default entry + if [[ $bootloader = "grub2" ]]; then + title="$default" + else + version="$default" + fi + + for i in ${!bls_file[@]}; do + if [[ $title = ${bls_title[$i]} || $version = ${bls_version[$i]} || + $i -eq $index ]]; then + echo $i + return + fi + done +} + +display_default_value() { + case "$display_default" in + kernel) + echo "${bls_linux[$default_index]}" + exit 0 + ;; + index) + echo "$default_index" + exit 0 + ;; + title) + echo "${bls_title[$default_index]}" + exit 0 + ;; + esac +} + +param_to_indexes() { + local param="$1" + local indexes="" + + if [[ $param = "ALL" ]]; then + for i in ${!bls_file[@]}; do + indexes="$indexes $i" + done + echo -n $indexes + return + fi + + if [[ $param = "DEFAULT" ]]; then + echo -n $default_index + return + fi + + for i in ${!bls_file[@]}; do + if [[ $param = "${bls_linux[$i]}" ]]; then + indexes="$indexes $i" + fi + + if [[ $param = "TITLE=${bls_title[$i]}" ]]; then + indexes="$indexes $i" + fi + + if [[ $param = $i ]]; then + indexes="$indexes $i" + fi + done + + if [[ -n $indexes ]]; then + echo -n $indexes + return + fi + + echo -n "-1" +} + +display_info_values() { + local indexes=($(param_to_indexes "$1")) + + for i in ${indexes[*]}; do + echo "index=$i" + echo "kernel=${bls_linux[$i]}" + echo "args=\"${bls_options[$i]}\"" + echo "initrd=${bls_initrd[$i]}" + echo "title=${bls_title[$i]}" + done + exit 0 +} + +mkbls() { + local kernel=$1 && shift + local kernelver=$1 && shift + local datetime=$1 && shift + + local debugname="" + local flavor="" + + if [[ $kernelver == *\+* ]] ; then + local flavor=-"${kernelver##*+}" + if [[ $flavor == "-debug" ]]; then + local debugname="with debugging" + local debugid="-debug" + fi + fi + + cat < "${bls_target}" + fi + + if [[ -n $title ]]; then + set_bls_value "${bls_target}" "title" "${title}" + fi + + if [[ -n $options ]]; then + set_bls_value "${bls_target}" "options" "${options}" + fi + + if [[ -n $initrd ]]; then + set_bls_value "${bls_target}" "initrd" "${initrd}" + fi + + if [[ -n $extra_initrd ]]; then + append_bls_value "${bls_target}" "initrd" "${extra_initrd}" + fi + + if [[ $MAKEDEBUG = "yes" ]]; then + arch="$(uname -m)" + bls_debug="$(echo ${bls_target} | sed -e "s/\.${arch}/-debug.${arch}/")" + cp -aT "${bls_target}" "${bls_debug}" + append_bls_value "${bls_debug}" "title" "${LINUX_DEBUG_TITLE_POSTFIX}" + append_bls_value "${bls_debug}" "version" "${LINUX_DEBUG_VERSION_POSTFIX}" + append_bls_value "${bls_debug}" "options" "${CMDLINE_LINUX_DEBUG}" + blsid="$(get_bls_value ${bls_debug} "id" | sed -e "s/\.${arch}/-debug.${arch}/")" + set_bls_value "${bls_debug}" "id" "${blsid}" + fi + + get_bls_values + + if [[ $make_default = "true" ]]; then + set_default_bls "TITLE=${title}" + fi + + exit 0 +} + +update_args() { + local args=$1 && shift + local remove_args=($1) && shift + local add_args=($1) && shift + + for arg in ${remove_args[*]}; do + args="$(echo $args | sed -e "s,$arg[^ ]*,,")" + done + + for arg in ${add_args[*]}; do + if [[ $arg = *"="* ]]; then + value=${arg##*=} + key=${arg%%=$value} + exist=$(echo $args | grep "${key}=") + if [[ -n $exist ]]; then + args="$(echo $args | sed -e "s,$key=[^ ]*,$key=$value,")" + else + args="$args $key=$value" + fi + else + exist=$(echo $args | grep $arg) + if ! [[ -n $exist ]]; then + args="$args $arg" + fi + fi + done + + echo ${args} +} + +update_bls_fragment() { + local indexes=($(param_to_indexes "$1")) && shift + local remove_args=$1 && shift + local add_args=$1 && shift + local initrd=$1 && shift + + for i in ${indexes[*]}; do + if [[ -n $remove_args || -n $add_args ]]; then + local new_args="$(update_args "${bls_options[$i]}" "${remove_args}" "${add_args}")" + set_bls_value "${bls_file[$i]}" "options" "${new_args}" + fi + + if [[ -n $initrd ]]; then + set_bls_value "${bls_file[$i]}" "initrd" "${initrd}" + fi + done +} + +set_default_bls() { + local index=($(param_to_indexes "$1")) + + if [[ $bootloader = grub2 ]]; then + grub2-editenv "${env}" set saved_entry="${bls_title[$index]}" + else + local default="${bls_version[$index]}" + local current="$(grep '^default=' ${zipl_config} | sed -e 's/^default=//')" + if [[ -n $current ]]; then + sed -i -e "s,^default=.*,default=${default}," "${zipl_config}" + else + echo "default=${default}" >> "${zipl_config}" + fi + fi +} + +remove_var_prefix() { + if [[ -n $remove_kernel && $remove_kernel =~ ^/ ]]; then + remove_kernel="/${remove_kernel##*/}" + fi + + if [[ -n $initrd ]]; then + initrd="/${initrd##*/}" + fi + + if [[ -n $extra_initrd ]]; then + extra_initrd=" /${extra_initrd##*/}" + fi + + if [[ -n $kernel ]]; then + kernel="/${kernel##*/}" + fi + + if [[ -n $update_kernel && $update_kernel =~ ^/ ]]; then + update_kernel="/${update_kernel##*/}" + fi +} + +print_usage() +{ + cat <&2 + echo "Try '${SCRIPTNAME} --help' to list supported options" >&2 + echo + exit 1 + ;; + --) + shift + break + ;; + *) + echo + echo "${SCRIPTNAME}: invalid option \"${1}\"" >&2 + echo "Try '${SCRIPTNAME} --help' for more information" >&2 + echo + exit 1 + ;; + esac + shift +done + +if [[ -z $blsdir ]]; then + blsdir="/boot/loader/entries" +fi + +if [[ -z $env ]]; then + env="/boot/grub2/grubenv" +fi + +if [[ -z $zipl_config ]]; then + zipl_config="/etc/zipl.conf" +fi + +get_bls_values + +default_index="$(get_default_index)" + +if [[ -n $display_default ]]; then + display_default_value +fi + +if [[ -n $display_info ]]; then + display_info_values "${display_info}" +fi + +if [[ $bootloader = grub2 ]]; then + remove_var_prefix +fi + +if [[ -n $kernel ]]; then + if [[ $copy_default = "true" ]]; then + opts="${bls_options[$default_index]}" + if [[ -n $args ]]; then + opts="${opts} ${args}" + fi + else + opts="${args}" + fi + + add_bls_fragment "${kernel}" "${title}" "${opts}" "${initrd}" \ + "${extra_initrd}" +fi + +if [[ -n $remove_kernel ]]; then + remove_bls_fragment "${remove_kernel}" +fi + +if [[ -n $update_kernel ]]; then + update_bls_fragment "${update_kernel}" "${remove_args}" "${args}" "${initrd}" +fi + +if [[ -n $set_default ]]; then + set_default_bls "${set_default}" +fi + +exit 0 diff --git a/grubby.in b/grubby.in new file mode 100644 index 0000000..f0036e9 --- /dev/null +++ b/grubby.in @@ -0,0 +1,8 @@ +#!/bin/bash +if [[ -x @@LIBEXECDIR@@/grubby-bls ]] ; then + exec @@LIBEXECDIR@@/grubby-bls "${@}" +elif [[ -x @@LIBEXECDIR@@/grubby ]] ; then + exec @@LIBEXECDIR@@/grubby "${@}" +fi +echo "Grubby is not installed correctly." >>/dev/stderr +exit 1 diff --git a/grubby.spec b/grubby.spec index e70b911..d40677c 100644 --- a/grubby.spec +++ b/grubby.spec @@ -1,6 +1,6 @@ Name: grubby Version: 8.40 -Release: 9%{?dist} +Release: 16%{?dist} Summary: Command line tool for updating bootloader configs License: GPLv2+ URL: https://github.com/rhinstaller/grubby @@ -9,15 +9,24 @@ URL: https://github.com/rhinstaller/grubby # git archive --format=tar --prefix=grubby-%%{version}/ HEAD |bzip2 > grubby-%%{version}.tar.bz2 # Source0: %%{name}-%%{version}.tar.bz2 Source0: https://github.com/rhboot/grubby/archive/%{version}-1.tar.gz +Source1: grubby-bls +Source2: grubby.in +Source3: installkernel.in Patch1: drop-uboot-uImage-creation.patch +Patch2: 0001-Change-return-type-in-getRootSpecifier.patch +Patch3: 0002-Add-btrfs-subvolume-support-for-grub2.patch +Patch4: 0003-Add-tests-for-btrfs-support.patch +Patch5: 0004-Honor-sbindir.patch +Patch6: 0005-installkernel-use-kernel-install.patch BuildRequires: pkgconfig glib2-devel popt-devel -BuildRequires: libblkid-devel git-core +BuildRequires: libblkid-devel git-core sed gcc make # for make test / getopt: BuildRequires: util-linux-ng %ifarch aarch64 i686 x86_64 %{power64} BuildRequires: grub2-tools-minimal Requires: grub2-tools-minimal +Requires: grub2-tools %endif %ifarch s390 s390x Requires: s390utils-base @@ -30,6 +39,8 @@ and zipl (s390) boot loaders. It is primarily designed to be used from scripts which install new kernels and need to find information about the current boot environment. +%global debug_package %{nil} + %prep %setup -q -n grubby-%{version}-1 @@ -51,17 +62,68 @@ make test %endif %install -make install DESTDIR=$RPM_BUILD_ROOT mandir=%{_mandir} +make install DESTDIR=$RPM_BUILD_ROOT mandir=%{_mandir} sbindir=%{_sbindir} + +mkdir -p %{buildroot}%{_libexecdir}/{grubby,installkernel}/ %{buildroot}%{_sbindir}/ +mv -v %{buildroot}%{_sbindir}/grubby %{buildroot}%{_libexecdir}/grubby/grubby +mv -v %{buildroot}%{_sbindir}/installkernel %{buildroot}%{_libexecdir}/installkernel/installkernel +cp -v %{SOURCE1} %{buildroot}%{_libexecdir}/grubby/ +sed -e "s,@@LIBEXECDIR@@,%{_libexecdir}/grubby,g" %{SOURCE2} \ + > %{buildroot}%{_sbindir}/grubby +sed -e "s,@@LIBEXECDIR@@,%{_libexecdir}/installkernel,g" %{SOURCE3} \ + > %{buildroot}%{_sbindir}/installkernel + +%package bls +Summary: Command line tool for updating BootLoaderSpec files +Conflicts: %{name} <= 8.40-13 +BuildArch: noarch + +%description bls +This package provides a grubby wrapper that manages BootLoaderSpec files and is +meant to only be used for legacy compatibility users with existing grubby users. %files %{!?_licensedir:%global license %%doc} %license COPYING -/sbin/installkernel -/sbin/new-kernel-pkg -/sbin/grubby +%dir %{_libexecdir}/grubby +%attr(0755,root,root) %{_libexecdir}/grubby/grubby +%dir %{_libexecdir}/installkernel +%attr(0755,root,root) %{_libexecdir}/installkernel/installkernel +%attr(0755,root,root) %{_sbindir}/grubby +%attr(0755,root,root) %{_sbindir}/installkernel +%attr(0755,root,root) %{_sbindir}/new-kernel-pkg +%{_mandir}/man8/*.8* + +%files bls +%{!?_licensedir:%global license %%doc} +%license COPYING +%dir %{_libexecdir}/grubby +%attr(0755,root,root) %{_libexecdir}/grubby/grubby-bls +%attr(0755,root,root) %{_sbindir}/grubby %{_mandir}/man8/*.8* %changelog +* Fri Aug 03 2018 Javier Martinez Canillas - 8.40-16 +- Make installkernel to use kernel-install scripts on BLS configuration + +* Tue Jul 24 2018 Javier Martinez Canillas - 8.40-15 +- Fix grubby wrapper paths + +* Tue Jul 24 2018 Peter Jones - 8.40-14 +- Fix permissions on /usr/sbin/grubby + +* Fri Jul 13 2018 Javier Martinez Canillas - 8.40-13 +- Add a grubby-bls package that conflicts with grubby + +* Tue Apr 10 2018 Javier Martinez Canillas - 8.40-12 +- Use .rpmsave as backup suffix when switching to BLS configuration + +* Fri Apr 06 2018 Javier Martinez Canillas - 8.40-11 +- Switch grub2 config to BLS configuration on %%postun + +* Sat Mar 03 2018 Nathaniel McCallum - 8.40-10 +- Add support for /boot on btrfs subvolumes + * Wed Feb 07 2018 Fedora Release Engineering - 8.40-9 - Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild diff --git a/installkernel.in b/installkernel.in new file mode 100644 index 0000000..87b81ee --- /dev/null +++ b/installkernel.in @@ -0,0 +1,8 @@ +#!/bin/bash +if [[ -x @@LIBEXECDIR@@/installkernel ]] ; then + exec @@LIBEXECDIR@@/installkernel "${@}" +elif [[ -x @@LIBEXECDIR@@/installkernel-bls ]] ; then + exec @@LIBEXECDIR@@/installkernel-bls "${@}" +fi +echo "installkernel is not installed correctly." >>/dev/stderr +exit 1