Source code for linuxnet.qos.qdiscs.fifo

# Copyright (c) 2021, 2022, 2023, Panagiotis Tsirigotis

# This file is part of linuxnet-qos.
#
# linuxnet-qos is free software: you can redistribute it and/or
# modify it under the terms of version 3 of the GNU Affero General Public
# License as published by the Free Software Foundation.
#
# linuxnet-qos is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
# License for more details.
#
# You should have received a copy of the GNU Affero General
# Public License along with linuxnet-qos. If not, see
# <https://www.gnu.org/licenses/>.

"""This module provides access to the pfifo_fast queueing discipline
"""

from typing import List, Optional, Sequence

from ..deps import get_logger
from ..exceptions import TcError, TcParsingError
from ..handle import Handle
from ..parsers import QDiscParser

from .qdisc import QDisc

_logger = get_logger('linuxnet.qos.qdiscs.fifo')


[docs]class PFifoFastQDisc(QDisc): """This class provides access to the pfifo_fast queueing discipline of Linux (see **tc-pfifo_fast(8)**). """ def __init__(self, qdisc_handle: Handle, parent_handle: Optional[Handle], *, txqueuelen: Optional[int] =None, bands: Optional[int] =None, priomap: Optional[Sequence[int]] =None): """ :param qdisc_handle: handle of this :class:`PFifoFastQDisc` :param parent_handle: handle of parent, or ``None`` if this is a root queuing discipline :param txqueuelen: as documented in **tc-pfifo_fast(8)** :param bands: as documented in **tc-pfifo_fast(8)** :param priomap: as documented in **tc-pfifo_fast(8)** Only ``txqueuelen`` is used when creating a new ``pfifo_fast`` queuing discipline. If ``bands`` or ``priomap`` are specified, this will raise a :class:`TcError` exception. """ super().__init__(qdisc_handle, parent_handle) self.__txqueuelen = txqueuelen self.__bands = bands self.__priomap = priomap def __str__(self): return f"PFifoFastQDisc({self.get_handle()})"
[docs] def get_description(self) -> str: """Returns a string describing the queuing discipline and its attributes """ description = super().get_description() if self.__txqueuelen: description += f' txqueuelen {self.__txqueuelen}' if self.__bands: description += f' bands {self.__bands}' if self.__priomap: priomap_str = ' '.join([str(i) for i in self.__priomap]) description += f' priomap {priomap_str}' return description
[docs] def get_txqueuelen(self) -> Optional[int]: """Returns the queue length for each band, if specified. """ return self.__txqueuelen
[docs] def set_txqueuelen(self, txqueuelen: Optional[int]) -> None: """Set the queue length for each band (if ``None``, use the interface's txqueuelen). """ if self.get_config() is not None: raise TcError('cannot change txqueuelen of instantiated pfifo_fast') self.__txqueuelen = txqueuelen
[docs] def qdisc_creation_args(self) -> List[str]: """Returns the arguments expected by the **tc(8)** command to create a ``pfifo_fast`` qdisc """ if self.__bands is not None: raise TcError('cannot specify bands of pfifo_fast') if self.__priomap is not None: raise TcError('cannot specify priomap of pfifo_fast') args = ['pfifo_fast'] if self.__txqueuelen is not None: args += ['txqueuelen', str(self.__txqueuelen)] return args
def _uninstantiate_qdisc(self, config) -> None: """Invoke the **tc(8)** command to delete the queuing discipline described by this object. :param config: a :class:`QDiscConfig` object """ super()._uninstantiate_qdisc(config) # We clear these attributes so that the object can be used # for instantiation again. self.__bands = None self.__priomap = None @classmethod def parse(cls, qdisc_output) -> 'PFifoFastQDisc': """Create a :class:`PFifoFastQDisc` object from the output of the **tc(8)** command. :meta private: """ field_iter = qdisc_output.get_field_iter() # # The fields are generated from a split of a line like this: # # qdisc pfifo_fast 0: root refcnt 2 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 # The next field to be returned from field_iter is 'bands' # bands = None priomap = None for field in field_iter: if field == 'bands': try: bands = int(next(field_iter)) except ValueError as valerr: raise TcParsingError('bad number of bands') from valerr elif field == 'priomap': priomap = [int(v) for v in field_iter] else: _logger.warning("unknown pfifo_fast parameter: %s", field) return PFifoFastQDisc(qdisc_output.get_handle(), qdisc_output.get_parent_handle(), bands=bands, priomap=priomap)
QDiscParser.register_qdisc('pfifo_fast', PFifoFastQDisc)