XEN PVUSB: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
Keine Bearbeitungszusammenfassung |
|||
Zeile 3: | Zeile 3: | ||
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''' (paravirtualized USB support for Xen, 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. | 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''' (paravirtualized USB support for Xen, 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 | <pre>#!/bin/sh | ||
# | # | ||
# paravirtualized USB Support | # paravirtualized USB Support | ||
Zeile 14: | Zeile 14: | ||
# $Log$ | # $Log$ | ||
set -e | |||
#set -x | #set -x | ||
Zeile 28: | Zeile 29: | ||
-d device_id # USB device_id e.g. "0912:1234" | -d device_id # USB device_id e.g. "0912:1234" | ||
-c comment # e.g. "Canon IP4000" | -c comment # e.g. "Canon IP4000" | ||
-l # list (default) actual PVUSB Devices | |||
-q # don't list PVUSB devices | |||
-w # write/activate PVUSB rule | -w # write/activate PVUSB rule | ||
EOT | EOT | ||
Zeile 155: | Zeile 158: | ||
# find out where USB-Device is connected | # find out where USB-Device is connected | ||
usb_ports="$(/bin/ls -1 /sys/bus/usb/devices/ | awk '/^[0-9]\-[0-9]$/ {print}')" | usb_ports="$(/bin/ls -1 /sys/bus/usb/devices/ | awk '/^[0-9]\-[0-9]$/ {print}')" | ||
usb_bus=$(lsusb | grep $ | usb_bus=$(lsusb | grep $usb_dev | awk '{printf "%d",$2}') | ||
usb_adr=$(lsusb | grep $ | usb_adr=$(lsusb | grep $usb_dev | awk '{printf "%d",$4}') | ||
for port in $(echo "$usb_ports"|grep "$usb_bus"); do | for port in $(echo "$usb_ports"|grep "$usb_bus"); do | ||
Zeile 183: | Zeile 186: | ||
# list static definitions here | # list static definitions here | ||
# ---------------------------- | # ---------------------------- | ||
# XXX: to be read from | # XXX: to be read from /etc/pvusb/usb_setup | ||
case $usb_dev in | case $usb_dev in | ||
04a9:1093) | 04a9:1093) | ||
Zeile 264: | Zeile 267: | ||
} | } | ||
pvusb_list () | |||
{ | { | ||
# tell me what happened | # tell me what happened | ||
# --------------------- | # --------------------- | ||
pvusb_grabbed="$(cat /sys/bus/usb/drivers/usbback/grabbed_devices)" | |||
for pvusb in $ | for pvusb in $pvusb_grabbed; do | ||
echo " | usb_port=$(echo $pvusb| awk -F: '{print $1}') | ||
domain=$(cat /sys/bus/usb/drivers/usbback/vports | awk -F: "/$usb_port/"' {print $2}') | |||
dev_id="$(cat /sys/bus/usb/devices/$usb_port/idVendor)" | |||
dev_id="$dev_id:$(cat /sys/bus/usb/devices/$usb_port/idProduct)" | |||
product=$(lsusb | grep $dev_id | cut -d\ -f6-) | |||
echo "PVUSB: $usb_port on `xm domname $domain` ($domain) $product" | |||
done | done | ||
} | } | ||
Zeile 278: | Zeile 286: | ||
# ------------------------ | # ------------------------ | ||
VUSB_ID=0 | VUSB_ID=0 | ||
list_pvusb=1 | |||
while getopts ":bc:d:hs: | while getopts ":bc:d:hs:lqu:w" opt; do | ||
case $opt in | case $opt in | ||
b) # boot host with static defined rules | b) # boot host with static defined rules | ||
pvusb_boot_host | pvusb_boot_host | ||
pvusb_setup | pvusb_setup | ||
pvusb_trigger $PVUSB_DOMAINS | pvusb_trigger $PVUSB_DOMAINS | ||
;; | ;; | ||
Zeile 303: | Zeile 311: | ||
pvusb_port $domain $usb_port "$comment" | pvusb_port $domain $usb_port "$comment" | ||
pvusb_setup | pvusb_setup | ||
pvusb_trigger $PVUSB_DOMAINS | pvusb_trigger $PVUSB_DOMAINS | ||
;; | |||
l) # list (default=on) PVUSB Ports | |||
list_pvusb=1 | |||
;; | |||
q) # don't list PVUSB Ports | |||
list_pvusb=0 | |||
;; | ;; | ||
h) | h) | ||
Zeile 314: | Zeile 327: | ||
esac | esac | ||
done | done | ||
[ $list_pvusb -gt 0 ] && pvusb_list | |||
</pre> | </pre> |
Version vom 20. August 2009, 11:19 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 (paravirtualized USB support for Xen, 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 # # paravirtualized USB Support # # Version: $Revision$ # Datum: $Date$ # # Author: neobiker # # $Log$ set -e #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" -l # list (default) actual PVUSB Devices -q # don't list PVUSB devices -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 $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 "$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 /etc/pvusb/usb_setup 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_list () { # tell me what happened # --------------------- pvusb_grabbed="$(cat /sys/bus/usb/drivers/usbback/grabbed_devices)" for pvusb in $pvusb_grabbed; do usb_port=$(echo $pvusb| awk -F: '{print $1}') domain=$(cat /sys/bus/usb/drivers/usbback/vports | awk -F: "/$usb_port/"' {print $2}') dev_id="$(cat /sys/bus/usb/devices/$usb_port/idVendor)" dev_id="$dev_id:$(cat /sys/bus/usb/devices/$usb_port/idProduct)" product=$(lsusb | grep $dev_id | cut -d\ -f6-) echo "PVUSB: $usb_port on `xm domname $domain` ($domain) $product" done } # ------------------------ # Script starts here # ------------------------ VUSB_ID=0 list_pvusb=1 while getopts ":bc:d:hs:lqu:w" opt; do case $opt in b) # boot host with static defined rules pvusb_boot_host pvusb_setup 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_trigger $PVUSB_DOMAINS ;; l) # list (default=on) PVUSB Ports list_pvusb=1 ;; q) # don't list PVUSB Ports list_pvusb=0 ;; h) usage ;; \?) echo "Invalid option: -$OPTARG" >&2 ;; esac done [ $list_pvusb -gt 0 ] && pvusb_list