I am trying to write a small backup application for Linux systems file by file if partitions are created by the user using fdisk. I am facing a problem when I am done with restoring the files. The problem is with UUID mismatch in restored fstab and menu.lst.
Using C I could create a partlist.txt file where I have 3 entries:
device_name, "UUID" mountpoint
Need to restore the following:
UUID in menu.lst by matching UUID of "/" from partlist.txt
Replace correct UUIDs from partlist.txt for all mountpoints in fstab
Also cannot depend on the ordering of lines anywhere.
Attached the sample generated partlist.txt and fstab + menu.lst from Red Hat 6.
I am not an expert in using sed and awk. So any help is really appreciated.
This is the script to modify menu.txt. It modifies the file in-place. It'd be safer to omit sed's '-i' switch in the second line, and let it print out the new version of menu.txt (redirect it into a new file); so that the original is kept untouched.
miro@miro-ntb:Downloads$ cat test.sh
#!/bin/bash
root_uuid=$(sed -n ' s/[^ ]* "// ;/\/[\r]*$/ s/".*//p' partlist.txt) #extract root UUID
sed -i 's/root=[^ ]*/root=UUID='$root_uuid'/' menu.txt #this file will get modified
miro@miro-ntb:Downloads$ cat menu.txt
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/mapper/VolGroup-lv_root
# initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title Red Hat Enterprise Linux (2.6.32-71.el6.i686)
root (hd0,0)
kernel /vmlinuz-2.6.32-71.el6.i686 ro root=/dev/mapper/VolGroup-lv_root rd_LVM_LV=VolGroup/lv_root rd_LVM_LV=VolGroup/lv_swap rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us crashkernel=auto rhgb quiet
initrd /initramfs-2.6.32-71.el6.i686.img
miro@miro-ntb:Downloads$ ./test.sh
miro@miro-ntb:Downloads$ cat menu.txt
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=UUID=f75b104c-678e-4f80-a618-70d4bf4a3ede
# initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title Red Hat Enterprise Linux (2.6.32-71.el6.i686)
root (hd0,0)
kernel /vmlinuz-2.6.32-71.el6.i686 ro root=UUID=f75b104c-678e-4f80-a618-70d4bf4a3ede rd_LVM_LV=VolGroup/lv_root rd_LVM_LV=VolGroup/lv_swap rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us crashkernel=auto rhgb quiet
initrd /initramfs-2.6.32-71.el6.i686.img
AFAIK awk doesn't support in-place editing. A workaround is needed. If anyone knows how to deal with this with the original "awk < (sed file1) file2" design, please post.
miro@miro-ntb:Downloads$ cat fstab.txt
#
# /etc/fstab
# Created by anaconda on Mon Feb 14 16:03:26 2011
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/VolGroup-lv_root / ext4 defaults 1 1
UUID=10cb97f9-e52e-472b-a20b-c1e90c6d561b /boot ext4 defaults 1 2
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
miro@miro-ntb:Downloads$ { rm fstab.txt && awk '
BEGIN{while ( (getline < "partlist.txt")>0) {
gsub(/\r|"/,""); a[$3]=$2;}
}
{
for(i in a) { if($2==i){$1="UUID=" a}};
print $0;
}' > fstab.txt; } < fstab.txt
miro@miro-ntb:Downloads$ cat fstab.txt
#
# /etc/fstab
# Created by anaconda on Mon Feb 14 16:03:26 2011
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=f75b104c-678e-4f80-a618-70d4bf4a3ede / ext4 defaults 1 1
UUID=psb8767c-678e-4f80-a618-70d4bf4a3ede /boot ext4 defaults 1 2
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
This workaround is adapted from here: sed / awk - inplace or inline edit. You can find an explanation how this '{ rm file && awk > file ; } < file' construct works.
Cheers
mirni