Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 907052 Details for
Bug 1094489
add support for btrfs in grub2 on /boot
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
v2.2 add support for btrfs when grub2 is bootloader
0002-v2.2-add-support-for-btrfs-when-grub2-is-bootloader.patch (text/plain), 11.63 KB, created by
Gene Czarcinski
on 2014-06-10 07:10:22 UTC
(
hide
)
Description:
v2.2 add support for btrfs when grub2 is bootloader
Filename:
MIME Type:
Creator:
Gene Czarcinski
Created:
2014-06-10 07:10:22 UTC
Size:
11.63 KB
patch
obsolete
>From 0d6b4afd45355d363253c73ca375263e1f9ba80e Mon Sep 17 00:00:00 2001 >From: Gene Czarcinski <gczarcinski@gmail.com> >Date: Tue, 10 Jun 2014 02:59:22 -0400 >Subject: [PATCH 2/5] v2.2 add support for btrfs when grub2 is bootloader >Content-Type: text/plain; charset="utf-8" >Content-Transfer-Encoding: 8bit > >This patch adds getSubvolPrefix() for handling a btrfs subvol >prefix on the filenames for grub2. If get_Root_Specifier() results >in a NULL rootspec, then getSubvolPrefix() is executed to extract any >btrfs subvol prefix. With this modification, booting off >/boot on a btrfs subvol is supported. > >To determine if booting is to be performed off a btrfs volume >or subvolume, the lines of the entry are scanned to detect >if "insmod btrfs" is present. If it is, then btrfs is assumed. > >If the kernel filename includes only one slash, then there is >no btrfs prefix. Otherwise, the first part defined by "/../" >will be the btrfs prefix if booting btrfs. Unless, of course, >there are 2 slashes in the filename but bootPrefix is zero length >in which case we are booting off a btrfs volume! > >Besides the kernel, the subvol prefix must also be on the >initrd filename. The subvol prefix for initrd is based on >the entry's kernel's filename. Note that the lines of >the entry must be scanned to determine if we are booting on >btrfs. > >Code was added to addLine(tmpl() so that the subvol prefix not added >for an initrd since updateInitrd() does that already. >--- > grubby.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 124 insertions(+), 8 deletions(-) > >diff --git a/grubby.c b/grubby.c >index e47e97b..60d75b4 100644 >--- a/grubby.c >+++ b/grubby.c >@@ -690,6 +690,8 @@ static int lineWrite(FILE * out, struct singleLine * line, > static int getNextLine(char ** bufPtr, struct singleLine * line, > struct configFileInfo * cfi); > static char * getRootSpecifier(char * str); >+static char * getSubvolPrefix(struct singleLine * line, char * str); >+static char * findBootPrefix(void); > static void requote(struct singleLine *line, struct configFileInfo * cfi); > static void insertElement(struct singleLine * line, > const char * item, int insertHere, >@@ -1843,6 +1845,57 @@ static int endswith(const char *s, char c) > return s[slen] == c; > } > >+ >+/* extract any btrfs prefix on filename */ >+/* the passed string is elements[1] */ >+static char * getSubvolPrefix(struct singleLine * line, char * str) { >+ char *idx, *svPrefix = NULL; >+ int slashcnt = 0; >+ const char * bootPrefix = findBootPrefix(); >+ static int btrfsBootFlag = 0; >+ >+ if (btrfsBootFlag == 0){ >+ for (; line; line = line->next) { >+ dbgPrintf("checkForBtrfsBoot(%s)\n", >+ line->numElements >0 ? line->elements[0].item : ""); >+ if (line->numElements >1) { >+ if ((strcasecmp(line->elements[0].item,"insmod")==0) && >+ (strcasecmp(line->elements[1].item,"btrfs")==0)) { >+ dbgPrintf("NOTE: booting from a btrfs volume or subvolume\n"); >+ btrfsBootFlag = -1; >+ break; >+ } >+ } >+ } >+ } >+ >+ idx = str; >+ while (*idx) { >+ if (*idx == '/') >+ slashcnt++; >+ idx++; >+ } >+ >+ if ((btrfsBootFlag == 0) || >+ (slashcnt == 0) || >+ (slashcnt == 1)) >+ svPrefix = NULL; >+ >+ else if ((slashcnt == 2) && (strlen(bootPrefix) == 0)) >+ svPrefix = NULL; >+ >+ else if ((btrfsBootFlag == -1) && (*str == '/')) { >+ idx = svPrefix = strdup(str); >+ idx++; >+ while(*idx && (*idx != '/') && (!isspace(*idx))) idx++; >+ *idx = '\0'; /* strip off the second slash */ >+ } >+ dbgPrintf("getSubvolPrefix(): btrfsBootFlag=%i, slashcnt=%i, str='%s', bootPrefix='%s', svPrefix='%s'\n", >+ btrfsBootFlag, slashcnt, str, bootPrefix, svPrefix); >+ >+ return svPrefix; >+} >+ > int suitableImage(struct singleEntry * entry, const char * bootPrefix, > int skipRemoved, int flags) { > struct singleLine * line; >@@ -1873,14 +1926,21 @@ int suitableImage(struct singleEntry * entry, const char * bootPrefix, > return 1; > } > >+ dbgPrintf("suitableImage(), bootPrefix='%s', type='%s'\n", >+ bootPrefix, line->elements[0].item); > fullName = alloca(strlen(bootPrefix) + > strlen(line->elements[1].item) + 1); > rootspec = getRootSpecifier(line->elements[1].item); >+ if (rootspec == NULL) { >+ rootspec = getSubvolPrefix(entry->lines, line->elements[1].item); >+ } > int rootspec_offset = rootspec ? strlen(rootspec) : 0; > int hasslash = endswith(bootPrefix, '/') || > beginswith(line->elements[1].item + rootspec_offset, '/'); > sprintf(fullName, "%s%s%s", bootPrefix, hasslash ? "" : "/", > line->elements[1].item + rootspec_offset); >+ dbgPrintf("suitbleImage(): fullName='%s' root/subvol prefix='%s'\n", >+ fullName, (rootspec != NULL) ? rootspec : ""); > if (access(fullName, R_OK)) { > notSuitablePrintf(entry, 0, "access to %s failed\n", fullName); > return 0; >@@ -2052,11 +2112,17 @@ struct singleEntry * findEntryByPath(struct grubConfig * config, > if (line && line->type != LT_MENUENTRY && > line->numElements >= 2) { > rootspec = getRootSpecifier(line->elements[1].item); >+ if (rootspec == NULL) { >+ rootspec = getSubvolPrefix(entry->lines, line->elements[1].item); >+ } > if (!strcmp(line->elements[1].item + > ((rootspec != NULL) ? strlen(rootspec) : 0), > kernel + strlen(prefix))) > break; > } >+ if(line->type == LT_MENUENTRY) >+ dbgPrintf("findEntryByPath: got:'%s', wanted='%s'\n", >+ line->elements[1].item, kernel); > if(line->type == LT_MENUENTRY && > !strcmp(line->elements[1].item, kernel)) > break; >@@ -2201,7 +2267,7 @@ struct singleEntry * findTemplate(struct grubConfig * cfg, const char * prefix, > return NULL; > } > >-char * findBootPrefix(void) { >+static char * findBootPrefix(void) { > struct stat sb, sb2; > > stat("/", &sb); >@@ -2828,17 +2894,23 @@ 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) && (tmplLine->type & (LT_HYPER|LT_KERNEL|LT_KERNEL_EFI|LT_KERNEL_16))) { >+ rootspec = getSubvolPrefix(entry->lines, tmplLine->elements[1].item); >+ } > if (rootspec != NULL) { > free(newLine->elements[1].item); > newLine->elements[1].item = > sdupprintf("%s%s", rootspec, val); > } > } >+ dbgPrintf("addLineTmpl(%s), type= 0x%x '%s'\n", >+ newLine->elements[0].item, tmplLine->type, >+ newLine->elements[1].item); >+ } else { >+ dbgPrintf("addLineTmpl(%s), type= 0x%x\n", newLine->numElements ? >+ newLine->elements[0].item : "", tmplLine->type); > } > >- dbgPrintf("addLineTmpl(%s)\n", newLine->numElements ? >- newLine->elements[0].item : ""); >- > if (!entry->lines) { > /* first one on the list */ > entry->lines = newLine; >@@ -3357,23 +3429,40 @@ int addMBInitrd(struct grubConfig * cfg, const char *newMBKernel, > struct singleEntry * entry; > struct singleLine * line, * kernelLine, *endLine = NULL; > int index = 0; >+ char * svPrefix = NULL; >+ char * newInitrd = NULL; > > if (!image) return 0; >+ dbgPrintf("addMBInitrd(), image='%s', prefix='%s', initrd='%s'\n", >+ image, prefix, initrd); > > for (; (entry = findEntryByPath(cfg, newMBKernel, prefix, &index)); index++) { > kernelLine = getLineByType(LT_MBMODULE, entry->lines); > if (!kernelLine) continue; >+ dbgPrintf("... index=%i, kernel: %s '%s'\n", index, >+ kernelLine->elements[0].item, >+ kernelLine->elements[1].item); >+ svPrefix = getSubvolPrefix(entry->lines, kernelLine->elements[1].item); > > if (prefix) { > int prefixLen = strlen(prefix); > if (!strncmp(initrd, prefix, prefixLen)) > initrd += prefixLen; > } >+ if (svPrefix) { >+ newInitrd = alloca(strlen(svPrefix) + strlen(initrd) + 2); >+ strcpy(newInitrd, svPrefix); >+ strcat(newInitrd, initrd); >+ } else >+ newInitrd = (char *)initrd; >+ dbgPrintf("... updated initrd='%s'\n", newInitrd); > endLine = getLineByType(LT_ENTRY_END, entry->lines); > if (endLine) > removeLine(entry, endLine); > line = addLine(entry, cfg->cfi, preferredLineType(LT_MBMODULE,cfg->cfi), >- kernelLine->indent, initrd); >+ kernelLine->indent, newInitrd); >+ if (svPrefix) >+ free(svPrefix); > if (!line) > return 1; > if (endLine) { >@@ -3393,12 +3482,20 @@ int updateInitrd(struct grubConfig * cfg, const char * image, > struct singleEntry * entry; > struct singleLine * line, * kernelLine, *endLine = NULL; > int index = 0; >+ char * svPrefix = NULL; >+ char * newInitrd = NULL; > > if (!image) return 0; >+ dbgPrintf("updateInitrd(), image='%s', prefix='%s', initrd='%s'\n", >+ image, prefix, initrd); > > for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) { > kernelLine = getLineByType(LT_KERNEL|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines); > if (!kernelLine) continue; >+ dbgPrintf("... index=%i, kernel: %s '%s'\n", index, >+ kernelLine->elements[0].item, >+ kernelLine->elements[1].item); >+ svPrefix = getSubvolPrefix(entry->lines, kernelLine->elements[1].item); > > line = getLineByType(LT_INITRD|LT_INITRD_EFI|LT_INITRD_16, entry->lines); > if (line) >@@ -3408,6 +3505,13 @@ int updateInitrd(struct grubConfig * cfg, const char * image, > if (!strncmp(initrd, prefix, prefixLen)) > initrd += prefixLen; > } >+ if (svPrefix) { >+ newInitrd = alloca(strlen(svPrefix) + strlen(initrd) + 2); >+ strcpy(newInitrd, svPrefix); >+ strcat(newInitrd, initrd); >+ } else >+ newInitrd = (char *)initrd; >+ dbgPrintf("... updated initrd='%s'\n", newInitrd); > endLine = getLineByType(LT_ENTRY_END, entry->lines); > if (endLine) > removeLine(entry, endLine); >@@ -3425,7 +3529,9 @@ int updateInitrd(struct grubConfig * cfg, const char * image, > default: > lt = preferredLineType(LT_INITRD, cfg->cfi); > } >- line = addLine(entry, cfg->cfi, lt, kernelLine->indent, initrd); >+ line = addLine(entry, cfg->cfi, lt, kernelLine->indent, newInitrd); >+ if (svPrefix) >+ free(svPrefix); > if (!line) > return 1; > if (endLine) { >@@ -3790,6 +3896,7 @@ int addNewKernel(struct grubConfig * config, struct singleEntry * template, > struct singleLine * newLine = NULL, * tmplLine = NULL, * masterLine = NULL; > int needs; > char * chptr; >+ char * svPrefix = NULL; > > if (!newKernelPath) return 0; > >@@ -3885,6 +3992,8 @@ int addNewKernel(struct grubConfig * config, struct singleEntry * template, > newLine = addLineTmpl(new, tmplLine, newLine, > newKernelPath + strlen(prefix), config->cfi); > needs &= ~NEED_KERNEL; >+ /* save svPrefix in case we need to do initrd */ >+ svPrefix = getSubvolPrefix(new->lines, tmplLine->elements[1].item); > } > > } else if (tmplLine->type == LT_HYPER && >@@ -3962,9 +4071,16 @@ int addNewKernel(struct grubConfig * config, struct singleEntry * template, > needs &= ~NEED_INITRD; > } > } else if (needs & NEED_INITRD) { >- char *initrdVal; >+ char *initrdVal, *newInitrdVal = NULL; > initrdVal = getInitrdVal(config, prefix, tmplLine, newKernelInitrd, extraInitrds, extraInitrdCount); >- newLine = addLineTmpl(new, tmplLine, newLine, initrdVal, config->cfi); >+ if (svPrefix) { >+ newInitrdVal = alloca(strlen(svPrefix) + strlen(initrdVal)); >+ strcpy(newInitrdVal, svPrefix); >+ strcat(newInitrdVal, initrdVal); >+ } >+ else >+ newInitrdVal = initrdVal; >+ newLine = addLineTmpl(new, tmplLine, newLine, newInitrdVal, config->cfi); > free(initrdVal); > needs &= ~NEED_INITRD; > } >-- >1.9.3 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1094489
:
892670
|
892671
|
893044
|
893046
|
903279
|
903280
|
903281
|
903283
|
906996
|
906997
|
906998
| 907052