My only home computer is, and has been for a while, a Nokia Booklet. It’s a
nice ultra-portable fanless laptop that gets about 6-7 hours of use per
charge, and is in my opinion one of the most stylish products ever shipped by
Nokia. Granted, it’s not too powerful, only sporting a dual-core Intel Atom
Z530 running at 1.6 GHz, and it has one major flaw from a Linux user’s
standpoint in that it has the almost infamous GMA500 graphics hardware
courtesy of the “Poulsbo” chipset. Support nowadays is
okay, in
that I run Maverick on it at native panel resolution, and can actually pretty
consistently put the machine to sleep with uswsusp and have it wake up
correctly, but I can’t for example run the snazzy new gnome-shell on it, or
use compiz.
Anyway, I used to have the original Windows 7 install on a second partition, but it soon became apparent that I would find no use for it and decided to use the whole disk for Ubuntu. I didn’t want to reinstall, however, and unfortunately hadn’t originally put it on LVM, so the exercise would be a bit more substantial than simply growing a logical volume.
This, then, was my plan of action:
- Nuke the windows partition, make a LVM partition in it’s place, and create a volume group and logical volume with it, then create a new ext4 fs on the logical volume.
- Copy over the running Ubuntu installation onto the new filesystem.
- Update grub to locate the new-old Ubuntu on the LVM filesystem.
- Boot from the logical volume.
- Add the old Ubuntu partition to the volume group and grow the logical volume and filesystem onto that.
Simple! There are a couple of glaring holes in the plan but we’ll handle those as we get to ‘em.
Nuke ‘em high
The first step was simple: first, just delete the windows partition and create
a new partition in its place with the partition type set to 0x8e for Linux
LVM. Then we need to tell LVM about this new partition, or “physical volume”
in LVM terminology, by running pvcreate on it (I’m running all these
commands as root):
# pvcreate /dev/sda1
Then we create a volume group, which is a container of physical volumes, and itself acts as a container for logical volumes:
# vgcreate vg-0 /dev/sda1
Finally, create a logical volume that fills up the new volume group:
# lvcreate -n root -l 100%VG vg-0
Now there’s a brand spanking new logical volume called root on the volume
group vg-0. As evidence of this, there is a new device node for it at
/dev/vg-0/root. Next, create the filesystem:
# mkfs.ext4 /dev/vg-0/root
Replica
Now the new filesystem can be mounted and the running installation copied onto it. There might be some cases where copying from a live fs might be a bad idea, but generally as long as you don’t do anything substantial at the same time, you shouldn’t have too much trouble.
I used rsync to do the actual copying, but any similar tool could be used as
long as it correctly preserves all file attributes. What’s just as important
is to skip all the special pseudofilesystems and the mountpoint itself:
# mount /dev/vg-0/root /mnt
# rsync -a / --exclude=/{dev,proc,sys,var/run,var/lock} /mnt | \
tee transfer.log; \
ogg123 /usr/share/sounds/ubuntu/stereo/system-ready.ogg
I used tee to capture the output from rsync and save it in a logfile, and
made it play a sound when it finished so I wouldn’t have to keep checking.
It’s always a good idea to do a dry run first, and rsync has the -n flag
for that. For me the command complained about not being able to copy all file
attributes, but even after trawling the verbose logs I couldn’t find any
specific file-related errors, so I decided to ignore that message and went
ahead with the real copy. All told the process took a couple of hours for 20+
GB.
Rub-a-dub-dub
I haven’t played with grub a whole lot, but after looking at how the thing was
configured on Ubuntu, I tentatively came to the conclusion that grub (version
2 that is) should find the copied Ubuntu from the logical volume and add it to
the boot menu automagically. So I updated grub.cfg:
# update-grub
The output hinted at what a look at /boot/grub/grub.cfg confirmed, i.e. that
grub had indeed found the copy. However, I happened to notice that the root
settings for the LVM kernels were incorrect, and had the UUIDs of my old root
partition. I didn’t think much of it, expecting them to be set correctly as I
ran update-grub from the new partition, and simply fixed them manually.
At this point I rebooted, selected the latest kernel from the logical volume and found Ubuntu running nicely. I used fdisk to delete the old root partition and created a new LVM partition in its place, and shutdown the machine, deciding to call it a day.
This was a near-catastrophic error, as it turns out. Well, catastrophic in a relative sense.
Disco inferno
Booting in the morning, I was greeted by a friendly grub message saying
“ERROR: no such disk”, and a grub-rescue> prompt that didn’t know a single
command, not even help.
After thinking about it for a few moments, my error was glaringly obvious:
grub on the MBR was still looking for it’s config file from the old root
partition, which I had nuked, because I had never reinstalled it, only
recreated the config file. And even if I had reinstalled it, it wouldn’t
have booted, because I had only updated the grub.cfg file on the old root,
not on the new one. Facepalm.
Well, thankfully I happened to have another Ubuntu machine available, so I quickly created a bootable USB stick and started fixing things. The default Ubuntu live image doesn’t have the userspace LVM tools, but as long as there’s network connectivity, one can just install them on the running ramdisk, so that’s no problem.
The first order of business was to get the new root mounted using the live image:
# apt-get install -y lvm2
# vgchange -a y vg-0
# mount /dev/vg-0/root /mnt
The vgchange command makes the volume group active, this is required so that
the logical volume can be mounted. Now the mounted root has all the tools
required to reinstall and reconfigure grub, so the easiest method is to chroot
into the mount and fix it from there. For this to work, the most important
pseudofilesystems need to be bind-mounted into the chroot:
# for d in dev/pts dev proc sys; do mount -B /$d /mnt/$d; done
Now we can chroot into the volume, reinstall grub and rebuild the configuration:
# chroot /mnt
# grub-install /dev/sda
# update-grub
Easy peasy. Now for a reboot…
…and the same error message.

I did the same boot from USB stick, install lvm, mount root rumba again and
started scratching my head and looking at files. In the end it was a simple
comment on some forum somewhere that tipped me off as to what the actual
problem was. I forget where (sorry) but someone said that the format for the
parameter for the set root command of grub was the same as the volume node
name in the /dev/mapper directory. Now, update-grub had put entries like
set root='(vg-0-root)' in the grub.cfg, but actually the dash in the
volume group name gets kinda-sorta escaped, so the node is in fact named
/dev/mapper/vg--0-root. It appears there is a bug in
update-grub
that causes this behavior.
As manually fixing the file would have just been a one-off solution, I renamed the volume group (which was thankfully very easy):
# umount /mnt
# vgchange -a n vg-0
# vgrename vg-0 vg0
# vgchange -a y vg0
# mount /dev/vg0/root /mnt
The volume group needs to be deactivated to rename it, but other than that
it’s straightforward. Now I grub-installed and update-grub‘d again and
confirmed that this time it generated correct config files. Time to wipe off
that cold sweat and lean back.
Grow your own
All that then remained was to add the old root’s physical volume to the volume group, then use up that space. For this, you first need to initialize the partition for LVM, then extend the volume group onto it, then grow the logical volume, and finally grow the filesystem to match the new volume size. Sounds complicated but is just a few simple steps really (/dev/sda6 is the old root partition here):
# pvcreate /dev/sda6
# vgextend vg0 /dev/sda6
# lvextend -l 100%VG vg0/root
# resize2fs /dev/vg0/root
And that’s it! One reboot later I’m here typing this and feeling a bit smug for shooting myself in the leg, then managing to bandage it up without doing any more damage in the process.
Comments
blog comments powered by Disqus