diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index b26346c1..de1d7c57 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -1308,6 +1308,7 @@ dependencies = [ "criterion", "log", "lqos_config", + "lqos_utils", "nix", "serde", "tokio", diff --git a/src/rust/lqos_bus/Cargo.toml b/src/rust/lqos_bus/Cargo.toml index e7a1fa12..88984e21 100644 --- a/src/rust/lqos_bus/Cargo.toml +++ b/src/rust/lqos_bus/Cargo.toml @@ -12,6 +12,7 @@ serde = { version = "1.0", features = ["derive"] } bincode = "1" anyhow = "1" lqos_config = { path = "../lqos_config" } +lqos_utils = { path = "../lqos_utils" } tokio = { version = "1.22", features = [ "rt", "macros", "net", "io-util", "time" ] } log = "0" nix = "0" diff --git a/src/rust/lqos_bus/src/bus/client.rs b/src/rust/lqos_bus/src/bus/client.rs index e3de572f..3ea5f6c5 100644 --- a/src/rust/lqos_bus/src/bus/client.rs +++ b/src/rust/lqos_bus/src/bus/client.rs @@ -1,6 +1,7 @@ use tokio::{net::UnixStream, io::{AsyncWriteExt, AsyncReadExt}}; use crate::{BUS_SOCKET_PATH, BusSession, BusRequest, encode_request, decode_response, BusResponse}; use anyhow::Result; +use super::PREALLOCATE_CLIENT_BUFFER_BYTES; /// Convenient wrapper for accessing the bus /// @@ -17,7 +18,7 @@ pub async fn bus_request(requests: Vec) -> Result> }; let msg = encode_request(&test)?; stream.write(&msg).await?; - let mut buf = Vec::new(); + let mut buf = Vec::with_capacity(PREALLOCATE_CLIENT_BUFFER_BYTES); let _ = stream.read_to_end(&mut buf).await.unwrap(); let reply = decode_response(&buf)?; diff --git a/src/rust/lqos_bus/src/bus/mod.rs b/src/rust/lqos_bus/src/bus/mod.rs index b2ede461..b185b1fc 100644 --- a/src/rust/lqos_bus/src/bus/mod.rs +++ b/src/rust/lqos_bus/src/bus/mod.rs @@ -20,7 +20,9 @@ pub const BUS_SOCKET_PATH: &str = "/run/lqos/bus"; /// The directory containing the bus socket. Used for ensuring /// that the directory exists. -pub(crate) const BUS_SOCKET_DIRECTORY: &str = "/run/lqos/."; +pub(crate) const BUS_SOCKET_DIRECTORY: &str = "/run/lqos"; + +const PREALLOCATE_CLIENT_BUFFER_BYTES: usize = 10240; /// Encodes a BusSession with `bincode`, providing a tight binary /// representation of the request object for TCP transmission. diff --git a/src/rust/lqos_bus/src/bus/persistent_client.rs b/src/rust/lqos_bus/src/bus/persistent_client.rs index 7890f149..3cd1906c 100644 --- a/src/rust/lqos_bus/src/bus/persistent_client.rs +++ b/src/rust/lqos_bus/src/bus/persistent_client.rs @@ -9,6 +9,7 @@ use tokio::{ net::UnixStream, time::timeout, }; +use super::PREALLOCATE_CLIENT_BUFFER_BYTES; /// Provides a lqosd bus client that persists between connections. Useful for when you are /// going to be repeatedly polling the bus for data (e.g. `lqtop`) and want to avoid the @@ -25,7 +26,7 @@ impl BusClient { pub async fn new() -> Result { Ok(Self { stream: Self::connect().await, - buffer: vec![0u8; 10240], + buffer: vec![0u8; PREALLOCATE_CLIENT_BUFFER_BYTES], timeout: Duration::from_millis(100), }) } diff --git a/src/rust/lqos_bus/src/bus/unix_socket_server.rs b/src/rust/lqos_bus/src/bus/unix_socket_server.rs index 3d066ea6..ca2e13bf 100644 --- a/src/rust/lqos_bus/src/bus/unix_socket_server.rs +++ b/src/rust/lqos_bus/src/bus/unix_socket_server.rs @@ -1,7 +1,6 @@ use std::{fs::remove_file, ffi::CString}; use crate::{BUS_SOCKET_PATH, decode_request, BusReply, encode_response, BusRequest, BusResponse}; use anyhow::Result; -use nix::libc::mode_t; use tokio::{net::{UnixListener, UnixStream}, io::{AsyncReadExt, AsyncWriteExt}}; use log::warn; @@ -15,8 +14,9 @@ impl UnixSocketServer { /// Creates a new `UnixSocketServer`. Will delete any pre-existing /// socket file. pub fn new() -> Result { - Self::check_directory()?; Self::delete_local_socket()?; + Self::check_directory()?; + Self::path_permissions()?; Ok(Self {}) } @@ -32,15 +32,19 @@ impl UnixSocketServer { if dir_path.exists() && dir_path.is_dir() { Ok(()) } else { - std::fs::create_dir(dir_path)?; - let unix_path = CString::new(BUS_SOCKET_DIRECTORY)?; - unsafe { - nix::libc::chmod(unix_path.as_ptr(), mode_t::from_le(666)); - } + std::fs::create_dir(dir_path)?; Ok(()) } } + fn path_permissions() -> Result<()> { + let unix_path = CString::new(BUS_SOCKET_DIRECTORY)?; + unsafe { + nix::libc::chmod(unix_path.as_ptr(), 777); + } + Ok(()) + } + fn delete_local_socket() -> Result<()> { let socket_path = std::path::Path::new(BUS_SOCKET_PATH); if socket_path.exists() { @@ -50,10 +54,7 @@ impl UnixSocketServer { } fn make_socket_public() -> Result<()> { - let unix_path = CString::new(BUS_SOCKET_PATH)?; - unsafe { - nix::libc::chmod(unix_path.as_ptr(), mode_t::from_le(666)); - } + lqos_utils::run_success!("/bin/chmod", "-R", "a+rwx", BUS_SOCKET_DIRECTORY); Ok(()) } @@ -78,7 +79,7 @@ impl UnixSocketServer { if let Ok(request) = decode_request(&buf) { let mut response = BusReply { - responses: Vec::new(), + responses: Vec::with_capacity(8), }; handle_bus_requests(&request.requests, &mut response.responses); let _ = reply_unix(&encode_response(&response).unwrap(), &mut socket).await; diff --git a/src/rust/lqos_config/src/lib.rs b/src/rust/lqos_config/src/lib.rs index 1e6e84b7..599c72e8 100644 --- a/src/rust/lqos_config/src/lib.rs +++ b/src/rust/lqos_config/src/lib.rs @@ -17,3 +17,6 @@ pub use etc::{BridgeConfig, BridgeInterface, BridgeVlan, EtcLqos, Tunables}; pub use libre_qos_config::LibreQoSConfig; pub use program_control::load_libreqos; pub use shaped_devices::{ConfigShapedDevices, ShapedDevice}; + +/// Used as a constant in determining buffer preallocation +pub const SUPPORTED_CUSTOMERS: usize = 16_000_000; \ No newline at end of file diff --git a/src/rust/lqos_config/src/shaped_devices/mod.rs b/src/rust/lqos_config/src/shaped_devices/mod.rs index b266a206..089d9eba 100644 --- a/src/rust/lqos_config/src/shaped_devices/mod.rs +++ b/src/rust/lqos_config/src/shaped_devices/mod.rs @@ -1,6 +1,6 @@ mod serializable; mod shaped_device; -use crate::etc; +use crate::{etc, SUPPORTED_CUSTOMERS}; use anyhow::Result; use csv::{QuoteStyle, WriterBuilder, ReaderBuilder}; use serializable::SerializableShapedDevice; @@ -38,7 +38,7 @@ impl ConfigShapedDevices { // Example: StringRecord(["1", "968 Circle St., Gurnee, IL 60031", "1", "Device 1", "", "", "192.168.101.2", "", "25", "5", "10000", "10000", ""]) - let mut devices = Vec::new(); + let mut devices = Vec::with_capacity(SUPPORTED_CUSTOMERS); for result in reader.records() { if let Ok(result) = result { if let Ok(device) = ShapedDevice::from_csv(&result) { diff --git a/src/rust/lqos_node_manager/src/tracker/cache/cpu_ram.rs b/src/rust/lqos_node_manager/src/tracker/cache/cpu_ram.rs index 1468d2ff..4f4b6d64 100644 --- a/src/rust/lqos_node_manager/src/tracker/cache/cpu_ram.rs +++ b/src/rust/lqos_node_manager/src/tracker/cache/cpu_ram.rs @@ -3,7 +3,7 @@ use parking_lot::RwLock; lazy_static! { /// Global storage of current CPU usage - pub static ref CPU_USAGE : RwLock> = RwLock::new(Vec::new()); + pub static ref CPU_USAGE : RwLock> = RwLock::new(Vec::with_capacity(128)); } lazy_static! { diff --git a/src/rust/lqos_node_manager/src/tracker/cache/lqosd_stats.rs b/src/rust/lqos_node_manager/src/tracker/cache/lqosd_stats.rs index 3e9238e7..b3ffcb72 100644 --- a/src/rust/lqos_node_manager/src/tracker/cache/lqosd_stats.rs +++ b/src/rust/lqos_node_manager/src/tracker/cache/lqosd_stats.rs @@ -3,15 +3,15 @@ use lqos_bus::IpStats; use parking_lot::RwLock; lazy_static! { - pub static ref TOP_10_DOWNLOADERS: RwLock> = RwLock::new(Vec::new()); + pub static ref TOP_10_DOWNLOADERS: RwLock> = RwLock::new(Vec::with_capacity(10)); } lazy_static! { - pub static ref WORST_10_RTT: RwLock> = RwLock::new(Vec::new()); + pub static ref WORST_10_RTT: RwLock> = RwLock::new(Vec::with_capacity(10)); } lazy_static! { - pub static ref RTT_HISTOGRAM: RwLock> = RwLock::new(Vec::new()); + pub static ref RTT_HISTOGRAM: RwLock> = RwLock::new(Vec::with_capacity(100)); } lazy_static! { diff --git a/src/rust/lqos_python/src/blocking.rs b/src/rust/lqos_python/src/blocking.rs index 59e30d0c..05a9acbb 100644 --- a/src/rust/lqos_python/src/blocking.rs +++ b/src/rust/lqos_python/src/blocking.rs @@ -4,7 +4,7 @@ use lqos_bus::{ }; pub fn run_query(requests: Vec) -> Result> { - let mut replies = Vec::new(); + let mut replies = Vec::with_capacity(8); tokio::runtime::Builder::new_current_thread() .enable_all() .build() diff --git a/src/rust/lqosd/src/file_lock.rs b/src/rust/lqosd/src/file_lock.rs index d057798d..810c671f 100644 --- a/src/rust/lqosd/src/file_lock.rs +++ b/src/rust/lqosd/src/file_lock.rs @@ -5,7 +5,7 @@ use sysinfo::{System, SystemExt, Pid, ProcessExt}; const LOCK_PATH: &str = "/run/lqos/lqosd.lock"; const LOCK_DIR: &str = "/run/lqos"; -const LOCK_DIR_PERMS: &str = "/run/lqos/."; +const LOCK_DIR_PERMS: &str = "/run/lqos"; pub struct FileLock {} @@ -46,8 +46,14 @@ impl FileLock { fn create_lock() -> Result<()> { let pid = unsafe { getpid() }; let pid_format = format!("{pid}"); - let mut f = File::create(LOCK_PATH)?; - f.write_all(pid_format.as_bytes())?; + { + let mut f = File::create(LOCK_PATH)?; + f.write_all(pid_format.as_bytes())?; + } + let unix_path = CString::new(LOCK_PATH)?; + unsafe { + nix::libc::chmod(unix_path.as_ptr(), mode_t::from_le(666)); + } Ok(()) } @@ -59,7 +65,7 @@ impl FileLock { std::fs::create_dir(dir_path)?; let unix_path = CString::new(LOCK_DIR_PERMS)?; unsafe { - nix::libc::chmod(unix_path.as_ptr(), mode_t::from_le(666)); + nix::libc::chmod(unix_path.as_ptr(), 777); } Ok(()) }