summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2025-04-17 16:33:01 +0200
committerSimon Rettberg2025-04-17 16:33:01 +0200
commit51c8532f39e710d25b2125c692fd923685c161c9 (patch)
treed1513d3d5e2eb4e0b7051f71d7fe4d4b06e8b4e2
parent[baseconfig_bwlp] Allow passing refresh rate with SLX_FORCE_RESOLUTION (diff)
downloadslx-admin-51c8532f39e710d25b2125c692fd923685c161c9.tar.gz
slx-admin-51c8532f39e710d25b2125c692fd923685c161c9.tar.xz
slx-admin-51c8532f39e710d25b2125c692fd923685c161c9.zip
[statistics/minilinux] Allow conditional initrd delivery
Initrds are filtered by special naming scheme. For now, filtering by PCI-IDs is implemented.
-rw-r--r--modules-available/minilinux/inc/linuxbootentryhook.inc.php4
-rw-r--r--modules-available/statistics/inc/hardwareinfo.inc.php46
2 files changed, 45 insertions, 5 deletions
diff --git a/modules-available/minilinux/inc/linuxbootentryhook.inc.php b/modules-available/minilinux/inc/linuxbootentryhook.inc.php
index 1424b6b9..acf97300 100644
--- a/modules-available/minilinux/inc/linuxbootentryhook.inc.php
+++ b/modules-available/minilinux/inc/linuxbootentryhook.inc.php
@@ -158,9 +158,9 @@ class LinuxBootEntryHook extends BootEntryHook
$exec->commandLine = IPxe::modifyCommandLine($exec->commandLine,
'-ipv4.router -ipv4.dns -ipv4.subnet');
}
- // GVT, PCI Pass-thru etc.
+ // GVT, PCI Pass-thru, NVIDIA drivers, etc.
if (Module::isAvailable('statistics')) {
- $hwextra = HardwareInfo::getKclModifications();
+ $hwextra = HardwareInfo::getKclModifications($exec->initRd);
if (!empty($hwextra)) {
$exec->commandLine = IPxe::modifyCommandLine($exec->commandLine, $hwextra);
}
diff --git a/modules-available/statistics/inc/hardwareinfo.inc.php b/modules-available/statistics/inc/hardwareinfo.inc.php
index 7e0bdba8..eb940ac2 100644
--- a/modules-available/statistics/inc/hardwareinfo.inc.php
+++ b/modules-available/statistics/inc/hardwareinfo.inc.php
@@ -22,13 +22,13 @@ class HardwareInfo
* @param ?string $uuid UUID of machine
* @param ?string $mac MAC of machine
*/
- public static function getKclModifications(?string $uuid = null, ?string $mac = null): string
+ public static function getKclModifications(array &$initRds, ?string $uuid = null, ?string $mac = null): string
{
if ($uuid === null && $mac === null) {
$uuid = Request::get('uuid', '', 'string');
$mac = Request::get('mac', '', 'string');
- $mac = str_replace(':', '-', $mac);
}
+ $mac = str_replace(':', '-', $mac);
$res = Database::simpleQuery("SELECT machineuuid, lastseen, cpumodel, locationid FROM machine
WHERE machineuuid = :uuid OR macaddr = :mac", ['uuid' => $uuid, 'mac' => $mac]);
$best = null;
@@ -80,7 +80,7 @@ class HardwareInfo
$hw->addGlobalColumn('vendor');
$hw->addGlobalColumn('device');
foreach ($hw->query() as $row) {
- $passthrough[$row['vendor'] . ':' . $row['device']] = 1;
+ $passthrough[strtolower($row['vendor'] . ':' . $row['device'])] = 1;
//error_log('Extra PT: ' . $row['vendor'] . ':' . $row['device']);
}
}
@@ -89,9 +89,49 @@ class HardwareInfo
if ($gvt) {
$kcl .= ' i915.enable_gvt=1';
}
+ // See if there's an nvidia addon in the initrd list. If so, check if the machine has an nvidia card
+ // that is not being used for pci passthrough. If so, keep the initrd; otherwise, remove.
+ foreach (array_keys($initRds) as $idx) {
+ $name = $initRds[$idx];
+ if (!preg_match('/^addon-[^_]*_(.*)$/', $name, $m))
+ continue;
+ $rules = explode('_', $m[1]);
+ $keep = false;
+ foreach ($rules as $rule) {
+ // addon-nvidia_pci-v10de-dxxxx
+ if (self::ruleMatches($best['machineuuid'], $rule, $passthrough)) {
+ $keep = true;
+ }
+ }
+ if (!$keep) {
+ unset($initRds[$idx]);
+ }
+ }
return $kcl;
}
+ private static function ruleMatches(string $uuid, string $rule, array $passthrough): bool
+ {
+ if (preg_match('/^pci-v([0-9a-fx]{4})-d([0-9a-fx]{4})$/', $rule, $out)) {
+ $hw = new HardwareQuery(self::PCI_DEVICE, $uuid, true);
+ $col = $hw->addGlobalColumn('vendor');
+ if ($out[1] !== 'xxxx') {
+ $col->addCondition('LIKE', str_replace('x', '_', $out[1]));
+ }
+ $col = $hw->addGlobalColumn('device');
+ if ($out[2] !== 'xxxx') {
+ $col->addCondition('LIKE', str_replace('x', '_', $out[2]));
+ }
+ foreach ($hw->query() as $row) {
+ $id = strtolower($row['vendor'] . ':' . $row['device']);
+ if (isset($passthrough[$id]))
+ continue;
+ return true; // Got a match not passed through, done
+ }
+ }
+ return false;
+ }
+
// For lookup (from https://en.wikipedia.org/wiki/GUID_Partition_Table)
const GPT = [
'00000000-0000-0000-0000-000000000000' => 'Unused entry',