How do you rename the volume group that contains the root volume in LVM?

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


Solution 1:

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.

Solution 2:

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