{"id":42,"date":"2011-01-25T11:58:55","date_gmt":"2011-01-25T16:58:55","guid":{"rendered":"http:\/\/www.nathanjohnson.info\/?p=42"},"modified":"2013-09-08T20:06:43","modified_gmt":"2013-09-09T02:06:43","slug":"bare-metal-linux-cloning","status":"publish","type":"post","link":"https:\/\/www.nathanjohnson.org\/?p=42","title":{"rendered":"Bare Metal Linux Cloning"},"content":{"rendered":"<h2 id=\"section-LinuxCloning-LinuxCloningProcedureInANutshell\">Linux cloning procedure in a nutshell<\/h2>\n<p>By Nathan Johnson<\/p>\n<p>Inspired in part by: <a class=\"external\" href=\"http:\/\/www.ebruni.it\/docs\/clone_linux\/t1.htm\" target=\"wikiext\">http:\/\/www.ebruni.it\/docs\/clone_linux\/t1.htm<\/a><\/p>\n<p>Note: while these instructions are meant to clone one working machine onto a blank target, this could pretty easily be modified to be a bare metal backup \/ restore procedure by simply storing a tarball instead of using netcat to copy to a live system, and for the restore to just use the tarball as a source and write to netcat versus reading from a live system<\/p>\n<p>Prerequisites: two machines with similar hardware \/ architecture. i.e., if source is 64 bit, dest must also be 64 bit. The closer the system architecures, the better.<\/p>\n<p>Source Machine running RHEL (for the purposes of this)<\/p>\n<p>RHEL installation DVD of same version as source machine (roughly)<\/p>\n<p>Boot from RHEL DVD in rescue mode. When the DVD boots and it&#8217;s prompting you with the boot: prompt,<\/p>\n<p>boot:<\/p>\n<p>type:<\/p>\n<pre>linux rescue<\/pre>\n<p>and hit enter.<\/p>\n<p>It will then ask you language, go with defaults (English \/ US). When it asks if you want to start the network interfaces, say no. When it asks if you want to find a linux installation, select Skip. It will dump you back to a shell. I&#8217;m going to assume that the source uses LVM.<\/p>\n<p>If the disk is already partitioned and LVM is already configured, skip to step 2.<\/p>\n<h3 id=\"section-LinuxCloning-Step1\">Step 1:<\/h3>\n<p>Regardless of whether lvm is used, we must first run fdisk as linux cannot boot from an LVM volume. Use the following to get the device names of the available disks on the system:<\/p>\n<pre>sh-3.2# fdisk -l<\/pre>\n<p>Then pick one to do the install on. Start fdisk on this device. For the purposes of this example, the disk device will be \/dev\/cciss\/c0d0<\/p>\n<pre>sh-3.2# fdisk \/dev\/cciss\/c0d0<\/pre>\n<p>select &#8216;n&#8217; to add a new partition, &#8216;p&#8217; for primary, 1 for partition number, go with default for first cylinder (1), and +500M to select a 500M partition for boot (this can be 100M or even less if you want, but 500M gives a lot of wiggle room). Now with the boot partition created, make it active by selecting &#8216;a&#8217; and select partition number &#8216;1&#8217;<\/p>\n<p>select &#8216;n&#8217; to add another partition, &#8216;p&#8217; for primary, &#8216;2&#8217; for partition number, go with default for first cylinder, and go with default for last (i.e., use the rest of the disk). This will be our LVM partition. Hit &#8216;t&#8217; to change the system ID of this partition, select partition number of &#8216;2&#8217;, and select &#8216;8e&#8217; as partition type for Linux LVM.<\/p>\n<p>Hit &#8216;p&#8217; and ensure that your layout. Here is an example of what we would have just configured above:<\/p>\n<pre>Disk \/dev\/cciss\/c0d0: 293.5 GB, 293563949056 bytes\r\n255 heads, 63 sectors\/track, 35690 cylinders\r\nUnits = cylinders of 16065 * 512 = 8225280 bytes\r\n\r\n           Device Boot      Start         End      Blocks   Id  System\r\n\/dev\/cciss\/c0d0p1   *           1          64      514048+  83  Linux\r\n\/dev\/cciss\/c0d0p2              65       35690   286165845   8e  Linux LVM<\/pre>\n<p>If all is well, hit &#8216;w&#8217; to write the partition table to disk and exit.<\/p>\n<p>At this point, we need to look at the logical volume layout on the source:<\/p>\n<h3 id=\"section-LinuxCloning-Step2\">step 2:<\/h3>\n<pre>[root@fisma-lin-app-1 ~]# lvm lvdisplay\r\n  --- Logical volume ---\r\n  LV Name                \/dev\/mainvolgroup\/rootvol\r\n  VG Name                mainvolgroup\r\n  LV UUID                yL9jYW-b12C-A0kN-iSve-tySm-JVIZ-o8EhuY\r\n  LV Write Access        read\/write\r\n  LV Status              available\r\n  # open                 1\r\n  LV Size                268.91 GB\r\n  Current LE             8605\r\n  Segments               1\r\n  Allocation             inherit\r\n  Read ahead sectors     auto\r\n  - currently set to     256\r\n  Block device           253:0\r\n\r\n  --- Logical volume ---\r\n  LV Name                \/dev\/mainvolgroup\/swapvol\r\n  VG Name                mainvolgroup\r\n  LV UUID                JF37pZ-hTlc-crSm-wdC3-jqlG-VOuM-e033oS\r\n  LV Write Access        read\/write\r\n  LV Status              available\r\n  # open                 1\r\n  LV Size                4.00 GB\r\n  Current LE             128\r\n  Segments               1\r\n  Allocation             inherit\r\n  Read ahead sectors     auto\r\n  - currently set to     256\r\n  Block device           253:1<\/pre>\n<p>Here we see two logical volumes, rootvol of size 268GB and swapvol of size 4GB, inside the volume group named mainvolgroup. Now we need to recreate the names at least to be the same, even if the sizes differ, on the target machine<\/p>\n<p>Create the physical volume on the target for the LVM partition we created with fdisk above:<\/p>\n<pre>sh-3.2# lvm pvcreate \/dev\/cciss\/c0d0p2<\/pre>\n<p>Now create the volume group (mainvolgroup in this case) to live on the physical volume:<\/p>\n<pre>sh-3.2# lvm vgcreate mainvolgroup \/dev\/cciss\/c0d0p2<\/pre>\n<p>Now create the logical volumes to live inside the volume group. In this example we&#8217;ll create a 4G partition called swapvol and then use the remaining free space for the root partition.<\/p>\n<pre>sh-3.2# lvm lvcreate -L 4G -n swapvol mainvolgroup\r\nsh-3.2# lvm lvcreate -l 100%FREE -n rootvol mainvolgroup<\/pre>\n<p>Skip ahead to Step 4<\/p>\n<h3 id=\"section-LinuxCloning-Step3\">Step 3:<\/h3>\n<p>If you have skipped ahead because the disk has already been partitioned, you may need to enable the volume groups (they will be active already if you&#8217;ve carved up the disk to this point). Assuming the volume group is called mainvolgroup, you can activate this using:<\/p>\n<pre>sh-3.2# lvm vgchange -ay mainvolgroup<\/pre>\n<h3 id=\"section-LinuxCloning-Step4\">Step 4:<\/h3>\n<p>Now we need to format our partitions:<\/p>\n<p>First boot:<\/p>\n<pre>sh-3.2# mke2fs -j \/dev\/cciss\/c0d0p1<\/pre>\n<p>Now root:<\/p>\n<pre>sh-3.2# mke2fs -j \/dev\/mainvolgroup\/rootvol<\/pre>\n<p>Now swap:<\/p>\n<pre>sh-3.2# mkswap \/dev\/mainvolgroup\/swapvol<\/pre>\n<h3 id=\"section-LinuxCloning-Step5\">Step 5:<\/h3>\n<p>Now let&#8217;s create a mount point and mount the root vol on the target machine:<\/p>\n<pre>sh-3.2# mkdir \/mnt\/rhroot\r\nsh-3.2# mount \/dev\/mainvolgroup\/rootvol \/mnt\/rhroot<\/pre>\n<h3 id=\"section-LinuxCloning-Step6\">Step 6<\/h3>\n<p>Now we need to create some directories:<\/p>\n<pre>sh-3.2# cd \/mnt\/rhroot\r\nsh-3.2# mkdir proc sys media misc mnt net selinux srv boot tmp\r\nsh-3.2# chmod 1777 tmp<\/pre>\n<p>Mount our boot partition:<\/p>\n<pre>sh-3.2# mount \/dev\/cciss\/c0d0p1 \/mnt\/rhroot\/boot<\/pre>\n<h3 id=\"section-LinuxCloning-Step7\">Step 7<\/h3>\n<p>Now we need to bring up a network interface.<\/p>\n<pre>sh-3.2# ifconfig eth0 10.200.99.10 netmask 255.255.255.128\r\nsh-3.2# route add default gw 10.200.99.5\r\nsh-3.2# echo \"nameserver 160.129.6.22\" &gt; \/etc\/resolv.conf<\/pre>\n<p>(obviously substituting the ip address and netmask you need here, preferably something not already in use, as well as gateway address and dns servers)<\/p>\n<p>note: if you have dhcp available, you could just do: &#8220;pump -i eth0&#8221; instead<\/p>\n<p>You will also need to assign 127.0.0.1 to loopback, this is not automatically done on the RHEL rescue. This is only required if doing ssh tunnels.<\/p>\n<pre>sh-3.2# ifconfig lo 127.0.0.1 netmask 255.0.0.0<\/pre>\n<p>If you do not have a port that can be opened directly from source to dest, skip to Step 8 for configuring an ssh tunnel. Otherwise skip to step 9<\/p>\n<h3 id=\"section-LinuxCloning-Step8\">Step 8<\/h3>\n<p>if the source and dest are separated by a firewall and there is no convenient port available for netcat to use, ssh forwarding can be used as long as the source can ssh to dest, or as long as there is a box that both the source and dest can ssh into.<\/p>\n<p>Using the first scenario:<\/p>\n<p>from dest, hit Ctrl+Alt+F2 to get to the second VC and type:<\/p>\n<p>ssh -Rlocalhost:6060:127.0.0.1:6060 user@dest<\/p>\n<p>Switch back over to the First VC for the rest by hitting Ctrl+Alt+F1<\/p>\n<p>Using the second scenario:<\/p>\n<p>From source, open up a second shell and type: ssh -L6060:localhost:6060 user@somehost<\/p>\n<p>from dest, hit Ctrl+Alt+F2 to get to the second VC and type: ssh -Rlocalhost:6060:127.0.0.1:6060 user@somehost<\/p>\n<p>Switch back over to the First VC for the rest by hitting Ctrl+Alt+F1<\/p>\n<h3 id=\"section-LinuxCloning-Step9\">Step 9<\/h3>\n<p>It is useful to set the time on the destination machine. Unfortunately there is no ntp client on the RHEL rescue image, so you will have to set it manually with the date command as well as set the timezone. Keep in mind that the date command on the rescue CD gives the following time format:<\/p>\n<p><span style=\"font-family: monospace;\"> MMDDhhmmCCYY.ss <\/span> So to set the time to 11\/11\/2010 15:30:45 You would give date -s 111115302010.45<\/p>\n<pre>sh-3.2# export TZ=CST\r\nsh-3.2# date -s 111115302010.45<\/pre>\n<h3 id=\"section-LinuxCloning-Step10\">Step 10:<\/h3>\n<p>Copy the data<\/p>\n<p>now, from the \/mnt\/rhroot directory of the source machine we need to start netcat to listen and pipe to tar:<\/p>\n<pre>sh-3.2# cd \/mnt\/rhroot\r\nsh-3.2# nc -l -p 6060 | tar xvp<\/pre>\n<p>where 6060 is some arbitrary port you want to listen on.<\/p>\n<p>Now, from the source machine:<\/p>\n<p>Create an excludes file, I&#8217;m going to name it ~\/excludes, with the following entries:<\/p>\n<pre>\/lost+found\/\r\n\/media\/\r\n\/misc\r\n\/mnt\r\n\/net\r\n\/proc\r\n\/selinux\r\n\/srv\r\n\/sys\r\n\/tmp<\/pre>\n<pre>tar cvOp --same-owner -X ~\/excludes  \/ | nc -w 5 10.200.99.10 6060<\/pre>\n<p>(the ip address will be localhost if you&#8217;re doing ssh forwarding)<\/p>\n<p>Go get coffee.<\/p>\n<h3 id=\"section-LinuxCloning-Step11\">Step 11<\/h3>\n<p>Once copying has finished, we will bind mount some pseudo filesystems and chroot to our new environment (dest), and do a little cleanup<\/p>\n<pre>sh-3.2# mount -o bind \/dev \/mnt\/rhroot\/dev\r\nsh-3.2# mount -o bind \/sys \/mnt\/rhroot\/sys\r\nsh-3.2# mount -o bind \/proc \/mnt\/rhroot\/proc\r\nsh-3.2# mount -o bind \/selinux \/mnt\/rhroot\/selinux\r\nsh-3.2# chroot \/mnt\/rhroot\r\nsh-3.2# su -\r\n[root@localhost]# cp \/proc\/mounts \/etc\/mtab\r\n[root@localhost]# cd \/dev\r\n[root@localhost]# ln -s mainvolgroup\/rootvol root<\/pre>\n<p>Obviously adjust this last line to match the dev entry for the root filesystem, but this symlink must be present. Alternately you can use mknod to create a &#8220;real&#8221; dev entry.<\/p>\n<h3 id=\"section-LinuxCloning-Step12\">Step 12<\/h3>\n<p>So now we need to modify some boot config files (possibly) and finalize our configuration, leaving the disk ready to be booted.<\/p>\n<p><strong>a)<\/strong> Modify \/etc\/fstab , paying particular attention to the \/boot partition as it may be different on dest than on source (don&#8217;t rely on LABEL, give a path to the device)<\/p>\n<p><strong>b)<\/strong> Modify the \/boot\/grub\/menu.lst to ensure that it has the proper boot device set, and install the boot loader into the MBR<\/p>\n<pre>sh-3.2# grub-install \/dev\/cciss\/c0d0<\/pre>\n<p><strong>c)<\/strong> Modify the \/etc\/sysconfig\/network-scripts\/ifcfg-eth0 to give it a new IP address, make sure to remove the HWADDR line as it will actually clone the Mac address of the original (unless this is desired).<\/p>\n<p><strong>d)<\/strong> Modify \/etc\/sysconfig\/network and update the hostname<\/p>\n<p><strong>e)<\/strong> Create initrd images for all of the kernels in \/boot<\/p>\n<p>For example:<\/p>\n<pre>[root@localhost]# ls -l \/boot\/vmlinuz*\r\n\r\n-rw-r--r-- 1 root root 1954780 Sep 17 04:11 \/boot\/vmlinuz-2.6.18-194.11.4.el5\r\n-rw-r--r-- 1 root root 1955036 Sep 20 06:17 \/boot\/vmlinuz-2.6.18-194.17.1.el5\r\n-rw-r--r-- 1 root root 1955356 Oct 29 13:26 \/boot\/vmlinuz-2.6.18-194.26.1.el5<\/pre>\n<p>So we could do the following:<\/p>\n<pre>[root@localhost]# mkinitrd -f \/boot\/initrd-2.6.18-194.26.1.el5.img 2.6.18-194.26.1.el5\r\n[root@localhost]# mkinitrd -f \/boot\/initrd-2.6.18-194.17.1.el5.img 2.6.18-194.17.1.el5\r\n[root@localhost]# mkinitrd -f \/boot\/initrd-2.6.18-194.11.4.el5.img 2.6.18-194.11.4.el5<\/pre>\n<p>the first argument is the initrd image, the second argument is the kernel version.<\/p>\n<h3 id=\"section-LinuxCloning-Step13\">Step 13<\/h3>\n<p>Final Cleanup<\/p>\n<p>Now exit out of the su shell, exit again out of chroot, then unmount everything and reboot!<\/p>\n<pre>[root@localhost ]# exit\r\nsh-3.2# exit\r\nsh-3.2# cd \/\r\nsh-3.2# umount \/mnt\/rhroot\/proc\r\nsh-3.2# umount \/mnt\/rhroot\/sys\r\nsh-3.2# umount \/mnt\/rhroot\/selinux\r\nsh-3.2# umount \/mnt\/rhroot\/dev\r\nsh-3.2# umount \/mnt\/rhroot\/boot\r\nsh-3.2# umount \/mnt\/rhroot<\/pre>\n<p>If it says it&#8217;s still busy, make sure you didn&#8217;t forget any, type &#8220;mount&#8221; and see what&#8217;s still mounted under \/mnt\/rhroot<\/p>\n<h3 id=\"section-LinuxCloning-Step14\">Step 14<\/h3>\n<p>Boot system from hard disk<\/p>\n<p>If all goes well, you can reboot from the hard drive and it should pull up your working clone.<\/p>\n<p>You will need to join the domain again if you are using samba \/ winbind. You will need to re-run rhn_register and give it a new license<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Linux cloning procedure in a nutshell By Nathan Johnson Inspired in part by: http:\/\/www.ebruni.it\/docs\/clone_linux\/t1.htm Note: while these instructions are meant to clone one working machine onto a blank target, this could pretty easily be modified to be a bare metal backup \/ restore procedure by simply storing a tarball instead of using netcat to copy [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,7],"tags":[14,13,12,15],"class_list":["post-42","post","type-post","status-publish","format-standard","hentry","category-linux","category-red-hat","tag-backup","tag-bare-metal-restore","tag-linux-2","tag-linux-cloning"],"_links":{"self":[{"href":"https:\/\/www.nathanjohnson.org\/index.php?rest_route=\/wp\/v2\/posts\/42","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.nathanjohnson.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.nathanjohnson.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.nathanjohnson.org\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.nathanjohnson.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=42"}],"version-history":[{"count":7,"href":"https:\/\/www.nathanjohnson.org\/index.php?rest_route=\/wp\/v2\/posts\/42\/revisions"}],"predecessor-version":[{"id":126,"href":"https:\/\/www.nathanjohnson.org\/index.php?rest_route=\/wp\/v2\/posts\/42\/revisions\/126"}],"wp:attachment":[{"href":"https:\/\/www.nathanjohnson.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=42"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.nathanjohnson.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=42"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.nathanjohnson.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=42"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}