If you have the ability to stick a second drive in your workstation or server, it can make a great recovery tool. True, there are a lot of CD recovery distributions out there, but the approach we use here will actually fit on a 100 Meg Zip disk. Further, it is portable to virtually any device by the very nature of the base distribution, which is freely available. As an added bonus, this article will show you how to bring up your own simple GNU/Linux distribution (uClibc/GNU/Linux?). We have talked about this quite a bit before in our GIAGD articles, but this particular approach is specific to recoverying a desktop we have running CentOS, which operates pretty much exactly like Red Hat Enterprise Linux. The lvmdiskscan command will quickly show you your available partitions:
[root@srv-1 usr-1]# /usr/sbin/lvmdiskscan /dev/hda1 [ 101.94 MB] /dev/sda1 [ 101.94 MB] /dev/hda2 [ 111.69 GB] LVM physical volume /dev/sda2 [ 1.95 GB] /dev/sda3 [ 15.08 GB] 0 disks 4 partitions 0 LVM physical volume whole disks 1 LVM physical volume [root@srv-1 usr-1]# |
Use fdisk to show more details on a particular disk:
[root@srv-1 usr-1]# /sbin/fdisk -l /dev/sda Disk /dev/sda: 18.4 GB, 18400000000 bytes 255 heads, 63 sectors/track, 2237 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sda1 * 1 13 104391 83 Linux /dev/sda2 14 268 2048287+ 82 Linux swap /dev/sda3 269 2237 15815992+ 83 Linux [root@srv-1 usr-1]# |
Make mount points for your recovery distribution, create filesystems, and mount them. Note that we are making a small boot partition at the beginning of the drive. Since the kernel will be kept in /boot of our CentOS install, we don’t really need the boot partition on the recovery drive; however, we will still set it up with a boot partition regardless. We set all of our drives up this way when manually partitioning. Some older BIOS/drive combinations require this, and by standardizing on this as much as possible, our config files don’t have to change as much. Here are the steps:
root@srv-1 usr-1]# mkdir /recovery root@srv-1 usr-1]# mkdir /recoveryboot [root@srv-1 /]# /sbin/mkfs.ext2 /dev/sda1 mke2fs 1.35 (28-Feb-2004) max_blocks 106893312, rsv_groups = 13049, rsv_gdb = 256 Filesystem label= OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) 26104 inodes, 104388 blocks 5219 blocks (5.00%) reserved for the super user First data block=1 Maximum filesystem blocks=67371008 13 block groups 8192 blocks per group, 8192 fragments per group 2008 inodes per group Superblock backups stored on blocks: 8193, 24577, 40961, 57345, 73729 Writing inode tables: done inode.i_blocks = 3074, i_size = 67383296 Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 31 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override. [root@srv-1 /]# [root@srv-1 /]# /sbin/mkfs.ext2 /dev/sda3 mke2fs 1.35 (28-Feb-2004) max_blocks 4048893952, rsv_groups = 123563, rsv_gdb = 965 Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) 1978592 inodes, 3953998 blocks 197699 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=4051697664 121 block groups 32768 blocks per group, 32768 fragments per group 16352 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208 Writing inode tables: done inode.i_blocks = 77208, i_size = 4243456 Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 38 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override. [root@srv-1 /]# [root@srv-1 usr-1]# [root@srv-1 usr-1]# mount -t ext2 /dev/sda1 /recoveryboot [root@srv-1 usr-1]# mount -t ext3 /dev/sda3 /recovery [root@srv-1 usr-1]# [root@srv-1 /]# df Filesystem 1K-blocks Used Available Use% Mounted on /dev/mapper/VolGroup00-LogVol00 113146552 4520012 102879036 5% / /dev/hda1 101086 12463 83404 14% /boot none 778028 0 778028 0% /dev/shm mondo:/share 177265344 102206976 66053816 61% /share /dev/sda1 101086 1550 94317 2% /recoveryboot /dev/sda3 15567620 71432 14705392 1% /recovery [root@srv-1 /]# |
We need some kind of live filesystem, a bootloader, and a kernel. We discussed how to configure the LILO bootloader for this recovery system in this article. For the filesystem, uClibc is a fabulous, preconfigured filesystem with a very small footprint available here:
Just decompress the image, mount it, tar it up, and extract it on your new filesystem:
[root@srv-1 /]# ls /usr/local bin games lib man rpms share etc include libexec root_fs_i386.ext2.bz2 sbin src [root@srv-1 /]# bzip2 -d /usr/local/root_fs_i386.ext2.bz2 [root@srv-1 /]# ls /usr/local bin games lib man rpms share etc include libexec root_fs_i386.ext2 sbin src [root@srv-1 /]# mount -t ext2 -o loop /usr/local/root_fs_i386.ext2 /uclibc [root@srv-1 /]# [root@srv-1 /]# mount /dev/mapper/VolGroup00-LogVol00 on / type ext3 (rw) none on /proc type proc (rw) none on /sys type sysfs (rw) none on /dev/pts type devpts (rw,gid=5,mode=620) usbfs on /proc/bus/usb type usbfs (rw) /dev/hda1 on /boot type ext3 (rw) none on /dev/shm type tmpfs (rw) none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw) sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw) mondo:/share on /share type nfs (rw,addr=10.50.100.72) /dev/sda1 on /recoveryboot type ext2 (rw) /dev/sda3 on /recovery type ext2 (rw) /usr/local/root_fs_i386.ext2 on /uclibc type ext2 (rw,loop=/dev/loop0) [root@srv-1 /]# [root@srv-1 /]# cd /uclibc [root@srv-1 uclibc]# ls bin etc lib lost+found opt root tmp var dev home linuxrc mnt proc sbin usr [root@srv-1 uclibc]# [root@srv-1 uclibc]# tar -cjpf /root/devsys.tar.bz2 . [root@srv-1 uclibc]# tar -tjpf /root/devsys.tar.bz2 | head ./ ./lost+found/ ./bin/ ./bin/cc ./bin/gcc ./bin/c++ ./bin/g++ ./bin/busybox ./bin/addgroup ./bin/adduser [root@srv-1 uclibc]# [root@srv-1 recovery]# cp /root/devsys.tar.bz2 ./ [root@srv-1 recovery]# tar -xjpf *.bz2 [root@srv-1 recovery]# ls bin devsys.tar.bz2 home linuxrc mnt proc sbin usr dev etc lib lost+found opt root tmp var [root@srv-1 recovery]# |
We also need a kernel. A lot of our utility boxes rely on 2.4. We also prefer to not use modules with these kernels, since they are usually application specific. We keep a minimal kernel config around, and just run make oldconfig to migrate:
[usr-1@srv-1 linux-2.4.30]$ ls arch Documentation init MAINTAINERS README COPYING drivers ipc Makefile REPORTING-BUGS CREDITS fs kernel mm Rules.make crypto include lib net scripts [usr-1@srv-1 linux-2.4.30]$ cp ../.config ./ [usr-1@srv-1 linux-2.4.30]$ [usr-1@srv-1 linux-2.4.30]$ make oldconfig rm -f include/asm ( cd include ; ln -sf asm-i386 asm) /bin/sh scripts/Configure -d arch/i386/config.in # # Using defaults found in .config # * * Code maturity level options * Support for console on serial port (CONFIG_SERIAL_CONSOLE) [N/y/?] (NEW) Y *** End of Linux kernel configuration. *** Check the top-level Makefile for additional configuration. *** Next, you must run 'make dep'. [usr-1@srv-1 linux-2.4.30]$ [usr-1@srv-1 linux-2.4.30]$ make menuconfig [usr-1@srv-1 linux-2.4.30]$ make dep clean bzImage . . . [root@srv-1 recovery]# cp /home/usr-1/newkern/lin*/arch/i386/boot/bzImage ./boot/recoverlinux |
We need to edit /etc/fstab:
[root@srv-1 usr-1]# cat /recovery/etc/fstab # /etc/fstab: static file system information. # # /dev/sda3 / ext2 rw,noauto 0 1 /dev/sda1 /boot ext2 rw,noauto 0 1 /dev/sda2 none swap sw 0 0 proc /proc proc defaults 0 0 devpts /dev/pts devpts defaults,gid=5,mode=620 0 0 tmpfs /tmp tmpfs defaults 0 0 [root@srv-1 usr-1]# |
Just edit lilo.conf to add the new kernel and root partition, as we did in this article, and you have an extremely minimal recovery distribution that is reasonably portable.