all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [PATCH proxmox-backup 2/2] fix #7198: metric collection: count veth uplink when running in a container
  2026-07-07 10:55 Jakob Klocker
@ 2026-07-07 10:56 ` Jakob Klocker
  0 siblings, 0 replies; 9+ messages in thread
From: Jakob Klocker @ 2026-07-07 10:56 UTC (permalink / raw)
  To: pve-devel; +Cc: Jakob Klocker

When PBS runs inside an LXC container, the network uplink is one end of
a veth pair rather than a physical NIC, so is_physical() returns false
and the interface is excluded from network utilization stats unless its
name happens to match PHYSICAL_NIC_REGEX. This drops graph data for
interfaces with custom names (e.g. wan0).

Check whether we are running in a container (via /run/systemd/container,
cached in a OnceLock) and, if so, also count veth interfaces as physical
for metric collection. This mirrors how a VM's NIC is already counted.

Link: https://bugzilla.proxmox.com/show_bug.cgi?id=7198
Signed-off-by: Jakob Klocker <j.klocker@proxmox.com>
---
 src/server/metric_collection/mod.rs | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/server/metric_collection/mod.rs b/src/server/metric_collection/mod.rs
index 18625b1a5..47882eb89 100644
--- a/src/server/metric_collection/mod.rs
+++ b/src/server/metric_collection/mod.rs
@@ -148,6 +148,11 @@ impl NetdevStat {
 }
 
 static NETWORK_INTERFACE_CACHE: OnceLock<HashMap<String, IpLink>> = OnceLock::new();
+static IN_CONTAINER_CACHE: OnceLock<bool> = OnceLock::new();
+
+fn running_in_container() -> bool {
+    Path::new("/run/systemd/container").exists()
+}
 
 fn collect_netdev_stats() -> Option<Vec<NetdevStat>> {
     use proxmox_sys::linux::procfs::read_proc_net_dev;
@@ -175,10 +180,11 @@ fn collect_netdev_stats() -> Option<Vec<NetdevStat>> {
     };
 
     let mut stat_devs = Vec::with_capacity(net_devs.len());
+    let in_container = *IN_CONTAINER_CACHE.get_or_init(running_in_container);
 
     for net_dev in net_devs {
         if let Some(ip_link) = ip_links.get(&net_dev.device) {
-            let ty = if ip_link.is_physical() {
+            let ty = if ip_link.is_physical() || (in_container && ip_link.is_veth()) {
                 NetdevType::Physical
             } else {
                 NetdevType::Virtual
-- 
2.47.3




^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC proxmox{,-backup} 0/2] fix #7198: count veth uplink for PBS running in an LXC
@ 2026-07-07 11:20 Jakob Klocker
  2026-07-07 11:20 ` [PATCH proxmox 1/2] network-api: add is_veth helper to IpLink Jakob Klocker
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Jakob Klocker @ 2026-07-07 11:20 UTC (permalink / raw)
  To: pbs-devel; +Cc: Jakob Klocker

When PBS runs inside an LXC container, network traffic graphs stay
empty for interfaces with non-standard names (e.g. wan0, vxb01). The
reporter [0] observed that renaming to eth0 and restarting made data
appear.

The cause is in collect_netdev_stats(): an interface is recorded as
NetdevType::Physical only if is_physical() returns true. Inside a
container the uplink is one end of a veth pair (info_kind = "veth"), so
is_physical() returns false and the code falls back to
PHYSICAL_NIC_REGEX, which only matches conventional names. A standard
name like eth0 matches the regex and is counted; a custom name does 
not, so its stats are silently dropped. In a VM the guest NIC appears
as a normal hardware NIC without info_kind, which is why the VM case
works.

This series adds is_veth() to proxmox-network-api and gates the
collector on whether PBS runs in a container (checking
/run/systemd/container). 


RFC / open questions:

This patch fixes the reported single-uplink case, but in a container 
with several veths it counts all of them, including a veth enslaved to 
a bridge. In testing (see below) a bridge-enslaved veth was still 
counted. An alternative would be to count root-level interfaces without 
a master instead of matching veth, which would exclude enslaved 
interfaces and also generalise beyond veth.
Also this fix does not work if PBS is run in docker/podman,
since the interface is not a veth there (it was `tap` in podman).
LXC is the case that matters for PVE, so not covering podman/docker
seems acceptable to me.


Related, not fixed here:

NETWORK_INTERFACE_CACHE is a OnceLock populated once at proxy startup 
and never refreshed, so interfaces added or renamed after startup are 
not picked up until a restart. This matches the reporter's note that a
restart was required. It's pre-existing and independent of this fix.


