summaryrefslogblamecommitdiffstats
path: root/modules-available/statistics/inc/hardwareinfo.inc.php
blob: 6a6c74cdc74603589fe11ecd10d7bf241a7ced12 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15














                                            




































































                                                                                                                
 
<?php

class HardwareInfo
{

	// Never change these!
	const RAM_MODULE = 'RAM';
	const MAINBOARD = 'MAINBOARD';
	const DMI_SYSTEM = 'DMI_SYSTEM';
	const POWER_SUPPLY = 'POWER_SUPPLY';
	const SYSTEM_SLOT = 'SYSTEM_SLOT';
	const PCI_DEVICE = 'PCI_DEVICE';
	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;
	}

}