|
|
|
@ -1,8 +1,10 @@
|
|
|
|
"""Linux control group constants, classes and utilities."""
|
|
|
|
"""Linux control group constants, classes and utilities."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import codecs
|
|
|
|
import dataclasses
|
|
|
|
import dataclasses
|
|
|
|
import pathlib
|
|
|
|
import pathlib
|
|
|
|
|
|
|
|
import re
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CGroupPath:
|
|
|
|
class CGroupPath:
|
|
|
|
@ -55,25 +57,54 @@ class CGroupEntry:
|
|
|
|
|
|
|
|
|
|
|
|
@dataclasses.dataclass(frozen=True)
|
|
|
|
@dataclasses.dataclass(frozen=True)
|
|
|
|
class MountEntry:
|
|
|
|
class MountEntry:
|
|
|
|
"""A single mount entry parsed from '/proc/{pid}/mounts' in the proc filesystem."""
|
|
|
|
"""A single mount info entry parsed from '/proc/{pid}/mountinfo' in the proc filesystem."""
|
|
|
|
device: pathlib.PurePosixPath
|
|
|
|
mount_id: int
|
|
|
|
|
|
|
|
parent_id: int
|
|
|
|
|
|
|
|
device_major: int
|
|
|
|
|
|
|
|
device_minor: int
|
|
|
|
|
|
|
|
root: pathlib.PurePosixPath
|
|
|
|
path: pathlib.PurePosixPath
|
|
|
|
path: pathlib.PurePosixPath
|
|
|
|
type: str
|
|
|
|
|
|
|
|
options: tuple[str, ...]
|
|
|
|
options: tuple[str, ...]
|
|
|
|
|
|
|
|
fields: tuple[str, ...]
|
|
|
|
|
|
|
|
type: str
|
|
|
|
|
|
|
|
source: pathlib.PurePosixPath
|
|
|
|
|
|
|
|
super_options: tuple[str, ...]
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@classmethod
|
|
|
|
def parse(cls, value: str) -> MountEntry:
|
|
|
|
def parse(cls, value: str) -> MountEntry:
|
|
|
|
"""Parse the given mount line from the proc filesystem and return a mount entry."""
|
|
|
|
"""Parse the given mount info line from the proc filesystem and return a mount entry."""
|
|
|
|
device, path, mtype, options, _a, _b = value.split(' ')
|
|
|
|
# See: https://man7.org/linux/man-pages/man5/proc.5.html
|
|
|
|
|
|
|
|
# See: https://github.com/torvalds/linux/blob/aea23e7c464bfdec04b52cf61edb62030e9e0d0a/fs/proc_namespace.c#L135
|
|
|
|
|
|
|
|
mount_id, parent_id, device_major_minor, root, path, options, *remainder = value.split(' ')
|
|
|
|
|
|
|
|
fields = remainder[:-4]
|
|
|
|
|
|
|
|
separator, mtype, source, super_options = remainder[-4:]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert separator == '-'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
device_major, device_minor = device_major_minor.split(':')
|
|
|
|
|
|
|
|
|
|
|
|
return cls(
|
|
|
|
return cls(
|
|
|
|
device=pathlib.PurePosixPath(device),
|
|
|
|
mount_id=int(mount_id),
|
|
|
|
path=pathlib.PurePosixPath(path),
|
|
|
|
parent_id=int(parent_id),
|
|
|
|
type=mtype,
|
|
|
|
device_major=int(device_major),
|
|
|
|
|
|
|
|
device_minor=int(device_minor),
|
|
|
|
|
|
|
|
root=_decode_path(root),
|
|
|
|
|
|
|
|
path=_decode_path(path),
|
|
|
|
options=tuple(options.split(',')),
|
|
|
|
options=tuple(options.split(',')),
|
|
|
|
|
|
|
|
fields=tuple(fields),
|
|
|
|
|
|
|
|
type=mtype,
|
|
|
|
|
|
|
|
source=_decode_path(source),
|
|
|
|
|
|
|
|
super_options=tuple(super_options.split(',')),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@classmethod
|
|
|
|
def loads(cls, value: str) -> tuple[MountEntry, ...]:
|
|
|
|
def loads(cls, value: str) -> tuple[MountEntry, ...]:
|
|
|
|
"""Parse the given output from the proc filesystem and return a tuple of mount entries."""
|
|
|
|
"""Parse the given output from the proc filesystem and return a tuple of mount info entries."""
|
|
|
|
return tuple(cls.parse(line) for line in value.splitlines())
|
|
|
|
return tuple(cls.parse(line) for line in value.splitlines())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _decode_path(value: str) -> pathlib.PurePosixPath:
|
|
|
|
|
|
|
|
"""Decode and return a path which may contain octal escape sequences."""
|
|
|
|
|
|
|
|
# See: https://github.com/torvalds/linux/blob/aea23e7c464bfdec04b52cf61edb62030e9e0d0a/fs/proc_namespace.c#L150
|
|
|
|
|
|
|
|
path = re.sub(r'(\\[0-7]{3})', lambda m: codecs.decode(m.group(0).encode('ascii'), 'unicode_escape'), value)
|
|
|
|
|
|
|
|
return pathlib.PurePosixPath(path)
|
|
|
|
|