Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
a2652a6
SRIOV Backend for boot.
SimonFair Nov 2, 2025
d941217
Make scripts executable
SimonFair Nov 2, 2025
b3f486e
Code rabbit updates
SimonFair Nov 3, 2025
be4fb3e
Initial GUI changes
SimonFair Nov 3, 2025
5677832
Change to run sriov process at boot
SimonFair Nov 3, 2025
1adbaf3
Move backend to rc.local
SimonFair Nov 6, 2025
4c86497
Change VF vfio processing.
SimonFair Nov 6, 2025
1266a3d
WIP Progress updates.
SimonFair Nov 9, 2025
0c49615
Update WIP.
SimonFair Nov 9, 2025
1ae804c
Make script executable
SimonFair Nov 9, 2025
5d5282b
Update WIP
SimonFair Nov 12, 2025
ff6a5ad
Update WIP
SimonFair Nov 13, 2025
c23ca18
Updates for Language support
SimonFair Nov 14, 2025
5425902
Fix rc files
SimonFair Nov 14, 2025
3c7228d
Fix errors
SimonFair Nov 14, 2025
7408b6e
Update error reporting.
SimonFair Nov 15, 2025
914c005
Updates t processing and acknowledge PCI additions
SimonFair Nov 16, 2025
c0a5cf8
Coderabbit fixes
SimonFair Nov 16, 2025
1b301c3
Coderabbit updates
SimonFair Nov 17, 2025
6ea8c0c
Coderabbit updates
SimonFair Nov 17, 2025
a6eabf9
Update SysDevs.php
SimonFair Nov 17, 2025
de96bdf
Update SysDevs.page
SimonFair Nov 17, 2025
1bba20c
Updates
SimonFair Nov 19, 2025
0fa2467
WIP Updates
SimonFair Nov 22, 2025
0c68b87
Status message and fixes.
SimonFair Nov 23, 2025
881d43c
Coderabbit and code formatting
SimonFair Nov 23, 2025
6f5e7b3
Update SysDevs.php
SimonFair Nov 23, 2025
a6d3f0d
Fix typo and apply processing if saved first
SimonFair Nov 24, 2025
837c650
Fix error processing
SimonFair Nov 24, 2025
f932fae
Coderabbit Fixes
SimonFair Nov 24, 2025
c1632c2
escape module.
SimonFair Nov 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
512 changes: 510 additions & 2 deletions emhttp/plugins/dynamix/SysDevs.page

Large diffs are not rendered by default.

512 changes: 512 additions & 0 deletions emhttp/plugins/dynamix/include/SriovHelpers.php

Large diffs are not rendered by default.

