Difference between revisions of "Talk:How to hotswap Ultrabay devices"

From ThinkWiki
Jump to: navigation, search
(fix script ultrabay.sh, device path is required)
Line 71: Line 71:
 
<pre>
 
<pre>
 
#!/bin/bash
 
#!/bin/bash
DEFAULT_DEVICE="/sys/class/scsi_device/1:0:0:0/device"
 
 
FORCE_SLEEP="1"
 
FORCE_SLEEP="1"
 
QUIET="0"
 
QUIET="0"
Line 82: Line 81:
 
true
 
true
 
     fi
 
     fi
 +
}
 +
 +
Usage()
 +
{
 +
    echo "usage: ${0/*\/} [options]"
 +
    echo "options:"
 +
    echo "    -q --quiet          No messages"
 +
    echo "    -n --no-force-sleep  Ignore fail when putting drive to sleep"
 +
    echo "    -d --device <path>  SCSI device (required)"
 +
    exit 1
 
}
 
}
  
Line 150: Line 159:
 
}
 
}
  
SCSI_DEVICE="$DEFAULT_DEVICE"
+
SCSI_DEVICE=""
 
for PARAM in $*; do
 
for PARAM in $*; do
 
     if [ "$PARAM_DEVICE" ]; then
 
     if [ "$PARAM_DEVICE" ]; then
Line 166: Line 175:
 
    ;;
 
    ;;
 
    *)
 
    *)
        echo "usage: ${0/*\/} [options]"
+
Usage
        echo "options:"
 
        echo "    -q --quiet          No messages"
 
        echo "    -n --no-force-sleep  Ignore fail when putting drive to sleep"
 
        echo "    -d --device <path>  SCSI device, default: $DEFAULT_DEVICE"
 
        exit 1
 
 
    ;;
 
    ;;
 
esac
 
esac
Line 177: Line 181:
 
done
 
done
  
if [ -d $SCSI_DEVICE ] && IsDocked "ata_bay"; then
+
[ -z "$SCSI_DEVICE" ] && Usage
 +
 +
