X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=PVE%2FQemuServer%2FUSB.pm;h=499574447735512ce05d39d37bc4ffa37deaedaf;hb=e3971865b4735a855123d563bf261954be8f529a;hp=fe541c1fbd30f8bd5f1a4b296d671d3bc3d1d997;hpb=0cf8d56c6df7e6d8896163233b4b7f5558793117;p=qemu-server.git diff --git a/PVE/QemuServer/USB.pm b/PVE/QemuServer/USB.pm index fe541c1..4995744 100644 --- a/PVE/QemuServer/USB.pm +++ b/PVE/QemuServer/USB.pm @@ -6,6 +6,7 @@ use PVE::QemuServer::PCI qw(print_pci_addr); use PVE::QemuServer::Machine; use PVE::QemuServer::Helpers qw(min_version windows_version); use PVE::JSONSchema; +use PVE::Mapping::USB; use base 'Exporter'; our @EXPORT_OK = qw( @@ -24,6 +25,7 @@ my $USB_PATH_RE = qr/(\d+)\-(\d+(\.\d+)*)/; my $usb_fmt = { host => { default_key => 1, + optional => 1, type => 'string', pattern => qr/(?:(?:$USB_ID_RE)|(?:$USB_PATH_RE)|[Ss][Pp][Ii][Cc][Ee])/, format_description => 'HOSTUSBDEVICE|spice', @@ -40,8 +42,18 @@ NOTE: This option allows direct access to host hardware. So it is no longer poss machines - use with special care. The value 'spice' can be used to add a usb redirection devices for spice. + +Either this or the 'mapping' key must be set. EODESCR }, + mapping => { + optional => 1, + type => 'string', + format_description => 'mapping-id', + format => 'pve-configid', + description => "The ID of a cluster wide mapping. Either this or the default-key 'host'" + ." must be set.", + }, usb3 => { optional => 1, type => 'boolean', @@ -63,21 +75,38 @@ our $usbdesc = { PVE::JSONSchema::register_standard_option("pve-qm-usb", $usbdesc); sub parse_usb_device { - my ($value) = @_; + my ($value, $mapping) = @_; - return if !$value; + return if $value && $mapping; # not a valid configuration my $res = {}; - if ($value =~ m/^$USB_ID_RE$/) { - $res->{vendorid} = $2; - $res->{productid} = $4; - } elsif ($value =~ m/^$USB_PATH_RE$/) { - $res->{hostbus} = $1; - $res->{hostport} = $2; - } elsif ($value =~ m/^spice$/i) { - $res->{spice} = 1; - } else { - return; + if (defined($value)) { + if ($value =~ m/^$USB_ID_RE$/) { + $res->{vendorid} = $2; + $res->{productid} = $4; + } elsif ($value =~ m/^$USB_PATH_RE$/) { + $res->{hostbus} = $1; + $res->{hostport} = $2; + } elsif ($value =~ m/^spice$/i) { + $res->{spice} = 1; + } + } elsif (defined($mapping)) { + my $devices = PVE::Mapping::USB::find_on_current_node($mapping); + die "USB device mapping not found for '$mapping'\n" if !$devices || !scalar($devices->@*); + die "More than one USB mapping per host not supported\n" if scalar($devices->@*) > 1; + eval { + PVE::Mapping::USB::assert_valid($mapping, $devices->[0]); + }; + if (my $err = $@) { + die "USB Mapping invalid (hardware probably changed): $err\n"; + } + my $device = $devices->[0]; + + if ($device->{path}) { + $res = parse_usb_device($device->{path}); + } else { + $res = parse_usb_device($device->{id}); + } } return $res; @@ -199,7 +228,7 @@ sub print_usbdevice_full { $usbdevice .= ",port=$port" if defined($port); } - my $parsed = parse_usb_device($device->{host}); + my $parsed = parse_usb_device($device->{host}, $device->{mapping}); if (defined($parsed->{vendorid}) && defined($parsed->{productid})) { $usbdevice .= ",vendorid=0x$parsed->{vendorid},productid=0x$parsed->{productid}";