Skip to content

drydenp/grub2-pvinstall

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 

Repository files navigation

Table of Contents

Grub2 LVM PV install

This fork contains the code to install GRUB2 directly on a LVM "physical volume" in a partitionless disk.

That means you would have no partitions and ONLY a PV on that disk in the 2nd, 3rd or 4th sector of the disk. The second sector is the default for a PV so we can say that this patch enables installation of Grub2 into a PV that was created normally with an additional flag (--bootloaderareasize 1M, as detailed below) but in its default location.

Intro

This fork has the code sitting in the pvinstall branch of this repo. To checkout the code you must do:

  git clone https://github.com/drydenp/grub2-pvinstall.git
  cd grub2-pvinstall
  git checkout pvinstall

to get at it. This branch contains all code. To see the diff against the 'master' branch you must do:

  git diff upstream/master..pvinstall

after setting it up as detailed below.

Branches of this repo

 * master:    contains this readme
 * savannah:  contains the upstream sources       (not on GitHub)
 * pvinstall: contains the modifications          (on GitHub)

You will find below instructions on how to actually set this up for development or maintenance. This master branch that you see now contains only documentation and possibly scripts. savannah is going to be set to point to upstream/master. The pvinstall branch will contain the latest changes, notably rebased on top of "savannah" usually.

Normally "savannah" would be up to date with upstream master and contain no additional changes.

Status

Upstream Grub2 just released GRUB 2.02rc2 (five days ago, 15-03-2017) and I haven't updated this repo in a while. Ideally it should be up to date with remote GRUB but I don't know if it applies cleanly at this point. Once GRUB 2.02 is released I will definitely try to find some time to at least get this up to date again and see if it cleanly applies, and make sure it does.

Overview

This (little) project is aimed at ensuring that Grub can detect and make use of a LVM2 "Physical Volume" in which space Grub2 core boot loader can be installed. A LVM2 "Physical Volume" typically reserves the boot loader area (first sector of 512 bytes) for a boot loader and installs itself (the Physical Volume header) in the 2nd sector and beyond. A Physical Volume created with

  pvcreate <parameters> --bootloaderareasize 1M

is capable of having the GRUB2 core.img installed into it, that is to say that this extra space is needed for the installation of Grub.

The code below (I mean this repo) is intended to provide the necessary functionality for detecting and verifying and installing into this extra space.

This patch is still a work in progress (why else have this site) but I have not yet had enough time, patience, arduous labour, and help from the Grub2 team (most notably Andrei Borzenkov, who did help me get started) to finish it. This patch operates perfectly but requires a little more sanity checking.

There are three questions remaining:

  1. How to properly detect leftover "garbage" from a previous PV that _was_ suitable to prevent installation into a PV that _is not currently suitable_
  2. Whether installation into a PV that does not yet have any VGs should be allowed
  3. Whether we should allow installation without the -s flag (Andrei was against it).
These are really the only questions. The patch currently works.

It's been in use (by me) for quite some time, never had issues.

Additionally the util-linux team updated libblkid to allow detection of a PV even if the bootsector already contains a bootloader (as would be the case with our patch) in their version 2.29. This version is not yet included in Xenial (16.10) of Ubuntu, but it is included in the upcoming Zesty (17.04). This version is required for auto-activation of physical volumes using the udev mechanism, which is the default for all SystemD systems.

Building

Building is easy peasy and although there are dedicated packages you need most, I will just say that apt build-dep grub2 will install anything and everything on Ubuntu unless you care about hard disk space but then it will still do it. I thought most of that space requirement went in to the Qemu packages though. That's some 171MB of stuff you will not use.

It's just that Ubuntu (Debian) contains other stuff such as the update-grub script which you could just copy, and I'm sure you could build it using their package scripts.

Ubuntu's base version of Grub2 is at least as old as January, 2014. They backport patches from upstream whenever they feel like it. The last backported patch (and also the last patch they have) is from January 20 (2016).

My current patches apply cleanly to the Ubuntu base though.

To obtain a patch of my work, you can create a diff against the "savannah" branch (the way it is now).

Patch of all the changes I've done

 git diff savannah pvinstall

But this will include any irrelevant house-keeping changes. Not that it matters.

A diff with only the most essential set of changes for the patch would have to be done against the last "housekeeping" commit from pvinstall. I just keep them in one branch although I could put the housekeeping changes in its own branch or just apply them to master. For now, I think this is cleaner.

Obtaining

 git clone https://github.com/drydenp/grub2-pvinstall.git