114 changes: 112 additions & 2 deletions emhttp/plugins/dynamix/include/SysDevs.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?PHP
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, Bergware International.
/* Copyright 2005-2025, Lime Technology
* Copyright 2012-2025, Bergware International.
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
Expand All @@ -13,6 +14,8 @@
<?
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
require_once "$docroot/webGui/include/Helpers.php";
require_once "$docroot/webGui/include/SriovHelpers.php";
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";

// add translations
$_SERVER['REQUEST_URI'] = 'tools';
Expand All @@ -36,6 +39,11 @@ function usb_physical_port($usbbusdev) {
return($physical_busid);
}

$sriov = json_decode(getSriovInfoJson(true),true);
$sriovvfs = getVfListByIommuGroup();
$sriov_devices=parseVFvalues();
$sriov_devices_settings=parseVFSettings();

switch ($_POST['table']) {
case 't1':
exec('for group in $(ls /sys/kernel/iommu_groups/ -1|sort -n);do echo "IOMMU group $group";for device in $(ls -1 "/sys/kernel/iommu_groups/$group"/devices/);do echo -n $\'\t\';lspci -ns "$device"|awk \'BEGIN{ORS=" "}{print "["$3"]"}\';lspci -s "$device";done;done',$groups);
Expand Down Expand Up @@ -71,6 +79,7 @@ function usb_physical_port($usbbusdev) {
}
$vfio_cfg_devices = array_values(array_unique($vfio_cfg_devices, SORT_STRING));
}

$disks = (array)parse_ini_file('state/disks.ini',true);
$devicelist = array_column($disks, 'device');
$lines = array ();
Expand Down Expand Up @@ -128,6 +137,7 @@ function usb_physical_port($usbbusdev) {
$ackparm = "";
foreach ($groups as $line) {
if (!$line) continue;
if (in_array($line,$sriovvfs)) continue;
if ($line[0]=='I') {
if (isset($spacer)) echo "<tr><td colspan='2' class='thin'></td>"; else $spacer = true;
echo "</tr><tr><td>$line:</td><td>";
Expand All @@ -143,6 +153,7 @@ function usb_physical_port($usbbusdev) {
// By default lspci does not output the <Domain> when the only domain in the system is 0000. Add it back.
$pciaddress = "0000:".$pciaddress;
}
if ( in_array($pciaddress,$sriovvfs)) continue;
echo ($append) ? "" : "<tr><td></td><td>";
exec("lspci -v -s $pciaddress", $outputvfio);
if (preg_grep("/vfio-pci/i", $outputvfio)) {
Expand Down Expand Up @@ -179,6 +190,105 @@ function usb_physical_port($usbbusdev) {
echo "</td></tr>";
}
}


if (array_key_exists($pciaddress,$sriov) && in_array(substr($sriov[$pciaddress]['class_id'],0,4),$allowedPCIClass)) {
echo "<tr><td></td><td></td><td></td><td></td><td>";
echo _("SRIOV Available VFs").":{$sriov[$pciaddress]['total_vfs']}";
$num_vfs= $sriov[$pciaddress]['num_vfs'];

if (isset($sriov_devices[$pciaddress]))
$file_numvfs = $sriov_devices[$pciaddress]['vf_count'];
else $file_numvfs = 0;

echo '<label for="vf'.$pciaddress.'"> '._('Select number of VFs').': </label>';
echo '<select class="narrow" name="vf'.$pciaddress.'" id="vf'.$pciaddress.'">';

// First option: None
$selected = ($file_numvfs == 0) ? ' selected' : '';
echo "<option value=\"0\"$selected>None</option>";

// Generate numeric options
for ($i = 1; $i <= $sriov[$pciaddress]['total_vfs']; $i++) {
$selected = ($file_numvfs == $i) ? ' selected' : '';
echo "<option value=\"$i\"$selected>$i</option>";
}

echo '</select>';
echo " "._("Current").":".$num_vfs;
echo ' <a class="info" href="#" title="'._("Save VFs config").'" onclick="saveVFsConfig(\''.htmlentities($pciaddress).'\',\''.htmlentities($vd).'\'); return false;"><i class="fa fa-save"> </i></a>';
echo ' <a class="info" href="#" title="'._("Action VFs update").'" onclick="applyVFsConfig(\''.htmlentities($pciaddress).'\',\''.htmlentities($vd).'\',\''.htmlentities($num_vfs).'\'); return false;"><i title="Apply now" class="fa fa-play"></i></a>';

if ($file_numvfs != $num_vfs) echo " <span id='vfnotice".$pciaddress."'><i class=\"fa fa-warning fa-fw orange-text\"></i> ".sprintf(_("Pending action or reboot"))."<?span>";

echo "</td></tr>";
foreach($sriov[$pciaddress]['vfs'] as $vrf) {
$pciaddress = $vrf['pci'];
if ($removed) $line=preg_replace('/R/', '', $line, 1);
if (preg_match($BDF_REGEX, $pciaddress)) {
// By default lspci does not output the <Domain> when the only domain in the system is 0000. Add it back.
$pciaddress = "0000:".$pciaddress;
}
echo "<tr><td></td><td>";
$outputvfio = $vrfline =[];
exec('lspci -ns "'.$pciaddress.'"|awk \'BEGIN{ORS=" "}{print "["$3"]"}\';lspci -s "'.$pciaddress.'"',$vrfline);

$vd = trim(explode(" ", $vrfline[0])[0], "[]");
exec("lspci -v -s $pciaddress", $outputvfio);
if (preg_grep("/vfio-pci/i", $outputvfio)) {
echo "<i class=\"fa fa-circle orb green-orb middle\" title=\"",_('Kernel driver in use: vfio-pci'),"\"></i>";
$isbound = "true";
}
echo "</td><td>";
if ((strpos($line, 'Host bridge') === false) && (strpos($line, 'PCI bridge') === false)) {
if (file_exists('/sys/bus/pci/devices/'.$pciaddress.'/reset')) echo "<i class=\"fa fa-retweet grey-orb middle\" title=\"",_('Function Level Reset (FLR) supported'),".\"></i>";
echo "</td><td>";
if (!$removed) {
echo '<input type="checkbox" id="vfvfio'.$pciaddress.'" class="vfiommu'.$vrf['iommu_group'].'" value="'.$pciaddress."|".$vd.'" ';
// check config file for two formats: <Domain:Bus:Device.Function>|<Vendor:Device> or just <Domain:Bus:Device.Function>
echo (array_key_exists($pciaddress,$sriov_devices_settings) && $sriov_devices_settings[$pciaddress]['vfio'] == 1) ? " checked>" : ">";
}
} else { echo "</td><td>"; }
echo '</td><td title="';
foreach ($outputvfio as $line2) echo htmlentities($line2,ENT_QUOTES)."&#10;";
echo '">IOMMU Group '.$vrf['iommu_group'].": ",$vrfline[0],'</td></tr>';
if (array_key_exists($pciaddress,$pci_device_diffs)) {
echo "<tr><td></td><td><td></td><td></td><td>";
echo "<i class=\"fa fa-warning fa-fw orange-text\" title=\""._('PCI Change')."\n"._('Click to acknowledge').".\" onclick=\"ackPCI('".htmlentities($pciaddress)."','".htmlentities($pci_device_diffs[$pciaddress]['status'])."')\"></i>";
echo _("PCI Device change");
echo " "._("Action").":".ucfirst(_($pci_device_diffs[$pciaddress]['status']))." ";
$ackparm .= $pciaddress.",".$pci_device_diffs[$pciaddress]['status'].";";
if ($pci_device_diffs[$pciaddress]['status']!="removed") echo $pci_device_diffs[$pciaddress]['device']['description'];
echo "</td></tr>";
if ($pci_device_diffs[$pciaddress]['status']=="changed") {
echo "<tr><td></td><td><td></td><td></td><td>";
echo _("Differences");
foreach($pci_device_diffs[$pciaddress]['differences'] as $key => $changes){
echo " $key "._("before").":{$changes['old']} "._("after").":{$changes['new']} ";
}
echo "</td></tr>";
}
}
if (isset($sriov_devices_settings[$pciaddress])) {
$mac = $sriov_devices_settings[$pciaddress]['mac'];
} else {
$mac = null;
}
$placeholder = empty($mac) ? _('Dynamic allocation') : '';
$value_attr = empty($mac) ? '' : htmlspecialchars($mac, ENT_QUOTES);
echo "<tr><td></td><td></td><td></td><td></td><td>";
echo '<label for="mac_address">'._("MAC Address").':</label>';
echo "<input class='narrow' type=\"text\" name=\"vfmac$pciaddress\" id=\"vfmac$pciaddress\" value=\"$value_attr\" placeholder=\"$placeholder\">";
echo ' <a class="info" href="#" title="'._("Generate MAC").'" onclick="generateMAC(\''.htmlentities($pciaddress).'\'); return false;"><i class="fa fa-refresh mac_generate"> </i></a>';
echo ' <a class="info" href="#" title="'._("Save MAC config").'" onclick="saveVFSettingsConfig(\''.htmlentities($pciaddress).'\',\''.htmlentities($vd).'\'); return false;"><i class="fa fa-save"> </i></a>';
echo ' <a class="info" href="#" title="'._("Action VFs update").'" onclick="applyVFSettings(\''.htmlentities($pciaddress).'\',\''.htmlentities($vd).'\',\''.htmlentities(isset(\$sriov_devices_settings[\$pciaddress]) && $sriov_devices_settings[$pciaddress]['vfio'] == 1 ? 'true':'false').'\',\''.$value_attr.'\'); return false;"><i title="Apply now VFIO and MAC Address" class="fa fa-play"></i></a> ';
if ($vrf['driver'] != "vfio-pci") echo _("Current").": ";
echo $vrf['driver'] == "vfio-pci" ? _("Bound to VFIO") : strtoupper($vrf['mac']);
echo " <span id=vfstatus$pciaddress></span>";
echo "</td></tr>";
}
}

unset($outputvfio);
switch (true) {
case (strpos($line, 'USB controller') !== false):
Expand Down
Loading
Loading