Random Bits

Random Bits

  • Home
  • Contact

Safely Removing External Drives in Linux

Backstory

About a year ago I bought an external SATA drive for backups. My normal usage consisted of:

  1. Power on and connect the drive
  2. mount /media/backup
  3. Run my backup script
  4. umount /media/backup
  5. Power off and unplug the drive

This seemed to work pretty well–at the very least, I wasn’t losing data–except the drive made a strange sound when I powered it off. It wasn’t a normal drive spin down sound; it was louder and shorter. So, I googled for authoritative instructions on using external drives with Linux. While most sources suggest doing exactly what I did, it’s not ideal.

It turns out that most cheap external USB/SATA/firewire enclosures don’t properly issue a stop command to the drive when you flick the power switch. Instead, the power switch simply cuts power to the drive, which forces the drive to do an emergency head retract. If you think that sounds bad, you’re right. Emergency retracts aren’t going to brick your drive immediately, but if they occur regularly they’re putting a lot of unnecessary wear and tear on the drive. In fact, some drives monitor how often this happens with S.M.A.R.T. attribute 192. (Check Wikipedia’s S.M.A.R.T. page for a comprehensive list of attributes)

Solution

The solution is to spin down the drive via software before turning it off and unplugging it. The best way to do this is with a utility called scsiadd. This program can add and remove drives to Linux’s SCSI subsystem. Additionally, with fairly modern kernels, removing a device will issue a stop command, which is exactly what we’re looking for. Run:

$ sudo scsiadd -p

which should print something like:

Attached devices:
Host: scsi0 Channel: 00 Id: 00 Lun: 00
  Vendor: ATA      Model: SAMSUNG HD300LJ  Rev: ZT10
  Type:   Direct-Access                    ANSI  SCSI revision: 05
Host: scsi4 Channel: 00 Id: 00 Lun: 00
  Vendor: LITE-ON  Model: DVDRW LH-20A1L   Rev: BL05
  Type:   CD-ROM                           ANSI  SCSI revision: 05
Host: scsi5 Channel: 00 Id: 00 Lun: 00
  Vendor: ATA      Model: WDC WD10EACS-00Z Rev: 01.0
  Type:   Direct-Access                    ANSI  SCSI revision: 05

Identify the drive you want to remove and then issue:

$ sudo scsiadd -r host channel id lun

substituting the corresponding values from the scsiadd -p output. For example, if I wanted to remove “WDC WD10EACS-00Z”, I would run:

$ sudo scsiadd -r 5 0 0 0

If everything works, scsiadd should print:

Attached devices:
Host: scsi0 Channel: 00 Id: 00 Lun: 00
  Vendor: ATA      Model: SAMSUNG HD300LJ  Rev: ZT10
  Type:   Direct-Access                    ANSI  SCSI revision: 05
Host: scsi4 Channel: 00 Id: 00 Lun: 00
  Vendor: LITE-ON  Model: DVDRW LH-20A1L   Rev: BL05
  Type:   CD-ROM                           ANSI  SCSI revision: 05

You can double-check the end of dmesg. You should see:

[608188.235216] sd 5:0:0:0: [sdb] Synchronizing SCSI cache
[608188.235362] sd 5:0:0:0: [sdb] Stopping disk
[608188.794296] ata6.00: disabled

At this point, the drive is removed from Linux’s SCSI subsystem and it should not be spinning. It’s safe to unplug and turn off.

Using scsiadd directly can be inconvenient because it requires looking up the host, channel, id, and lun of the drive. I wrote a short script that will take a normal Linux device file like /dev/sdb, figure out the correct arguments to scsiadd, and run scsiadd -r. I use this script in my larger backup script.

#!/bin/sh

if [ $# -ne 1 ]; then
    echo "Usage: $0 <device>"
    exit 1
fi

if ! which lsscsi >/dev/null 2>&1; then
    echo "Error: lsscsi not installed";
    exit 1
fi

if ! which scsiadd >/dev/null 2>&1; then
    echo "Error: scsiadd not installed"
    exit 1
fi

device=`lsscsi | grep $1`
if [ -z "$device" ]; then
    echo "Error: could not find device: $1"
    exit 1
fi

hcil=`echo $device | awk \
    '{split(substr($0, 2, 7),a,":"); print a[1], a[2], a[3], a[4]}'`

scsiadd -r $hcil

It does require the lsscsi command to be present on the system.

Related Posts:

  • Monitoring Hard Drive Health on Linux with smartmontools

    S.M.A.R.T. is a system in modern hard drives designed to...

  • How to Shrink an LVM Volume Safely

    Logical Volume Management is a vast improvement over standard partitioning...

  • Monitoring a UPS with nut on Debian or Ubuntu Linux

    There are two different ways to monitor a UPS with...

  • Fixing uTorrent File Associations in Linux

    Running uTorrent under wine works pretty well in Linux. For...

  • Log iptables Messages to a Separate File with rsyslog

    Learn how to filter iptables log messages to a separate...

Sponsored Links:

This entry was posted on Sunday, January 4th, 2009 at 5:47 PM and is filed under Linux. You can leave a response, or trackback from your own site.

8 Comments on “Safely Removing External Drives in Linux”

  1. storma says:
    June 22, 2009 at 2:21 AM

    Thanks. :)

    I’ve just bought an external sata housing and came across this while doing a bit of research for it. That script of yours will save me some time.

    Thanks again.

    Reply
  2. Kyle says:
    August 2, 2009 at 12:18 PM

    Does not work here (Arch Linux 2.6.30). But calling sdparm (twice) does work:

    sdparm –command=stop $device

    Reply
    • Phil Pemberton says:
      August 3, 2009 at 7:56 PM

      ‘eject’ should also do the same job — it either ejects a CD-ROM drive, or will also (IME) spin down hard drives. For example:

      $ sudo eject /dev/sdd

      spins down /dev/sdd

      Reply
  3. bobsmith says:
    August 3, 2009 at 12:41 AM

    Thank you very much for this! It appears to work in Ubuntu Jaunty – at least all the right messages are coming up. And I can even hear a kind of soft “clink” sound as soon as I issue the command – which I think is the heads parking. I still have a rather loud sound when cutting the power to the drive, however, but maybe it’s the fan shutting off combined with the click of the switch – I’m not sure. Was there a noticable change in the sound when you cut the power after doing this? I’m using an eSATA enclosure – it’s a Rosewill brand that cost about $40.00.

    I wish there were a way to be absolutely sure the drive has spun down properly. But I do get this with dmesg, so maybe that should be assurance enough:

    sd 6:0:0:0: [sdb] Synchronizing SCSI cache
    sd 6:0:0:0: [sdb] Stopping disk
    ata7.00: disabled

    Again, thanks very much for this!

    Reply
  4. Andrew (djharuko) 's status on Monday, 03-Aug-09 22:19:02 UTC - Identi.ca says:
    August 3, 2009 at 6:19 PM

    [...] http://blog.shadypixel.com/safely-removing-external-drives-in-linux/ [...]

    Reply
  5. SCSI 80 PIN says:
    October 15, 2009 at 6:51 AM

    Thank you for all the info very useful for us I will try this method to backup my fiele server and media server thank you again

    Reply
  6. Ubuntu 10.04 Server: Lucid Print and File Server for Home Network « Badger Bait says:
    March 15, 2010 at 9:30 PM

    [...] meant to be left on all the time. There’s a really great script available over at shadypixel that will shut the hard drive entirely down, save it to the server and make it executable. To have [...]

    Reply
  7. ingo says:
    May 1, 2010 at 1:02 PM

    Thank you for inspiring me to write a GUI for just this (see screenshots):
    http://github.com/ingob/dfmon

    This tool lists all scsi devices in the system and umounts/removes them (with truecrypt support) from the scsi bus at request. Often, I want to remove SATA devices from the system which are mounted with truecrypt.
    Atm, it’s a python script which uses Qt. I’ll add a standalone binary soon.

    What do you think about this ?

    Reply

Leave a Reply

Click here to cancel reply.

  • Topics

    • Personal (1)
    • Technology (13)
      • Linux (11)
      • Web (4)
  • Archives

    • April 2009
    • March 2009
    • January 2009
    • December 2008
    • August 2008
    • July 2008
  • Meta

    • Register
    • Log in
    • Valid XHTML

Feed | Privacy Policy
Copyright © 2008-2009 Random Bits
Powered by Wordpress