Compare commits

...

3 Commits
master ... f27

Author SHA1 Message Date
Nathaniel McCallum 1bff09db51 Add support for /boot on btrfs 2018-03-21 11:12:23 -04:00
Peter Jones 9348c3a907 Actually require grub2-tools-minimal, which has grub2-editenv in it.
Signed-off-by: Peter Jones <pjones@redhat.com>
2017-09-12 10:07:10 -04:00
Peter Jones 9a7c3c8860 Cleanup deps for new grub2 packaging.
- Explicitly require grub2-tools on platforms that need grub2-editenv
- Minor packaging cleanups

Signed-off-by: Peter Jones <pjones@redhat.com>
2017-09-12 09:34:38 -04:00
6 changed files with 2243 additions and 7 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
grubby-*.tar.bz2
clog
*.rpm
/8.40-1.tar.gz

View File

@ -0,0 +1,143 @@
From c1c46d21182974181f5b4c2ed0a02288b4bfd880 Mon Sep 17 00:00:00 2001
From: Nathaniel McCallum <npmccallum@redhat.com>
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

View File

@ -0,0 +1,209 @@
From 5dec033b19bb5b07a0a136a7357e16c8ca9f5dd6 Mon Sep 17 00:00:00 2001
From: Nathaniel McCallum <npmccallum@redhat.com>
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

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,18 @@
Name: grubby
Version: 8.40
Release: 6%{?dist}
Release: 8%{?dist}
Summary: Command line tool for updating bootloader configs
Group: System Environment/Base
License: GPLv2+
URL: https://github.com/rhinstaller/grubby
# we only pull git snaps at the moment
# git clone git@github.com:rhinstaller/grubby.git
# git archive --format=tar --prefix=grubby-%{version}/ HEAD |bzip2 > grubby-%{version}.tar.bz2
Source0: %{name}-%{version}.tar.bz2
# 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
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
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: pkgconfig glib2-devel popt-devel
@ -16,7 +20,8 @@ BuildRequires: libblkid-devel git
# for make test / getopt:
BuildRequires: util-linux-ng
%ifarch aarch64 i686 x86_64 ppc ppc64
BuildRequires: /usr/bin/grub2-editenv
BuildRequires: grub2-tools-minimal
Requires: grub2-tools-minimal
%endif
%ifarch s390 s390x
Requires: s390utils-base
@ -33,7 +38,7 @@ which install new kernels and need to find information about the current boot
environment.
%prep
%setup -q
%setup -q -n grubby-%{version}-1
git init
git config user.email "noone@example.com"
@ -79,6 +84,13 @@ rm -rf $RPM_BUILD_ROOT
%endif
%changelog
* Wed Mar 21 2018 Nathaniel McCallum <npmccallum@redhat.com> - 8.40-8
- Add support for /boot on btrfs subvolumes
* Tue Sep 12 2017 Peter Jones <pjones@redhat.com> - 8.40-7
- Explicitly require grub2-tools on platforms that need grub2-editenv
- Minor packaging cleanups
* Wed Aug 02 2017 Fedora Release Engineering <releng@fedoraproject.org> - 8.40-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
@ -411,7 +423,7 @@ rm -rf $RPM_BUILD_ROOT
Resolves: rhbz#520515
* Wed Sep 09 2009 Hans de Goede <hdegoede@redhat.com> - 7.0.4-1
- Add --dracut cmdline argument for %post generation of dracut initrd
- Add --dracut cmdline argument for %%post generation of dracut initrd
* Wed Aug 26 2009 Hans de Goede <hdegoede@redhat.com> - 7.0.3-1
- Silence error when no /etc/sysconfig/keyboard (#517187)

View File

@ -1 +1 @@
bcad3c0dc804c4f526374616c1154469 grubby-8.40.tar.bz2
SHA512 (8.40-1.tar.gz) = 956ea6ccec2e7285fc8ebbf1d7659c4f41b1e9eda913d99a9712af9103144a13e66e93dce4c089b64ab370d1fed63656e922eafb88a0a39f843a6a6d166f72c5