From 782be7dae2d638dc2709d12fc8d9a60b402262d7 Mon Sep 17 00:00:00 2001 From: Dominik Csapak Date: Thu, 22 Nov 2018 11:35:41 +0100 Subject: [PATCH] api/Scan: allow to scan a nodes PCI devices Signed-off-by: Dominik Csapak --- PVE/API2/Scan.pm | 124 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/PVE/API2/Scan.pm b/PVE/API2/Scan.pm index b67c1041..15c8b48a 100644 --- a/PVE/API2/Scan.pm +++ b/PVE/API2/Scan.pm @@ -46,6 +46,7 @@ __PACKAGE__->register_method ({ { method => 'usb' }, { method => 'zfs' }, { method => 'cifs' }, + { method => 'pci' }, ]; return $res; @@ -422,4 +423,127 @@ __PACKAGE__->register_method ({ return PVE::SysFSTools::scan_usb(); }}); +my $default_class_blacklist = "05;06;08;0b"; + +__PACKAGE__->register_method ({ + name => 'pciscan', + path => 'pci', + method => 'GET', + description => "List local PCI devices.", + protected => 1, + proxyto => "node", + permissions => { + check => ['perm', '/', ['Sys.Modify']], + }, + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + 'pci-class-blacklist' => { + type => 'string', + format => 'string-list', + default => $default_class_blacklist, + optional => 1, + description => "A list of blacklisted PCI classes, which will ". + "not be returned. Following are filtered by ". + "default: Memory Controller (05), Bridge (06), ". + "Generic System Peripheral (08) and ". + "Processor (0b).", + }, + verbose => { + type => 'boolean', + default => 1, + optional => 1, + description => "If disabled, does only print the PCI IDs. " + ."Otherwise, additional information like vendor " + ."and device will be returned.", + }, + }, + }, + returns => { + type => 'array', + items => { + type => "object", + properties => { + id => { + type => 'string', + description => "The PCI ID.", + }, + class => { + type => 'string', + description => 'The PCI Class of the device.', + }, + vendor => { + type => 'string', + description => 'The Vendor ID.', + }, + vendor_name => { + type => 'string', + optional => 1, + }, + device => { + type => 'string', + description => 'The Device ID.', + }, + device_name => { + type => 'string', + optional => 1, + }, + subsystem_vendor => { + type => 'string', + description => 'The Subsystem Vendor ID.', + optional => 1, + }, + subsystem_vendor_name => { + type => 'string', + optional => 1, + }, + subsystem_device => { + type => 'string', + description => 'The Subsystem Device ID.', + optional => 1, + }, + subsystem_device_name => { + type => 'string', + optional => 1, + }, + iommugroup => { + type => 'integer', + description => "The IOMMU group in which the device is in.". + " If no IOMMU group is detected, it is set to -1.", + }, + mdev => { + type => 'boolean', + optional => 1, + description => "If set, marks that the device is capable " + ."of creating mediated devices.", + } + }, + }, + }, + code => sub { + my ($param) = @_; + + my $blacklist = $param->{'pci-class-blacklist'} // $default_class_blacklist; + my $class_regex = join('|', PVE::Tools::split_list($blacklist)); + + my $filter; + + if ($class_regex ne '') { + $filter = sub { + my ($pcidevice) = @_; + + if ($pcidevice->{class} =~ m/^0x(?:$class_regex)/) { + return 0; + } + + return 1; + }; + } + + my $verbose = $param->{verbose} // 1; + + return PVE::SysFSTools::lspci($filter, $verbose); + }}); + 1;