Debian root on a flash disk and the data on a hard disk

This article is about installing Debian on a flash disk, like SD card, flash disk, Solid State Disk etc. The goal is to have the data on a hard disk. This will increase the lifetime of the flash disk.

Assumption of this article is that Debian is already installed on a flash disk in the root “/”-directory.

In the article Installing Debian on the Sheevaplug there is also a separate “/boot” ext2 partition, because U-Boot is unable to read from ext3 partitions. This article is written while installing Debian Squeeze on the SheevaPlug, but this article can also be used for other Debian or Ubuntu systems. Only the device names and partitions can be different.

Data directories and swap

The question is which directories are changing a lot. Here are some Linux partitioning guidelines: Partitioning_guidelines

The following directories and swap will have their partition on the hard disk:

  • swap - Advice: one till two times the amount of RAM, depends on the situation
  • /tmp - 1 till 10GB (in case of burning discs)
  • /var - 100GB (used for logging, web server, mail etc)
  • /home - User data

Partitioning the hard disk

If you use an external hard disk, please attach the hard disk. With the following command:

$ dmesg
[ 2758.322260] scsi 2:0:0:0: Direct-Access     WD       3200JB External  0108 PQ: 0 ANSI: 0
[ 2758.375699] sd 2:0:0:0: [sda] 625142448 512-byte logical blocks: (320 GB/298 GiB)
[ 2758.384571] sd 2:0:0:0: [sda] Write Protect is off
[ 2758.389414] sd 2:0:0:0: [sda] Mode Sense: 03 00 00 00
[ 2758.389425] sd 2:0:0:0: [sda] Assuming drive cache: write through
[ 2758.398067] sd 2:0:0:0: [sda] Assuming drive cache: write through
[ 2758.404191]  sda: sda1 sda2 sda3
[ 2758.428938] sd 2:0:0:0: [sda] Assuming drive cache: write through
[ 2758.435069] sd 2:0:0:0: [sda] Attached SCSI disk

Here you can see that the disk is attached as a SCSI disk to device /dev/sda. And that the disk is already partitioned in sda1, sda2 and sda3. For partitioning we are using fdisk. We are going to use the following commands in fdisk:

p’ - Show the current partition table ‘d’ - Remove a partition ‘n’ - Create a new partition

We are going to remove this partitions first, if there are already partitions available:

$ fdisk /dev/sda
Command (m for help): d
Partition number (1-4): 1

Command (m for help): d
Partition number (1-4): 2

Command (m for help): d
Selected partition 3

And now we can create the 4 partitions with fdisk:

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-38913, default 1):<enter>
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-38913, default 38913): +10G

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (1307-38913, default 1307):<enter>
Using default value 1307
Last cylinder, +cylinders or +size{K,M,G} (1307-38913, default 38913): +100G

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 3
First cylinder (14362-38913, default 14362):<enter>
Using default value 14362
Last cylinder, +cylinders or +size{K,M,G} (14362-38913, default 38913): +1G

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Selected partition 4
First cylinder (14494-38913, default 14494):<enter>
Using default value 14494
Last cylinder, +cylinders or +size{K,M,G} (14494-38913, default 38913):<enter>
Using default value 38913

Command (m for help):

Now we are going to change the system type of partition 3 to a linux swap type:

Command (m for help): t
Partition number (1-4): 3
Hex code (type L to list codes): 82
Changed system type of partition 3 to 82 (Linux swap / Solaris)

Check the result with the ‘p’ command:

Command (m for help): p

Disk /dev/sda: 320.1 GB, 320072933376 bytes
255 heads, 63 sectors/track, 38913 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x8f9c798a

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1               1        1306    10490413+  83  Linux
/dev/sda2            1307       14361   104864287+  83  Linux
/dev/sda3           14362       14493     1060290   82  Linux swap / Solaris
/dev/sda4           14494       38913   196153650   83  Linux

We are going to save this partition table with the ‘w’ command:

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Creating the ext4 filesystem on the new partitions:

$ mkfs.ext4 /dev/sda1
$ mkfs.ext4 /dev/sda2
$ mkfs.ext4 /dev/sda4

Create the swap space with:

$ mkswap /dev/sda3

Copying the data to the new directories/partitions

The current directories /tmp, /var and /home are already containing data, which should be copied to the new partitions on the hard disk. First the new partitions should be mounted:

$ mkdir /mnt/tmp
$ mkdir /mnt/var
$ mkdir /mnt/home
$ mount /dev/sda1 /mnt/tmp
$ mount /dev/sda1 /mnt/var
$ mount /dev/sda1 /mnt/home

Now we can copy the data to the new partitions:

$ cp -rav /tmp/* /mnt/tmp
$ cp -rav /var/* /mnt/var
$ cp -rav /home/* /mnt/home

Mounting the partitions to the directories

This new partitions need to be mounted when on boot time. First we need the UUID’s of the partitions:

$ blkid /dev/sda*
/dev/sda1: UUID="1222c0a5-8244-44e7-9833-80fbc30d409d" TYPE="ext4"
/dev/sda2: UUID="d3a84386-e9c3-42a0-ad9b-0a5dfaf354a9" TYPE="ext4"
/dev/sda3: UUID="f114b506-e0f9-4c1e-86f9-84a98481bd44" TYPE="swap"
/dev/sda4: UUID="b2c2b221-1ccc-4b41-8845-9707769ea07c" TYPE="ext4"

Now we need to put this mount points into the fstab file. The noatime mount option will get the external hard disk in spindown quicker:

$ vi /etc/fstab
#/dev/sda1
UUID=1222c0a5-8244-44e7-9833-80fbc30d409d /tmp ext4    defaults,noatime        0       0
#/dev/sda2
UUID=d3a84386-e9c3-42a0-ad9b-0a5dfaf354a9 /var ext4    defaults,noatime        0       0
#/dev/sda3
UUID=f114b506-e0f9-4c1e-86f9-84a98481bd44 none swap    sw                      0       0
#/dev/sda4
UUID=b2c2b221-1ccc-4b41-8845-9707769ea07c /home ext4   defaults,noatime        0       0

Activate the swap space with:

$ swapon /dev/sda3

Check if the swap is active with:

$ swapon -s
Filename                                Type            Size    Used    Priority
/dev/mmcblk0p5                          partition       220152  0       -1
/dev/sda3                               partition       1060280 0       -2

You see that the old swap is still active, disable this swap space by putting a ‘#’ in front of the swap mount in /etc/fstab. And put the noatime mount option to the root ‘/’ mount point in this file. The ‘noatime’ option prevents that the files/directories access times will be stored when you access them.

$ vi /etc/fstab
$ / was on /dev/mmcblk0p2 during installation
UUID=b38c47db-1654-46dd-a613-c842cd7e2ba6 / ext3 errors=remount-ro,noatime 0       1

$ swap was on /dev/mmcblk0p5 during installation
#UUID=84405858-3862-4b36-80e8-3a12ec00e0c6 none swap    sw         0       0

To mount the directories, we need to add the mount command to rc.local:

$ vi /etc/rc.local
mount -U 1222c0a5-8244-44e7-9833-80fbc30d409d # /dev/sda1  (/tmp)
mount -U d3a84386-e9c3-42a0-ad9b-0a5dfaf354a9 # /dev/sda2  (/var)
mount -U b2c2b221-1ccc-4b41-8845-9707769ea07c # /dev/sda4  (/home)
mount --bind /home/root /root                 # /home/root (/root)

Now mount the /home partition by manually:

$ mount -U b2c2b221-1ccc-4b41-8845-9707769ea07c

The /root directory is still on the flash disk. But /root/.viminfo is also changed every time you use vim. It does not need a separate partition, but we will create the /home/root directory. And bind the /root-directory to /home/root. The binding of /home/root is already in the /etc/rc.local file. You can still use /root or /home/root. These directories are equal, but the data is stored in /home/root:

$ mkdir /home/root

Now reboot the system:

$ reboot

Checking the results

And after the reboot, check if the swap space is correct

$ swapon -s
Filename                                Type            Size    Used    Priority
/dev/sda3                               partition       1060280 0       -1

And are all directories mounted successfully?

$ mount/dev/mmcblk0p2 on / type ext3 (rw,noatime,errors=remount-ro)
tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)
/dev/mmcblk0p1 on /boot type ext2 (rw)
/dev/sda1 on /tmp type ext4 (rw,noatime)
/dev/sda2 on /var type ext4 (rw,noatime)
/dev/sda4 on /home type ext4 (rw,noatime)
tmpfs on /var/run/samba type tmpfs (rw)
tmpfs on /var/cache/samba type tmpfs (rw)
nfsd on /proc/fs/nfsd type nfsd (rw)
/home/root on /root type none (rw,bind)

Measuring the hard disk data transfer speed. I used an old Western Digital MyBook 320GB external USB hard disk. We need the hdparm command to do this, if you do not have it installed yet, do this by entering:

$ apt-get install hdparm

And this are the results in combination with the SheevaPlug:

$ hdparm -tT /dev/sda1

/dev/sda4:
 Timing cached reads:   616 MB in  2.00 seconds = 307.34 MB/sec
 Timing buffered disk reads:  88 MB in  3.03 seconds =  29.07 MB/sec

Or do the test with the ‘dd’ command:

$ dd if=/dev/zero of=/tmp/speed.tst bs=8k count=256k
262144+0 records in
262144+0 records out
2147483648 bytes (2.1 GB) copied, 68.0084 s, 31.6 MB/s
$ rm /tmp/speed.tst

I am curious what the results will be with an eSATA disk and the SheevaPlug.