From 0fa24671475f52b2b34dfdcabf53c8ddab3845fa Mon Sep 17 00:00:00 2001
From: SimonFair <39065407+SimonFair@users.noreply.github.com>
Date: Sat, 22 Nov 2025 22:23:28 +0000
Subject: [PATCH] WIP Updates
---
emhttp/plugins/dynamix/SysDevs.page | 49 ++++++------
.../plugins/dynamix/include/SriovHelpers.php | 2 +-
.../dynamix/include/update.sriov-cfg.php | 10 +--
.../dynamix/include/update.vfio-pci-cfg.php | 76 ++++++++++++++++++-
emhttp/plugins/dynamix/sheets/SysDevs.css | 9 +++
sbin/sriov | 4 +-
6 files changed, 115 insertions(+), 35 deletions(-)
diff --git a/emhttp/plugins/dynamix/SysDevs.page b/emhttp/plugins/dynamix/SysDevs.page
index 4ecd1b432..20b3ce07b 100644
--- a/emhttp/plugins/dynamix/SysDevs.page
+++ b/emhttp/plugins/dynamix/SysDevs.page
@@ -25,7 +25,7 @@ $(function(){
function applyCfg() {
var message = "_(System Devices)_: _(A reboot is required to apply changes)_";
var string = "BIND=";
- var string2 = "V=";
+ var string2 = "VFSETTINGS=";
var elements = document.getElementById("vfiopci").elements;
for (var i = 0, element; element = elements[i++];) {
if (element.type === "checkbox" && element.checked === true && element.className.substring(0, 5) === "iommu")
@@ -44,19 +44,30 @@ function applyCfg() {
string = "";
}
string2 = string2.trim();
- if (string2 === "V=") {
+ if (string2 === "VFSETTINGS=") {
string2 = "";
}
- $.post( "/plugins/dynamix/include/update.vfio-pci-cfg.php", { cfg: string } )
+ $.post( "/plugins/dynamix/include/update.vfio-pci-cfg.php", { cfg: string, vfcfg:string2} )
.done(function(d) {
- if (d==1) {
- addRebootNotice(message);
- document.getElementById("warning").innerHTML = "_(ALERT)_: _(Changes saved)_. _(Reboot to take effect)_.";
- } else {
- removeRebootNotice(message);
- document.getElementById("warning").innerHTML = "_(No changes)_.";
- }
+ switch (d) {
+ case "1":
+ addRebootNotice(message);
+ document.getElementById("warning").innerHTML = "_(ALERT)_: VFIO _(Changes saved)_. _(Reboot to take effect)_.";
+ break;
+ case "2":
+ addRebootNotice(message);
+ document.getElementById("warning").innerHTML = "_(ALERT)_: SRIOV VFs _(Changes saved)_. _(Reboot to take effect)_.";
+ break;
+ case "3":
+ addRebootNotice(message);
+ document.getElementById("warning").innerHTML = "_(ALERT)_: VFIO _(and)_ SRIOV VFs _(saved)_. _(Reboot to take effect)_.";
+ break;
+ default:
+ removeRebootNotice(message);
+ document.getElementById("warning").innerHTML = "_(No changes)_.";
+ break;
+ }
$("#applycfg").attr("disabled",true);
});
}
@@ -209,7 +220,7 @@ function applyVFsConfig(pciId, vd, vfs) {
const plural = vmCount === 1 ? _("VM is") : _("VMs are");
const messageText =
- _("The following") + plural + _("currently using this device") + ":\n\n" +
+ _("The following") + " " + plural + " " + _("currently using this device") + ":\n\n" +
vmListText +
"\n\n" + _("Please stop") + " " +
(vmCount === 1 ? "it" : "them") +
@@ -317,7 +328,7 @@ function applyVFSettings(pciId, vd, currentvfio, currentmac) {
const plural = vmCount === 1 ? _("VM is") : _("VMs are");
const messageText =
- _("The following") + plural + _("currently using this device") + ":\n\n" +
+ _("The following") + " " + plural + " " + _("currently using this device") + ":\n\n" +
vmListText +
"\n\n" + _("Please stop") + " " +
(vmCount === 1 ? "it" : "them") +
@@ -593,20 +604,6 @@ function ackPCI(pcidevice, action) {
}
-
0):?>
diff --git a/emhttp/plugins/dynamix/include/SriovHelpers.php b/emhttp/plugins/dynamix/include/SriovHelpers.php
index 2b2ca6124..d1d1e8b80 100644
--- a/emhttp/plugins/dynamix/include/SriovHelpers.php
+++ b/emhttp/plugins/dynamix/include/SriovHelpers.php
@@ -419,7 +419,7 @@ function setVfMacAddress(string $vf_pci, array $sriov, string $mac, ?string $reb
if ($ret === 0) {
$result['mac_set'] = true;
- $result['details'] = [sprintf(_("MAC address set to %s"),strtoupper($mac))];
+ $result['details'] = [sprintf(_("MAC address set to %s"),($mac != "00:00:00:00:00:00") ? strtoupper($mac) : _("Dyanamic allocation"))];
} else {
$result['error'] = _("Failed to set MAC").": " . implode("; ", $output);
}
diff --git a/emhttp/plugins/dynamix/include/update.sriov-cfg.php b/emhttp/plugins/dynamix/include/update.sriov-cfg.php
index 782daea14..a5b461001 100644
--- a/emhttp/plugins/dynamix/include/update.sriov-cfg.php
+++ b/emhttp/plugins/dynamix/include/update.sriov-cfg.php
@@ -32,7 +32,7 @@ if (isset($pciid) && isset($vd)) {
switch($type) {
case "sriov":
$old = is_file($sriov) ? rtrim(file_get_contents($sriov)) : '';
- $newexplode = explode(" ",str_replace("VFS=","",$old));
+ $newexplode = preg_split('/\s+/', str_replace("VFS=","",$old), -1, PREG_SPLIT_NO_EMPTY);
$new = $old;
$numvfs= _var($_POST,'numvfs');
$found = false;
@@ -54,7 +54,7 @@ if (isset($pciid) && isset($vd)) {
break;
case "sriovsettings":
$old = is_file($sriovvfs) ? rtrim(file_get_contents($sriovvfs)) : '';
- $newexplode = explode(" ",str_replace("VFSETTINGS=","",$old));
+ $newexplode = preg_split('/\s+/', str_replace("VFSETTINGS=","",$old), -1, PREG_SPLIT_NO_EMPTY);
$mac= _var($_POST,'mac');
if ($mac == "") $mac = "00:00:00:00:00:00";
$vfio= _var($_POST,'vfio');
@@ -62,7 +62,7 @@ if (isset($pciid) && isset($vd)) {
$found = false;
foreach($newexplode as $key => $newelement) {
if (strpos($newelement,$newelement_check) !== false) {
- $found = true;
+ $found = true;
if($mac == "00:00:00:00:00:00" && $vfio == 0) {
unset($newexplode[$key]) ;
break;
@@ -72,8 +72,8 @@ if (isset($pciid) && isset($vd)) {
}
}
}
- if (!$found && $vfio != 0) $newexplode[] = $newelement_check.$vfio."|".$mac;
- $new = "VFSETTINGS=".implode(" ",$newexplode);
+ if (!$found && ($vfio != 0 || $mac != "00:00:00:00:00:00")) $newexplode[] = $newelement_check.$vfio."|".$mac;
+ if ($newexplode) $new = "VFSETTINGS=".implode(" ",$newexplode);
$file = $sriovvfs;
break;
}
diff --git a/emhttp/plugins/dynamix/include/update.vfio-pci-cfg.php b/emhttp/plugins/dynamix/include/update.vfio-pci-cfg.php
index 99e7e74a0..3572129a4 100644
--- a/emhttp/plugins/dynamix/include/update.vfio-pci-cfg.php
+++ b/emhttp/plugins/dynamix/include/update.vfio-pci-cfg.php
@@ -15,7 +15,67 @@ $docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
require_once "$docroot/webGui/include/Secure.php";
require_once "$docroot/webGui/include/Wrappers.php";
+function parseVF($str)
+{
+ $blocks = preg_split('/\s+/', trim($str));
+ $result = [];
+ foreach ($blocks as $block) {
+ if ($block === '') continue;
+ $parts = explode('|', $block);
+ for ($i = 0; $i < 4; $i++) if (!isset($parts[$i])) $parts[$i] = '';
+ $key = $parts[0] . '|' . $parts[1];
+ $result[$key] = [$parts[2], $parts[3]];
+ }
+ return $result;
+}
+
+function isValidVF($fields)
+{
+ list($fn, $mac) = $fields;
+ $mac = strtolower(trim($mac));
+ $isZeroMac = ($mac === '00:00:00:00:00:00');
+ $hasMac = ($mac !== '' && !$isZeroMac);
+ if ($fn === '1') return true;
+ if ($fn > 1) return true;
+ if ($fn === '0') return $hasMac;
+ return $hasMac;
+}
+
+function updateVFSettings($input, $saved)
+{
+ $inputParsed = parseVF($input);
+ $savedParsed = parseVF($saved);
+ $updated = [];
+ foreach ($savedParsed as $key => $_) {
+ if (isset($inputParsed[$key]) && isValidVF($inputParsed[$key])) $updated[$key] = $inputParsed[$key];
+ }
+ foreach ($inputParsed as $key => $fields) {
+ if (!isset($savedParsed[$key]) && isValidVF($fields)) $updated[$key] = $fields;
+ }
+ $result = [];
+ foreach ($savedParsed as $key => $_) {
+ if (!isset($updated[$key])) continue;
+ list($pci,$vd) = explode('|',$key);
+ list($fn,$mac) = $updated[$key];
+ if ($fn === '1' && ($mac === '' || $mac === null)) $mac = '00:00:00:00:00:00';
+ $result[] = "$pci|$vd|$fn|$mac";
+ }
+ foreach ($inputParsed as $key => $_) {
+ if (isset($savedParsed[$key])) continue;
+ if (!isset($updated[$key])) continue;
+ list($pci,$vd) = explode('|',$key);
+ list($fn,$mac) = $updated[$key];
+ if ($fn === '1' && ($mac === '' || $mac === null)) $mac = '00:00:00:00:00:00';
+ $result[] = "$pci|$vd|$fn|$mac";
+ }
+ return implode(' ', $result);
+}
+
+
$vfio = '/boot/config/vfio-pci.cfg';
+$sriovvfs = '/boot/config/sriovvfs.cfg';
+
+#Save Normal VFIOs
$old = is_file($vfio) ? rtrim(file_get_contents($vfio)) : '';
$new = _var($_POST,'cfg');
@@ -23,7 +83,21 @@ $reply = 0;
if ($new != $old) {
if ($old) copy($vfio,"$vfio.bak");
if ($new) file_put_contents($vfio,$new); else @unlink($vfio);
- $reply = 1;
+ $reply |= 1;
}
+
+#Save SRIOV VFS
+$oldvfcfg = is_file($sriovvfs) ? rtrim(file_get_contents($sriovvfs)) : '';
+$newvfcfg = _var($_POST,'vfcfg');
+$oldvfcfg_updated = updateVFSettings($newvfcfg,$oldvfcfg);
+if (strpos($oldvfcfg_updated,"VFSETTINGS=") !== 0 && $oldvfcfg_updated != "") $oldvfcfg_updated = "VFSETTINGS=".$oldvfcfg_updated;
+
+#file_put_contents("/tmp/updatevfs",[json_encode($oldvfcfg_updated),json_encode($oldvfcfg)]);
+if ($oldvfcfg_updated != $oldvfcfg) {
+ if ($oldvfcfg) copy($sriovvfs,"$sriovvfs.bak");
+ if ($oldvfcfg_updated) file_put_contents($sriovvfs,$oldvfcfg_updated); else @unlink($sriovvfs);
+ $reply |= 2;
+}
+
echo $reply;
?>
diff --git a/emhttp/plugins/dynamix/sheets/SysDevs.css b/emhttp/plugins/dynamix/sheets/SysDevs.css
index 42597cef9..3da284b96 100644
--- a/emhttp/plugins/dynamix/sheets/SysDevs.css
+++ b/emhttp/plugins/dynamix/sheets/SysDevs.css
@@ -13,3 +13,12 @@ table tr td.thin {
line-height: 8px;
height: 8px;
}
+.sweet-alert.swal-hostid-input input {
+ width: 60px !important;
+ margin: 12px auto 0 auto !important;
+ text-align: center !important;
+ display: block !important;
+ padding-left: 0 !important;
+ padding-right: 0 !important;
+ box-sizing: border-box !important;
+}
\ No newline at end of file
diff --git a/sbin/sriov b/sbin/sriov
index 815009c83..385f4cd6c 100755
--- a/sbin/sriov
+++ b/sbin/sriov
@@ -24,7 +24,7 @@ CFG=/boot/config/sriov.cfg
[[ ! -f "$CFG" ]] && exit
grep -q "^VFS=" "$CFG" || exit
-echo "Loading VFs config from $CFG"
+echo -e "Loading VFs config from $CFG\n"
cat $CFG
echo "---"
@@ -53,7 +53,7 @@ CFG_VFS=/boot/config/sriovvfs.cfg
[[ ! -f "$CFG_VFS" ]] && exit
grep -q "VFSETTINGS=" "$CFG_VFS" || exit
-echo "Loading settings config from $CFG_VFS"
+echo -e "Loading settings config from $CFG_VFS/n"
cat "$CFG_VFS"
echo "---"