if [ -d "$SCSI_DEVICE" ] && IsDocked "ata_bay"; then
 
     sync
 
     sync
 
     for BLOCK in $(/bin/cat $SCSI_DEVICE/block/*/*/dev $SCSI_DEVICE/block/*/dev 2> /dev/null); do
 
     for BLOCK in $(/bin/cat $SCSI_DEVICE/block/*/*/dev $SCSI_DEVICE/block/*/dev 2> /dev/null); do
Line 196: Line 202:
 
if [ ! -d $SCSI_DEVICE ] && $(IsDocked "ata_bay"); then
 
if [ ! -d $SCSI_DEVICE ] && $(IsDocked "ata_bay"); then
 
     if Undock "ata_bay"; then
 
     if Undock "ata_bay"; then
Message "AtaBay undocked"
+
Message "UltraBay undocked"
exit 0
 
    else
 
Message "cannot undock AtaBay"
 
exit 1
 
    fi
 
fi
 
 
 
if $(IsDocked "battery_bay"); then
 
    if Undock "battery_bay"; then
 
Message "BatteryBay undocked"
 
 
exit 0
 
exit 0
 
     else
 
     else
Message "cannot undock BatteryBay"
+
Message "cannot undock UltraBay"
 
exit 1
 
exit 1
 
     fi
 
     fi

Revision as of 14:09, 8 June 2009

HAL script

If the script works, your lshal output should contain something similar to this. In this case the Ultrabay device was a second HDD (/dev/sdb).

Note that in the example, storage.hotpluggable = true while before it was false, so the script worked.

udi = '/org/freedesktop/Hal/devices/storage_serial_SATA_HTS726060M9AT00_MRH453M4H11ARB'
  block.device = '/dev/sdb'  (string)
  block.is_volume = false  (bool)
  block.major = 8  (0x8)  (int)
  block.minor = 16  (0x10)  (int)
  block.storage_device = '/org/freedesktop/Hal/devices/storage_serial_SATA_HTS726060M9AT00_MRH453M4H11ARB'  (string)
  info.capabilities = {'storage', 'block'} (string list)
  info.category = 'storage'  (string)
  info.parent = '/org/freedesktop/Hal/devices/pci_8086_24ca_scsi_host_0_scsi_device_lun0'  (string)
  info.product = 'HTS726060M9AT00'  (string)
  info.udi = '/org/freedesktop/Hal/devices/storage_serial_SATA_HTS726060M9AT00_MRH453M4H11ARB'  (string)
  info.vendor = 'ATA'  (string)
  linux.hotplug_type = 3  (0x3)  (int)
  linux.sysfs_path = '/sys/devices/pci0000:00/0000:00:1f.1/host1/target1:0:0/1:0:0:0/block/sdb'  (string)
  storage.automount_enabled_hint = true  (bool)
  storage.bus = 'pci'  (string)
  storage.drive_type = 'disk'  (string)
  storage.firmware_version = 'MH4O'  (string)
  storage.hotpluggable = true  (bool)
  storage.lun = 0  (0x0)  (int)
  storage.media_check_enabled = false  (bool)
  storage.model = 'HTS726060M9AT00'  (string)
  storage.no_partitions_hint = false  (bool)
  storage.originating_device = '/org/freedesktop/Hal/devices/computer'  (string)
  storage.partitioning_scheme = 'mbr'  (string)
  storage.removable = false  (bool)
  storage.removable.media_available = true  (bool)
  storage.removable.media_size = 60011642880  (0xdf8f90000)  (uint64)
  storage.requires_eject = false  (bool)
  storage.serial = 'SATA_HTS726060M9AT00_MRH453M4H11ARB'  (string)
  storage.size = 60011642880  (0xdf8f90000)  (uint64)
  storage.vendor = 'ATA'  (string)
Known South Bridge PCI IDs
ID ThinkPad model South Bridge chip (for Ultrabay) parent device (host_0, lun0 = 2nd ATA controller, master device)
8086_7111 T20, T21, T22, X20, X21 Intel 82371AB/EB/MB PIIX4 IDE /org/freedesktop/Hal/devices/pci_8086_7111_scsi_host_0_scsi_device_lun0
8086_248a T23, T30, X22, X23, X24, X30 Intel 82801CAM IDE U100 (rev 2) /org/freedesktop/Hal/devices/pci_8086_248a_scsi_host_0_scsi_device_lun0
8086_24ca R50, R51, T40, T40p, T41, T41p, T42, T42p, X31, X32, X40 Intel 82801DBM (ICH4-M) /org/freedesktop/Hal/devices/pci_8086_24ca_scsi_host_0_scsi_device_lun0
8086_2653 R52, T43, T43p, X41, Z60m, Z60t Intel 82801FBM (ICH6-M) /org/freedesktop/Hal/devices/pci_8086_2653_scsi_host_scsi_device_lun0
8086_27c4 R60, X60 Intel 82801GBM (ICH7 Family) /org/freedesktop/Hal/devices/pci_8086_27c4_scsi_host_scsi_device_lun0
8086_27df T60, T60p, Z61m, Z61t, Z61p Intel 82801GBM/GHM (ICH7 Family) /org/freedesktop/Hal/devices/pci_8086_27df_scsi_host_scsi_device_lun0
8086_2850 R61, T61, T61p, X300 Intel 82801H (ICH8 Family) /org/freedesktop/Hal/devices/pci_8086_2850_scsi_host_scsi_device_lun0
8086_2929 R400, R500, T400, T500, W500, W700, X200, X301 Intel 82801I ICH9 Family /org/freedesktop/Hal/devices/pci_8086_2929_scsi_host_0_scsi_device_lun0

lshal output

Please place your lshal output here if you had problems, or if you have a A or W series ThinkPad

bash script for hotswapping UltraBay

Here is my script for hotswapping ultrabay, is more complex, supports swap partition on drive in ultrabay and more :)

Help needed
Please test on difrent models

ultrabay.sh

#!/bin/bash
FORCE_SLEEP="1"
QUIET="0"

Message()
{
    if [ $QUIET = "0" ]; then
	echo "${0/*\//}: $*"
    else
	true
    fi
}

Usage()
{
    echo "usage: ${0/*\/} [options]"
    echo "options:"
    echo "    -q --quiet           No messages"
    echo "    -n --no-force-sleep  Ignore fail when putting drive to sleep"
    echo "    -d --device <path>   SCSI device (required)"
    exit 1
}

Block2Device()
{
    /bin/readlink -e "/dev/block/$1"	
}

IsSwap()
{
    /sbin/swapon -s | grep -q -e "^$1\b"
}

IsMounted()
{
    mount | grep -q -e "^$DEVICE\b"
}

ReleaseDevice()
{
    if IsMounted "$1"; then
	if ! umount "$1" &> /dev/null; then
	    Message "cannot umount $DEVICE"
	    false
	fi
    elif IsSwap "$1"; then
	if ! /sbin/swapoff "$1" &> /dev/null; then
	    Message "cannot disable swapping on $DEVICE"
	    false
	fi
    fi
}

SleepDrive()
{
    if ! /sbin/hdparm -Y "$1" &> /dev/null; then
	Message "cannot put drive to sleep"
	if [ $FORCE_SLEEP = "0" ]; then
	    true
	else
	    false
	fi
    fi
}

DeleteScsiDevice()
{
    if ! { echo 1 > $SCSI_DEVICE/delete; } &> /dev/null; then
	Message "cannot delete device"
	false
    fi
}

GetDock()
{
    grep "$1" /sys/devices/platform/dock.*/type | sed -e s%/type:.*%%
}

