XEN PVUSB: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
Keine Bearbeitungszusammenfassung |
|||
| Zeile 1: | Zeile 1: | ||
=== PVUSB mit XEN 3.4 === | === PVUSB mit XEN 3.4 === | ||
Bei mir gab es Probleme mit USB per PCI-Delegation unter XEN 3.4.1 auf Lenny (die Netzwerkkarten gingen, lsusb hat auch die USB Hostcontroller angezeigt, aber es wurden keine USB-Devices sichtbar), deshalb habe ich die seit Xen 3.4 neue USB-Virtualisierung PVUSB getestet und unter Lenny eingebaut. Dabei ist folgendes Skript herausgekommen, welches ich in '/etc/rc.local' als '''pvusb -b''' aufrufe, um beim booten des Host-Systems den USB-Drucker an meine Printer-Domain durchzureichen. | Bei mir gab es Probleme mit USB per PCI-Delegation unter XEN 3.4.1 auf Lenny (die Netzwerkkarten gingen, lsusb hat auch die USB Hostcontroller angezeigt, aber es wurden keine USB-Devices sichtbar), deshalb habe ich die seit Xen 3.4 neue USB-Virtualisierung '''PVUSB''' (Details siehe [http://www.nabble.com/-RFC--PATCH-0-4--PVUSB:-add-paravirtualized-USB-support-for-Xen-td22550607.html hier]) getestet und unter Lenny eingebaut. Dabei ist folgendes Skript herausgekommen, welches ich in '/etc/rc.local' als '''pvusb -b''' aufrufe, um beim booten des Host-Systems den USB-Drucker an meine Printer-Domain durchzureichen. | ||
<pre>#!/bin/sh -e | <pre>#!/bin/sh -e | ||
Version vom 20. August 2009, 08:25 Uhr
PVUSB mit XEN 3.4
Bei mir gab es Probleme mit USB per PCI-Delegation unter XEN 3.4.1 auf Lenny (die Netzwerkkarten gingen, lsusb hat auch die USB Hostcontroller angezeigt, aber es wurden keine USB-Devices sichtbar), deshalb habe ich die seit Xen 3.4 neue USB-Virtualisierung PVUSB (Details siehe hier) getestet und unter Lenny eingebaut. Dabei ist folgendes Skript herausgekommen, welches ich in '/etc/rc.local' als pvusb -b aufrufe, um beim booten des Host-Systems den USB-Drucker an meine Printer-Domain durchzureichen.
#!/bin/sh -e
#
# paravirtualized USB Support
#
# Version: $Revision$
# Datum: $Date$
#
# Author: neobiker
#
# $Log$
#set -x
usage ()
{
cat <<-EOT
usage: $(basename $0) -b
$(basename $0) -d device_id -s domain [-c comment] -w
$(basename $0) -u usb-port -s domain [-c comment] -w
------------
-b # boot host with static defined PVUSB rules
-s domain # server domainname or -id
-u usb-port # USB-PORT e.g. "3-2"
-d device_id # USB device_id e.g. "0912:1234"
-c comment # e.g. "Canon IP4000"
-w # write/activate PVUSB rule
EOT
}
#
# paravirtualized USB Support
# ---------------------------
XSWRITE=/usr/bin/xenstore-write
XSCHMOD=/usr/bin/xenstore-chmod
pvusb_init_xenstore ()
{
# Setup and initialize the XenStore for PVUSB
# based on init_xs.sh by Noboru Iwamatsu
FRONT_ID=$(xm domid "$1") # use domain id if dommane given
DEV_ID=$2 # vusb_bus typical 0
DEV_NAME=vusb # fix name
NUM_PORTS=8 # Max 16 ports.
# Write backend information into the location that frontend look for.
$XSWRITE /local/domain/$FRONT_ID/device/$DEV_NAME/$DEV_ID/backend-id 0
$XSWRITE /local/domain/$FRONT_ID/device/$DEV_NAME/$DEV_ID/backend \
/local/domain/0/backend/$DEV_NAME/$FRONT_ID/$DEV_ID
# Write frontend information into the location that backend look for.
$XSWRITE /local/domain/0/backend/$DEV_NAME/$FRONT_ID/$DEV_ID/frontend-id $FRONT_ID
$XSWRITE /local/domain/0/backend/$DEV_NAME/$FRONT_ID/$DEV_ID/frontend \
/local/domain/$FRONT_ID/device/$DEV_NAME/$DEV_ID
# Write virtual root hub field.
$XSWRITE /local/domain/0/backend/$DEV_NAME/$FRONT_ID/$DEV_ID/num-ports $NUM_PORTS
for i in $(seq 1 $NUM_PORTS)
do
# Set all port to disconnected state
$XSWRITE /local/domain/0/backend/$DEV_NAME/$FRONT_ID/$DEV_ID/port-$i "0"
done
# Set permission
$XSCHMOD /local/domain/$FRONT_ID/device/$DEV_NAME/$DEV_ID n$FRONT_ID r0
$XSCHMOD /local/domain/$FRONT_ID/device/$DEV_NAME/$DEV_ID/backend-id n$FRONT_ID r0
$XSCHMOD /local/domain/$FRONT_ID/device/$DEV_NAME/$DEV_ID/backend n$FRONT_ID r0
$XSCHMOD /local/domain/0/backend/$DEV_NAME/$FRONT_ID/$DEV_ID n0 r$FRONT_ID
$XSCHMOD /local/domain/0/backend/$DEV_NAME/$FRONT_ID/$DEV_ID/frontend-id n0 r$FRONT_ID
$XSCHMOD /local/domain/0/backend/$DEV_NAME/$FRONT_ID/$DEV_ID/frontend n0 r$FRONT_ID
$XSCHMOD /local/domain/0/backend/$DEV_NAME/$FRONT_ID/$DEV_ID/num-ports n0 r$FRONT_ID
for i in $(seq 1 $NUM_PORTS)
do
$XSCHMOD /local/domain/0/backend/$DEV_NAME/$FRONT_ID/$DEV_ID/port-$i n0 r$FRONT_ID
done
# Set state to XenbusStateInitialising
$XSWRITE /local/domain/$FRONT_ID/device/$DEV_NAME/$DEV_ID/state 1
$XSCHMOD /local/domain/$FRONT_ID/device/$DEV_NAME/$DEV_ID/state n$FRONT_ID r0
$XSWRITE /local/domain/0/backend/$DEV_NAME/$FRONT_ID/$DEV_ID/state 1
$XSCHMOD /local/domain/0/backend/$DEV_NAME/$FRONT_ID/$DEV_ID/state n0 r$FRONT_ID
}
pvusb_init ()
{
[ "$VUSB_ID" ] || return
VUSB_ID=1
# 1) First, you have to start from the state that no device is connected.
# remove all usb modules but usbbk
usb_mods="$(lsmod | grep usb | grep -v usbcore | grep -v usbbk | awk '/^usb/ {print $1}')"
[ -n "$usb_mods" ] && rmmod $usb_mods
# stop udevd fetching events before the backend driver
udevadm control --stop_exec_queue
# load usb (backend) modules
modprobe usbbk
}
pvusb_setup ()
{
# connect USB devices to backend (and restart udevd afterwards)
# XXX: better way to connect USB devices dynamically without udevd?
rmmod uhci_hcd ehci_hcd
modprobe -a uhci_hcd ehci_hcd
# start udevd again after we have finished
udevadm control --start_exec_queue
}
pvusb_port ()
{
dom_id=$1 # domain to connect PVUSB Port
usb_bus=$2 # where is usb device connected
comment=$3 # a name for usb device
vusb_bus=0 # virtual USB Bus in domain (we use always usb bus 0)
((++VUSB_ID))
if [ -z "$dom_id" ]; then
echo "missing option -s <dom_id>"
return
fi
if [ -z "$usb_bus" ]; then
echo "missing option -u <usb_port>"
return
fi
# initialise paravirtualized USB Support in domain with pv-usb bus 0
pvusb_init_xenstore $dom_id $vusb_bus
# 2) test and remove existing hotplug-rule
actual_vport=$(cat /sys/bus/usb/drivers/usbback/vports | awk "/$usb_bus/"'{print}')
[ -n "$actual_vport" ] && echo "$actual_vport" > /sys/bus/usb/drivers/usbback/remove_vport
# 2) Write the hotplug-rule through the sysfs interface of the backenend driver
echo "$usb_bus:$dom_id:$vusb_bus:$VUSB_ID" > /sys/bus/usb/drivers/usbback/new_vport
# tell me what happened
actual_vport=$(cat /sys/bus/usb/drivers/usbback/vports | awk "/$usb_bus/"'{print}')
echo "xen PVUSB Rule written: $actual_vport $comment on domain $DOM_NAME ($dom_id)"
}
get_usb_port ()
{
usb_dev="$1"
usb_port=""
# find out where USB-Device is connected
usb_ports="$(/bin/ls -1 /sys/bus/usb/devices/ | awk '/^[0-9]\-[0-9]$/ {print}')"
usb_bus=$(lsusb | grep $usbdev | awk '{printf "%d",$2}')
usb_adr=$(lsusb | grep $usbdev | awk '{printf "%d",$4}')
for port in $(echo "$usb_ports"|grep "$usb_bus"); do
adr=$(cat /sys/bus/usb/devices/$port/devnum)
if [ "$adr" = "$usb_adr" ]; then
usb_port=$port
break
fi
done
echo "$usb_port"
}
pvusb_write_connected_devices_static ()
{
# Define where to connect my USB-Devices (static definitions)
# -----------------------------------------------------------
# see dmesg (syslog) where device ist connected:
# e.g.: usb 3-2: new full speed USB device using uhci_hcd and address 4
devices="$1"
usb_ports="$(/bin/ls -1 /sys/bus/usb/devices/ | awk '/^[0-9]\-[0-9]$/ {print}')"
for usb_dev in $devices; do
# where to connect my usb devices to?
# list static definitions here
# ----------------------------
# XXX: to be read from e.g. /etc/xen/pvusb.conf
case $usb_dev in
04a9:1093)
comment="Canon-IP4000"
server=srv
domain=$(xm domid $server)
;;
13fe:1d00)
comment="Sun USB-Stick 1GB"
server=srv
domain=$(xm domid $server)
;;
090c:1000)
comment="Novell USB-Stick 2GB"
server=srv
domain=$(xm domid $server)
;;
*)
continue
;;
esac
# find out where USB-Device is connected
usb_bus=$(lsusb | grep $usb_dev | awk '{printf "%d",$2}')
usb_adr=$(lsusb | grep $usb_dev | awk '{printf "%d",$4}')
for port in $(echo "$usb_ports"|grep "$usb_bus"); do
adr=$(cat /sys/bus/usb/devices/$port/devnum)
if [ "$adr" = "$usb_adr" ]; then
usb_port=$port
break
fi
done
echo "found $comment ($usb_dev) on USB-Port $usb_port"
# PVUSB write xen backend rules for usb device
# --------------------------------------------
pvusb_port $domain $usb_port "$comment"
# remember domain to be triggered
PVUSB_DOMAINS=$(cat <<-EOT | sort -u
$PVUSB_DOMAINS
$domain)
done
}
pvusb_boot_host ()
{
# get all connected USB devices
usb_devices=$(lsusb | grep -v '0000:0000' | awk '{print $6}')
# ready if no devices are found
if [ -z "$usb_devices" ]; then
echo "$(basename $0): No USB Devices found"
return
fi
# PVUSB initialising / prerequisits
# ------------------
pvusb_init
# PVUSB write backend rules
# -------------------------
pvusb_write_connected_devices_static "$usb_devices"
}
pvusb_trigger ()
{
# PVUSB trigger for all relevant domains
# --------------------------------------
[ -n "$PVUSB" ] || return
# tell PV domain to reload USB
# XXX: better way to trigger domU?
for server in $(echo "$1" | sort -u); do
ssh $server "[ -n \"\$(lsusb|grep -v '0000:0000')\" ] || exit 0 ;
rmmod xen_hcd usbcore ;
modprobe xen_hcd
"
done
}
pvusb_logme ()
{
# tell me what happened
# ---------------------
PVUSB="$(cat /sys/bus/usb/drivers/usbback/grabbed_devices)"
for pvusb in $PVUSB; do
echo "xen PVUSB grabbed USB-Port=$pvusb"
done
}
# ------------------------
# Script starts here
# ------------------------
VUSB_ID=0
while getopts ":bc:d:hs:u:w" opt; do
case $opt in
b) # boot host with static defined rules
pvusb_boot_host
pvusb_setup
pvusb_logme
pvusb_trigger $PVUSB_DOMAINS
;;
c) # COMMENT (Canon IP4000)
comment=$OPTARG
;;
d) # USB DEVICE_ID (0912:1234)
usb_port=$(get_usb_port $OPTARG)
;;
s) # Server Domain name od id
domain=$OPTARG
;;
u) # USB-PORT (3-2)
usb_port=$OPTARG
;;
w) # write rule PVUSB
pvusb_init
pvusb_port $domain $usb_port "$comment"
pvusb_setup
pvusb_logme
pvusb_trigger $PVUSB_DOMAINS
;;
h)
usage
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done