From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 0DD131FF14F for ; Fri, 08 May 2026 14:49:09 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 23EFB17D6B; Fri, 8 May 2026 14:49:08 +0200 (CEST) From: Erik Fastermann To: pbs-devel@lists.proxmox.com Subject: [PATCH proxmox-backup] fix #7187: report: add ethtool output for physical interfaces Date: Fri, 8 May 2026 14:48:26 +0200 Message-ID: <20260508124826.3228-1-e.fastermann@proxmox.com> X-Mailer: git-send-email 2.47.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods RDNS_NONE 0.793 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [report.rs] Message-ID-Hash: RWZSW7YL4EP6YYUVTOJSX66DMMFSED7F X-Message-ID-Hash: RWZSW7YL4EP6YYUVTOJSX66DMMFSED7F X-MailFrom: root@erik-test-pbs.proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Erik Fastermann X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Backup Server development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Signed-off-by: Erik Fastermann --- NOTE: A similar patch was applied to all products: pmg, pve, pbs, pdm. src/server/report.rs | 65 ++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 21 deletions(-) diff --git a/src/server/report.rs b/src/server/report.rs index e4c761cdb..46218b79e 100644 --- a/src/server/report.rs +++ b/src/server/report.rs @@ -2,6 +2,8 @@ use std::fmt::Write; use std::path::Path; use std::process::Command; +use proxmox_network_api::NetworkInterfaceType; + fn get_top_processes() -> String { let (exe, args) = ("top", vec!["-b", "-c", "-w512", "-n", "1", "-o", "TIME"]); let output = Command::new(exe).args(&args).output(); @@ -63,34 +65,55 @@ fn files() -> Vec<(&'static str, Vec<&'static str>)> { ] } -fn commands() -> Vec<(&'static str, Vec<&'static str>)> { - vec![ - // ("", vec![]) - ("date", vec!["-R"]), - ("proxmox-backup-manager", vec!["versions", "--verbose"]), - ("proxmox-backup-manager", vec!["subscription", "get"]), - ("proxmox-backup-manager", vec!["ldap", "list"]), - ("proxmox-backup-manager", vec!["openid", "list"]), - ("proxmox-boot-tool", vec!["status"]), - ("df", vec!["-h"]), +fn commands() -> Vec<(&'static str, Vec)> { + // ("", vec![]) + const BASE_COMMANDS: &[(&str, &[&str])] = &[ + ("date", &["-R"]), + ("proxmox-backup-manager", &["versions", "--verbose"]), + ("proxmox-backup-manager", &["subscription", "get"]), + ("proxmox-backup-manager", &["ldap", "list"]), + ("proxmox-backup-manager", &["openid", "list"]), + ("proxmox-boot-tool", &["status"]), + ("df", &["-h"]), ( "lsblk", - vec![ + &[ "--ascii", "-M", "-o", "+HOTPLUG,ROTA,PHY-SEC,FSTYPE,MODEL,TRAN", ], ), - ("bash", vec!["-c", "ls -l /dev/disk/by-*/"]), - ("zpool", vec!["status"]), - ("zfs", vec!["list"]), - ("zarcstat", vec![]), - ("dmidecode", vec!["-t", "bios"]), - ("lscpu", vec![]), - ("lspci", vec!["-nnk"]), - ("ip", vec!["-details", "-statistics", "a"]), - ] + ("bash", &["-c", "ls -l /dev/disk/by-*/"]), + ("zpool", &["status"]), + ("zfs", &["list"]), + ("zarcstat", &[]), + ("dmidecode", &["-t", "bios"]), + ("lscpu", &[]), + ("lspci", &["-nnk"]), + ("ip", &["-details", "-statistics", "a"]), + ]; + + let mut commands: Vec<_> = BASE_COMMANDS + .into_iter() + .map(|(cmd, args)| (*cmd, args.into_iter().map(|arg| arg.to_string()).collect())) + .collect(); + + match proxmox_network_api::config() { + Ok((config, _)) => { + let ethtool_commands = config + .interfaces + .into_iter() + .filter(|(_, iface)| iface.interface_type == NetworkInterfaceType::Eth) + .map(|(name, _)| ("ethtool", vec![name])); + commands.extend(ethtool_commands) + } + Err(err) => { + eprintln!("error while querying network interfaces: {err}") + } + }; + + commands } // (description, function()) @@ -160,7 +183,7 @@ fn get_directory_content(path: impl AsRef) -> String { out } -fn get_command_output(exe: &str, args: &Vec<&str>) -> String { +fn get_command_output(exe: &str, args: &[String]) -> String { let output = Command::new(exe) .env("PROXMOX_OUTPUT_NO_BORDER", "1") .args(args) -- 2.47.3