Testing:

Reproduced in a PVE LXC running PBS with a custom-named veth uplink
("test"). Before: the interface produces no graph data. After: it is
counted. Verified via a temporary debug print in the collector that:

  * the custom-named veth uplink is counted,
  * a bridge (info_kind = bridge) is correctly excluded,
  * with multiple veths present, all veths are counted, including a
    bridge-enslaved one - the limitation noted above.

[0] https://bugzilla.proxmox.com/show_bug.cgi?id=7198


proxmox:

Jakob Klocker (1):
  network-api: add is_veth helper to IpLink

 proxmox-network-api/src/config/helper.rs | 13 +++++++++++++
 1 file changed, 13 insertions(+)


proxmox-backup:

Jakob Klocker (1):
  fix #7198: metric collection: count veth uplink when running in a
    container

 src/server/metric_collection/mod.rs | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)


Summary over all repositories:
  2 files changed, 20 insertions(+), 1 deletions(-)

-- 
Generated by murpp 0.12.0



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH proxmox 1/2] network-api: add is_veth helper to IpLink
  2026-07-07 11:20 [RFC proxmox{,-backup} 0/2] fix #7198: count veth uplink for PBS running in an LXC Jakob Klocker
@ 2026-07-07 11:20 ` Jakob Klocker
  2026-07-07 11:20 ` [PATCH proxmox-backup 2/2] fix #7198: metric collection: count veth uplink when running in a container Jakob Klocker
  2026-07-07 12:14 ` [RFC proxmox{,-backup} 0/2] fix #7198: count veth uplink for PBS running in an LXC Gabriel Goller
  2 siblings, 0 replies; 9+ messages in thread
From: Jakob Klocker @ 2026-07-07 11:20 UTC (permalink / raw)
  To: pbs-devel; +Cc: Jakob Klocker

Add a method to check whether an interface is one end of a veth pair
(info_kind = "veth"). This is used to identify a LXC container's network
uplink, which is a veth rather than a physical NIC and therefore is
not recognized by is_physical().

Signed-off-by: Jakob Klocker <j.klocker@proxmox.com>
---
 proxmox-network-api/src/config/helper.rs | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/proxmox-network-api/src/config/helper.rs b/proxmox-network-api/src/config/helper.rs
index a9ae35fc..a13d6cc3 100644
--- a/proxmox-network-api/src/config/helper.rs
+++ b/proxmox-network-api/src/config/helper.rs
@@ -207,6 +207,19 @@ impl IpLink {
         PHYSICAL_NIC_REGEX.is_match(&self.ifname)
     }
 
+    /// Whether this is a `veth` (virtual ethernet) interface.
+    ///
+    /// Checks whether `info_kind` in `linkinfo` is set to `"veth"`. Inside an
+    /// LXC container, the uplink is one end of a veth pair rather than a physical
+    /// NIC, so this is used alongside [`is_physical`] to decide whether an
+    /// interface carries the machine's network traffic.
+    pub fn is_veth(&self) -> bool {
+        self.linkinfo
+            .as_ref()
+            .and_then(|li| li.info_kind.as_deref())
+            == Some("veth")
+    }
+
     /// The name of the interface (ifname / IFLA_IFNAME).
     pub fn name(&self) -> &str {
         &self.ifname
-- 
2.47.3




^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH proxmox-backup 2/2] fix #7198: metric collection: count veth uplink when running in a container
  2026-07-07 11:20 [RFC proxmox{,-backup} 0/2] fix #7198: count veth uplink for PBS running in an LXC Jakob Klocker
  2026-07-07 11:20 ` [PATCH proxmox 1/2] network-api: add is_veth helper to IpLink Jakob Klocker
@ 2026-07-07 11:20 ` Jakob Klocker
  2026-07-07 12:14 ` [RFC proxmox{,-backup} 0/2] fix #7198: count veth uplink for PBS running in an LXC Gabriel Goller
  2 siblings, 0 replies; 9+ messages in thread
From: Jakob Klocker @ 2026-07-07 11:20 UTC (permalink / raw)
  To: pbs-devel; +Cc: Jakob Klocker

When PBS runs inside an LXC container, the network uplink is one end of
a veth pair rather than a physical NIC, so is_physical() returns false
and the interface is excluded from network utilization stats unless its
name happens to match PHYSICAL_NIC_REGEX. This drops graph data for
interfaces with custom names (e.g. wan0).

