#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TransmitSysfsQueue<'a>
{
network_interface_name: &'a NetworkInterfaceName,
queue_identifier: QueueIdentifier,
}
impl<'a> SysfsQueue<'a> for TransmitSysfsQueue<'a>
{
const Prefix: &'static str = "tx";
fn new(network_interface_name: &'a NetworkInterfaceName, queue_identifier: QueueIdentifier) -> Self
{
Self
{
network_interface_name,
queue_identifier,
}
}
#[inline(always)]
fn network_interface_name(&self) -> &'a NetworkInterfaceName
{
self.network_interface_name
}
#[inline(always)]
fn queue_identifier(&self) -> QueueIdentifier
{
self.queue_identifier
}
}
impl<'a> TransmitSysfsQueue<'a>
{
pub fn traffic_class(&self, sys_path: &SysPath) -> io::Result<Option<TransmitQueueTrafficClass>>
{
match self.file_path(sys_path, "traffic_class").read_raw_without_line_feed()
{
Ok(value) =>
{
let value = &value[..];
let mut bytes = value.split_bytes_n(2, b'-');
Ok
(
Some
(
TransmitQueueTrafficClass
{
traffic_class: ParseNumber::parse_decimal_number(bytes.next().unwrap()).map_err(io_error_invalid_data)?,
subordinate_device: match bytes.next()
{
Some(subordinate_device_bytes) => Some(ParseNumber::parse_decimal_number(subordinate_device_bytes).map_err(io_error_invalid_data)?),
None => None,
},
}
)
)
},
Err(error) => if error.raw_os_error() == Some(ENOENT)
{
Ok(None)
}
else
{
Err(error)
}
}
}
#[inline(always)]
pub fn maximum_rate_in_megabits_per_second(&self, sys_path: &SysPath) -> io::Result<Option<NonZeroU32>>
{
self.tx_maxrate_file_path(sys_path).read_value()
}
#[inline(always)]
pub fn set_maximum_rate_in_megabits_per_second(&self, sys_path: &SysPath, maximum_rate_in_megabits_per_second: Option<NonZeroU32>) -> io::Result<bool>
{
assert_effective_user_id_is_root("write /sys/class/net/<network_interface_name>/queues/tx-<queue_identifier/tx_maxrate");
let file_path = self.tx_maxrate_file_path(sys_path);
if file_path.exists()
{
let maximum_rate_in_megabits_per_second: u32 = unsafe { transmute(maximum_rate_in_megabits_per_second) };
match file_path.write_value(UnpaddedDecimalInteger(maximum_rate_in_megabits_per_second))
{
Ok(()) => Ok(true),
Err(error) => if error.raw_os_error() == Some(EOPNOTSUPP)
{
Ok(false)
}
else
{
Err(error)
}
}
}
else
{
Ok(false)
}
}
#[inline(always)]
pub fn number_of_timeout_events(&self, sys_path: &SysPath) -> io::Result<usize>
{
self.file_path(sys_path, "tx_timeout").read_value()
}
#[inline(always)]
pub fn transmit_packet_steering_hyper_thread_affinity(&self, sys_path: &SysPath) -> io::Result<Option<HyperThreads>>
{
match self.xps_cpus_file_path(sys_path).parse_comma_separated_bit_set()
{
Ok(bit_set) => Ok(Some(HyperThreads(bit_set))),
Err(error) => if error.raw_os_error() == Some(ENOENT)
{
Ok(None)
}
else
{
Err(error)
}
}
}
#[inline(always)]
pub fn set_transmit_packet_steering_hyper_thread_affinity(&self, sys_path: &SysPath, hyper_threads: &HyperThreads) -> io::Result<bool>
{
assert_effective_user_id_is_root("write /sys/class/net/<network_interface_name>/queues/tx-<queue_identifier/xps_cpus");
let file_path = self.xps_cpus_file_path(sys_path);
if file_path.exists()
{
let mask = IntoBitMask(hyper_threads);
match file_path.write_value(mask)
{
Ok(()) => Ok(true),
Err(error) => if error.raw_os_error() == Some(ENOENT)
{
Ok(false)
}
else
{
Err(error)
}
}
}
else
{
Ok(false)
}
}
#[inline(always)]
pub fn transmit_packet_steering_receive_queue_affinity(&self, sys_path: &SysPath) -> io::Result<QueueIdentifiers>
{
self.xps_rxqs_file_path(sys_path).parse_comma_separated_bit_set().map(QueueIdentifiers)
}
#[inline(always)]
pub fn set_transmit_packet_steering_receive_queue_affinity(&self, sys_path: &SysPath, receive_queues_to_map_to: &QueueIdentifiers) -> io::Result<()>
{
assert_effective_user_id_is_root("write /sys/class/net/<network_interface_name>/queues/tx-<queue_identifier/xps_rxqs");
let file_path = self.xps_rxqs_file_path(sys_path);
if file_path.exists()
{
let mask = IntoBitMask(receive_queues_to_map_to);
file_path.write_value(mask)
}
else
{
Ok(())
}
}
#[inline(always)]
pub fn byte_limits_hold_time(&self, sys_path: &SysPath) -> io::Result<Milliseconds>
{
self.byte_queue_limits_hold_time_file_path(sys_path).read_value()
}
#[inline(always)]
pub fn set_byte_limits_hold_time(&self, sys_path: &SysPath, hold_time: Milliseconds) -> io::Result<()>
{
assert_effective_user_id_is_root("write /sys/class/net/<network_interface_name>/queues/tx-<queue_identifier/byte_queue_limits/hold_time");
let file_path = self.byte_queue_limits_hold_time_file_path(sys_path);
if file_path.exists()
{
file_path.write_value(hold_time)
}
else
{
Ok(())
}
}
#[inline(always)]
pub fn number_of_bytes_inflight(&self, sys_path: &SysPath) -> io::Result<u64>
{
self.byte_queue_limits_file_path(sys_path, "inflight").read_value()
}
#[inline(always)]
pub fn minimum_current_byte_limit(&self, sys_path: &SysPath) -> io::Result<Option<NonZeroU64>>
{
self.byte_queue_limits_limit_min_file_path(sys_path).read_value()
}
#[inline(always)]
pub fn set_minimum_current_byte_limit(&self, sys_path: &SysPath, minimum_current_byte_limit: Option<NonZeroU64>) -> io::Result<()>
{
assert_effective_user_id_is_root("write /sys/class/net/<network_interface_name>/queues/tx-<queue_identifier/byte_queue_limits/limit_min");
let file_path = self.byte_queue_limits_limit_min_file_path(sys_path);
if file_path.exists()
{
let value: u64 = unsafe { transmute(minimum_current_byte_limit) };
file_path.write_value(UnpaddedDecimalInteger(value))
}
else
{
Ok(())
}
}
#[inline(always)]
pub fn current_byte_limit(&self, sys_path: &SysPath) -> io::Result<Option<NonZeroU64>>
{
self.byte_queue_limits_limit_file_path(sys_path).read_value()
}
#[inline(always)]
pub fn set_current_byte_limit(&self, sys_path: &SysPath, current_byte_limit: Option<NonZeroU64>) -> io::Result<()>
{
assert_effective_user_id_is_root("write /sys/class/net/<network_interface_name>/queues/tx-<queue_identifier/byte_queue_limits/limit");
let file_path = self.byte_queue_limits_limit_file_path(sys_path);
if file_path.exists()
{
let value: u64 = unsafe { transmute(current_byte_limit) };
file_path.write_value(UnpaddedDecimalInteger(value))
}
else
{
Ok(())
}
}
#[inline(always)]
pub fn maximum_current_byte_limit(&self, sys_path: &SysPath) -> io::Result<NonZeroU64>
{
self.byte_queue_limits_limit_max_file_path(sys_path).read_value()
}
#[inline(always)]
pub fn set_maximum_current_byte_limit(&self, sys_path: &SysPath, maximum_current_byte_limit: NonZeroU64) -> io::Result<()>
{
assert_effective_user_id_is_root("write /sys/class/net/<network_interface_name>/queues/tx-<queue_identifier/byte_queue_limits/limit_max");
let file_path = self.byte_queue_limits_limit_max_file_path(sys_path);
if file_path.exists()
{
file_path.write_value(UnpaddedDecimalInteger(maximum_current_byte_limit))
}
else
{
Ok(())
}
}
#[inline(always)]
fn tx_maxrate_file_path(&self, sys_path: &SysPath) -> PathBuf
{
self.file_path(sys_path, "tx_maxrate")
}
#[inline(always)]
fn xps_cpus_file_path(&self, sys_path: &SysPath) -> PathBuf
{
self.file_path(sys_path, "xps_cpus")
}
#[inline(always)]
fn xps_rxqs_file_path(&self, sys_path: &SysPath) -> PathBuf
{
self.file_path(sys_path, "xps_rxqs")
}
#[inline(always)]
fn byte_queue_limits_limit_min_file_path(&self, sys_path: &SysPath) -> PathBuf
{
self.byte_queue_limits_file_path(sys_path, "limit_min")
}
#[inline(always)]
fn byte_queue_limits_limit_max_file_path(&self, sys_path: &SysPath) -> PathBuf
{
self.byte_queue_limits_file_path(sys_path, "limit_max")
}
#[inline(always)]
fn byte_queue_limits_limit_file_path(&self, sys_path: &SysPath) -> PathBuf
{
self.byte_queue_limits_file_path(sys_path, "limit")
}
#[inline(always)]
fn byte_queue_limits_hold_time_file_path(&self, sys_path: &SysPath) -> PathBuf
{
self.byte_queue_limits_file_path(sys_path, "hold_time")
}
#[inline(always)]
fn byte_queue_limits_file_path(&self, sys_path: &SysPath, file_name: &str) -> PathBuf
{
self.file_path(sys_path, "byte_queue_limits").append(file_name)
}
}