diff options
Diffstat (limited to 'modules-available/statistics/inc/hardwareinfo.inc.php')
-rw-r--r-- | modules-available/statistics/inc/hardwareinfo.inc.php | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/modules-available/statistics/inc/hardwareinfo.inc.php b/modules-available/statistics/inc/hardwareinfo.inc.php index 5ef94365..6a6c74cd 100644 --- a/modules-available/statistics/inc/hardwareinfo.inc.php +++ b/modules-available/statistics/inc/hardwareinfo.inc.php @@ -13,4 +13,73 @@ class HardwareInfo const HDD = 'HDD'; const CPU = 'CPU'; + /** + * Get a KCL modification string for the given machine, enabling GVT, PCI passthrough etc. + * You can provide a UUID and/or MAC, or nothing. If nothing is provided, + * the "uuid" and "mac" GET parameters will be used. If both are provided, + * the resulting machine that has the greatest "lastseen" value will be used. + * @param ?string $uuid UUID of machine + * @param ?string $mac MAC of machine + * @return string + */ + public static function getKclModifications($uuid = null, $mac = null): string + { + if ($uuid === null && $mac === null) { + $uuid = Request::get('uuid', '', 'string'); + $mac = Request::get('mac', '', 'string'); + $mac = str_replace(':', '-', $mac); + } + $res = Database::simpleQuery("SELECT machineuuid, lastseen FROM machine + WHERE machineuuid = :uuid OR macaddr = :mac", ['uuid' => $uuid, 'mac' => $mac]); + $best = null; + foreach ($res as $row) { + if ($best === null || $best['lastseen'] < $row['lastseen']) { + $best = $row; + } + } + if ($best === null) + return ''; + $hw = new HardwareQuery(self::PCI_DEVICE, $best['machineuuid'], true); + // TODO: Get list of enabled pass through groups for this client's location + $hw->addWhere(true, '@PASSTHROUGH', 'IN', ['GPU', 'GVT']); + $hw->addGlobalColumn('vendor'); + $hw->addGlobalColumn('device'); + $hw->addLocalColumn('slot'); + $res = $hw->query(); + $passthrough = []; + $slots = []; + $gvt = false; + foreach ($res as $row) { + if ($row['@PASSTHROUGH'] === 'GVT') { + $gvt = true; + } else { + $passthrough[$row['vendor'] . ':' . $row['device']] = 1; + error_log('Passthouorgh: ' . $row['vendor'] . ':' . $row['device']); + $slots[preg_replace('/\.[0-9]+$/', '', $row['slot'])] = 1; + } + } + $kcl = ''; + if ($gvt || !empty($passthrough)) { + $kcl = '-iommu -intel_iommu iommu=pt intel_iommu=on'; // TODO AMD + } + if (!empty($passthrough)) { + foreach (array_keys($slots) as $slot) { + error_log('Querying slot ' . $slot); + $hw = new HardwareQuery(self::PCI_DEVICE, $best['machineuuid'], true); + $hw->addWhere(false, 'slot', 'LIKE', $slot . '.%'); + $hw->addGlobalColumn('vendor'); + $hw->addGlobalColumn('device'); + foreach ($hw->query() as $row) { + $passthrough[$row['vendor'] . ':' . $row['device']] = 1; + error_log('Extra PT: ' . $row['vendor'] . ':' . $row['device']); + } + } + $kcl .= ' vfio-pci.ids=' . implode(',', array_keys($passthrough)); + } + if ($gvt) { + $kcl .= ' i915.enable_gvt=1'; + } + return $kcl; + } + } |