Linux UltraBay Hotswap
Linux UltraBay Hotswap
Hier wird eine funktionierende Lösung für den Hotswap von UltraBay-Geräten auf einem T61 unter Debian Linux präsentiert. Es handelt sich dabei um eine angepasste Version der Skripte von www.thinkwiki.org/wiki/How_to_hotswap_Ultrabay_devices#Script_for_Ultrabay_eject
Erfolgreich getestet wurde diese Version bisher auf einem T61 mit Debian Linux (unstable) und Kernel 3.8.5 aus dem experimentellen Bereich von Debian. Für andere ThinkPads sind gegebenenfalls Anpassungen der DEVPATH-Variablen am Anfang der jeweiligen Skripte vorzunehmen.
Voraussetzungen
Die unten aufgeführten Skripte benachrichtigen den Anwender mittels notify-send über den Erfolgsstatus der Hotswap-Skripte, und setzen deswegen die Installation des Debian-Pakets libnotify-bin vorraus:
apt-get -u -m install libnotify-bin
Da die UltraBay eines T61 im Gegensatz zu neueren ThinkPad-Modellen noch auf ATA-Basis statt SATA funktioniert, ist es zu empfehlen, darauf zu achten, das Kernel-Modul ata_piix möglichst erst am Ende des Bootvorgangs laden zu lassen. Das bietet den Vorteil, dass eine in der UltraBay enthaltene zweite Festplatte niemals fälschlicherweise als erste Systemplatte /dev/sda eingebunden wird.
Zu diesem Zwecke legt man zuerst die Datei "/etc/modprobe.d/blacklist-ata_piix.conf" mit folgendem Inhalt an:
### module ata_piix is loaded in /etc/rc.local after reboot, to make sure ### that ultrabay disk always gets assigned a disk device file other than ### /dev/sda and thus leaving sda to the internal SATA system disk. blacklist ata_piix
Im zweiten Schritt fügt man in "/etc/rc.local" folgende Einträge hinzu:
### module ata_piix blacklisted in /etc/modprobe.d/blacklist.conf and ### loaded manually after reboot, in order to make sure that ultrabay ### disk always gets assigned a disk device file other than /dev/sda and ### thus leaving sda to the internal SATA system disk. /sbin/modprobe ata_piix ### Do a vgscan to have any LV located on ultrabay disk noticed by LVM. /sbin/vgscan # enable still inactive logical volumes if any is found: for LVOL in $(/sbin/lvscan | /bin/grep inactive | /usr/bin/cut -d\/ -f3 | /usr/bin/sort -u) do [ "$(/bin/echo $LVOL)" != "" ] && /sbin/vgchange -a y $LVOL done # Make sure that the script will "exit 0" on success or any other value on error. exit 0
Skripte zur Bereitstellung der Hotswap-Funktionalität
Folgendes Skript als "/etc/udev/rules.d/50-thinkpad-ultrabay.rules" speichern und mit dem Befehl udevadm control --reload-rules im System ativieren:
# Change the DEVPATH variable to match your system, if it doesn't match your ThinkPad model # The DEVPATH value used here should hopefully be working out of the box on any T6x ThinkPad. # To find the correct value for your ThinkPad, insert the UltraBay optical drive and execute: # udevadm info --query=path --name=/dev/sr0 | perl -pe 's!/block/...$!!' SUBSYSTEMS=="block", DEVPATH=="/devices/pci0000:00/0000:00:1f.1/ata4/host3/*", ENV{UDISKS_SYSTEM_INTERNAL}="0" ENV{EVENT}=="undock", KERNEL=="dock.1", ACTION=="change", SUBSYSTEM=="platform", RUN+="/usr/local/sbin/ultrabay_eject" ENV{EVENT}=="dock", KERNEL=="dock.1", ACTION=="change", SUBSYSTEM=="platform", RUN+="/usr/local/sbin/ultrabay_insert"
Folgendes Skript als "/usr/local/sbin/ultrabay_eject" speichern und Ausführungsrechte mit "chmod 754 /usr/local/sbin/ultrabay_eject" setzen:
#!/bin/bash #set -x # Sources: # http://www.thinkwiki.org/wiki/How_to_hotswap_Ultrabay_devices#Script_for_Ultrabay_eject # http://www.thinkwiki.org/wiki/Talk:How_to_hotswap_Ultrabay_devices SCRIPTNAME="$(basename $0)" # Change the DEVPATH variable to match your system, if it doesn't match your ThinkPad model # The DEVPATH value used here should hopefully be working out of the box on any T6x ThinkPad. # To find the correct value for your ThinkPad, insert the UltraBay optical drive and execute: # udevadm info --query=path --name=/dev/sr0 | perl -pe 's!/block/...$!!' if [ "$DEVPATH" = "" ] then DEVPATH="/devices/pci0000:00/0000:00:1f.1/ata4/host3/target3:0:0/3:0:0:0" fi shopt -s nullglob export DISPLAY=:0.0 # required for notify-send DISP0_USER=$(who | grep "tty" | awk '{ print $1 }') DISP0_USER_HOME=`getent passwd ${DISP0_USER} | cut -d':' -f6` export XAUTHORITY=${DISP0_USER_HOME}/.Xauthority # also required for notify-send ULTRABAY_SYSDIR=/sys$DEVPATH # Find generic dock interface for UltraBay dock=$(dirname $(/bin/grep -l ata_bay /sys/devices/platform/dock.?/type)) if [ ! -n "$dock" -a -d "$dock" ]; then logger "$SCRIPTNAME": cannot locate bay dock device notify-send -u critical -t 100000 "ThinkPad Ultrabay eject failed" "Cannot locate bay dock device" exit 1 fi # Umount the filesystem(s) backed by the given major:minor device(s) unmount_rdev() { perl - "$@" <<'EOPERL' # let's do it in Perl for $major_minor (@ARGV) { $major_minor =~ m/^(\d+):(\d+)$/ or die; push(@tgt_rdevs, ($1<<8)|$2); } # Sort by reverse length of mount point, to unmount sub-directories first open MOUNTS,"</proc/mounts" or die "$!"; @mounts=sort { length($b->[1]) <=> length($a->[1]) } map { [ split ] } <MOUNTS>; close MOUNTS; foreach $m (@mounts) { ($dev,$dir)=@$m; next unless -b $dev; $rdev=(stat($dev))[6]; next unless grep($_==$rdev, @tgt_rdevs); system("umount","-v","$dir")==0 or $bad=1; if ($bad == 1) { system("logger","ultrabay_eject","ERROR unmounting",$dev,$dir); system("notify-send -u critical -t 100000 \"Error unmounting $dir\" \"Unmounting of $dir on $dev failed!\""); } else { system("logger","ultrabay_eject","unmounted",$dev,$dir); system("notify-send -u normal -t 5000 \"Unmounted $dir\""); }; } exit 1 if $bad; EOPERL } # Get the UltraBay's /dev/foo block device node ultrabay_dev_node() { UDEV_PATH="`readlink -e "$ULTRABAY_SYSDIR/block/"*`" || return 1 UDEV_NAME="`udevadm info --query=name --path=$UDEV_PATH`" || return 1 echo /dev/$UDEV_NAME } if [ $( cat $dock/docked ) == 0 ]; then logger "$SCRIPTNAME": dock reports empty else if [ -d $ULTRABAY_SYSDIR ]; then logger "$SCRIPTNAME": dock occupied, shutting down storage device $DEVPATH sync # Unmount filesystems backed by this device ## This seems to be very inelegant and prone to failure unmount_rdev `cat $ULTRABAY_SYSDIR/block/*/dev \ $ULTRABAY_SYSDIR/block/*/*/dev` \ || { logger "$SCRIPTNAME": umounting failed notify-send -u critical -t 100000 "ThinkPad Ultrabay eject failed" "Please do not pull the device, doing so could cause file corruption and possibly hang the system. Unmounting of the filesystem on the ThinkPad Ultrabay device failed. Please put the eject leaver back in place, and try to unmount the filesystem manually. If this succeeds you can try the eject again" exit 1; } sync # Nicely power off the device DEVNODE=`ultrabay_dev_node` && hdparm -Y $DEVNODE # Let HAL+KDE notice the unmount and let the disk spin down sleep 0.5 # Unregister this SCSI device: sync echo 1 > $ULTRABAY_SYSDIR/delete else logger "$SCRIPTNAME": bay occupied but incorrect device path $DEVPATH notify-send -u critical -t 100000 "ThinkPad Ultrabay eject failed" "Bay occupied but incorrect device path" exit 1 fi fi # We need to sleep here to wait for the bay and the drive to disconnect sleep 1 # Undocking the UltraBay: logger "$SCRIPTNAME": undocking $dock if [ "$(cat $dock/docked)" != "0" ]; then echo 1 > $dock/undock else # Tell the user we're OK once done logger "$SCRIPTNAME": successfully completed notify-send -u normal -t 10000 "Safe to remove device" "The ThinkPad Ultrabay device can now be safely removed" exit 0 fi
Folgendes Skript als "/usr/local/sbin/ultrabay_insert" speichern und Ausführungsrechte mit "chmod 754 /usr/local/sbin/ultrabay_insert" setzen
#!/bin/bash #set -x # Source: # http://www.thinkwiki.org/wiki/How_to_hotswap_Ultrabay_devices#Script_for_Ultrabay_eject # http://www.thinkwiki.org/wiki/Talk:How_to_hotswap_Ultrabay_devices SCRIPTNAME="$(basename $0)" export DISPLAY=:0.0 # required for notify-send DISP0_USER=$(who | grep "tty" | awk '{ print $1 }') DISP0_USER_HOME=`getent passwd ${DISP0_USER} | cut -d':' -f6` export XAUTHORITY=${DISP0_USER_HOME}/.Xauthority # also required for notify-send # Change the DEVPATH variable to match your system, if it doesn't match your ThinkPad model # The DEVPATH value used here should hopefully be working out of the box on any T6x ThinkPad. # To find the correct value for your ThinkPad, insert the UltraBay optical drive and execute: # udevadm info --query=path --name=/dev/sr0 | perl -pe 's!/block/...$!!' if [ "$DEVPATH" = "" ] then DEVPATH="/devices/pci0000:00/0000:00:1f.1/ata4/host3/target3:0:0/3:0:0:0" fi ULTRABAY_SYSDIR=/sys$DEVPATH # Get the UltraBay's /dev/foo block device node ultrabay_dev_node() { UDEV_PATH="`readlink -e "$ULTRABAY_SYSDIR/block/"*`" || return 1 UDEV_NAME="`udevadm info --query=name --path=$UDEV_PATH`" || return 1 echo /dev/$UDEV_NAME } DOCKDEVICE=$(lsscsi | grep $(ultrabay_dev_node) | tr -s " ") # Find generic dock interface for UltraBay dock=$(dirname $(/bin/grep -l ata_bay /sys/devices/platform/dock.?/type)) if [ ! -n "$dock" -a -d "$dock" ]; then logger "$SCRIPTNAME": cannot locate bay dock device notify-send -u critical -t 100000 "ThinkPad Ultrabay device docking failed" "Cannot locate bay dock device" exit 1 fi # Tell the user we're OK once done if [ "$(cat $dock/docked)" = "1" ]; then sync logger "$SCRIPTNAME": Scanning ThinkPad Ultrabay for new device echo 0 0 0 > /sys/class/scsi_host/host3/scan logger "$SCRIPTNAME": Docking of ThinkPad Ultrabay device successfully completed. notify-send -u normal -t 10000 "Docking ThinkPad Ultrabay device completed" "The ThinkPad Ultrabay device is now available for use." exit 0 else logger "$SCRIPTNAME": ThinkPad Ultrabay device docking failed notify-send -u normal -t 10000 "Docking ThinkPad Ultrabay device failed" "Docking the ThinkPad Ultrabay device failed. Please check what went wrong and fix it." exit 1 fi
Beschreibung des Hotswap-Vorgangs
Sobald die oben aufgeführten Skripte mit den jeweils notwendigen Zugriffsrechten erstellt und aktiviert wurden, bewirkt die Betätigung des Schiebeschalters zur Initialisierung des Auswurfvorgangs an der UltraBay die automatische Abschaltung des in der UltraBay enthaltenen Geräts. Vorher noch wird versucht, alle gemounteten Dateisysteme des Gerätes zu umounten.
Sobald das Gerät erfolgreich deaktiviert wurde, erscheint eine Desktop-Benachrichtigung in Form einer Textblase mit einem entsprechenden Hinweis, bzw. im Fehlerfalle mit einer entsprechenden Fehlermeldung. Im Erfolgsfalle kann das Gerät nun einfach an der herausgesprungenen Lasche der Ultrabay herausgezogenen werden.
Wenn ein Gerät in die UltraBay eingesetzt wird, dann wird es automatisch aktiviert, und der Desktop-Benutzer erhält eine Benachrichtigung über den Erfolgsstatus.