Check whether we are running in a container (via /run/systemd/container,
cached in a OnceLock) and, if so, also count veth interfaces as physical
for metric collection. This mirrors how a VM's NIC is already counted.

Link: https://bugzilla.proxmox.com/show_bug.cgi?id=7198
Signed-off-by: Jakob Klocker <j.klocker@proxmox.com>
---
 src/server/metric_collection/mod.rs | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/server/metric_collection/mod.rs b/src/server/metric_collection/mod.rs
index 18625b1a5..47882eb89 100644
--- a/src/server/metric_collection/mod.rs
+++ b/src/server/metric_collection/mod.rs
@@ -148,6 +148,11 @@ impl NetdevStat {
 }
 
 static NETWORK_INTERFACE_CACHE: OnceLock<HashMap<String, IpLink>> = OnceLock::new();
+static IN_CONTAINER_CACHE: OnceLock<bool> = OnceLock::new();
+
+fn running_in_container() -> bool {
+    Path::new("/run/systemd/container").exists()
+}
 
 fn collect_netdev_stats() -> Option<Vec<NetdevStat>> {
     use proxmox_sys::linux::procfs::read_proc_net_dev;
@@ -175,10 +180,11 @@ fn collect_netdev_stats() -> Option<Vec<NetdevStat>> {
     };
 
     let mut stat_devs = Vec::with_capacity(net_devs.len());
+    let in_container = *IN_CONTAINER_CACHE.get_or_init(running_in_container);
 
     for net_dev in net_devs {
         if let Some(ip_link) = ip_links.get(&net_dev.device) {
-            let ty = if ip_link.is_physical() {
+            let ty = if ip_link.is_physical() || (in_container && ip_link.is_veth()) {
                 NetdevType::Physical
             } else {
                 NetdevType::Virtual
-- 
2.47.3




^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [RFC proxmox{,-backup} 0/2] fix #7198: count veth uplink for PBS running in an LXC
  2026-07-07 11:20 [RFC proxmox{,-backup} 0/2] fix #7198: count veth uplink for PBS running in an LXC Jakob Klocker
  2026-07-07 11:20 ` [PATCH proxmox 1/2] network-api: add is_veth helper to IpLink Jakob Klocker
  2026-07-07 11:20 ` [PATCH proxmox-backup 2/2] fix #7198: metric collection: count veth uplink when running in a container Jakob Klocker
@ 2026-07-07 12:14 ` Gabriel Goller
  2026-07-07 12:47   ` Fabian Grünbichler
  2026-07-08  8:11   ` Jakob Klocker
  2 siblings, 2 replies; 9+ messages in thread
From: Gabriel Goller @ 2026-07-07 12:14 UTC (permalink / raw)
  To: Jakob Klocker; +Cc: pbs-devel

This seems a bit like a band-aid fix to me. Why do we not just get the uplink
interface via the default route: e.g. `ip -j route get 1.1.1.1 | jq .[0].dev`?




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC proxmox{,-backup} 0/2] fix #7198: count veth uplink for PBS running in an LXC
  2026-07-07 12:14 ` [RFC proxmox{,-backup} 0/2] fix #7198: count veth uplink for PBS running in an LXC Gabriel Goller
@ 2026-07-07 12:47   ` Fabian Grünbichler
  2026-07-08  8:49     ` Gabriel Goller
  2026-07-08  8:11   ` Jakob Klocker
  1 sibling, 1 reply; 9+ messages in thread
From: Fabian Grünbichler @ 2026-07-07 12:47 UTC (permalink / raw)
  To: Gabriel Goller, Jakob Klocker; +Cc: pbs-devel

On July 7, 2026 2:14 pm, Gabriel Goller wrote:
> This seems a bit like a band-aid fix to me. Why do we not just get the uplink
> interface via the default route: e.g. `ip -j route get 1.1.1.1 | jq .[0].dev`?

there might be more than one relevant interface, that's why we are
counting "physical" interfaces here, and not just the default one used
as default uplink?




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC proxmox{,-backup} 0/2] fix #7198: count veth uplink for PBS running in an LXC
  2026-07-07 12:14 ` [RFC proxmox{,-backup} 0/2] fix #7198: count veth uplink for PBS running in an LXC Gabriel Goller
  2026-07-07 12:47   ` Fabian Grünbichler
@ 2026-07-08  8:11   ` Jakob Klocker
  2026-07-08  8:45     ` Fabian Grünbichler
  1 sibling, 1 reply; 9+ messages in thread
From: Jakob Klocker @ 2026-07-08  8:11 UTC (permalink / raw)
  To: pbs-devel

On 7/7/26 2:15 PM, Gabriel Goller wrote:
> This seems a bit like a band-aid fix to me. Why do we not just get the uplink
> interface via the default route: e.g. `ip -j route get 1.1.1.1 | jq .[0].dev`?
> 

As Fabian mentioned, this wouldn't cover multiple interfaces. If one
separates backup traffic onto a dedicated interface, that traffic
wouldn't get picked up.

IMO the `veth` check is the right call here, at least I haven't found
a better way. I'm open for suggestions though.

What I'm still concerned about is whether it is necessary to handle
enslaved veth, since they would get picked up. I can't think of a real
use case where one would want to create such a setup in an LXC, but
since I'm not that experienced in that topic I'm happy for input!

Since running a PBS in an LXC is already not that common, paired with
renaming the interface to a not "normal" name, I would argue that
handling the enslaved veth is not really necessary.




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC proxmox{,-backup} 0/2] fix #7198: count veth uplink for PBS running in an LXC
  2026-07-08  8:11   ` Jakob Klocker
@ 2026-07-08  8:45     ` Fabian Grünbichler
  0 siblings, 0 replies; 9+ messages in thread
From: Fabian Grünbichler @ 2026-07-08  8:45 UTC (permalink / raw)
  To: Jakob Klocker, pbs-devel

On July 8, 2026 10:11 am, Jakob Klocker wrote:
> On 7/7/26 2:15 PM, Gabriel Goller wrote:
>> This seems a bit like a band-aid fix to me. Why do we not just get the uplink
>> interface via the default route: e.g. `ip -j route get 1.1.1.1 | jq .[0].dev`?
>> 
> 
> As Fabian mentioned, this wouldn't cover multiple interfaces. If one
> separates backup traffic onto a dedicated interface, that traffic
> wouldn't get picked up.
> 
> IMO the `veth` check is the right call here, at least I haven't found
> a better way. I'm open for suggestions though.

I think the only other (more flexible) solution would be to have a file
listing the interfaces that should be counted..

> What I'm still concerned about is whether it is necessary to handle
> enslaved veth, since they would get picked up. I can't think of a real
> use case where one would want to create such a setup in an LXC, but
> since I'm not that experienced in that topic I'm happy for input!
> 
> Since running a PBS in an LXC is already not that common, paired with
> renaming the interface to a not "normal" name, I would argue that
> handling the enslaved veth is not really necessary.




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC proxmox{,-backup} 0/2] fix #7198: count veth uplink for PBS running in an LXC
  2026-07-07 12:47   ` Fabian Grünbichler
@ 2026-07-08  8:49     ` Gabriel Goller
  0 siblings, 0 replies; 9+ messages in thread
From: Gabriel Goller @ 2026-07-08  8:49 UTC (permalink / raw)
  To: Fabian Grünbichler; +Cc: Jakob Klocker, pbs-devel

On 07.07.2026 14:47, Fabian Grünbichler wrote:
> On July 7, 2026 2:14 pm, Gabriel Goller wrote:
> > This seems a bit like a band-aid fix to me. Why do we not just get the uplink
> > interface via the default route: e.g. `ip -j route get 1.1.1.1 | jq .[0].dev`?
> 
> there might be more than one relevant interface, that's why we are
> counting "physical" interfaces here, and not just the default one used
> as default uplink?

Ah, missed this -- I thought we only show a single interface...




^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-07-08  8:50 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-07 11:20 [RFC proxmox{,-backup} 0/2] fix #7198: count veth uplink for PBS running in an LXC Jakob Klocker
2026-07-07 11:20 ` [PATCH proxmox 1/2] network-api: add is_veth helper to IpLink Jakob Klocker
2026-07-07 11:20 ` [PATCH proxmox-backup 2/2] fix #7198: metric collection: count veth uplink when running in a container Jakob Klocker
2026-07-07 12:14 ` [RFC proxmox{,-backup} 0/2] fix #7198: count veth uplink for PBS running in an LXC Gabriel Goller
2026-07-07 12:47   ` Fabian Grünbichler
2026-07-08  8:49     ` Gabriel Goller
2026-07-08  8:11   ` Jakob Klocker
2026-07-08  8:45     ` Fabian Grünbichler
  -- strict thread matches above, loose matches on Subject: below --
2026-07-07 10:55 Jakob Klocker
2026-07-07 10:56 ` [PATCH proxmox-backup 2/2] fix #7198: metric collection: count veth uplink when running in a container Jakob Klocker

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal