Module rsyscall.linux.memfd
Expand source code Browse git
from __future__ import annotations
from rsyscall._raw import ffi, lib # type: ignore
import os
import typing as t
import enum
class MFD(enum.IntFlag):
NONE = 0
CLOEXEC = lib.MFD_CLOEXEC
ALLOW_SEALING = lib.MFD_ALLOW_SEALING
HUGETLB = lib.MFD_HUGETLB
HUGE_2MB = lib.MFD_HUGE_2MB
HUGE_1GB = lib.MFD_HUGE_1GB
#### Classes ####
from rsyscall.handle.fd import T_fd, FileDescriptorTask
if t.TYPE_CHECKING:
from rsyscall.handle.pointer import WrittenPointer
class MemfdTask(FileDescriptorTask[T_fd]):
async def memfd_create(self, name: WrittenPointer[t.Union[str, os.PathLike]], flags: MFD=MFD.NONE) -> T_fd:
with name.borrow(self) as name_n:
fd = await _memfd_create(self.sysif, name_n, flags|MFD.CLOEXEC)
return self.make_fd_handle(fd)
#### Raw syscalls ####
import rsyscall.near.types as near
from rsyscall.near.sysif import SyscallInterface
from rsyscall.sys.syscall import SYS
async def _memfd_create(sysif: SyscallInterface,
name: near.Address, flags: MFD) -> near.FileDescriptor:
return near.FileDescriptor(await sysif.syscall(SYS.memfd_create, name, flags))
Classes
class MFD (value, names=None, *, module=None, qualname=None, type=None, start=1)
-
An enumeration.
Expand source code Browse git
class MFD(enum.IntFlag): NONE = 0 CLOEXEC = lib.MFD_CLOEXEC ALLOW_SEALING = lib.MFD_ALLOW_SEALING HUGETLB = lib.MFD_HUGETLB HUGE_2MB = lib.MFD_HUGE_2MB HUGE_1GB = lib.MFD_HUGE_1GB
Ancestors
- enum.IntFlag
- builtins.int
- enum.Flag
- enum.Enum
Class variables
var NONE
var CLOEXEC
var ALLOW_SEALING
var HUGETLB
var HUGE_2MB
var HUGE_1GB
class MemfdTask (sysif: SyscallInterface, near_process: Process, fd_table: FDTable, address_space: AddressSpace, pidns: PidNamespace)
-
A wrapper around
SyscallInterface
which tracks the namespaces of the underlying processNote that this is a base class for the more fully featured
Task
.We store namespace objects to represent the namespaces that we believe that underlying processes is in. Since we have complete control over the process, we can make sure this belief is accurate, by updating our stored namespaces when the process changes namespace. That isn't done here; it's done in handle.Task.
Currently, we store only one
PidNamespace
. But each process actually has two pid namespaces:- the process's own pid namespace, which determines the pids returned from getpid, clone, and other syscalls.
- the pid namespace that new children will be in.
The two pid namespaces only differ if we call unshare(CLONE.NEWPID). Currently we don't do that because unshare(CLONE.NEWPID) makes monitoring children more complex, since they can be deleted without leaving a zombie at any time if the pid namespace shuts down. But if we did call unshare(CLONE.NEWPID), we'd need to handle this right.
In the analogy to near and far pointers, this is like a segment register, if a segment register was write-only. Then we'd need to maintain the knowledge of what the segment register was set to, outside the segment register itself. That's what we do here.
There actually were systems where segment registers were, if not quite write-only, at least expensive to set and expensive to read. For example, x86_64 - the FS and GS segment registers can only be set via syscall. If you wanted to use segmentation on such systems, you'd probably have a structure much like this one.
Expand source code Browse git
class MemfdTask(FileDescriptorTask[T_fd]): async def memfd_create(self, name: WrittenPointer[t.Union[str, os.PathLike]], flags: MFD=MFD.NONE) -> T_fd: with name.borrow(self) as name_n: fd = await _memfd_create(self.sysif, name_n, flags|MFD.CLOEXEC) return self.make_fd_handle(fd)
Ancestors
- FileDescriptorTask
- Task
- typing.Generic
Subclasses
Class variables
var sysif : SyscallInterface
var near_process : Process
var fd_table : FDTable
var address_space : AddressSpace
var pidns : PidNamespace
Methods
async def memfd_create(self, name: WrittenPointer[t.Union[str, os.PathLike]], flags: MFD = MFD.NONE) ‑> T_fd
-
Expand source code Browse git
async def memfd_create(self, name: WrittenPointer[t.Union[str, os.PathLike]], flags: MFD=MFD.NONE) -> T_fd: with name.borrow(self) as name_n: fd = await _memfd_create(self.sysif, name_n, flags|MFD.CLOEXEC) return self.make_fd_handle(fd)
Inherited members