should fetch this repo and set up the remote origin

 cd grub2-pvinstall
 git remote add upstream git://git.savannah.gnu.org/grub.git
 git fetch upstream master
 git branch -t savannah upstream/master

will set up upstream and create a local branch savannah to track it. Savannah is not stored here on Github as a consequenc.

To have convenient access to the ubuntu branch you must do:

 git symbolic-ref refs/heads/ubuntu refs/heads/pvinstall_ubuntu2.02beta2

Maintenance

Updating local savannah

 git checkout savannah
 git pull

Rebasing changes on top of local savannah

 git checkout pvinstall
 git rebase savannah

Updating the Ubuntu branch

The ubuntu branch is actually named in full "pvinstall_ubuntu2.02beta2" but as you have seen I have created a local symbolic reference called "ubuntu". This also gets updated by the below script that updates the Ubuntu source.

In order to update the Ubuntu branch with my commits:

 git checkout ubuntu                    # I have tagged the "split-off" point "ubuntu_ignore"
 git reset --hard ubuntu_ignore         # Remove any commits I have copied over from pvinstall previously
 git cherry-pick savannah..pvinstall    # Copy commits from pvinstall onto the Ubuntu sources

An alternative way of finding the commit that changed the .gitignore file is:

 git log --oneline .gitignore | head -1 | sed "s/ .*//"

Replacing the Ubuntu sources

You could do this by hand, but this works perfectly.

It does the following:

  • fetch the latest grub2 source
  • find its version number
  • stash any changes in the working dir
  • create a new branch for it
  • empty the branch and remove all untracked files except ignored files
  • move the Ubuntu sources to it
  • add it with a commit message
  • commit the ubuntu_ignore commit that will create a .gitignore file
  • update the newly created commit to reference the tag
  • move the temporary branch to a branch with the ubuntu version in it
  • update the symbolic reference "ubuntu"
  • remove remaining temporary files and the tmp directory
After this you will have a new "Ubuntu source" branch named after the version with the full set of files from the download as the initial commit and an ignore file as the second commit. At that point you can copy commits to it from pvinstall if that is what you were intending to do.

I do not maintain that branch that way though, so what you will see online or if you clone it will be the "bare" Ubuntu branch/repo.

 ask_for_stash() {
   local answer
   echo "You have changes in your working directory. Aborting procedure"
   echo -e "\nExecute git stash -a to stash changes. Do you want me to do it for you?"
   read -ep "stash changes [y/n]: " answer
   if [ "$answer" = "y" ]; then
     echo "Saving current branch"
     oldbranch=$( git symbolic-ref HEAD --short ) && {
       echo "Stashing changes..."
       git stash -a
     } || {
       echo "Failed to stash. Need to abort now."
       false
     }
   fi
 }

 revert_stash() {
   echo "Your old branch was stashed because the working directory was not clean." \
     "Changing back to $oldbranch now and popping changes"
   git checkout $oldbranch && { git stash pop || echo "Popping failed, take care"; } ||
     echo "Checking out failed, there should be changes in your stash"
 }

 tmp=$( mktemp -d ) && { 
   cd $tmp && apt source grub2 && {
     subdir=$( ls -d * --file-type | grep "/$" | sed 's@/$@@' ) &&
     version=$( echo "$subdir" | sed "s/grub2-//" | tr -d '~' ) &&
     cd - && [ -z "$( git status -s )" ] || ask_for_stash && 
       git checkout --orphan pvinstall_ubuntu${version}_temp && { 
       git rm -rf --ignore-unmatch . && git clean -df && mv $tmp/$subdir/* . &&
       git add . && git commit -m "Ubuntu sources $version" &&
       git cherry-pick ubuntu_ignore &&
       git tag -af ubuntu_ignore -m "Tag pointing to most recent Ubuntu .gitignore commit" && {
         git branch -M pvinstall_ubuntu${version}_temp pvinstall_ubuntu${version} &&
         { git symbolic-ref refs/heads/ubuntu refs/heads/pvinstall_ubuntu${version}; true; }
       } ||
       git branch -D pvinstall_ubuntu${version}_temp
       [ $oldbranch ] && revert_stash
     }  
     rm -rf $tmp/*
   }
   rmdir $tmp
 }

I just put that stashing code into its own functions for now. Without those functions it will just abort. I was actually meaning to reduce the mount of safety code, but instead I increased it :-/.

About

Contains code to install GRUB2 into an LVM PV

Resources

Stars

Watchers

Forks

Packages

No packages published