Sometimes we need to clone a Linux system for the following reason :
- Install new Linux server with the same software level as existing one.
- Moving the Linux operating system to the server hardware.
- Change the root disk to the bigger one.
This article will show you how to move a running Debian Linux system to larger disk. In this how-to document I will use the following Debian version :
root@debian01:~# lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 7.1 (wheezy) Release: 7.1 Codename: wheezy root@debian01:~#
Lets start with examining the existing Linux system.
- To check the hostname and kernel version we can use
uname -a
command as shown below :root@debian01:~# uname -a Linux debian01 3.2.0-4-686-pae #1 SMP Debian 3.2.46-1+deb7u1 i686 GNU/Linux root@debian01:~#
- To check mounted filesystem we can use
df
command as shown below :root@debian01:~# df -h Filesystem Size Used Avail Use% Mounted on rootfs 19G 1.3G 17G 7% / udev 10M 0 10M 0% /dev tmpfs 406M 268K 406M 1% /run /dev/disk/by-uuid/9cd78397-4505-4c80-bddb-703543cdc46f 19G 1.3G 17G 7% / tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 987M 0 987M 0% /run/shm root@debian01:~#
From the output we can see that, all directory stored under root filesystem. It didn’t separate directory like
/boot
,/var
, or even/home
. This information will affect the way we clone the disk to the new disks. We will talk about this later when we setup the partition on the new disk. - To check the partition layout on the existing disk we can use
fdisk
command :root@debian01:~# fdisk -l Disk /dev/sda: 21.5 GB, 21474836480 bytes 255 heads, 63 sectors/track, 2610 cylinders, total 41943040 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00029de3 Device Boot Start End Blocks Id System /dev/sda1 * 2048 40136703 20067328 83 Linux /dev/sda2 40138750 41940991 901121 5 Extended /dev/sda5 40138752 41940991 901120 82 Linux swap / Solaris root@debian01:~#
- To check the partition type on existing disk we can use
blkid
command. In the following command, we can see that existing disk only consist of 2 partition : root & swap. Root partition usesext4
filesystem.root@debian01:~# blkid /dev/sda5: UUID="5e43e27b-038a-45e2-bf84-2f31105b63a0" TYPE="swap" /dev/sda1: UUID="9cd78397-4505-4c80-bddb-703543cdc46f" TYPE="ext4" root@debian01:~#
- To check active network configuration we can use
ifconfig
command as shown below :root@debian01:~# ifconfig -a eth0 Link encap:Ethernet HWaddr 08:00:27:10:f3:d2 inet addr:192.168.10.62 Bcast:192.168.10.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:fe10:f3d2/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:433 errors:0 dropped:0 overruns:0 frame:0 TX packets:170 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:94304 (92.0 KiB) TX bytes:23369 (22.8 KiB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) root@debian01:~#
So lets move on by attach the new disk to the system. In this case I use a disk with bigger size than the existing root disk. Depends on the server itself, we can instantly attaching the new disk or it probably require reboot to let the system recognize the new disk. To check whether the new disk already attached we can use the fdisk
command as shown below :
root@debian01:~# fdisk -l Disk /dev/sda: 21.5 GB, 21474836480 bytes 255 heads, 63 sectors/track, 2610 cylinders, total 41943040 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00029de3 Device Boot Start End Blocks Id System /dev/sda1 * 2048 40136703 20067328 83 Linux /dev/sda2 40138750 41940991 901121 5 Extended /dev/sda5 40138752 41940991 901120 82 Linux swap / Solaris Disk /dev/sdb: 42.9 GB, 42949672960 bytes 255 heads, 63 sectors/track, 5221 cylinders, total 83886080 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000 Disk /dev/sdb doesn't contain a valid partition table root@debian01:~#
Before able to use new disk (/dev/sdb
) as clone target, we need to prepare its partition first. We will use fdisk
command to prepare the partition, below is the step-by-step guide to use fdisk
:
- Start by invoking the
fdisk
command on/dev/sdb
as shown below :root@debian01:~# fdisk /dev/sdb Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel Building a new DOS disklabel with disk identifier 0x9c5d68fe. Changes will remain in memory only, until you decide to write them. After that, of course, the previous content won't be recoverable. Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite) Command (m for help):
- Type
p
and press Enter to see the existing partition layout :Command (m for help): p Disk /dev/sdb: 42.9 GB, 42949672960 bytes 255 heads, 63 sectors/track, 5221 cylinders, total 83886080 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x9c5d68fe Device Boot Start End Blocks Id System Command (m for help):
Since the disk doesn’t have any partition at all then it shows empty partition layout. If there is any partition in the disk, we better delete it first by typing
d
(as for delete). - To start create a partition on the disk type
n
as in “new partition”. Then we must decide whether we want to create primary or extended partition type. In this sample I choose to create primary partition type.Command (m for help): n Partition type: p primary (0 primary, 0 extended, 4 free) e extended Select (default p): p Partition number (1-4, default 1): Using default value 1 First sector (2048-83886079, default 2048): Using default value 2048 Last sector, +sectors or +size{K,M,G} (2048-83886079, default 83886079): +15G Command (m for help):
We need to define 3 value for each partition, they are :
- Partition number : this will define the order of each partition, it define the name of partition later (
/dev/sda1
,/dev/sdb2
, etc, etc). - First sector : this define the starting point of the partition. We can see that the whole disk consist of number of sectors start from sector number 2048–83886079. Logically we start from the beginning of the disk, sector 2048.
- Last sector : last sector will define how big the partition will be. Since defining the partition using sector unit will be difficult,
fdisk
will let us define the size using human-readable size unit like K (for kilobyte), M (for Megabyte), or G (for Gigabyte). Just remember to start the value with+
sign. In the example above, I choose to create 15G partition.
- Partition number : this will define the order of each partition, it define the name of partition later (
- Print the parition layout to verify the first partition created successfully :
Command (m for help): p Disk /dev/sdb: 42.9 GB, 42949672960 bytes 255 heads, 63 sectors/track, 5221 cylinders, total 83886080 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x9c5d68fe Device Boot Start End Blocks Id System /dev/sdb1 2048 31459327 15728640 83 Linux Command (m for help):
- Then we need to create second partition with 4GB size, we will use this partition as swap partition.
Command (m for help): n Partition type: p primary (1 primary, 0 extended, 3 free) e extended Select (default p): Using default response p Partition number (1-4, default 2): Using default value 2 First sector (31459328-83886079, default 31459328): Using default value 31459328 Last sector, +sectors or +size{K,M,G} (31459328-83886079, default 83886079): +4G Command (m for help):
See that the first sector now started from sector number 31459328.
fdisk
already know that the first partition will ended on 31459327 so the next available space will start on 31459328. - Print the parition layout to verify the second partition created successfully :
Command (m for help): p Disk /dev/sdb: 42.9 GB, 42949672960 bytes 255 heads, 63 sectors/track, 5221 cylinders, total 83886080 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x9c5d68fe Device Boot Start End Blocks Id System /dev/sdb1 2048 31459327 15728640 83 Linux /dev/sdb2 31459328 39847935 4194304 83 Linux Command (m for help):
- I want to separate the
/home
as separate partition, so I create the 3rd partition and assign the rest available space to that.Command (m for help): n Partition type: p primary (2 primary, 0 extended, 2 free) e extended Select (default p): p Partition number (1-4, default 3): Using default value 3 First sector (39847936-83886079, default 39847936): Using default value 39847936 Last sector, +sectors or +size{K,M,G} (39847936-83886079, default 83886079): Using default value 83886079 Command (m for help):
- Print the partition again to verify all partition already correct :
Command (m for help): p Disk /dev/sdb: 42.9 GB, 42949672960 bytes 255 heads, 63 sectors/track, 5221 cylinders, total 83886080 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x9c5d68fe Device Boot Start End Blocks Id System /dev/sdb1 2048 31459327 15728640 83 Linux /dev/sdb2 31459328 39847935 4194304 83 Linux /dev/sdb3 39847936 83886079 22019072 83 Linux Command (m for help):
- Then we need to toggle bootable flag on the 1st partition since it act as root partition which contains
/boot
directory. Typea
to start assign the bootable flag and then later type1
to choose partition number 1.Command (m for help): a Partition number (1-4): 1 Command (m for help): p Disk /dev/sdb: 42.9 GB, 42949672960 bytes 255 heads, 63 sectors/track, 5221 cylinders, total 83886080 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x9c5d68fe Device Boot Start End Blocks Id System /dev/sdb1 * 2048 31459327 15728640 83 Linux /dev/sdb2 31459328 39847935 4194304 83 Linux /dev/sdb3 39847936 83886079 22019072 83 Linux Command (m for help):
If the partition already marked as bootable, then you can see the
*
sign in that partition. - To make the changes permanently we need to type
w
as in “write into partition table” :Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks. root@debian01:~#
After have the partition setup, we need to create the filesystem on top of it. In this example, we will use ext3
filesystem on partition 1 & 3. Also we need to activate partition number 2 as swap partition. To create the ext3
filesystem, we will use mkfs.ext3
command as shown in the following sample :
root@debian01:~# mkfs.ext3 /dev/sdb1 mke2fs 1.42.5 (29-Jul-2012) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 983040 inodes, 3932160 blocks 196608 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=4026531840 120 block groups 32768 blocks per group, 32768 fragments per group 8192 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208 Allocating group tables: done Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: done root@debian01:~# mkfs.ext3 /dev/sdb3 mke2fs 1.42.5 (29-Jul-2012) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 1376256 inodes, 5504768 blocks 275238 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=0 168 block groups 32768 blocks per group, 32768 fragments per group 8192 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000 Allocating group tables: done Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: done root@debian01:~#
To activate the second partition as swap we will use mkswap
command as shown below :
root@debian01:~# mkswap /dev/sdb2 Setting up swapspace version 1, size = 4194300 KiB no label, UUID=c891f223-4912-4c4d-adbc-0158c89b8aff root@debian01:~#
Once filesystem created, then we can mount the partition as shown on the following example :
root@debian01:~# mkdir /media/newroot root@debian01:~# mkdir /media/newhome root@debian01:~# mount /dev/sdb1 /media/newroot/ root@debian01:~# mount /dev/sdb3 /media/newhome/
We will use rsync
command to do data synchronization between old disk to the new one. If you don’t have rsync
installed on your system, then go install it first. Here is the sample installing rsync
in Debian-based Linux distribution :
root@debian01:~# apt-get install rsync Reading package lists... Done Building dependency tree Reading state information... Done The following NEW packages will be installed: rsync 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 357 kB of archives. After this operation, 639 kB of additional disk space will be used. Get:1 http://kambing.ui.ac.id/debian/ wheezy/main rsync i386 3.0.9-4 [357 kB] Fetched 357 kB in 0s (397 kB/s) Selecting previously unselected package rsync. (Reading database ... 45874 files and directories currently installed.) Unpacking rsync (from .../rsync_3.0.9-4_i386.deb) ... Processing triggers for man-db ... Setting up rsync (3.0.9-4) ... update-rc.d: using dependency based boot sequencing root@debian01:~#
Below is the sample how we use rsync
to copy root partition to the new disk :
root@debian01:~# rsync -ar --exclude "/home" --exclude "/media/newroot" --exclude "/media/newhome" --exclude "/proc" --exclude "/sys" /* /media/newroot root@debian01:~#
We will exclude some directory like /proc/
and /sys
because both aren’t needed for this cloning process. We also excluding the partition of new disk as well.
We will copy /home/
partition to dedicated partition as well :
root@debian01:~# rsync -ar /home/* /media/newhome/ root@debian01:~#
Here is the status after synchronization process finished :
root@debian01:~# df -h Filesystem Size Used Avail Use% Mounted on rootfs 19G 1.3G 17G 8% / udev 10M 0 10M 0% /dev tmpfs 406M 280K 406M 1% /run /dev/disk/by-uuid/9cd78397-4505-4c80-bddb-703543cdc46f 19G 1.3G 17G 8% / tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 987M 0 987M 0% /run/shm /dev/sdb1 15G 1.3G 13G 10% /media/newroot /dev/sdb3 21G 173M 20G 1% /media/newhome root@debian01:~#
Then we will chroot
-ing to the new root partition (/dev/sdb1
which mounted at /media/newroot
at the moment). There are some step should be executed before we can chroot
to the new root environment :
root@debian01:~# mkdir /media/newroot/proc root@debian01:~# mkdir /media/newroot/dev root@debian01:~# mkdir /media/newroot/sys root@debian01:~# mount -o bind /dev /media/newroot/dev/ root@debian01:~# mount -t proc none /media/newroot/proc root@debian01:~# mount -t sysfs none /media/newroot/sys root@debian01:~# chroot /media/newroot
There are some steps will be executed from inside chroot
environment :
- Before begin we need to verify that we already inside the
chroot
environment. The simplest task is usingdf -h
command as shown below :root@debian01:/# df -h df: `/media/newhome': No such file or directory Filesystem Size Used Avail Use% Mounted on rootfs 15G 1.3G 13G 10% / udev 10M 0 10M 0% /dev devpts 10M 0 10M 0% /dev/pts tmpfs 15G 1.3G 13G 10% /run /dev/disk/by-uuid/9cd78397-4505-4c80-bddb-703543cdc46f 15G 1.3G 13G 10% / tmpfs 15G 1.3G 13G 10% /run/lock tmpfs 15G 1.3G 13G 10% /run/shm rpc_pipefs 15G 1.3G 13G 10% /var/lib/nfs/rpc_pipefs /dev/sdb1 15G 1.3G 13G 10% / udev 10M 0 10M 0% /dev root@debian01:/# root@debian01:/# pwd / root@debian01:/#
See that there is no
/dev/sdb1
&/dev/sdb3
being mounted, since we are already inside that/dev/sdb1
. - Then we need to modify
/etc/fstab
file. This file will define the list of partition that must be mounted during boot process. Copy the existingfstab
file as backup.root@debian01:/# cd /etc/ root@debian01:/etc# cp fstab fstab-orig
Once have the backup, we can safely edit the
fstab
file. We need to change the disk identification so all partition information pointed to the new disk (/dev/sdb1
). We can useblkid
command to check the UUID of the new disk :root@debian01:/etc# blkid /dev/sda5: UUID="5e43e27b-038a-45e2-bf84-2f31105b63a0" TYPE="swap" /dev/sda1: UUID="9cd78397-4505-4c80-bddb-703543cdc46f" TYPE="ext4" /dev/sdb1: UUID="d9e6bd2b-8446-4f61-9636-9b078c0d966a" SEC_TYPE="ext2" TYPE="ext3" /dev/sdb2: UUID="c891f223-4912-4c4d-adbc-0158c89b8aff" TYPE="swap" /dev/sdb3: UUID="2cbe1cb3-1084-4229-92ff-847cd53e408a" SEC_TYPE="ext2" TYPE="ext3" root@debian01:/etc#
Then we can change the UUID informatio inside the
fdisk
file :root@debian01:/etc# vi fstab # /etc/fstab: static file system information. # # Use 'blkid' to print the universally unique identifier for a # device; this may be used with UUID= as a more robust way to name devices # that works even if disks are added and removed. See fstab(5). # # <file system> <mount point> <type> <options> <dump> <pass> # / was on /dev/sda1 during installation UUID=d9e6bd2b-8446-4f61-9636-9b078c0d966a / ext3 errors=remount-ro 0 1 # swap was on /dev/sda5 during installation UUID=c891f223-4912-4c4d-adbc-0158c89b8aff none swap sw 0 0 UUID=2cbe1cb3-1084-4229-92ff-847cd53e408a /home ext3 defaults 0 1 /dev/sr0 /media/cdrom0 udf,iso9660 user,noauto 0 0 root@debian01:/etc#
We can compare the backup
fstab
with the one we just modified :root@debian01:/etc# diff -u fstab-orig fstab --- /etc/fstab 2013-09-21 11:03:34.000000000 +0700 +++ /etc/fstab-orig 2013-09-21 10:57:55.000000000 +0700 @@ -6,8 +6,7 @@ # # <file system> <mount point> <type> <options> <dump> <pass> # / was on /dev/sda1 during installation -UUID=d9e6bd2b-8446-4f61-9636-9b078c0d966a / ext3 errors=remount-ro 0 1 +UUID=9cd78397-4505-4c80-bddb-703543cdc46f / ext4 errors=remount-ro 0 1 # swap was on /dev/sda5 during installation -UUID=c891f223-4912-4c4d-adbc-0158c89b8aff none swap sw 0 0 -UUID=2cbe1cb3-1084-4229-92ff-847cd53e408a /home ext3 defaults 0 1 +UUID=5e43e27b-038a-45e2-bf84-2f31105b63a0 none swap sw 0 0 /dev/sr0 /media/cdrom0 udf,iso9660 user,noauto 0 0 root@debian01:/etc#
- If we want to clone this new disk as new server then we probably need to modify the hostname & IP configuration. We can do it now :
root@debian01:/etc# cat /etc/hostname debian01 root@debian01:/etc# vi /etc/hostname debian01-new root@debian01:/etc#
- In this step we need to reinstall the boot loader into new disk’s MBR. In this example, system use GRUB boot loader so we will use the following command to reinstall the GRUB :
root@debian01:/etc# update-grub Generating grub.cfg ... Found linux image: /boot/vmlinuz-3.2.0-4-686-pae Found initrd image: /boot/initrd.img-3.2.0-4-686-pae done root@debian01:/etc# grub-install /dev/sdb Installation finished. No error reported. root@debian01:/etc#
- Exit the
chroot
environment :root@debian01:/etc# exit root@debian01:~# df -h Filesystem Size Used Avail Use% Mounted on rootfs 19G 1.3G 17G 8% / udev 10M 0 10M 0% /dev tmpfs 406M 280K 406M 1% /run /dev/disk/by-uuid/9cd78397-4505-4c80-bddb-703543cdc46f 19G 1.3G 17G 8% / tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 987M 0 987M 0% /run/shm /dev/sdb1 15G 1.3G 13G 10% /media/newroot /dev/sdb3 21G 173M 20G 1% /media/newhome udev 10M 0 10M 0% /media/newroot/dev root@debian01:~#
At this point we have successfully clone the complete Linux system to the new disk. We can shutdown the server and swap the disk or we can use the second disk (/dev/sdb
) to boot another server.
root@debian01:~# shutdown -h now Broadcast message from root@debian01 (pts/0) (Sat Sep 21 11:00:57 2013): The system is going down for system halt NOW! root@debian01:~#
If everything is right then system will be able to boot using the /dev/sdb
:
$ ssh root@192.168.10.62 root@192.168.10.62's password: Linux debian01-new 3.2.0-4-686-pae #1 SMP Debian 3.2.46-1+deb7u1 i686 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Sat Sep 21 11:06:54 2013 root@debian01-new:~# uname -a Linux debian01-new 3.2.0-4-686-pae #1 SMP Debian 3.2.46-1+deb7u1 i686 GNU/Linux root@debian01-new:~# df -h Filesystem Size Used Avail Use% Mounted on rootfs 15G 1.3G 13G 10% / udev 10M 0 10M 0% /dev tmpfs 406M 268K 406M 1% /run /dev/disk/by-uuid/d9e6bd2b-8446-4f61-9636-9b078c0d966a 15G 1.3G 13G 10% / tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 1.6G 0 1.6G 0% /run/shm /dev/sda3 21G 173M 20G 1% /home root@debian01-new:~# su - ttirtawi ttirtawi@debian01-new:~$ pwd /home/ttirtawi ttirtawi@debian01-new:~$
See that the disk with UUID d9e6bd2b-8446-4f61-9636-9b078c0d966a
is mounted as root now.
Congratulation you have your Linux live on the new disk now.
Illustration from : http://www.linux.org/resources/debian.11/