feat(monitoring): add dry-run mode to simulate qdisc rate changes

Enable a monitoring-only mode that logs intended bandwidth adjustments without applying them to the system via netlink.
This commit is contained in:
Nils Andreas Svee committed 2026-04-13 12:11:05 +07:00
1 parent 6d44556d63
commit f0fb3c9640
4 files changed
+29 -5

No files matched your search

+8
View File
@@ -84,6 +84,9 @@ pub struct Config {
pub speed_hist_size: u32, pub speed_hist_size: u32,
pub tick_interval: f64, pub tick_interval: f64,
pub upload_delay_ms: f64, pub upload_delay_ms: f64,
// Monitoring / dry-run
pub dry_run: bool,
} }
impl Config { impl Config {
@@ -186,6 +189,11 @@ impl Config {
"sqm-autorate.@advanced_settings[0].upload_delay_ms", "sqm-autorate.@advanced_settings[0].upload_delay_ms",
Some(15.0), Some(15.0),
)?, )?,
dry_run: Self::get::<bool>(
"SQMA_DRY_RUN",
"sqm-autorate.@advanced_settings[0].dry_run",
Some(false),
)?,
}; };
let mut config = config; let mut config = config;
+5 -2
View File
@@ -39,6 +39,9 @@ fn main() -> anyhow::Result<()> {
let config = Config::new()?; let config = Config::new()?;
log::init(config.log_level)?; log::init(config.log_level)?;
if config.dry_run {
info!("*** MONITORING MODE ACTIVE — qdisc rates will NOT be changed ***");
}
let mut reflectors = config.load_reflectors()?; let mut reflectors = config.load_reflectors()?;
let start_t = Instant::now(); let start_t = Instant::now();
@@ -111,8 +114,8 @@ fn main() -> anyhow::Result<()> {
"Setting shaper rates to minimum (D/L): {} / {}", "Setting shaper rates to minimum (D/L): {} / {}",
config.download_min_kbits, config.upload_min_kbits config.download_min_kbits, config.upload_min_kbits
); );
Netlink::set_qdisc_rate(down_qdisc, config.download_min_kbits as u64)?; Netlink::set_qdisc_rate(down_qdisc, config.download_min_kbits as u64, config.dry_run)?;
Netlink::set_qdisc_rate(up_qdisc, config.upload_min_kbits as u64)?; Netlink::set_qdisc_rate(up_qdisc, config.upload_min_kbits as u64, config.dry_run)?;
// Sleep for a few seconds to give the shaper a chance // Sleep for a few seconds to give the shaper a chance
// to control the queue if load is heavy // to control the queue if load is heavy
+10 -1
View File
@@ -1,6 +1,7 @@
use std::io; use std::io;
use std::str::Utf8Error; use std::str::Utf8Error;
use log::info;
use netlink_bindings::{rt_link, tc}; use netlink_bindings::{rt_link, tc};
use netlink_socket2::NetlinkSocket; use netlink_socket2::NetlinkSocket;
use thiserror::Error; use thiserror::Error;
@@ -111,7 +112,15 @@ impl Netlink {
Netlink::qdisc_from_ifindex(ifindex, ifname) Netlink::qdisc_from_ifindex(ifindex, ifname)
} }
pub fn set_qdisc_rate(qdisc: Qdisc, bandwidth_kbit: u64) -> Result<(), NetlinkError> { pub fn set_qdisc_rate(qdisc: Qdisc, bandwidth_kbit: u64, dry_run: bool) -> Result<(), NetlinkError> {
if dry_run {
info!(
"dry-run: would set qdisc ifindex={} to {} kbit/s",
qdisc.ifindex, bandwidth_kbit
);
return Ok(());
}
let mut socket = NetlinkSocket::new(); let mut socket = NetlinkSocket::new();
let bandwidth = bandwidth_kbit * 1000 / 8; let bandwidth = bandwidth_kbit * 1000 / 8;
+6 -2
View File
@@ -282,10 +282,12 @@ impl Ratecontroller {
Netlink::set_qdisc_rate( Netlink::set_qdisc_rate(
self.state_dl.qdisc, self.state_dl.qdisc,
self.state_dl.current_rate.round() as u64, self.state_dl.current_rate.round() as u64,
self.config.dry_run,
)?; )?;
Netlink::set_qdisc_rate( Netlink::set_qdisc_rate(
self.state_ul.qdisc, self.state_ul.qdisc,
self.state_ul.current_rate.round() as u64, self.state_ul.current_rate.round() as u64,
self.config.dry_run,
)?; )?;
let mut speed_hist_fd: Option<File> = None; let mut speed_hist_fd: Option<File> = None;
@@ -346,10 +348,12 @@ impl Ratecontroller {
Netlink::set_qdisc_rate( Netlink::set_qdisc_rate(
self.state_dl.qdisc, self.state_dl.qdisc,
self.state_dl.next_rate as u64, self.state_dl.next_rate as u64,
self.config.dry_run,
)?; )?;
Netlink::set_qdisc_rate( Netlink::set_qdisc_rate(
self.state_ul.qdisc, self.state_ul.qdisc,
self.state_ul.next_rate as u64, self.state_ul.next_rate as u64,
self.config.dry_run,
)?; )?;
self.state_dl.current_rate = self.state_dl.next_rate; self.state_dl.current_rate = self.state_dl.next_rate;
@@ -370,11 +374,11 @@ impl Ratecontroller {
} }
if self.state_dl.next_rate != self.state_dl.current_rate { if self.state_dl.next_rate != self.state_dl.current_rate {
Netlink::set_qdisc_rate(self.state_dl.qdisc, self.state_dl.next_rate as u64)?; Netlink::set_qdisc_rate(self.state_dl.qdisc, self.state_dl.next_rate as u64, self.config.dry_run)?;
} }
if self.state_ul.next_rate != self.state_ul.current_rate { if self.state_ul.next_rate != self.state_ul.current_rate {
Netlink::set_qdisc_rate(self.state_ul.qdisc, self.state_ul.next_rate as u64)?; Netlink::set_qdisc_rate(self.state_ul.qdisc, self.state_ul.next_rate as u64, self.config.dry_run)?;
} }
self.state_dl.current_rate = self.state_dl.next_rate; self.state_dl.current_rate = self.state_dl.next_rate;