SATA HotPlug in Ubuntu

Posted in Debian, Ubuntu on 2011-08-16 at 22:09:29 by Chris – 28 Comments

Because hard disks are cheap, I use them for backups. I have extended a couple of SATA ports (numbered SATA3 and SATA4 on my motherboard) to the front of my 19" rack case. The hinged front panel of the case is just the right size to temporarily hold a SATA disk on its back:

Naturally, for this to work as a backup solution it must be possible to connect and disconnect drives with the power on. Luckily, most modern operating systems support SATA hotplug.

On Linux, you can tell the system to rescan an individual SATA port. My motherboard has four of them, labelled SATA1..4 on the PCB. These appear as host0..3 under /sys/class/scsi_host/. So to rescan the SATA3 port, just do:

echo "- - -" | sudo tee -a /sys/class/scsi_host/host2/scan

The system will scan the drive and add entries to /dev/ for the drive and its individual partitions (e.g /dev/sdb, /dev/sdb1, /dev/sdb2). Ubuntu will automount any mountable partitions under /media and put an icon on the desktop.

Once you've finished doing backup synchronisation, unmount all the drive's partitions (right click->"Unmount") and tell the system to power down the drive with:

echo 1 | sudo tee -a /sys/block/sdb/device/delete

You can now unplug everything and put the drive somewhere safe (I keep mine on top of my magnet collection). I'm sure someone will eventually make it work without this command-line magic, but until then...

Update: I have since switched to Debian and started using the following script for scanning the bus:

#!/bin/bash
export SCAN_TEMP=$(mktemp -d)
ls /dev/sd? > ${SCAN_TEMP}/before.txt
for i in /sys/class/scsi_host/host*/scan
do
  echo "- - -" >> $i
done
ls /dev/sd? > ${SCAN_TEMP}/after.txt
for i in $(diff ${SCAN_TEMP}/before.txt ${SCAN_TEMP}/after.txt | grep \> | awk -F/ '{print $NF}'); do
  echo Added /dev/$i:
  /sbin/sfdisk -uM -l /dev/$i | grep -E "^/dev/$i" | awk '{print "    "$1" "$4" MiB"}'
done
rm -rf ${SCAN_TEMP}

...and the following script to unmount & power-down:

#!/bin/bash
if [ $# != 1 ]; then
  echo "Synopsis: stopsata.sh <drive>"
  exit 1
fi
export DRIVE=$1
for i in $(mount | grep ${DRIVE} | awk '{print $1}'); do
  echo Unmounting $i
  umount $i
done
echo Powering down ${DRIVE}
echo 1 >> /sys/block/${DRIVE}/device/delete
echo You may now safely disconnect the drive

They may be used like this:

chris@wotan$ # Connect drive
chris@wotan$ sudo /usr/local/bin/scansata.sh
Added /dev/sdc:
    /dev/sdc1 190 MiB
    /dev/sdc2 48 MiB
    /dev/sdc3 22888 MiB
    /dev/sdc4 692277 MiB
chris@wotan$ # Mount a partition, e.g "Places->Removable Media->726 GB Filesystem"
chris@wotan$ 
chris@wotan$ # Now unmount and power-down
chris@wotan$ sudo /usr/local/bin/stopsata.sh sdc
Unmounting /dev/sdc4
Powering down sdc
You may now safely disconnect the drive
chris@wotan$

28 Comments

I'm not sure if there is a proper GUI in recent linux distribs now. Some time ago, I wrote a small GUI to do this for eSATA drives I use for backup. It should be distrib and desktop independent (but requires Qt, but NOT kde).

https://github.com/ibressler/dfmon

Reply

Since I wrote this post I moved from Ubuntu to Debian. On Debian, dfmon doesn't work very well. It doesn't show new SATA drives when attached; I still need to do the above command to scan the bus. When the scan completes the new drive appears in dfmon. I right-click a partition and choose "mount with trucrypt", but nothing happens. So I mount it the usual way using "Places->Removable Media->726 GB Filesystem". When I'm finished with it I right-click again on the mounted partition in dfmon and choose "umount", and again nothing happens. So I try to close dfmon and it fails with "Action 'umount' failed: Failed to umount '/dev/sdc4': No sudo handler found: '-c'". Also it shows my LVM2 SSD drive as not in use, even though it is being used.

Reply

cesar lopez says:

2014-02-24 at 21:07:36 UTC

tranks a lot it works perfect on mint 13

Reply

Great! Thanks for letting me know.

Chris

Reply

cesar lopez says:

2014-02-25 at 14:12:35 UTC

Tested on amd a75 chipset all 6 sata work fine.
Tested on an old via chipset and via pci cards fail
Kernel 3.2
Seem to be limitation on the chipset
Thanks a lot

Reply

this was great info. succinct, and to the point. thank you.

question -- i'm running ubuntu 12.04, and the stopsata part works exactly as expected. but when i (re)connect a disk, it's recognized immediately -- no scan is necessary. seems like some daemon is doing that for me? i'd actually prefer to need the manual scan -- any idea what's making it happen by itself?

Reply

No, I don't know for sure, but at a guess it's udev - the same mechanism that automounts USB drives.

Reply

CrackMech says:

2014-03-01 at 14:48:40 UTC

Nice and concise instructions. Probably worked for me on Ubuntu 12.04LTS amd64. I say probably because I don't hear the drive power down, but it does disappear from the disk manager. Any clue about checking sone dmesg log or something?
Also, I have read in other few places about using 'sync' and 'hdparm -y'. Does that make any difference?

Thanks for the info!

Reply

You should definitely hear/feel the drive spinning down when you run stopsata.sh. If you don't, it's probably not safe to unplug it. The script already unmounts the drive, which will do the same as sync. I'm not sure about hdparm -y.

Reply

CrackMech says:

2014-03-01 at 15:42:00 UTC

So, I actually did not try the script, but did the following:
1) Unmounted the drive uding 'Disk Utility'
2) run 'hdparm -y /dev/sdx' : this apparently issues standby command to the hard disk and the head is parked
3) run 'echo 1 | sudo tee /sys/block/sdf/device/delete' : this should power down the drive.

