From ff6a5adb50049fb865a68517715aeb2aade59cff Mon Sep 17 00:00:00 2001 From: SimonFair <39065407+SimonFair@users.noreply.github.com> Date: Thu, 13 Nov 2025 16:29:40 +0000 Subject: [PATCH] Update WIP --- emhttp/plugins/dynamix/SysDevs.page | 158 +++-- emhttp/plugins/dynamix/api/SysDevs.page | 583 ++++++++++++++++++ .../plugins/dynamix/include/SriovHelpers.php | 109 ++-- .../dynamix/include/SysDriversInit.php | 2 +- .../dynamix/include/apply.sriov-cfg.php | 86 ++- .../dynamix/include/update.sriov-cfg.php | 10 +- sbin/sriov | 2 +- sbin/sriov-setvfs.sh | 2 +- sbin/sriov-vfsettings.sh | 5 + 9 files changed, 798 insertions(+), 159 deletions(-) create mode 100644 emhttp/plugins/dynamix/api/SysDevs.page diff --git a/emhttp/plugins/dynamix/SysDevs.page b/emhttp/plugins/dynamix/SysDevs.page index 95225e9f0..53da3f50e 100644 --- a/emhttp/plugins/dynamix/SysDevs.page +++ b/emhttp/plugins/dynamix/SysDevs.page @@ -55,19 +55,19 @@ function saveVFSettingsConfig(pciId,vd,interactive=1) { $.post( "/plugins/dynamix/include/update.sriov-cfg.php", { type:"sriovsettings", pciid: pciId, vd:vd, vfio:vfio, mac:mac } ) .done(function(d) { if (d==1) { - addRebootNotice(message); - document.getElementById("warning").innerHTML = "_(ALERT)_: _(Changes saved)_. _(Reboot to take effect)_."; + //addRebootNotice(message); + // document.getElementById("warning").innerHTML = "_(ALERT)_: _(Changes saved)_. _(Reboot to take effect)_."; if (interactive == 1) swal({ - title: "VF Settings", - text: "Configuration saved.", + title: _("VF Settings"), + text: _("Configuration saved") + ".", type: "success", timer: 3000, showConfirmButton: false }); } else { - removeRebootNotice(message); - document.getElementById("warning").innerHTML = "_(No changes)_."; +//removeRebootNotice(message); +//document.getElementById("warning").innerHTML = "_(No changes)_."; } }); } @@ -78,19 +78,19 @@ function saveVFsConfig(pciId,vd,interactive=1) { $.post( "/plugins/dynamix/include/update.sriov-cfg.php", { type:"sriov", pciid: pciId, vd:vd, numvfs:numvfs } ) .done(function(d) { if (d==1) { - addRebootNotice(message); - document.getElementById("warning").innerHTML = "_(ALERT)_: _(Changes saved)_. _(Reboot to take effect)_."; + // addRebootNotice(message); + // document.getElementById("warning").innerHTML = "_(ALERT)_: _(Changes saved)_. _(Reboot to take effect)_."; if (interactive == 1) swal({ title: "VFs", - text: "Configuration saved.", + text: _("Configuration saved") + ".", type: "success", timer: 3000, showConfirmButton: false }); } else { - removeRebootNotice(message); - document.getElementById("warning").innerHTML = "_(No changes)_."; + // removeRebootNotice(message); + // document.getElementById("warning").innerHTML = "_(No changes)_."; } if (interactive == 1) $('#t1').load('/webGui/include/SysDevs.php', { table: 't1' }); }); @@ -99,7 +99,7 @@ function saveVFsConfig(pciId,vd,interactive=1) { function generateMAC(pciId) { if (!pciId) { - swal("Error", "No PCI ID provided to generateMAC()", "error"); + swal("Error", _("No PCI ID provided to generateMAC()"), "error"); return; } @@ -107,7 +107,7 @@ function generateMAC(pciId) { var pciPattern = /^([0-9a-fA-F]{4}):([0-9a-fA-F]{2}):([0-9a-fA-F]{2})\.([0-7])$/; var match = pciId.match(pciPattern); if (!match) { - swal("Invalid PCI ID", "Expected format: 0000:03:00.2", "error"); + swal(_("Invalid PCI ID"), _("Expected format: 0000:03:00.2"), "error"); return; } @@ -314,11 +314,7 @@ function applyVFSettings(pciId, vd, currentvfio, currentmac) { return; } - saveVFSettingsConfig(pciId, vd, 0); - - - doVFSettingApply(pciId, vd, vfio, mac, currentvfio,currentmac,message); - + doVFSettingApply(pciId, vd, vfio, mac, currentvfio,currentmac,message); }) .fail(function (xhr, status, error) { console.error("Active check failed:", status, error, xhr.responseText); @@ -370,9 +366,9 @@ function doVFSettingApply(pciId, vd, vfio, mac, currentvfio, currentmac, message // Handle structured PHP result if (data.success) { - addRebootNotice(message); - document.getElementById("warning").innerHTML = - "_(ALERT)_: _(Changes saved)_. _(Reboot to take effect)_."; + //addRebootNotice(message); + // document.getElementById("warning").innerHTML = + // "_(ALERT)_: _(Changes saved)_. _(Reboot to take effect)_."; saveVFSettingsConfig(pciId, vd, 0); swal({ title: "Update Complete", @@ -382,8 +378,8 @@ function doVFSettingApply(pciId, vd, vfio, mac, currentvfio, currentmac, message showConfirmButton: false }); } else { - removeRebootNotice(message); - const errorMsg = data.error || "No changes detected or operation failed."; + //removeRebootNotice(message); + // const errorMsg = data.error || "No changes detected or operation failed."; document.getElementById("warning").innerHTML = "" + errorMsg + ""; swal({ @@ -407,6 +403,18 @@ function doVFSettingApply(pciId, vd, vfio, mac, currentvfio, currentmac, message }); } + // Helper: safely stringify nested structures + function formatDetails(details) { + if (details == null) return ""; + if (typeof details === "string") return details; + if (Array.isArray(details)) + return details.map(formatDetails).join("\n"); + if (typeof details === "object") + return Object.entries(details) + .map(([k, v]) => `${k}: ${formatDetails(v)}`) + .join("\n\n"); + return String(details); + } function doVFApply(pciId, vd, numvfs, message) { // Show "updating" alert @@ -426,55 +434,73 @@ function doVFApply(pciId, vd, numvfs, message) { vd: vd, numvfs: numvfs }) -.done(function (data) { - // Normalize to JSON object - if (typeof data === "string") { - try { data = JSON.parse(data); } - catch (e) { - data = { success: false, error: "Invalid JSON: " + e.message }; + .done(function (data) { + // Parse JSON safely + if (typeof data === "string") { + try { data = JSON.parse(data); } + catch (e) { + data = { success: false, error: "Invalid JSON: " + e.message }; + } } - } - // Extract a clean message - let msg = "Configuration successfully applied."; + // Helper: recursively format details to plain text + function formatDetails(obj, indent = 0) { + const pad = " ".repeat(indent); + if (obj == null) return ""; + if (typeof obj === "string") return pad + obj; + if (typeof obj === "number" || typeof obj === "boolean") return pad + obj; + if (Array.isArray(obj)) return obj.map(x => formatDetails(x, indent)).join("\n"); + if (typeof obj === "object") { + return Object.entries(obj).map(([key, val]) => { + if (typeof val === "object" && val !== null) { + // Special case for VF result objects + if ("success" in val || "error" in val || "details" in val) { + const symbol = val.success ? "✔" : "✖"; + const msg = val.error || val.details || ""; + return `${pad}${key}\n${pad} ${symbol} ${msg}`; + } + return `${pad}${key}:\n${formatDetails(val, indent + 1)}`; + } + return `${pad}${key}: ${val}`; + }).join("\n"); + } + return pad + String(obj); + } -if (data.error) { - msg = "Error: " + data.error; -} else if (data.details) { - if (Array.isArray(data.details)) { - msg = data.details.join("\n"); - } else if (typeof data.details === "object") { - msg = Object.entries(data.details) - .map(([k, v]) => `${k}: ${JSON.stringify(v, null, 2)}`) - .join("\n\n"); - } else if (typeof data.details === "string") { - msg = data.details; - } -} + // Build message + let msg = ""; + if (data.error) { + msg = "Error: " + data.error; + } else if (data.details) { + msg = formatDetails(data.details); + } else { + msg = "Configuration successfully applied."; + } - // Pick alert type + // Show alert const ok = data.success === true || data.success === 1; - saveVFsConfig(pciId, vd, 0); - // Show success or failure alert - swal({ - title: data.success ? "Update Complete" : "Update Failed", - text: msg, - type: data.success ? "success" : "error", - timer: data.success ? 3000 : null, - showConfirmButton: !data.success - }); - // Always reload the table after handling - $('#t1').load('/webGui/include/SysDevs.php', { table: 't1' }); - }) - .fail(function (xhr, status, error) { - swal({ - title: "Network Error", - text: "Failed to communicate with the server.\n" + (error || status), - type: "error", - showConfirmButton: true - }); - }); + saveVFsConfig(pciId, vd, 0); + + swal({ + title: ok ? "Update Complete" : "Update Failed", + text: msg, + type: ok ? "success" : "error", + timer: ok ? 3000: null, + showConfirmButton: !ok + }); + + // Reload table + $('#t1').load('/webGui/include/SysDevs.php', { table: 't1' }); +}) +.fail(function (xhr, status, error) { + swal({ + title: "Network Error", + text: "Failed to communicate with the server.\n" + (error || status), + type: "error", + showConfirmButton: true + }); +}); } diff --git a/emhttp/plugins/dynamix/api/SysDevs.page b/emhttp/plugins/dynamix/api/SysDevs.page new file mode 100644 index 000000000..2d4686aac --- /dev/null +++ b/emhttp/plugins/dynamix/api/SysDevs.page @@ -0,0 +1,583 @@ +Menu="UNRAID-OS" +Title="System Devices" +Icon="icon-hardware" +Tag="server" +--- + + + + + 0):?> +**_(PCI Devices and IOMMU Groups)_** + +**_(PCI Devices (No IOMMU Groups Available))_** + + +:sysdevs_iommu_groups_help: + + +

_(Warning)_: _(Your system has booted with the PCIe ACS Override setting enabled)_. _(The below list doesn't not reflect the way IOMMU would naturally group devices)_.
+.

+ + +

+ +**_(CPU Thread Pairings)_** + +:sysdevs_thread_pairings_help: + +

+ +**_(USB Devices)_** + +:sysdevs_usb_devices_help: + +

+ +**_(SCSI Devices)_** + +:sysdevs_scsi_devices_help: + +
+ diff --git a/emhttp/plugins/dynamix/include/SriovHelpers.php b/emhttp/plugins/dynamix/include/SriovHelpers.php index c5125bec0..6b2017979 100644 --- a/emhttp/plugins/dynamix/include/SriovHelpers.php +++ b/emhttp/plugins/dynamix/include/SriovHelpers.php @@ -13,16 +13,11 @@ ?> $vf,'success'=>false,'error'=>null,'details'=>[]]; $vf_path = "/sys/bus/pci/devices/$vf"; $physfn = "$vf_path/physfn"; - if (!is_link($physfn)) return $res + ['error'=>"Missing physfn link"]; + if (!is_link($physfn)) return $res + ['error'=>_("Missing physfn link")]; $pf = basename(readlink($physfn)); $vf_info = $sriov[$pf]['vfs'][$vf] ?? null; - if (!$vf_info) return $res + ['error'=>"VF not found in \$sriov for PF $pf"]; + if (!$vf_info) return $res + ['error'=>_("VF not found in sriov for PF")." $pf"]; $orig_mod = $vf_info['modules'][0] ?? $sriov[$pf]['module'] ?? null; $curr_drv = $vf_info['driver'] ?? null; - if (!$orig_mod) return $res + ['error'=>"No module info for $vf"]; + if (!$orig_mod) return $res + ['error'=>_("No module info for")." $vf"]; $drv_override = "$vf_path/driver_override"; @@ -187,13 +181,12 @@ function rebindVfDriver($vf, $sriov, $target = 'original') $bound = basename(readlink($drv_link)); if ($bound === $new_drv) { $res['success'] = true; - $res['details'][] = "Bound to $new_drv"; + $res['details'][] = _("Bound to")." $new_drv"; return $res; } - return $res + ['error'=>"Bound to $bound instead of $new_drv"]; + return $res + ['error'=> sprintf(_("Bound to %s instead of %s"),$bound,$new_drv)]; } - - return $res + ['error'=>"No driver link after reprobe"]; + return $res + ['error'=>_("No driver link after reprobe")]; } @@ -268,7 +261,7 @@ function getVfListByIommuGroup(): array { $iommu_group = "unknown"; } - $groups[] = "IOMMU group " . $iommu_group; + $groups[] = "IOMMU group " . $iommu_group; $groups[] = $vf_pci; } @@ -280,28 +273,26 @@ function getVfListByIommuGroup(): array { // Parse SR-IOV VF counts // ---------------------- function parseVFvalues() { - $sriov_devices = []; - $DBDF_SRIOV_REGEX = '/^[[:xdigit:]]{4}:[[:xdigit:]]{2}:[[:xdigit:]]{2}\.[[:xdigit:]]\|[[:xdigit:]]{4}:[[:xdigit:]]{4}\|[[:digit:]]+$/'; - if (is_file("/boot/config/sriov.cfg")) { - $file = trim(file_get_contents("/boot/config/sriov.cfg")); - $file = preg_replace('/^VFS=/', '', $file); // Remove prefix - $entries = preg_split('/\s+/', $file, -1, PREG_SPLIT_NO_EMPTY); + $sriov_devices = []; + $DBDF_SRIOV_REGEX = '/^[[:xdigit:]]{4}:[[:xdigit:]]{2}:[[:xdigit:]]{2}\.[[:xdigit:]]\|[[:xdigit:]]{4}:[[:xdigit:]]{4}\|[[:digit:]]+$/'; + if (is_file("/boot/config/sriov.cfg")) { + $file = trim(file_get_contents("/boot/config/sriov.cfg")); + $file = preg_replace('/^VFS=/', '', $file); // Remove prefix + $entries = preg_split('/\s+/', $file, -1, PREG_SPLIT_NO_EMPTY); - foreach ($entries as $entry) { - if (preg_match($DBDF_SRIOV_REGEX, $entry)) { - // Format: || - [$dbdf, $ven_dev, $vf_count] = explode('|', $entry); - $sriov_devices[$dbdf] = [ - 'dbdf' => $dbdf, - 'vendor' => $ven_dev, - 'vf_count' => (int)$vf_count, - ]; - } - } - - # $sriov_devices = array_values(array_unique($sriov_devices, SORT_REGULAR)); + foreach ($entries as $entry) { + if (preg_match($DBDF_SRIOV_REGEX, $entry)) { + // Format: || + [$dbdf, $ven_dev, $vf_count] = explode('|', $entry); + $sriov_devices[$dbdf] = [ + 'dbdf' => $dbdf, + 'vendor' => $ven_dev, + 'vf_count' => (int)$vf_count, + ]; + } + } + } return $sriov_devices; - } } // --------------------------------- @@ -311,27 +302,25 @@ function parseVFSettings() { $sriov_devices_settings = []; $DBDF_SRIOV_SETTINGS_REGEX = '/^[[:xdigit:]]{4}:[[:xdigit:]]{2}:[[:xdigit:]]{2}\.[[:xdigit:]]\|[[:xdigit:]]{4}:[[:xdigit:]]{4}\|[01]\|([[:xdigit:]]{2}:){5}[[:xdigit:]]{2}$/'; if (is_file("/boot/config/sriovvfs.cfg")) { - $file = trim(file_get_contents("/boot/config/sriovvfs.cfg")); - $file = preg_replace('/^VFSETTINGS=/', '', $file); // Remove prefix - $entries = preg_split('/\s+/', $file, -1, PREG_SPLIT_NO_EMPTY); + $file = trim(file_get_contents("/boot/config/sriovvfs.cfg")); + $file = preg_replace('/^VFSETTINGS=/', '', $file); // Remove prefix + $entries = preg_split('/\s+/', $file, -1, PREG_SPLIT_NO_EMPTY); - foreach ($entries as $entry) { - if (preg_match($DBDF_SRIOV_SETTINGS_REGEX, $entry)) { - // Format: ||| - [$dbdf, $ven_dev, $vfio_flag, $mac] = explode('|', $entry); - if ($mac == "00:00:00:00:00:00") $mac = ""; - $sriov_devices_settings[$dbdf] = [ - 'dbdf' => $dbdf, - 'vendor' => $ven_dev, - 'vfio' => (int)$vfio_flag, - 'mac' => strtoupper($mac), - ]; - } - } - - # $sriov_devices_settings = array_values(array_unique($sriov_devices_settings, SORT_REGULAR)); + foreach ($entries as $entry) { + if (preg_match($DBDF_SRIOV_SETTINGS_REGEX, $entry)) { + // Format: ||| + [$dbdf, $ven_dev, $vfio_flag, $mac] = explode('|', $entry); + if ($mac == "00:00:00:00:00:00") $mac = ""; + $sriov_devices_settings[$dbdf] = [ + 'dbdf' => $dbdf, + 'vendor' => $ven_dev, + 'vfio' => (int)$vfio_flag, + 'mac' => strtoupper($mac), + ]; + } + } + } return $sriov_devices_settings; - } } /** @@ -364,14 +353,14 @@ function setVfMacAddress(string $vf_pci, string $mac, ?string $rebindDriver = nu ]; if (!is_dir($vf_path)) { - $result['error'] = "VF path not found: $vf_path"; + $result['error'] = _("VF path not found").": $vf_path"; return $result; } // --- Find parent PF (Physical Function) --- $pf_link = "$vf_path/physfn"; if (!is_link($pf_link)) { - $result['error'] = "No PF link for $vf_pci (not an SR-IOV VF?)"; + $result['error'] = sprintf("No PF link for %s (not an SR-IOV VF?)",$vf_pci); return $result; } $pf_pci = basename(readlink($pf_link)); @@ -381,7 +370,7 @@ function setVfMacAddress(string $vf_pci, string $mac, ?string $rebindDriver = nu $pf_net = glob("/sys/bus/pci/devices/{$pf_pci}/net/*"); $pf_iface = ($pf_net && isset($pf_net[0])) ? basename($pf_net[0]) : null; if (!$pf_iface) { - $result['error'] = "Could not detect PF interface for $pf_pci"; + $result['error'] = _("Could not detect PF interface for")." $pf_pci"; return $result; } $result['pf_iface'] = $pf_iface; @@ -389,7 +378,7 @@ function setVfMacAddress(string $vf_pci, string $mac, ?string $rebindDriver = nu // --- Detect VF index --- $vf_index = getVfIndex($pf_pci, $vf_pci); if ($vf_index === null) { - $result['error'] = "Could not determine VF index for $vf_pci under $pf_pci"; + $result['error'] = sprintf(_("Could not determine VF index for %s under %s"),$vf_pci,$pf_pci); return $result; } $result['vf_index'] = $vf_index; @@ -406,7 +395,7 @@ function setVfMacAddress(string $vf_pci, string $mac, ?string $rebindDriver = nu file_put_contents($unbind_path, $vf_pci); $result['unbind'] = true; } else { - $result['error'] = "Cannot unbind VF $vf_pci from $vf_driver (permissions)"; + $result['error'] = sprintf(_("Cannot unbind VF %s from %s (permissions)"),$vf_pci,$vf_driver); return $result; } } @@ -424,7 +413,7 @@ function setVfMacAddress(string $vf_pci, string $mac, ?string $rebindDriver = nu if ($ret === 0) { $result['mac_set'] = true; } else { - $result['error'] = "Failed to set MAC: " . implode("; ", $output); + $result['error'] = _("Failed to set MAC").": " . implode("; ", $output); } // --- Rebind logic --- @@ -437,7 +426,7 @@ function setVfMacAddress(string $vf_pci, string $mac, ?string $rebindDriver = nu $result['rebind'] = true; $result['driver_after'] = $target_driver; } else { - $result['error'] = "Cannot rebind VF $vf_pci to $target_driver (permissions)"; + $result['error'] = sprintf(_("Cannot rebind VF %s to %s (permissions)"),$vf_pci,$target_driver); } } } diff --git a/emhttp/plugins/dynamix/include/SysDriversInit.php b/emhttp/plugins/dynamix/include/SysDriversInit.php index 03e1c83a2..afd9272b2 100755 --- a/emhttp/plugins/dynamix/include/SysDriversInit.php +++ b/emhttp/plugins/dynamix/include/SysDriversInit.php @@ -1,4 +1,4 @@ - #!/usr/bin/php +#!/usr/bin/php $details ]; - echo json_encode($response, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); + $json = json_encode($response, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); + file_put_contents("/tmp/vfactionjson",$json); + echo $json; exit; } +function safe_file_put_contents($path, $data) +{ + // Check that the file or its directory is writable + $dir = is_dir($path) ? $path : dirname($path); + if (!is_writable($dir)) { + throw new RuntimeException("Path not writable: $path"); + } + + $result = @file_put_contents($path, $data); + if ($result === false) { + $err = error_get_last(); + throw new RuntimeException("Failed to write to $path: " . ($err['message'] ?? 'unknown error')); + } + + return $result; +} + function action_settings($pciid) { @@ -64,6 +84,8 @@ function action_settings($pciid) // Skip if no action needed if ($vfio == 0 && $mac == "") continue; + if ($mac == "") $mac="00:00:00:00:00:00"; + $cmd = "/usr/local/sbin/sriov-vfsettings.sh " . escapeshellarg($vfpci) . " " . escapeshellarg($vf['vd']) . " " . @@ -77,19 +99,17 @@ function action_settings($pciid) // Clean output: remove blank lines and trim whitespace $output = array_filter(array_map('trim', $output)); - file_put_contents("/tmp/vfaction", "$ret\n$cmd\n" . json_encode($output) . "\n"); - if ($ret !== 0) { // Only include relevant lines for error reporting - $results[] = [ + $results[$vfpci] = [ 'success' => false, - 'error' => implode("\n", $output) ?: "Unknown error (exit code $ret)" + 'error' => implode("\n", $output) ?: sprintf(_("Unknown error (exit code %s)"),$ret) ]; } else { // Success: include minimal details or last few lines - $results[] = [ + $results[$vfpci] = [ 'success' => true, - 'details' => 'Applied VF settings' + 'details' => _('Applied VF settings') ]; } } @@ -103,47 +123,63 @@ $pciid = _var($_POST, 'pciid'); $vd = _var($_POST, 'vd'); if (!isset($pciid) || !isset($vd)) { - echo json_response(false, "Missing PCI ID or virtual device"); + echo json_response(false, _("Missing PCI ID or virtual device")); exit; } + + switch ($type) { // -------------------------------------------------------- // SR-IOV enable/disable & VF count changes // -------------------------------------------------------- case "sriov": - $numvfs = _var($_POST, 'numvfs'); + $numvfs = _var($_POST, 'numvfs'); $currentvfs = _var($_POST, 'currentvfs'); - $filepath = "/sys/bus/pci/devices/$pciid/sriov_numvfs"; + $filepath = "/sys/bus/pci/devices/$pciid/sriov_numvfs"; if (!is_writable($filepath)) { - echo json_response(false, "Cannot modify $filepath"); - break; + json_response(false, "Cannot modify $filepath"); } try { + // Disable all VFs if ($numvfs == 0) { - file_put_contents($filepath, 0); - echo json_response(true, null, ["Disabled all VFs"]); - break; + safe_file_put_contents($filepath, 0); + json_response(true, null, [_("Disabled all VFs")]); } + // Change VF count if ($numvfs != $currentvfs) { - file_put_contents($filepath, 0); - file_put_contents($filepath, $numvfs); + safe_file_put_contents($filepath, 0); + safe_file_put_contents($filepath, $numvfs); + $results = action_settings($pciid); - echo json_response(true, null, ["Changed VF count to $numvfs", $results]); - break; + + $all_success = array_reduce($results, fn($ok, $r) => $ok && ($r['success'] ?? false), true); + + safe_file_put_contents( + "/tmp/vfactionres2", + json_encode(['all_success' => $all_success, 'results' => $results], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) + ); + + json_response(true, null, [sprintf(_("Changed VF count to %d"), $numvfs), $results]); } - file_put_contents($filepath, $numvfs); + // Reapply VF settings + safe_file_put_contents($filepath, $numvfs); $results = action_settings($pciid); - echo json_response(true, null, ["Reapplied VF settings", $results]); + json_response(true, null, [_("Reapplied VF settings"), $results]); + } catch (Throwable $e) { - echo json_response(false, "Failed to change VF count: " . $e->getMessage()); + // Log internal details for debugging + @file_put_contents("/tmp/vfaction_error.log", date('c') . " " . $e->getMessage() . "\n", FILE_APPEND); + + json_response(false, _("Failed to change VF count") . ": " . $e->getMessage()); } break; + // -------------------------------------------------------- // VF driver binding, MAC changes // -------------------------------------------------------- @@ -181,9 +217,9 @@ switch ($type) { } // Nothing changed - echo json_response(true, null, ["No changes detected"]); + echo json_response(true, null, [_("No changes detected")]); } catch (Throwable $e) { - echo json_response(false, "Error applying VF settings: " . $e->getMessage()); + echo json_response(false, _("Error applying VF settings").": ".$e->getMessage()); } break; @@ -197,7 +233,7 @@ switch ($type) { break; default: - echo json_response(false, "Unknown request type: $type"); + echo json_response(false, _("Unknown request type").": $type"); break; } diff --git a/emhttp/plugins/dynamix/include/update.sriov-cfg.php b/emhttp/plugins/dynamix/include/update.sriov-cfg.php index c4e214774..cf818ea1f 100644 --- a/emhttp/plugins/dynamix/include/update.sriov-cfg.php +++ b/emhttp/plugins/dynamix/include/update.sriov-cfg.php @@ -49,7 +49,7 @@ if (isset($pciid) && isset($vd)) { } } } - if (!$found) $newexplode[] = $newelement_check.$numvfs; + if (!$found && $numvfs != "0") $newexplode[] = $newelement_check.$numvfs; $new = "VFS=".implode(" ",$newexplode); $file = $sriov; break; @@ -73,10 +73,10 @@ if (isset($pciid) && isset($vd)) { } } } - if (!$found) $newexplode[] = $newelement_check.$vfio."|".$mac; - $new = "VFSETTINGS=".implode(" ",$newexplode); - $file = $sriovvfs; - break; + if (!$found && $vfio != 0) $newexplode[] = $newelement_check.$vfio."|".$mac; + $new = "VFSETTINGS=".implode(" ",$newexplode); + $file = $sriovvfs; + break; } } diff --git a/sbin/sriov b/sbin/sriov index 8884260d7..815009c83 100755 --- a/sbin/sriov +++ b/sbin/sriov @@ -14,7 +14,7 @@ # accepts space-separated list of or followed by an optional "|" and | # example:VFSETTINGS=0000:04:11.5|8086:1520|62:00:04:11:05:01 -SRIOV_ENABLED_FILE=/boot/config/sriov_enabled +SRIOV_DISABLED_FILE=/boot/config/sriov_disabled if [[ -f $SRIOV_DISABLED_FILE ]] ; then echo 'SRIOV Processing disabled.' exit diff --git a/sbin/sriov-setvfs.sh b/sbin/sriov-setvfs.sh index 204c4f87b..44f8c404a 100755 --- a/sbin/sriov-setvfs.sh +++ b/sbin/sriov-setvfs.sh @@ -53,7 +53,7 @@ if [[ $EUID -ne 0 ]]; then exit 1 fi -if [[ -z "$@" ]]; then +if [[ $# -eq 0 ]]; then echo "Error: Please provide Domain:Bus:Device.Function (dddd:bb:dd.f) and/or Vendor:Device (vvvv:dddd)" 1>&2 exit 1 fi diff --git a/sbin/sriov-vfsettings.sh b/sbin/sriov-vfsettings.sh index d9ca60457..6bc15f698 100755 --- a/sbin/sriov-vfsettings.sh +++ b/sbin/sriov-vfsettings.sh @@ -90,6 +90,11 @@ for arg in "$@"; do fi done +if [[ -z "$BDF" ]]; then + echo "Error: No valid Bus:Device.Function provided" 1>&2 + exit 1 +fi + TARGET_DEV_SYSFS_PATH="/sys/bus/pci/devices/$BDF" if [[ ! -d $TARGET_DEV_SYSFS_PATH ]]; then