XEN: различия между версиями
imported>Supportadmin Нет описания правки |
imported>Vix Нет описания правки |
||
(не показано 10 промежуточных версий 2 участников) | |||
Строка 1: | Строка 1: | ||
'''Здесь все что касается XEN''' | '''Здесь все что касается XEN''' | ||
[[Опции доменов Xen]] - описание параметров файлов виртуальных машин Xen (доменов DomU) | *[[Опции доменов Xen]] - описание параметров файлов виртуальных машин Xen (доменов DomU) | ||
[http://www.meadowcourt.org/downloads/ Драйверы] | *[http://www.meadowcourt.org/downloads/ Драйверы] | ||
---- | ---- | ||
* [http://bits.xensource.com/oss-xen/release/4.3.0/xen-4.3.0.tar.gz Исходники XEN-4.3] | * [http://bits.xensource.com/oss-xen/release/4.3.0/xen-4.3.0.tar.gz Исходники XEN-4.3] | ||
Строка 10: | Строка 10: | ||
* [[Сборка Xen 4.2 в Debian Wheezy и проброс устройств в гипервизор Xen]] | * [[Сборка Xen 4.2 в Debian Wheezy и проброс устройств в гипервизор Xen]] | ||
* [[Xen 4.2.x Сборка пакета deb для Wheezy]] - upstream | |||
* [[Установка Xen 4.1 на Debian Squeeze]] | * [[Установка Xen 4.1 на Debian Squeeze]] | ||
Строка 31: | Строка 32: | ||
* [http://how-it.ru/public/root/43-ustanovka_paravirtualnyh_draiverov_v_windows_server_2008.html Установка паравиртуальных драйверов в Windows Server 2008] | * [http://how-it.ru/public/root/43-ustanovka_paravirtualnyh_draiverov_v_windows_server_2008.html Установка паравиртуальных драйверов в Windows Server 2008] | ||
Скрипт настройки XEN при обновлении Grub: | |||
/etc/grub.d/20_linux_xen | |||
#! /bin/sh | |||
set -e | |||
# grub-mkconfig helper script. | |||
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. | |||
# | |||
# GRUB is free software: you can redistribute it and/or modify | |||
# it under the terms of the GNU General Public License as published by | |||
# the Free Software Foundation, either version 3 of the License, or | |||
# (at your option) any later version. | |||
# | |||
# GRUB is distributed in the hope that it will be useful, | |||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
# GNU General Public License for more details. | |||
# | |||
# You should have received a copy of the GNU General Public License | |||
# along with GRUB. If not, see <http://www.gnu.org/licenses/>. | |||
prefix="/usr" | |||
exec_prefix="${prefix}" | |||
datarootdir="${prefix}/share" | |||
. "${datarootdir}/grub/grub-mkconfig_lib" | |||
export TEXTDOMAIN=grub | |||
export TEXTDOMAINDIR="${datarootdir}/locale" | |||
CLASS="--class gnu-linux --class gnu --class os --class xen" | |||
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then | |||
OS=GNU/Linux | |||
else | |||
OS="${GRUB_DISTRIBUTOR} GNU/Linux" | |||
CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1) ${CLASS}" | |||
fi | |||
# loop-AES arranges things so that /dev/loop/X can be our root device, but | |||
# the initrds that Linux uses don't like that. | |||
case ${GRUB_DEVICE} in | |||
/dev/loop/*|/dev/loop[0-9]) | |||
GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"` | |||
# We can't cope with devices loop-mounted from files here. | |||
case ${GRUB_DEVICE} in | |||
/dev/*) ;; | |||
*) exit 0 ;; | |||
esac | |||
;; | |||
esac | |||
if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \ | |||
|| ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \ | |||
|| uses_abstraction "${GRUB_DEVICE}" lvm; then | |||
LINUX_ROOT_DEVICE=${GRUB_DEVICE} | |||
else | |||
LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID} | |||
fi | |||
# Allow overriding GRUB_CMDLINE_LINUX and GRUB_CMDLINE_LINUX_DEFAULT. | |||
if [ "${GRUB_CMDLINE_LINUX_XEN_REPLACE}" ]; then | |||
GRUB_CMDLINE_LINUX="${GRUB_CMDLINE_LINUX_XEN_REPLACE}" | |||
fi | |||
if [ "${GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT}" ]; then | |||
GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT}" | |||
fi | |||
if [ "x`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2>/dev/null || true`" = xbtrfs ] \ | |||
|| [ "x`stat -f --printf=%T /`" = xbtrfs ]; then | |||
rootsubvol="`make_system_path_relative_to_its_root /`" | |||
rootsubvol="${rootsubvol#/}" | |||
if [ "x${rootsubvol}" != x ]; then | |||
GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}" | |||
fi | |||
fi | |||
linux_entry () | |||
{ | |||
os="$1" | |||
version="$2" | |||
xen_version="$3" | |||
recovery="$4" | |||
args="$5" | |||
xen_args="$6" | |||
if ${recovery} ; then | |||
title="$(gettext_quoted "%s, with Xen %s and Linux %s (recovery mode)")" | |||
else | |||
title="$(gettext_quoted "%s, with Xen %s and Linux %s")" | |||
fi | |||
# дополнительные опции - можно выставить самому... | |||
printf 'set default="0" \n' | |||
printf 'set timeout=5 \n' | |||
# ------------------------------------------------ | |||
printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${xen_version}" "${version}" | |||
if ! ${recovery} ; then | |||
save_default_entry | sed -e "s/^/\t/" | |||
fi | |||
if [ -z "${prepare_boot_cache}" ]; then | |||
prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" | |||
fi | |||
printf '%s\n' "${prepare_boot_cache}" | |||
xmessage="$(gettext_printf "Loading Xen %s ..." ${xen_version})" | |||
lmessage="$(gettext_printf "Loading Linux %s ..." ${version})" | |||
cat << EOF | |||
echo '$xmessage' | |||
multiboot ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} | |||
echo '$lmessage' | |||
module ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args} | |||
EOF | |||
if test -n "${initrd}" ; then | |||
message="$(gettext_printf "Loading initial ramdisk ...")" | |||
cat << EOF | |||
echo '$message' | |||
module ${rel_dirname}/${initrd} | |||
EOF | |||
fi | |||
cat << EOF | |||
} | |||
EOF | |||
} | |||
linux_list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* /boot/kernel-*; do | |||
if grub_file_is_not_garbage "$i"; then | |||
basename=$(basename $i) | |||
version=$(echo $basename | sed -e "s,^[^0-9]*-,,g") | |||
dirname=$(dirname $i) | |||
config= | |||
for j in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do | |||
if test -e "${j}" ; then | |||
config="${j}" | |||
break | |||
fi | |||
done | |||
if (grep -qx "CONFIG_XEN_DOM0=y" "${config}" 2> /dev/null || grep -qx "CONFIG_XEN_PRIVILEGED_GUEST=y" "${config}" 2> /dev/null); then echo -n "$i " ; fi | |||
fi | |||
done` | |||
if [ "x${linux_list}" = "x" ] ; then | |||
exit 0 | |||
fi | |||
xen_list=`for i in /boot/xen*; do | |||
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi | |||
done` | |||
prepare_boot_cache= | |||
while [ "x${xen_list}" != "x" ] ; do | |||
list="${linux_list}" | |||
current_xen=`version_find_latest $xen_list` | |||
xen_basename=`basename ${current_xen}` | |||
xen_dirname=`dirname ${current_xen}` | |||
rel_xen_dirname=`make_system_path_relative_to_its_root $xen_dirname` | |||
xen_version=`echo $xen_basename | sed -e "s,.gz$,,g;s,^xen-,,g"` | |||
echo "submenu \"Xen ${xen_version}\" {" | |||
while [ "x$list" != "x" ] ; do | |||
linux=`version_find_latest $list` | |||
echo "Found linux image: $linux" >&2 | |||
basename=`basename $linux` | |||
dirname=`dirname $linux` | |||
rel_dirname=`make_system_path_relative_to_its_root $dirname` | |||
version=`echo $basename | sed -e "s,^[^0-9]*-,,g"` | |||
alt_version=`echo $version | sed -e "s,\.old$,,g"` | |||
linux_root_device_thisversion="${LINUX_ROOT_DEVICE}" | |||
initrd= | |||
for i in "initrd.img-${version}" "initrd-${version}.img" \ | |||
"initrd-${version}" "initrd.img-${alt_version}" \ | |||
"initrd-${alt_version}.img" "initrd-${alt_version}" \ | |||
"initramfs-genkernel-${version}" \ | |||
"initramfs-genkernel-${alt_version}" ; do | |||
if test -e "${dirname}/${i}" ; then | |||
initrd="$i" | |||
break | |||
fi | |||
done | |||
if test -n "${initrd}" ; then | |||
echo "Found initrd image: ${dirname}/${initrd}" >&2 | |||
else | |||
# "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here. | |||
linux_root_device_thisversion=${GRUB_DEVICE} | |||
fi | |||
linux_entry "${OS}" "${version}" "${xen_version}" false \ | |||
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" "${GRUB_CMDLINE_XEN} ${GRUB_CMDLINE_XEN_DEFAULT}" | |||
if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then | |||
linux_entry "${OS}" "${version}" "${xen_version}" true \ | |||
"single ${GRUB_CMDLINE_LINUX}" "${GRUB_CMDLINE_XEN}" | |||
fi | |||
list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '` | |||
done | |||
echo "}" | |||
xen_list=`echo $xen_list | tr ' ' '\n' | grep -vx $current_xen | tr '\n' ' '` | |||
done | |||
=='''Монтирование образа хоста XEN'''== | |||
используем утилиту losetup: | |||
проверяем наличие свободных устройств: | |||
losetup -a | |||
если все свободно, монтируем сначала образ: | |||
losetup /dev/loop5 disk.img | |||
смотрим смещение относительно начала: | |||
fdisk -l /dev/loop5 | |||
пример вывода: | |||
Disk /dev/loop5: 115.3 GB, 115343360000 bytes | |||
255 heads, 63 sectors/track, 14023 cylinders, total 225280000 sectors | |||
Units = sectors of 1 * 512 = 512 bytes | |||
Sector size (logical/physical): 512 bytes / 512 bytes | |||
I/O size (minimum/optimal): 512 bytes / 512 bytes | |||
Disk identifier: 0x390038ff | |||
Device Boot Start End Blocks Id System | |||
/dev/loop5p1 * 63 104872319 52436128+ 7 HPFS/NTFS/exFAT | |||
смещение для этого раздела равно 63, размер сектора 512 байт, для программного сдвига offset=63*512 (32256) | |||
создаем устройство типа /dev/sda1 только в варианте loop с которым будем работать: | |||
losetup -o 32256 /dev/loop6 /dev/loop5 | |||
теперь у нас аналог /dev/sda1 только устройство /dev/loop6 | |||
можно например его примонтировать: | |||
ntfs-3g /dev/loop6 /mnt | |||
и делать там все что угодно.. | |||
* [http://mypvn.blogspot.ru/2010/09/xen-how-to-mount-xen-image.html по теме] | |||
* [http://how-it.ru/public/root/388-montiruem_obraz_diska_xen__nevazhno___windows_tam_vnutri_ili__nix__bez_samogo_xen.html так же по теме] | |||
* [http://www.desktopbsd.ru/info/6233-xen-skript-montirovaniya-obraza-sistemy-img-for-centos.html пример автоматизации] | |||
==Xen HVM guest qemu-dm USB== | |||
Qemu-dm used for Xen HVM (fully virtualized) guests supports USB passthru of devices from dom0 to the guest. Qemu-dm emulates USB 1.1 UHCI 2-port controller, which is pretty slow and limited in features and device support. Qemu-dm USB 1.1 passthru support is in all Xen 3.x (and newer) versions. | |||
Qemu-dm USB 1.1 passthru doesn't require any additional backend drivers in dom0 or any additional frontend drivers in the guest! | |||
As of Xen 4.2, HVM passthru is not available via xl, only xm. Support is slated for the 4.3 release. | |||
Usage example in /etc/xen/<guest> cfgfile: | |||
usb = 1 | |||
usbdevice = "host:xxxx:yyyy" | |||
You can find out the "xxxx:yyyy" part by using "lsusb" command in dom0. | |||
You can also plug a device into a running VM using usb-add and usb-del: | |||
xm usb-add domain host:xxxx:yyyy | |||
xm usb-del domain host:xxxx:yyyy |
Текущая версия от 22:18, 13 октября 2014
Здесь все что касается XEN
- Опции доменов Xen - описание параметров файлов виртуальных машин Xen (доменов DomU)
- Драйверы
- Сборка Xen 4.2 в Debian Wheezy и проброс устройств в гипервизор Xen
- Xen 4.2.x Сборка пакета deb для Wheezy - upstream
- Установка Xen 4.1 на Debian Squeeze
VBoxManage clonehd centos6.vdi centos6.img -format RAW
Скрипт настройки XEN при обновлении Grub:
/etc/grub.d/20_linux_xen
#! /bin/sh set -e # grub-mkconfig helper script. # Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # GRUB is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GRUB. If not, see <http://www.gnu.org/licenses/>. prefix="/usr" exec_prefix="${prefix}" datarootdir="${prefix}/share" . "${datarootdir}/grub/grub-mkconfig_lib" export TEXTDOMAIN=grub export TEXTDOMAINDIR="${datarootdir}/locale" CLASS="--class gnu-linux --class gnu --class os --class xen" if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then OS=GNU/Linux else OS="${GRUB_DISTRIBUTOR} GNU/Linux" CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1) ${CLASS}" fi # loop-AES arranges things so that /dev/loop/X can be our root device, but # the initrds that Linux uses don't like that. case ${GRUB_DEVICE} in /dev/loop/*|/dev/loop[0-9]) GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"` # We can't cope with devices loop-mounted from files here. case ${GRUB_DEVICE} in /dev/*) ;; *) exit 0 ;; esac ;; esac if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \ || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \ || uses_abstraction "${GRUB_DEVICE}" lvm; then LINUX_ROOT_DEVICE=${GRUB_DEVICE} else LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID} fi # Allow overriding GRUB_CMDLINE_LINUX and GRUB_CMDLINE_LINUX_DEFAULT. if [ "${GRUB_CMDLINE_LINUX_XEN_REPLACE}" ]; then GRUB_CMDLINE_LINUX="${GRUB_CMDLINE_LINUX_XEN_REPLACE}" fi if [ "${GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT}" ]; then GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT}" fi if [ "x`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2>/dev/null || true`" = xbtrfs ] \ || [ "x`stat -f --printf=%T /`" = xbtrfs ]; then rootsubvol="`make_system_path_relative_to_its_root /`" rootsubvol="${rootsubvol#/}" if [ "x${rootsubvol}" != x ]; then GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}" fi fi linux_entry () { os="$1" version="$2" xen_version="$3" recovery="$4" args="$5" xen_args="$6" if ${recovery} ; then title="$(gettext_quoted "%s, with Xen %s and Linux %s (recovery mode)")" else title="$(gettext_quoted "%s, with Xen %s and Linux %s")" fi # дополнительные опции - можно выставить самому... printf 'set default="0" \n' printf 'set timeout=5 \n' # ------------------------------------------------ printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${xen_version}" "${version}" if ! ${recovery} ; then save_default_entry | sed -e "s/^/\t/" fi if [ -z "${prepare_boot_cache}" ]; then prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" fi printf '%s\n' "${prepare_boot_cache}" xmessage="$(gettext_printf "Loading Xen %s ..." ${xen_version})" lmessage="$(gettext_printf "Loading Linux %s ..." ${version})" cat << EOF echo '$xmessage' multiboot ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} echo '$lmessage' module ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args} EOF if test -n "${initrd}" ; then message="$(gettext_printf "Loading initial ramdisk ...")" cat << EOF echo '$message' module ${rel_dirname}/${initrd} EOF fi cat << EOF } EOF } linux_list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* /boot/kernel-*; do if grub_file_is_not_garbage "$i"; then basename=$(basename $i) version=$(echo $basename | sed -e "s,^[^0-9]*-,,g") dirname=$(dirname $i) config= for j in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do if test -e "${j}" ; then config="${j}" break fi done if (grep -qx "CONFIG_XEN_DOM0=y" "${config}" 2> /dev/null || grep -qx "CONFIG_XEN_PRIVILEGED_GUEST=y" "${config}" 2> /dev/null); then echo -n "$i " ; fi fi done` if [ "x${linux_list}" = "x" ] ; then exit 0 fi xen_list=`for i in /boot/xen*; do if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi done` prepare_boot_cache= while [ "x${xen_list}" != "x" ] ; do list="${linux_list}" current_xen=`version_find_latest $xen_list` xen_basename=`basename ${current_xen}` xen_dirname=`dirname ${current_xen}` rel_xen_dirname=`make_system_path_relative_to_its_root $xen_dirname` xen_version=`echo $xen_basename | sed -e "s,.gz$,,g;s,^xen-,,g"` echo "submenu \"Xen ${xen_version}\" {" while [ "x$list" != "x" ] ; do linux=`version_find_latest $list` echo "Found linux image: $linux" >&2 basename=`basename $linux` dirname=`dirname $linux` rel_dirname=`make_system_path_relative_to_its_root $dirname` version=`echo $basename | sed -e "s,^[^0-9]*-,,g"` alt_version=`echo $version | sed -e "s,\.old$,,g"` linux_root_device_thisversion="${LINUX_ROOT_DEVICE}" initrd= for i in "initrd.img-${version}" "initrd-${version}.img" \ "initrd-${version}" "initrd.img-${alt_version}" \ "initrd-${alt_version}.img" "initrd-${alt_version}" \ "initramfs-genkernel-${version}" \ "initramfs-genkernel-${alt_version}" ; do if test -e "${dirname}/${i}" ; then initrd="$i" break fi done if test -n "${initrd}" ; then echo "Found initrd image: ${dirname}/${initrd}" >&2 else # "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here. linux_root_device_thisversion=${GRUB_DEVICE} fi linux_entry "${OS}" "${version}" "${xen_version}" false \ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" "${GRUB_CMDLINE_XEN} ${GRUB_CMDLINE_XEN_DEFAULT}" if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then linux_entry "${OS}" "${version}" "${xen_version}" true \ "single ${GRUB_CMDLINE_LINUX}" "${GRUB_CMDLINE_XEN}" fi list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '` done echo "}" xen_list=`echo $xen_list | tr ' ' '\n' | grep -vx $current_xen | tr '\n' ' '` done
Монтирование образа хоста XEN
используем утилиту losetup:
проверяем наличие свободных устройств:
losetup -a
если все свободно, монтируем сначала образ:
losetup /dev/loop5 disk.img
смотрим смещение относительно начала:
fdisk -l /dev/loop5
пример вывода:
Disk /dev/loop5: 115.3 GB, 115343360000 bytes 255 heads, 63 sectors/track, 14023 cylinders, total 225280000 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x390038ff Device Boot Start End Blocks Id System /dev/loop5p1 * 63 104872319 52436128+ 7 HPFS/NTFS/exFAT
смещение для этого раздела равно 63, размер сектора 512 байт, для программного сдвига offset=63*512 (32256) создаем устройство типа /dev/sda1 только в варианте loop с которым будем работать:
losetup -o 32256 /dev/loop6 /dev/loop5
теперь у нас аналог /dev/sda1 только устройство /dev/loop6 можно например его примонтировать:
ntfs-3g /dev/loop6 /mnt
и делать там все что угодно..
Xen HVM guest qemu-dm USB
Qemu-dm used for Xen HVM (fully virtualized) guests supports USB passthru of devices from dom0 to the guest. Qemu-dm emulates USB 1.1 UHCI 2-port controller, which is pretty slow and limited in features and device support. Qemu-dm USB 1.1 passthru support is in all Xen 3.x (and newer) versions.
Qemu-dm USB 1.1 passthru doesn't require any additional backend drivers in dom0 or any additional frontend drivers in the guest!
As of Xen 4.2, HVM passthru is not available via xl, only xm. Support is slated for the 4.3 release.
Usage example in /etc/xen/<guest> cfgfile:
usb = 1 usbdevice = "host:xxxx:yyyy"
You can find out the "xxxx:yyyy" part by using "lsusb" command in dom0.
You can also plug a device into a running VM using usb-add and usb-del:
xm usb-add domain host:xxxx:yyyy xm usb-del domain host:xxxx:yyyy