I do hear the drive getting into standby mode when I execute 'hrparm -y' but if I just issue 'echo 1 | sudo tee /sys/block/sdf/device/delete' after unmounting (no hdparm -y), I do not hear the drive getting powered down. Any clues? I am using Western Digital Caviar Green drives (ones with 'intelligent' power management!).

Thanks,
CrackMech

Reply

Why not just try the script I wrote?

CrackMech says:

2014-03-05 at 09:52:36 UTC

Well.. Your script does powerdown the drive, but I am trying to see if using hdparm can be an option to be explored. I can hear your script powering down the drive in same manner as 'hdparm -y /dev/sdx/'. I will try to look for the difference between issuing hdparm command and tee command.

Thanks for your efforts though. I do appreciate that.
Cheers!

Reply

My guess is that they are both identical, ultimately: using hdparm will issue the shutdown command to the drive using some sort of ioctl, and writing to the node under /sys/block will instruct the kernel to do the same thing. Look at the SATA block device driver code and the hdparm code to find out.

Reply

CrackMech says:

2014-03-05 at 10:41:58 UTC

Hmm.. seems logical. But till it works I don't have much issues how it works at the kernel level. I'm just over cautious as the disks I tend to remove on the go are for work, and losing data at work can be difficult. I sometimes need to change around 8 disks in a day so powering down the system everytime seems too much, hence all this exercise. :)

Reply

I understand. FWIW, I've been using these scripts for a few years without loss of data, and I assume from the existence of several "works for me" comments but lack of "you destroyed my drive you #@$&*#@!" comments, several others have too. I don't think hot-swapping drives like this is any more dangerous than shutting down and cold-swapping. Just maintain a proper backup schedule and you'll be fine.

enPassant says:

2014-05-01 at 12:23:09 UTC

Perfect!
Works with CentOS6 and allows to activate eSATA device on server hpProlian without tinkering with the bios like turning around in google ...

Thank you very much for the solution, clarity of explanation and very relevant scripts

Reply

I'd like to use unical ID HDD instead its name like sdb or sdc, because I have some HDD, and don't know exactly what's a HDD will be sdb or sdc, without check out it using fdisk or other utilities.
Using your script stopsata.sh may I use ID HDD instead its name like sdb or sdc

Reply

I don't know what a unical ID is, and a Google search didn't help me.

Reply

sorry I'm not good at English - I mean unique ID for every HDD to stop it using your script.

Reply

Oh I see, like the UUID? Unfortunately I think the UUID links to partitions (e.g /dev/sda1) rather than actual drives (e.g /dev/sda). Try doing ls -la /dev/disk/by-uuid/ and you'll see what I mean.

Reply

Yes, that's a problem, I need unique ID for all HDD,not only for one partition, like Disk identifier: 0x000ccbf2

Reply

Disk /dev/sdb: 1000.2 GB, 1000204886016 bytes
255 heads, 63 sectors/track, 121601 cylinders, total 1953525168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk identifier: 0x000ccbf2

Reply

What about the IDs you get from ls -la /dev/disk/by-id/? There seem to be whole-disk links in there. Will they do?

Reply

For example:

sudo stopsata.sh $(ls -la /dev/disk/by-id/ata-Hitachi_HDS722020ALA330_1YAG4ZYHS | awk -F/ '{print $NF}')
Reply

or maybe make Label for all HDD. How can we mark all HDD and then stop it using script?

Reply

# ls -la /dev/disk/by-id/
total 0
lrwxrwxrwx 1 root root 9 мая 20 13:15 ata-WDC_WD10EZEX-00RKKA0_WD-WMC1S0097610 -> ../../sdb
lrwxrwxrwx 1 root root 10 мая 20 07:39 ata-WDC_WD10EZEX-00RKKA0_WD-WMC1S0097610-part1 -> ../../sdb1
lrwxrwxrwx 1 root root 10 мая 20 07:39 ata-WDC_WD10EZEX-00RKKA0_WD-WMC1S0097610-part2 -> ../../sdb2
lrwxrwxrwx 1 root root 10 мая 20 07:39 ata-WDC_WD10EZEX-00RKKA0_WD-WMC1S0097610-part3 -> ../../sdb3
lrwxrwxrwx 1 root root 9 мая 20 13:15 wwn-0x50014ee0034fbeb5 -> ../../sdb
lrwxrwxrwx 1 root root 10 мая 20 07:39 wwn-0x50014ee0034fbeb5-part1 -> ../../sdb1
lrwxrwxrwx 1 root root 10 мая 20 07:39 wwn-0x50014ee0034fbeb5-part2 -> ../../sdb2

but I don't understand yet command language of Bash - how can I write it to stop sdb using your script

Reply

Like this:

sudo stopsata.sh $(ls -la /dev/disk/by-id/wwn-0x50014ee0034fbeb5 | awk -F/ '{print $NF}')
Reply

thanks, but how can I make it as a single script file - what should I edit in your script - stopdata to make it for stopping my sdb disk. I want to make scripts for all my SATA HDD and use each of them as separate script.

Reply

Leave a Reply

You may use TWiki syntax in your comment. Your email address will not be published.

| Home | About |

Powered by WordPress & MakeStuff theme, with Silk icons