[pve-devel] r6473 - in qemu-server/pve2: . PVE

svn-commits at proxmox.com svn-commits at proxmox.com
Mon Aug 15 08:39:57 CEST 2011


Author: dietmar
Date: 2011-08-15 08:39:57 +0200 (Mon, 15 Aug 2011)
New Revision: 6473

Modified:
   qemu-server/pve2/ChangeLog
   qemu-server/pve2/PVE/QemuServer.pm
Log:
	(parse_usb_device): impl. new syntax for usb devices (-usb0,
	-usb1, ...)



Modified: qemu-server/pve2/ChangeLog
===================================================================
--- qemu-server/pve2/ChangeLog	2011-08-15 05:19:39 UTC (rev 6472)
+++ qemu-server/pve2/ChangeLog	2011-08-15 06:39:57 UTC (rev 6473)
@@ -2,6 +2,8 @@
 
 	* PVE/QemuServer.pm (config_to_command): use -device instead of
 	-usbdevice, try to assigng fixed port to tablet device
+	(parse_usb_device): impl. new syntax for usb devices (-usb0,
+	-usb1, ...)
 
 2011-08-12  Proxmox Support Team  <support at proxmox.com>
 

Modified: qemu-server/pve2/PVE/QemuServer.pm
===================================================================
--- qemu-server/pve2/PVE/QemuServer.pm	2011-08-15 05:19:39 UTC (rev 6472)
+++ qemu-server/pve2/PVE/QemuServer.pm	2011-08-15 06:39:57 UTC (rev 6473)
@@ -276,21 +276,6 @@
 	enum => [qw(std cirrus vmware)],
 	default => 'cirrus',
     },
-    hostusb => {
-	optional => 1,
-	type => 'string', format => 'pve-qm-hostusb',
-	typetext => "HOSTUSBDEVICE { , HOSTUSBDEVICE }",
-	description => <<EODESCR,
-Map host usb devices. HOSTUSBDEVICE syntax is:
-
-'bus.addr' (decimal numbers) or 
-'vendor_id:product_id' (hexadeciaml numbers)
-
-You can use the 'lsusb' command to list existing usb devices (or take a look at '/proc/bus/usb/devices'.
-
-Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
-EODESCR
-    },
     hostpci => {
 	optional => 1,
         type => 'string', format => 'pve-qm-hostpci',
@@ -394,7 +379,6 @@
 #bootp => 'file',
 ##tftp => 'dir',
 ##smb => 'dir',
-##usb
 #kernel => 'file',
 #append => 'string',
 #initrd => 'file',
@@ -407,6 +391,7 @@
 my $MAX_IDE_DISKS = 4;
 my $MAX_SCSI_DISKS = 16;
 my $MAX_VIRTIO_DISKS = 16;
+my $MAX_USB_DEVICES = 5;
 my $MAX_NETS = 32;
 my $MAX_UNUSED_DISKS = 8;
 
@@ -473,6 +458,26 @@
 };
 PVE::JSONSchema::register_standard_option("pve-qm-virtio", $virtiodesc);
 
+my $usbdesc = {
+    optional => 1,
+    type => 'string', format => 'pve-qm-usb-device',
+    typetext => 'host=HOSTUSBDEVICE',
+    description => <<EODESCR,
+Configure an USB device (n is 0 to 5). This can be used to
+pass-through usb devices to the guest. HOSTUSBDEVICE syntax is:
+
+'bus-port(.port)*' (decimal numbers) or 
+'vendor_id:product_id' (hexadeciaml numbers)
+
+You can use the 'lsusb -t' command to list existing usb devices.  
+
+Note: This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
+
+EODESCR
+};
+PVE::JSONSchema::register_standard_option("pve-qm-usb", $usbdesc);
+
+
 for (my $i = 0; $i < $MAX_IDE_DISKS; $i++)  {
     $drivename_hash->{"ide$i"} = 1;
     $confdesc->{"ide$i"} = $idedesc;
@@ -488,6 +493,10 @@
     $confdesc->{"virtio$i"} = $virtiodesc;
 }
 
+for (my $i = 0; $i < $MAX_USB_DEVICES; $i++)  {
+    $confdesc->{"usb$i"} = $usbdesc;
+}
+
 my $unuseddesc = {
     optional => 1,
     type => 'string', format => 'pve-volume-id',
@@ -978,20 +987,44 @@
     return $value;
 }
 
-PVE::JSONSchema::register_format('pve-qm-hostusb', \&verify_hostusb);
-sub verify_hostusb {
-    my ($value, $noerr) = @_;
+sub parse_usb_device {
+    my ($value) = @_;
 
+    return undef if !$value;
+
     my @dl = split (/,/, $value);
+    my $found;
+
+    my $res = {};
     foreach my $v (@dl) {
-	if ($v !~ m/^(\d+.(\d+|\*)|[0-9A-Fa-f]+:([0-9A-Fa-f]+|\*))$/) {
-	    return undef if $noerr;
-	    die "unable to parse usb id\n";
+	if ($v =~ m/^host=([0-9A-Fa-f]{4}):([0-9A-Fa-f]{4})$/) {
+	    $found = 1;
+	    $res->{vendorid} = $1;
+	    $res->{productid} = $2;
+	} elsif ($v =~ m/^host=(\d+)\-(\d+(\.\d+)*)$/) {
+	    $found = 1;
+	    $res->{hostbus} = $1;
+	    $res->{hostport} = $2;
+	} else {
+	    return undef;
 	}
     }
-    return $value;
+    return undef if !$found;
+
+    return $res;
 }
+ 
+PVE::JSONSchema::register_format('pve-qm-usb-device', \&verify_usb_device);
+sub verify_usb_device {
+    my ($value, $noerr) = @_;
 
+    return $value if parse_usb_device($value);
+
+    return undef if $noerr;
+    
+    die "unable to parse usb device\n";
+}
+
 PVE::JSONSchema::register_format('pve-qm-parallel', \&verify_parallel);
 sub verify_parallel {
     my ($value, $noerr) = @_;
@@ -1054,8 +1087,9 @@
 	return int($1) if $value =~ m/^(\d+)$/;
 	die "type check ('integer') failed - got '$value'\n";
     } elsif ($type eq 'string') {
-	if (my $fmt = $confdesc->{format}) {
+	if (my $fmt = $confdesc->{$key}->{format}) {
 	    if ($fmt eq 'pve-qm-drive') {
+		# special case - we need to pass $key to parse_drive()
 		my $drive = parse_drive ($key, $value);
 		return $value if $drive;
 		die "unable to parse drive options\n";
@@ -1846,7 +1880,18 @@
 	    push @$cmd, '-device', "pci-assign,host=$dev" if $dev;
 	}
     }
-    # host usb devices
+
+    # usb devices
+    for (my $i = 0; $i < $MAX_USB_DEVICES; $i++)  {
+	my $d = parse_usb_device($conf->{"usb$i"});
+	next if !$d;
+	if ($d->{vendorid} && $d->{productid}) {
+	    push @$cmd, '-device', "usb-host,vendorid=$d->{vendorid},productid=$d->{productid}";
+	} elsif (defined($d->{hostbus}) && defined($d->{hostport})) {
+	    push @$cmd, '-device', "usb-host,hostbus=$d->{hostbus},hostport=$d->{hostport}";
+	}
+    }
+
     if (my $usbdl = $conf->{hostusb}) {
 	my @dl = split (/,/, $usbdl);
 	foreach my $dev (@dl) {



More information about the pve-devel mailing list