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

From ThinkWiki
Jump to: navigation, search
(bash script for hotswapping UltraBay: new section)
Line 61: Line 61:
 
==lshal output==
 
==lshal output==
 
Please place your lshal output here if you had problems, or if you have a A or W series ThinkPad
 
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 ==
 +
 +
Hi,
 +
here is my script for hotswapping ultrabay, is more complex, supports swap partition on drive in ultrabay and more :)
 +
 +
{{HELP|Please test on difrent models}}
 +
 +
hotswap.sh
 +
<pre>
 +
#!/bin/bash
 +
DEFAULT_DEVICE="/sys/class/scsi_device/1:0:0:0/device"
 +
FORCE_SLEEP="1"
 +
QUIET="0"
 +
 +
Message()
 +
{
 +
    if [ $QUIET = "0" ]; then
 +
echo "${0/*\//}: $*"
 +
    else
 +
true
 +
    fi
 +
}
 +
 +
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="$DEFAULT_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"
 +
    ;;
 +
    *)
 +
        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, default: $DEFAULT_DEVICE"
 +
        exit 1
 +
    ;;
 +
esac
 +
    fi
 +
done
 +
 +
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 "AtaBay 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
 +
    else
 +
Message "cannot undock BatteryBay"
 +
exit 1
 +
    fi
 +
fi
 +
 +
Message "UltraBay is already undock"
 +
exit 1
 +
</pre>
 +
 +
UDEV rule
 +
<pre>
 +
ENV{BAY_EVENT}=="3", ACTION=="change", SUBSYSTEM=="scsi", RUN+="/usr/local/sbin/ultrabay.sh -q -d /sys$DEVPATH"
 +
</pre>

Revision as of 15:05, 7 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

Hi, 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

hotswap.sh

#!/bin/bash
DEFAULT_DEVICE="/sys/class/scsi_device/1:0:0:0/device"
FORCE_SLEEP="1"
QUIET="0"

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

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="$DEFAULT_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"
	    ;;
	    *)
	        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, default: $DEFAULT_DEVICE"
	        exit 1
	    ;;
	esac
    fi
done

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 "AtaBay 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
    else
	Message "cannot undock BatteryBay"
	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"