Tuesday, July 23, 2013

Running From an External Hard Drive

The SD card of the Raspberry Pi is required for booting.  While you may not be able to boot from an external hard drive, moving the / partition there will significantly speed up the Raspberry Pi.  There are many uses where this configuration particularly useful.  File servers and media servers are good examples.  I need a system like this for a MySQL database server.


There are a number of variations to the process, but basically, the steps are:
o  Install OS on SD Card and boot 
o  Plug in external hard drive
o  Partition and Format hard drive
o  Copy system to hard drive
o  Mount the new system and modify configuration to use the hard drive

I decided not to re-invent the wheel.  The following instructions are just my variations on the instructions provided by Rattus here: 

http://www.raspberrypi.org/phpBB3/viewtopic.php?f=26&t=10914&p=129474&hilit=resizefs#p122476  
Note about the sudo command:  All of the following must be done as root.  You must put sudo before each of the commands.  Or, you can follow the (not recommended, bad practice) habit I have and just enter sudo bash to run a shell as root and skip saying sudo all the time.
Load SD Card with Raspbian in the usual way. Update the system software and firmware with the following three commands.  This can take quite a while to complete.
apt-get update
apt-get upgrade

rpi-update

reboot

List the partitions  This should show only the /boot and / partitions on the SD card.

fdisk –l

Plug external hard drive into USB and list the partitions again.  This should show another HD probably at /dev/sda

Modify the partition table for the external drive.   
fdisk /dev/sda
Delete partitions by entering “n” and then the number of the partition to delete.  Delete all the partitions.  Entering “p” will list the partitions. 

At this point, you have a few options.  
a)  Create a single partition and move the root there.  This will leave the swap file on the SD card.
b)  Create a root partition that fills most of the drive and a small swap partition.
c)  Create a partition for the OS, a small swap partition, and a large partition for application data. 


I am using the third option.  The following instructions are fairly easy to change to use one of the other options.  While still in the fdisk program, do these steps.

- Create the root partition:  I made mine 16GB.  Enter “n” to create a partition, “p” to select primary partition and then “1” to select partition number one.  Select the default start sector.  Enter +16G to specify the size.  
- Create the swap partition:  Enter “n” to create a partition, “p” to select primary partition and then “2” to select partition number two.  Select the default start sector.  Enter +2G to specify the size.  Enter “t” to set the type of a partition.  Enter “2” and then “82” to make this one a swap partition. 
- Create the data partition:  Enter “n” to create a partition, “p” to select primary partition and then “3” to select partition number three.  Select the default start sector and default end sector to fill up the rest of the disk.  
- Enter “p” to list the partitions and verify things are like you expect. 
- Enter “w” to write the new partition table and exit.

Create (format) the data partition with an EXTv4 file system.  This command takes a few minutes to finish.  There is no need to format the first partition since we are going to do a raw copy of an existing file system over it anyway. 
mkfs.ext4 /dev/sda3
Initialize the swap partition
 

mkswap /dev/sda2

Copy the second partition of the SD card to the first partition of your hard disk (mmcblk0p2 may not be correct for you see the output of fdisk earlier.)  This also takes a while.
dd if=/dev/mmcblk0p2 of=/dev/sda1 bs=32M conv=noerror,sync

Check the file system for errors.  Press “y” if any errors are found.
e2fsck -f /dev/sda1

The file system that was copied still looks like a small one to the system.  Do the following to re-size the file system to fill the partition.
resize2fs /dev/sda1

Use your editor of choice (I  use vi) to modify the boot configuration to use the new root partition.  First make a backup copy.
cp /boot/cmdline.txt /boot/cmdline.orig
vi /boot/cmdline.txt

Change  /dev/mmcblk0p2 /  to be   /dev/sda1


Change the mount configuration file on the new root.  It has to be mounted first. 
mount /dev/sda1 /mnt
vi /mnt/etc/fstab

Change the root device  /dev/mmcblk0p2 /   to be  /dev/sda1
Add /dev/sda2  as  a swap partition by adding this line.
/dev/sda2    none      swap    sw           0       0

Finally, stop the system from using the swap file that it normally uses. 
rm /etc/rc2.d/ S02dphys-swapfile

Flush the disk and reboot.sync
reboot


The Pi should now be running from the external hard drive.  If it fails, use another machine to 
copy /boot/cmdline.orig   to  /boot/cmdline.txt  and then reboot again.


One problem that some people have run into is controllers that take too long to complete the USB discovery.  This can be compensated for by adding delays in the /boot/cmdline.txt file with the bootdelay and rootdelay options.

50 comments:

  1. Hello Ted,

    I have a project and i need a tehnical consultant. After reading your blog i would like to be you.

    Could you give me an email so that we can talk in private about the price and how could we do this ?

    Thank you

    PS: Also... it's kinda urgent, so if you could hurry up would be great :)

    ReplyDelete
    Replies
    1. It would help if you left your email address. The link from your user name wasn't any help.
      To put it bluntly, I don't have time. Seriously. I can't keep up with this blog and I am about 3 months behind on my personal projects. Also, you probably don't want to pay my rate - $150/hr.
      If you do, then I can be reached at ted(dot)b(dot)hale(at)gmail.com

      Delete
    2. kinda urgent? lol... engineering takes time and money.

      Delete
    3. You can have it quick, you can have it good, you can have it cheap. Choose any two. :-)

      Delete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
  3. This comment has been removed by a blog administrator.

    ReplyDelete
    Replies
    1. This comment has been removed by a blog administrator.

      Delete
  4. Thank you so much for this tutorial.
    A few comments for other noobs like me who had a little trouble:

    1. When copying the image to the hard drive, I had to choose /dev/mmcblk0p6 instead of /dev/mmcblk0p2. (I dont understand though why this is the partition listed as Linux (and not Linux "Extended")
    dd if=/dev/mmcblk0p6 of=/dev/sda1 bs=32M conv=noerror,sync

    2. Change /dev/mmcblk0p2 / to be /dev/sda1
    Not sure if this was required, but I have deleted the middle slash as well. Did not try without just to make sure I dont screw up everything:)

    3. rm /etc/rc2.d/ S02dphys-swapfile
    I had to remove the space between the last forward slash and the "S"

    Thanks a lot, this was a very nice and easy to follow tutorial:)

    ReplyDelete
  5. Nicely done. I would recommend one addition, and one emphasis.

    Emphasis: When you first do 'fdisk -l' and locate the usb hdd, it may be listed as /dev/sdaX, where X is a number. That refers to an existing partition on /dev/sda. When you then do 'fdisk /dev/sda' DO NOT include the number. I went down that rabbit hole and it took some time to find my way back. :-)

    Addition: While you are modifying the /dev/sda1/etc/fstab file, include a line for the data partition you created so that it too will be mounted at boot. Mine looks like:

    /dev/sda3 /mnt/data ext4 defaults 0 0

    Your mount point might differ.

    Again, thanks.

    ReplyDelete
  6. As a Linux/Raspberry newbie, I am trying to follow your tutorial. However, After copying the second partition, I get hundreds of error messages like "Inode not valid, recreate?" "Wrong size 4164617681 should be 0, resize?" "Superblock has an invalid journal, clear?"
    What does that mean, I what are the consequences of doing all of it?

    ReplyDelete
    Replies
    1. That is why the e2fsck command must be run. This should correct all those errors. Did you run this command?

      Delete
    2. I previously had this problem it is caused by copying the wrong data to the hard drive
      if you do this right you should have little or no errors.
      Try copying mmcblk0p6 or the other partition that is linux NOT linux extened you can check this by saying sudo fdisk -l

      Delete
    3. With this problem it is not only 2 or 3 like regularly it is literally HUNDREDS of errors I spent half an hour and never got through it in the end I corrupted the files and restarted after I realized what I had done.

      Delete
  7. Thanks for step by step but it's freeze when I do the partition. Please suggest me for the solution.

    ReplyDelete
    Replies
    1. Be sure you are doing the partition on the correct device. It is normally /dev/sda (not /dev/sda1 and certainly not /dev/mmcblk0. Also be sure you have enough power. You should be running the external drive from a powered USB hub.

      Delete
  8. Hi,

    I have successfully done all the steps above until resize2fs. By now, after running resize2fs to expand the partition to use 20GB I left available in a separate partition (btw I had to umount /dev/sda1 first because on first try resize2fs told it was not possibile to resize online) it has been over 48 hours (!!!) that the command is running, with no other output than:

    pi@raspberrypi /mnt $ sudo resize2fs /dev/sda1
    resize2fs 1.42.5 (29-Jul-2012)


    Is this normal? How long could it take for resize2fs to resize to a 20GB partition (6GB were copied using dd previously)? It's an ext4 filesystem.

    ReplyDelete
    Replies
    1. I wouldn't expect it to take more than an hour. Probably a lot less.
      Did you run the e2fsck command immediately after doing the dd copy? You must do that before you try to mount the device.
      All I can suggest is trying again.

      Delete
    2. Yes, e2fsck reported clean filesystem. Then I tried resize2fs with the partirion *mounted* and got

      pi@raspberrypi:~$ sudo resize2fs /dev/sda1
      resize2fs 1.42.5 (29-Jul-2012)
      Filesystem at /dev/sda1 is mounted on /mnt/test; on-line resizing required
      old desc_blocks = 2, new_desc_blocks = 1
      resize2fs: Permission denied to resize filesystem


      So I have *umounted* it and then

      pi@raspberrypi /mnt $ sudo resize2fs /dev/sda1
      resize2fs 1.42.5 (29-Jul-2012)



      Thank you anyway... I had to kill it, after 80 hours running still no feedback. I'll try again later.

      Delete
    3. killed it.
      rebooted.
      run e2fsck, fixed some errors.
      run resize2fs and after a few minutes it was done!

      Delete
  9. Best to remove all rc scripts for the dphys-swapfile, e.g. in the rc.2, 3, 4 and 5 directories, not just 2

    rm /etc/rc?.d/S02dphys-swapfile

    ReplyDelete
  10. This all worked perfectly for me - thanks for writing it up

    ReplyDelete
  11. Excellent clear description of how to do this.
    Thanks

    ReplyDelete
  12. This comment has been removed by a blog administrator.

    ReplyDelete
  13. Hello. First, thanks for this post.

    Got it working with only minor modifications for my unique situation.

    However, my external HDD apparently "times out", sleeps, or hibernates after a certain period of inactivity, which makes it impossible for me to log in via SSH (using PuTTY) once it does. (I'm running headless.)

    The ext HDD is a Toshiba Canvio 3.0 Plus, 1.5TB.

    Furthermore, while I can physically power down the Pi and restart, "sudo reboot" does not seem to work: the Pi lights up, however, I cannot SSH in.

    I do run:

    sudo apt-get -y update
    sudo apt-get -y dist-upgrade
    sudo rpi-update

    regularly.

    Any ideas? (Other than "use another drive", please; that is not really an
    option right now.)

    Thanks in advance!

    (Cross-posted to:
    Raspberry Pi • View topic - USB HDD
    http://www.raspberrypi.org/phpBB3/viewtopic.php?f=26&t=10914&p=129474&hilit=resizefs#p122476)

    ReplyDelete
    Replies
    1. try this:
      apt-get install sdparm
      then
      sdparm --clear=STANDBY /dev/sdX
      (where X is the appropriate letter for your drive)

      if that works, then you can run it at each boot by adding it to /etc/rc.local

      As a last resort, you could do a cron job to access the drive regularly to keep it awake.

      crontab-e
      (this will open the cron config file using nano as the edittor)
      Add this line (again with the correct letter for your drive)
      */5 * * * * /bin/touch /dev/sdX &>/dev/null

      This will access the device every 5 minutes.
      Hope this helps.

      Delete
    2. Thanks for the prompt replies.

      Actually, I think I have resolved my problem. Before I could implement your
      advice, I barely bumped the USB hub and the power failed. That led to a
      corrupt SD card, and time spent rebuilding to the point where I could try
      setting up to run my Pi from an ext HD. Once I replaced what was obviously a
      flaky USB Hub, the problems I described in my first post went away.

      So, again, thank you all so much for your attempts to help me. I do think,
      however, that it was all down to a faulty USB Hub. For anyone who has similar
      issues, if you can, swap out your hub, just to be sure that's not the problem.

      Thanks again!


      (Cross-posted to:
      Raspberry Pi • View topic - USB HDD
      http://www.raspberrypi.org/phpBB3/viewtopic.php?f=26&t=10914&p=129474&hilit=resizefs#p122476)

      Delete
  14. A few other typos than those mentioned, above, but this noob finally figured out the problems and I seem to be running Raspbian off of the HD. It worked first shot. Does some work in the SD then the HD wakes up and starts flashing for the rest of the time and no more flashing of the SD access LED.

    Now we will see if there are timeout problems or anything else. Thanks for the instructions. Would be nice to do just a couple of minutes of cleanup on them and fix the remaining problems.

    I also had to change mmcblk0p2 to mmcblk0p6. One can tell which is should be by looking in /boot/cmdline.txt. It will have the correct name on one of the first lines.

    Mike Morrow
    ILikeTheInternet.com

    ReplyDelete
  15. That is very kind of you to write this share for us, thanks a lot I could get lot more knowledge from your article.. thanks for sharing.

    ReplyDelete
  16. Thanks a lot!
    I just have one question: is the SD card necessary after this process?
    I suppose so. So... Is everything on the SD necessary or i can use a smaller one to keep just the needed files? How can i use a really small SD to just make the Rpi boot from an USB HDD?
    Thank you

    ReplyDelete
    Replies
    1. I'm not sure if the SD card is needed once booting completes but taking it out while the Pi is running would probably be a bad idea. All that you really need to boot a system configured like this are the files on the small FAT partition at the beginning of the SD card and probably something from the boot sector of the drive. You can use a disk imaging tool (or just the dd command) to copy just that little bit and then write that to a very small SD card. I never see anything smaller than 4Gbytes these days but there are lots of older ones still around that are smaller. Beware though, some of those older SD cards may not be compatible with the Pi.

      Delete
  17. Thank you, I got this all going for my rPi and external HDD. The only special thing I did was shrink my HDD volume by 8GB, then use GParted in Ubuntu to make your suggested partitions in the 8GB volume. No need to have the entire external HDD taken over by the rPi, only 8GB! Yay,

    ReplyDelete
  18. Me having a problem,
    I tried to send AT command from my Lxterminal to minicom
    by "echo -n "AT" > /dev/ttyAMA0
    for typing next xommad i need to pass enter to minicom.
    how can i do that?

    ReplyDelete
    Replies
    1. the -n option is suppressing the output of the trailing newline.
      Since you are using AT commands, I will assume that you have a modem connected to the serial port.
      Try using printf instead of echo. It will interpret escaped special characters. "\n" is the enter character.
      For example:
      printf "AT+BAUD2\nATDT123456789\n"
      The exact commands and the delays needed in between will depend on your modem and the service you are connecting to.
      Hope that helps you.

      PS
      I thought the days of modems were long behind me. However, a few years ago I had to configure a Linux system to use an Iridium satellite modem. In the middle of a desert, In an "unspecified location"

      Delete
  19. Hi Ted! Can you tell me, what kind of power supply do you use for this construction? Especially, what output current is in it?
    Thank for sharing your experience.

    ReplyDelete
    Replies
    1. The system pictured suffered a hard drive failure and the USB hub has now also failed.
      Typically, this type application needs about 2A of 5V current.
      I am building a new system using this hub, chosen for the small size:
      Belkin F4U040v USB 2.0 4-Port Ultra-Slim Series Hub
      http://www.newegg.com/Product/Product.aspx?Item=N82E16817394179

      It includes a 2.6A power supply and the system has been working great so far.
      I will be adding multi-segment LED displays for showing CPU and IO utilization, which will be covered in an upcoming blog post.

      Delete
  20. I've always been very aware of the (lack of) performance of the Pi. Is there any sort of comparison between your setup and a vanilla one? Might I suggest a video with boot times side by side, or something like it. This is way out of my league (at least for now), but can this also be done with RaspBMC?

    Thanks for the GREAT tutorial!
    Miguel

    ReplyDelete
  21. Thanks for the how-to (kept me from guessing). I did have to reboot before "rpi-update" would work (and then rebooted again after).

    ReplyDelete
  22. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. Thanks for the Tutorial It really helped!!!

      Delete
  23. Does This Install all the operating systems that are on the SD card or just Debian?

    ReplyDelete
    Replies
    1. If it is not could you tell us how to move multiple operating systems onto a hard drive?

      Delete
    2. These instructions were made assuming a standard image of Raspbian is used. I should have mentioned that, but it seemed obvious at the time. The popular image now is NOOBS, which let's you load one of several OSes. I plan in experimenting with NOOBS and moving all or part of it to the external drive.

      The same basic process described above would be used. The main difference is that NOOBS has several partitions for the different OSes so you have to know which partition to copy and how to set up the boot sequence to use the external drive. Hopefully I can get to this soon. This post gets a lot of traffic and is a bit out of date now.

      Delete
  24. Excellent guide. New to the RPi platform, and this guide was exactly what I needed. Thank you for taking the time to post this.

    ReplyDelete
  25. Hi i have some questions.

    My cmdline.txt had mmcblk0p6 as the root. So i copied that instead of blk0p2. Was that alright to do?

    When i mounted sda1 and went to edit /mnt/etc/fstab it has mmcblk0p5 as the root, and mmcblk0p6 was listed on the next line (blk0p6 was not listed as root). I chose to change out blk0p5.
    I do not think it worked for me. Can anyone help me out?
    Thanks!

    ReplyDelete
    Replies
    1. I have a NOOBS sd card. Sorry I ready your post about how this guide is for standard raspbian not NOOBS after I submitted my post

      Delete
  26. Just a recommendation this post would work quite well with this setup all you would have to do is create a 4th partition http://www.stuffaboutcode.com/2012/08/raspberry-pi-auto-backups.html

    ReplyDelete
  27. THANKS Ted.
    I follow your explanation Word by Word, and end up with a working system first time.
    Thats is a really GOOD toturial.
    Regards Ole Andersen in Denmark.

    ReplyDelete