25

I want to rename the volume group that my root volume is on. How can I do this?

2
  • Just curious: Why would I want to do this?
    – guntbert
    Apr 29, 2016 at 19:07
  • 2
    My use case is that I have a VMWare template that I installed with the hostname "template". Once I deploy that template, I'd rather the vgname not be "template-vg" for all those machines. Sticking with the general idea that the vgname is related to the hostname, I have my setup script for the template rename the vg with the hostname. It also allow me to easily assure I'm working on the correct vg and not in the wrong ssh session somehow.
    – flickerfly
    Apr 29, 2016 at 19:14

8 Answers 8

30

NOTE: Your distro may discourage editing /boot/grub/grub.cfg. If that is the case, this script may be a bad idea. Alternately, you may just be able to run grub-mkconfig to fix that. I haven't tested on those distros, so check your situation.

First, You need to know the volume group name may have a dash in it. If it does, than any use of the /dev/mapper/ reference will need to have two dashes. In 16.04, it defaults to having a "-vg" appended to the name so this should be assumed.

Second, you should know that messing this up can cause your system to be unbootable and result in having to boot from a rescue disk and fix stuff causing downtime. (aka: Don't do this in production.)

To do the actual rename use lvrename oldname newname.

After renaming you must edit both /etc/fstab and /boot/grub/grub.cfg to update the use of the name for any reference to your root and probably also your swap locations.

Additionally, you need to run this command to update the initramfs for all the kernels.

update-initramfs -c -k all

I use the following script to handle this when deploying a new template. Again, don't do this in production unless you have a high tolerance for downtime.

#!/bin/bash

# Must be run with root permissions 
# sudo will be sufficient

if [ "$(id -u)" != "0" ]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi

#Ask for new hostname $newhost
read -p "Enter new hostname: "
newhostname=$REPLY
oldhostname=$(cat /etc/hostname)

echo "Changing LVM names"
# ${var//-} syntax removes all dashes from the name simplifying the 
# requirement to use a double-dash in some places to escape the dash
newvg=${newhostname//-}

# Find the volume group that root is in 
vg=`lvdisplay -C|awk '$1=="root" {print $2}'`
if [[ ${vg} == *"-"* ]]; then
    #has dashes in current name
    vgrename ${vg} ${newhostname//-}
    vg=`echo $vg|sed "s/-/--/g"`
    sed -i "s/${vg}/${newvg}/g" /etc/fstab
    sed -i "s/${vg}/${newvg}/g" /boot/grub/grub.cfg
  else
    #no dashes in current name
    vgrename ${vg} ${newvg}
    sed -i "s/${vg}/${newvg}/g" /etc/fstab
    sed -i "s/${vg}/${newvg}/g" /boot/grub/grub.cfg
fi

update-initramfs -c -k all

If you have any improvements of this script, please share. I'm always looking for ways to improve and account for various edge cases.

8
  • If you run sed -i without an input file, it errors sed: no input files. Remove the -i flag.
    – wjandrea
    Apr 6, 2017 at 3:50
  • Ah, okay. That makes sense. Wonder if my version of sed handled that differently. Also, looks like @Diego Souza pulled it off without sed entirely in another comment.
    – flickerfly
    Apr 6, 2017 at 12:37
  • 2
    I believe you meant vgrename rather then lvrename, and since /boot/grub/grub.cfg is generated from entries in /etc/grub.d, you will need to run update-grub after renaming rather than editing it directly. Jun 30, 2017 at 17:54
  • No, I meant volume group. Also, perhaps your distro differs from mine in the grub configuration.
    – flickerfly
    Jul 3, 2017 at 16:05
  • 3
    It seems that update-grub can't run properly before the reboot - it fails with an error of /usr/sbin/grub-probe: error: failed to get canonical path of '/dev/mapper/ubuntu--vg-root' for me. For systems where /boot/grub/grub.cfg is auto-generated, perhaps the safest option is to update manually, as in this script, then reboot, then run update-grub, then reboot again. Mar 29, 2018 at 10:09
1

Here is a revised version, fix on string replacement of vg and also print updated files.

#!/bin/bash

# Must be run with root permissions
# sudo will be sufficient
if [ "$(id -u)" -ne 0 ]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi

# Ask for new hostname $newhost
read newhostname -p "Enter new hostname: "
#oldhostname=$(cat /etc/hostname)

echo "Changing LVM names"
# ${var//-} syntax removes all dashes from the name simplifying the
# requirement to use a double-dash in some places to escape the dash
newvg=${newhostname//-}

# Find the volume group that root is in
vg=$(lvdisplay -C | awk '$1=="root" {print $2}')
echo "old vg name: " $vg
echo "new vg name: " $newvg
if [[ ${vg} == *"-"* ]]; then
    # has dashes in current name
    vgrename ${vg} ${newhostname//-}
    vg=${vg//-/--}
    sed -i "s/${vg}/${newvg}/g" /etc/fstab
    sed -i "s/${vg}/${newvg}/g" /boot/grub/grub.cfg
    sed -i "s/${vg}/${newvg}/g" /etc/initramfs-tools/conf.d/resume
else
    # no dashes in current name
    vgrename ${vg} ${newvg}
    sed -i "s/${vg}/${newvg}/g" /etc/fstab
    sed -i "s/${vg}/${newvg}/g" /boot/grub/grub.cfg
    sed -i "s/${vg}/${newvg}/g" /etc/initramfs-tools/conf.d/resume
fi

#check files
echo fstab update:
grep ${newvg} /etc/fstab

echo grub.cfg update:
grep ${newvg} /boot/grub/grub.cfg

echo resume update:
grep ${newvg} /etc/initramfs-tools/conf.d/resume

update-initramfs -c -k all

When using this script, the machine may not shutdown correctly as it tries to "stop" the mappings. Depending on your config this may even seem as the machine is in a boot state while in reality it isn't even shutdown first.

It is helpful to remove "quiet splash" from GRUB_CMDLINE_LINUX_DEFAULT as you then see the messages.

1

I did a little modification on the script to also change hostname.

#!/bin/bash

# Must be run with root permissions
# sudo will be sufficient

if [ "$(id -u)" != "0" ]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi

#Ask for new hostname $newhost
read -p "Enter new hostname: "
newhostname=$REPLY
oldhostname=`cat /etc/hostname`

# ${var//-} syntax removes all dashes from the name simplifying the
# requirement to use a double-dash in some places to escape the dash
newvg=${newhostname//-}

# Find the volume group that root is in
vg=`lvdisplay -C|awk '$1=="root" {print $2}'`
echo
echo "old hostname          : " $oldhostname
echo "old vg name           : " $vg
echo "new hostname / vg name: " $newvg

echo
echo "Changing LVM names..."
vgrename ${vg} ${newvg}
if [[ ${vg} == *"-"* ]]; then
    #has dashes in current name
    vg=`echo $vg|sed "s/-/--/g"`
fi
sed -i "s/${vg}/${newvg}/g" /etc/fstab
sed -i "s/${vg}/${newvg}/g" /boot/grub/grub.cfg
sed -i "s/${vg}/${newvg}/g" /etc/initramfs-tools/conf.d/resume

echo
echo "Changing Hostname..."
sed -i "s/${oldhostname}/${newvg}/g" /etc/hostname
sed -i "s/${oldhostname}/${newvg}/g" /etc/hosts

#check files
echo
echo fstab update:
grep ${newvg} /etc/fstab

echo grub.cfg update:
grep ${newvg} /boot/grub/grub.cfg

echo resume update:
grep ${newvg} /etc/initramfs-tools/conf.d/resume

echo hostname update:
grep ${newvg} /etc/hostname

echo hosts update:
grep ${newvg} /etc/hosts

update-initramfs -c -k all
1

File /boot/grub/grub.cfg shouldn't be edited manually.

There is file header below:

"
 DO NOT EDIT THIS FILE

 It is automatically generated by grub-mkconfig using templates
 from /etc/grub.d and settings from /etc/default/grub

BEGIN /etc/grub.d/00_header
"
1
  • Yep, my answer is getting a little old and my use-case for this is no longer at thing. I'd encourage you to contribute anything you learn to bring it up-to-date. What distribution and version are you seeing this on?
    – flickerfly
    Nov 26, 2018 at 18:22
1

There is an alternative approach that does not require worrying about changing (and messing up) the boot process.

When renaming a volume group, the UUID of logical volumes does not change.

If you first specify all mounts in /etc/fstab with their UUIDs (like /dev/disk/by-uuid/UUID), you can safely rename a volume group.

To get the UUIDs for disks you can inspect the output of lsblk -o name,uuid,mountpoint,size.

1
  • Yep this is a handy way to handle it. I tend to prefer readability of the /etc/fstab over UUID, but there certainly is a case for this point if you aren't likely to be dealing with /etc/fstab manually.
    – flickerfly
    Apr 15, 2021 at 16:01
0

After renaming you must edit both /etc/fstab and /boot/grub/grub.cfg to update the use of the name for any reference to your root and probably also your swap locations. /etc/initramfs-tools/conf.d/resume is needed, too.

So, add this code:

sed -i "s/${vg}/${newvg}/g" /etc/initramfs-tools/conf.d/resume
1
  • I didn't have need to do this on Ubuntu. 'update-initramfs -c -k all' was sufficient. What distro are you using that showed this need? Does it not have the update-initramfs tool? I do a reboot immediately after running the script that includes this so that may also be a factor in my different results.
    – flickerfly
    Aug 3, 2016 at 15:07
0

The boot menu also needed editing on Ubuntu 18 (and probably others). So - simplified for only changing a vg name and preserving the use of a dash in the name:

#!/bin/bash

oldvg="ubu16svr-vg"
oldvgdash="ubu16svr--vg"
newvg="ubusvr-vg"
newvgdash="ubusvr--vg"

if [ "$(id -u)" != "0" ]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi

vgrename ${oldvg} ${newvg}
sed -i "s/${oldvg}/${newvg}/g" /etc/fstab
sed -i "s/${oldvgdash}/${newvgdash}/g" /etc/fstab
sed -i "s/${oldvg}/${newvg}/g" /boot/grub/grub.cfg
sed -i "s/${oldvgdash}/${newvgdash}/g" /boot/grub/grub.cfg
sed -i "s/${oldvg}/${newvg}/g" /boot/grub/menu.lst
sed -i "s/${oldvgdash}/${newvgdash}/g" /boot/grub/menu.lst
sed -i "s/${oldvg}/${newvg}/g" /etc/initramfs-tools/conf.d/resume
sed -i "s/${oldvgdash}/${newvgdash}/g" /etc/initramfs-tools/conf.d/resume
update-initramfs -c -k all
0

I wanted to do exactly this and after googling around and reading many blogs etc, I came to the conclusion there must be a better way than editing files that should be managed by maintainer scripts, (grub.cfg). Certainly this is the case when considering a single desktop machine, rather than a whole bunch of VMs. Therefore I studied the matter and found that the process is potentially painless. However having said this I think care should always be taken to avoid any boot-time screws ups. What surprised me was the references constantly made suggesting that it is necessary to update the initramfs. I found this step is not necessary. So read fully and proceed with caution:

Assuming the system is already booted you should see that in grub.cfg there are 2 important entries.

set root='lvmid/BKJJuy-Zs3w-O9Hu-Onbc-k4Zf-uxzZ-X9cdws/b7S0Z8-R6KC-ukz5-J9Ov-Jc2n-THMZ-tgFwBM'

linux   /boot/vmlinuz-5.4.0-96-generic root=/dev/mapper/<old-VG-name>-root ro

The 'set root' line tells GRUB2 where it can find the root device. This is critical as otherwise Grub can not load the initramfs needed to actually activate the LVM VG on which '/' resides. In this case the root device is identified using UUID and consists of the VG-UUID + LV-UUID. You may well ask, well if the LVM module is not loaded how can Grub read from this device to find the initramfs; rather 'chicken and egg'. Actually the answer is quite simple; GRUB2 contains its own code base that can understand the LVM metadata found on the raw disk. Therefore it can use the LVM UUIDs to locate the root filesystem and therefore find, load and decompress /boot/initrd.img. For a better understanding of this bootstrap process see: https://www.system-rescue.org/lvm-guide-en/Booting-linux-from-LVM-volumes/

Once the initramfs is mounted the init script from Ubuntu, (which is embedded in the initramfs), uses the information found on the virtual filesystem /proc/cmdline which was already generated by grub by parsing the 'linux' line from grub.cfg. This is used by initramfs 'init' procedure to map and activate the correct LVM logical volume used as '/'. Therefore AFAIK there are no references to the LVM VG name embedded into the initramfs and an update of this is not necessary.

Therefore to make the change to a LV mounted as root, first modify the name of the VG:

vgchange -v <old-VG-name> <new-VG-name>

Then modify /etc/fstab to reflect this change in the mount definition of the root device:

/dev/mapper/<new-VG-name>-root /               ext4    errors=remount-ro 0       1

If you have other entries in fstab which also reference the old VG name, such as swap etc, these too must be modified to ensure systemd generator creates the correct .mount units at boot time.

At this stage I would simply reboot, having made a careful note of the new VG name you have used. You may find that the system hangs on the way down, due I believe to the old systemd generator unit which still contain the old VG name. It gets a bit confused. Still don't worry its a one time issue.

Upon reboot enter the GRUB2 menu, if you have your system configured to hide the menu, you will need to ensure you have requested the menu option, as I remember by holding 'shift' at boot time. However first check this works before you make any changes as some BIOS issues can make accessing the grub menu problematic and its critical you can get to the menu. Assuming that you have use 'e' to enter edit mode, then modify the entry on the 'linux' line which defines 'root=' and change this to match the new VG name. ctrl-x after the changes and boot the system.

This should bring up the system fully and normally.

Finally we must now update the menu entries in grub.cfg. This can be done using:

update-grub

Hope that works for others. As for myself, I prefer this to manually editing the grub.cfg file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.