Lee Yarwood has uploaded a new change for review.
Change subject: Add hostusbdirect hook to vdsm_hooks.
......................................................................
Add hostusbdirect hook to vdsm_hooks.
This is a slight variation of the hostusb hook. This version uses the bus and
device IDs to attach host USB device to the guest using the following libvirt XML :
<hostdev mode='subsystem' type='usb' managed='yes'>
<source>
<address bus='001' device='003'/>
</source>
</hostdev>
In the future this could be merged with the hostusb hook.
Change-Id: I00b4b03993cd7290462b0e17457892b23dd41b31
Signed-off-by: Lee Yarwood <lyarwood(a)redhat.com>
---
M configure.ac
M vdsm.spec.in
M vdsm_hooks/Makefile.am
A vdsm_hooks/hostusbdirect/Makefile.am
A vdsm_hooks/hostusbdirect/README
A vdsm_hooks/hostusbdirect/after_vm_destroy.py
A vdsm_hooks/hostusbdirect/before_vm_migrate_source.py
A vdsm_hooks/hostusbdirect/before_vm_start.py
A vdsm_hooks/hostusbdirect/sudoers.vdsm_hook_hostusbdirect
9 files changed, 262 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/28/17428/1
diff --git a/configure.ac b/configure.ac
index 0ccca95..39e31f0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -225,6 +225,7 @@
vdsm_hooks/fileinject/Makefile
vdsm_hooks/floppy/Makefile
vdsm_hooks/hostusb/Makefile
+ vdsm_hooks/hostusbdirect/Makefile
vdsm_hooks/hugepages/Makefile
vdsm_hooks/isolatedprivatevlan/Makefile
vdsm_hooks/macspoof/Makefile
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 235d1db..c1b9431 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -389,6 +389,15 @@
Hook is getting vendor and product id of USB device
disconnect it from host and attach it to VM
+%package hook-hostusb-direct
+Summary: Allow attaching USB device from host by bus and device ids.
+BuildArch: noarch
+Requires: usbutils
+
+%description hook-hostusb-direct
+Hook is getting bus and device id of USB device
+disconnect it from host and attach it to VM
+
%package hook-hugepages
Summary: Huge pages enable user to handle VM with 2048KB page files.
BuildArch: noarch
diff --git a/vdsm_hooks/Makefile.am b/vdsm_hooks/Makefile.am
index 8a8d594..fb4052b 100644
--- a/vdsm_hooks/Makefile.am
+++ b/vdsm_hooks/Makefile.am
@@ -30,6 +30,7 @@
fileinject \
floppy \
hostusb \
+ hostusbdirect \
hugepages \
isolatedprivatevlan \
macspoof \
diff --git a/vdsm_hooks/hostusbdirect/Makefile.am b/vdsm_hooks/hostusbdirect/Makefile.am
new file mode 100644
index 0000000..9d0cdbc
--- /dev/null
+++ b/vdsm_hooks/hostusbdirect/Makefile.am
@@ -0,0 +1,52 @@
+#
+# Copyright 2013 Red Hat, Inc.
+#
+# This program 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 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+EXTRA_DIST = \
+ after_vm_destroy.py \
+ before_vm_migrate_source.py \
+ before_vm_start.py \
+ sudoers.vdsm_hook_hostusbdirect
+
+install-data-hook:
+ chmod 440 $(DESTDIR)$(sysconfdir)/sudoers.d/50_vdsm_hook_hostusbdirect
+
+install-data-local: install-data-sudoers
+ $(MKDIR_P) $(DESTDIR)$(vdsmhooksdir)/before_vm_start
+ $(INSTALL_SCRIPT) $(srcdir)/before_vm_start.py \
+ $(DESTDIR)$(vdsmhooksdir)/before_vm_start/50_hostusbdirect
+ $(MKDIR_P) $(DESTDIR)$(vdsmhooksdir)/after_vm_destroy
+ $(INSTALL_SCRIPT) $(srcdir)/after_vm_destroy.py \
+ $(DESTDIR)$(vdsmhooksdir)/after_vm_destroy/50_hostusbdirect
+ $(MKDIR_P) $(DESTDIR)$(vdsmhooksdir)/before_vm_migrate_source
+ $(INSTALL_SCRIPT) $(srcdir)/before_vm_migrate_source.py \
+ $(DESTDIR)$(vdsmhooksdir)/before_vm_migrate_source/50_hostusbdirect
+
+uninstall-local: uninstall-data-sudoers
+ $(RM) $(DESTDIR)$(vdsmhooksdir)/before_vm_start/50_hostusbdirect
+ $(RM) $(DESTDIR)$(vdsmhooksdir)/after_vm_destroy/50_hostusbdirect
+ $(RM) $(DESTDIR)$(vdsmhooksdir)/before_vm_migrate_source/50_hostusbdirect
+
+install-data-sudoers:
+ $(MKDIR_P) $(DESTDIR)$(sysconfdir)/sudoers.d
+ $(INSTALL_DATA) $(srcdir)/sudoers.vdsm_hook_hostusbdirect \
+ $(DESTDIR)$(sysconfdir)/sudoers.d/50_vdsm_hook_hostusbdirect
+
+uninstall-data-sudoers:
+ $(RM) $(DESTDIR)$(sysconfdir)/sudoers.d/50_vdsm_hook_hostusbdirect
diff --git a/vdsm_hooks/hostusbdirect/README b/vdsm_hooks/hostusbdirect/README
new file mode 100644
index 0000000..297c559
--- /dev/null
+++ b/vdsm_hooks/hostusbdirect/README
@@ -0,0 +1,18 @@
+host usb hook direct
+====================
+add hosts usb device/s to VM using bus and device ids:
+
+<hostdev mode='subsystem' type='usb'>
+ <source>
+ <address bus='001' device='003'/>
+ </source>
+</hostdev>
+
+syntax:
+ hostusbdirect=001:003&001:002
+ i.e.
+ hostusb=bus:device (can add more then one with '&' separator)
+
+Note:
+ The VM must be pinned to host and this hook will
+ fail any migration attempt.
diff --git a/vdsm_hooks/hostusbdirect/after_vm_destroy.py
b/vdsm_hooks/hostusbdirect/after_vm_destroy.py
new file mode 100755
index 0000000..3882347
--- /dev/null
+++ b/vdsm_hooks/hostusbdirect/after_vm_destroy.py
@@ -0,0 +1,64 @@
+#!/usr/bin/python
+
+import os
+import sys
+import traceback
+
+import hooking
+
+'''
+after_vm_destroy:
+return the original owner of the usb device
+'''
+
+HOOK_HOSTUSB_PATH = '/var/run/vdsm/hooks/hostusbdirect-permissions'
+
+
+def get_owner(devpath):
+ uid = pid = -1
+ content = ''
+
+ if not os.path.isfile(HOOK_HOSTUSB_PATH):
+ return uid, pid
+
+ f = file(HOOK_HOSTUSB_PATH, 'r')
+ for line in f:
+ if len(line) > 0 and line.split(':')[0] == devpath:
+ entry = line.split(':')
+ uid = entry[1]
+ pid = entry[2]
+ elif len(line) > 0:
+ content += line + '\n'
+
+ f.close()
+ if uid != -1:
+ f = file(HOOK_HOSTUSB_PATH, 'w')
+ f.writelines(content)
+ f.close()
+
+ return uid, pid
+
+
+def chown(bus, device):
+ devpath = '/dev/bus/usb/' + bus + '/' + device
+ uid, gid = get_owner(devpath)
+
+ owner = str(uid) + ':' + str(gid)
+ command = ['/bin/chown', owner, devpath]
+ retcode, out, err = hooking.execCmd(command, sudo=True, raw=True)
+ if retcode != 0:
+ sys.stderr.write('hostusbdirect: error chown %s to %s, err = %s\n' %
+ (devpath, owner, err))
+ sys.exit(2)
+
+
+if 'hostusbdirect' in os.environ:
+ try:
+ for usb in os.environ['hostusbdirect'].split('&'):
+ bus, device = usb.split(':')
+ chown(bus, device)
+
+ except:
+ sys.stderr.write('hostusb after_vm_destroy: [unexpected error]: %s\n' %
+ traceback.format_exc())
+ sys.exit(2)
diff --git a/vdsm_hooks/hostusbdirect/before_vm_migrate_source.py
b/vdsm_hooks/hostusbdirect/before_vm_migrate_source.py
new file mode 100755
index 0000000..43a2eca
--- /dev/null
+++ b/vdsm_hooks/hostusbdirect/before_vm_migrate_source.py
@@ -0,0 +1,8 @@
+#!/usr/bin/python
+
+import os
+import sys
+
+if 'hostusbdirect' in os.environ:
+ sys.stderr.write("hostusbdirect: can't migrate VM with host usb
devices\n")
+ sys.exit(2)
diff --git a/vdsm_hooks/hostusbdirect/before_vm_start.py
b/vdsm_hooks/hostusbdirect/before_vm_start.py
new file mode 100755
index 0000000..57307aa
--- /dev/null
+++ b/vdsm_hooks/hostusbdirect/before_vm_start.py
@@ -0,0 +1,108 @@
+#!/usr/bin/python
+
+import os
+import sys
+import grp
+import pwd
+import traceback
+
+import hooking
+
+'''
+host usb hook direct
+====================
+
+syntax:
+ hostusbdirect=001:001&001:002
+ i.e.
+ hostusbdirect=bus:device (can add more then one with '&' separator)
+
+Note:
+ The VM must be pinned to host and this hook will
+ fail any migration attempt.
+'''
+
+HOOK_HOSTUSB_PATH = '/var/run/vdsm/hooks/hostusbdirect-permissions'
+
+
+def log_dev_owner(devpath, user, group):
+ entry = devpath + ":" + str(user) + ":" + str(group)
+
+ if not os.path.isdir(os.path.dirname(HOOK_HOSTUSB_PATH)):
+ os.mkdir(os.path.dirname(HOOK_HOSTUSB_PATH))
+
+ if os.path.isfile(HOOK_HOSTUSB_PATH):
+ f = file(HOOK_HOSTUSB_PATH, 'r')
+ for line in f:
+ if entry == line:
+ f.close()
+ return
+
+ f = file(HOOK_HOSTUSB_PATH, 'a')
+ f.writelines(entry)
+ f.close()
+
+
+def chown(bus, device):
+
+ devpath = '/dev/bus/usb/' + bus + '/' + device
+ stat = os.stat(devpath)
+
+ group = grp.getgrnam('qemu')
+ gid = group.gr_gid
+ user = pwd.getpwnam('qemu')
+ uid = user.pw_uid
+
+ owner = str(uid) + ':' + str(gid)
+ command = ['/bin/chown', owner, devpath]
+ retcode, out, err = hooking.execCmd(command, sudo=True, raw=True)
+ if retcode != 0:
+ sys.stderr.write('hostusbdirect: error chown %s to %s, err = %s\n' %
+ (devpath, owner, err))
+ sys.exit(2)
+
+ log_dev_owner(devpath, stat.st_uid, stat.st_gid)
+
+
+def add_devices(domxml, devices):
+ domain = domxml.getElementsByTagName('devices')[0]
+
+ for device in devices:
+ # Add the following for each device :
+ #<hostdev mode='subsystem' type='usb'
managed='yes'>
+ # <source>
+ # <address bus='001' device='003'/>
+ # </source>
+ #</hostdev>
+
+ hostdev = domxml.createElement('hostdev')
+ hostdev.setAttribute('mode', 'subsystem')
+ hostdev.setAttribute('type', 'usb')
+ hostdev.setAttribute('managed', 'yes')
+
+ source = domxml.createElement('source')
+ hostdev.appendChild(source)
+
+ address = domxml.createElement('address')
+ address.setAttribute('bus', device['bus'])
+ address.setAttribute('device', device['device'])
+ source.appendChild(address)
+
+ domain.appendChild(hostdev)
+
+if 'usbhostdirect' in os.environ:
+ try:
+ domxml = hooking.read_domxml()
+ devices = []
+
+ for usb in os.environ['usbhostdirect'].split('&'):
+ bus, device = usb.split(':')
+ chown(bus, device)
+ devices.append({'bus': bus, 'device': device})
+
+ add_devices(domxml, devices)
+ hooking.write_domxml(domxml)
+ except:
+ sys.stderr.write('hostusbdirect: [unexpected error]: %s\n' %
+ traceback.format_exc())
+ sys.exit(2)
diff --git a/vdsm_hooks/hostusbdirect/sudoers.vdsm_hook_hostusbdirect
b/vdsm_hooks/hostusbdirect/sudoers.vdsm_hook_hostusbdirect
new file mode 100644
index 0000000..cba601d
--- /dev/null
+++ b/vdsm_hooks/hostusbdirect/sudoers.vdsm_hook_hostusbdirect
@@ -0,0 +1 @@
+vdsm ALL=(ALL) NOPASSWD: /bin/chown
--
To view, visit
http://gerrit.ovirt.org/17428
To unsubscribe, visit
http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I00b4b03993cd7290462b0e17457892b23dd41b31
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Lee Yarwood <lyarwood(a)redhat.com>