IsDocked()
{
    [ $(cat $(GetDock "$1")/docked) -ne 0 ]
}

Undock()
{
    { echo 0 > $(GetDock "$1")/undock; } &> /dev/null
    ! IsDocked "$1"
}

SCSI_DEVICE=""
for PARAM in $*; do
    if [ "$PARAM_DEVICE" ]; then
	SCSI_DEVICE="$PARAM"
    else
	case "$PARAM" in
    	    "--quiet"|"-q")
		QUIET="1"
	    ;;
	    "--no-force-sleep"|"-n")
	        FORCE-SLEEP="0"
	    ;;
	    "--device"|"-d")
	        PARAM_DEVICE="1"
	    ;;
	    *)
		Usage
	    ;;
	esac
    fi
done

[ -z "$SCSI_DEVICE" ] && Usage
 
if [ -d "$SCSI_DEVICE" ] && IsDocked "ata_bay"; then
    sync
    for BLOCK in $(/bin/cat $SCSI_DEVICE/block/*/*/dev $SCSI_DEVICE/block/*/dev 2> /dev/null); do
	DEVICE=$(Block2Device "$BLOCK") && ReleaseDevice "$DEVICE" || FAIL="1"
    done
    if [ $FAIL ]; then
	exit 1
    fi

    sync
    BLOCK=$(cat $SCSI_DEVICE/block/*/dev 2> /dev/null) &&
    DEVICE=$(Block2Device "$BLOCK") && SleepDrive "$DEVICE" || exit 1 
    sleep 3
    DeleteScsiDevice "$SCSI_DEVICE" || exit 1
    sleep 1
fi

if [ ! -d $SCSI_DEVICE ] && $(IsDocked "ata_bay"); then
    if Undock "ata_bay"; then
	Message "UltraBay undocked"
	exit 0
    else
	Message "cannot undock UltraBay"
	exit 1
    fi
fi

Message "UltraBay is already undock"
exit 1

UDEV rule

ENV{BAY_EVENT}=="3", ACTION=="change", SUBSYSTEM=="scsi", RUN+="/usr/local/sbin/ultrabay.sh -q -d /sys$DEVPATH"

Supported models: R400 - linux-2.6.29

comments

Interesting, especially the support for swap partitions. but I have two comments, first your calling your script hotswap.sh and then having udev call ultrabay.sh?

Then your hard coding the location of the Ultrabay device. This is not guarenteed to be correct, although it will be in most cases. In particular the A and W-series machines. A-series had support for more then one Ultrabay device, while W-series has support for more then one internal HDD in addition to the Ultrabay device, so the Ultrabay location will shift. That is why the Ultrabay Eject script on the main page gets the eject device information from udev.

comments

Hi, thanks, I fix name of script :) Udev calling ultrabay.sh with option -d, so it remove correct device, if you want remove device manualy, is default device useful. But option may be required...