Documentation ¶
Overview ¶
Package portable provides so-called “portable” namespace references with validation and “locking” to the referenced namespace open and thus alive.
There's an unavoidable non-zero timing window between the discovery of namespaces (and their references) and attempting to use them for switching namespaces. In this window, namespace references might become invalid without noticing it at first: when using a namespace ID or a bind-mounted namespace path, in the worst case the old namespace might have been garbage collected, yet the reference might now point to a different namespace with a recycled reference.
To correctly detect such unwanted situations, more namespace-related data is needed to thoroughly cross-check a namespace reference before using it. This cross-check information is represented in form of PortableReference objects. A PortableReference additionally ensures that the namespace cannot change anymore between cross-checking it and using it, for instance with ops.Enter.
Cross-checking, or validation, is done together with “locking” the namespace in one integral step by calling Open() on a given PortableReference. In the following example we've left out proper error checking for sake of brevity:
portref := portable.PortableReference{ ID: 4026531837, Type: species.CLONE_NEWNET, PID: 12345, StartingTime: 1234567890, } lockedref, unlocker, _ := portref.Open() defer unlocker() ops.Execute( func()interface{}{ // do something useful in here while attached to the network namespace... return nil }, lockedref)
Important ¶
Make sure that the returned lockedref doesn't get garbage collected too early. In the above example this is ensured by ops.Executing getting the lockedref passed. Depending on your specific use case you might need to place a runtime.KeepAlive(lockedref) beyond the point where you definitely need the lockedref to be still correctly locked.
Note ¶
As with switching namespaces in Go applications in general, please remember that it is not possible to switch the mount and user namespaces in OS multi-threaded applications.
For mount namespaces consider using github.com/thediveo/lxkns/ops/mountineer.Mountineer instead.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func LocateNamespace ¶
func LocateNamespace(nsid species.NamespaceID, nstype species.NamespaceType) model.Namespace
LocateNamespace tries to recover the path reference to a “lost” namespace based on its ID and type by running a slightly reduced discovery and searching the namestack for the needle (or so). Returns a model.Namespace if successful, otherwise nil. Please see also L[ocateNamespaceInNamespaces] in case a discovery result is ready at hand, thus avoiding the need for an additional namespace discovery.
func LocateNamespaceInNamespaces ¶
func LocateNamespaceInNamespaces(nsid species.NamespaceID, nstype species.NamespaceType, allnamespaces model.AllNamespaces) model.Namespace
LocateNamespaceInNamespaces tries to recover the path reference to a “lost” namespace based on its ID and type, using the specified namespace information (map).
Types ¶
type PortableReference ¶
type PortableReference struct { ID species.NamespaceID // if known, ID of namespace Type species.NamespaceType // if known, type of namespace Path string // if known, filesystem path reference to namespace PID model.PIDType // if known, process for verification Starttime uint64 // if known, start time of process for verification }
PortableReference describes one or several aspects of a portable namespace reference, where portable refers to being transferable between different processes on the same host, but not across different hosts.
func (PortableReference) Open ¶
func (portref PortableReference) Open() (rel relations.Relation, closer func(), err error)
Open opens a portable namespace reference and validates the opened namespace against the information contained in the portable reference.
When the caller supplies a namespace ID instead of a namespace path, then Open will try to locate a suitable namespace path first by running a namespace discovery and trying to find the namespace by its ID, using the path of a match. (See also: LocateNamespace)
When the caller supplies a path and if the namespace referenced by this path doesn't match an optionally specified ID and/or type, then Open fails.
When opening a portable namespace reference, the following checks are carried out (or not), depending on the information supplied:
- just the namespace ID is known, nothing else: namespace is located via ID requiring a discovery.
- namespace ID and type is known: namespace is located ID with discovery, then type is cross-checked.
- just the path is known, nothing else: no checks beyond successfully opening as a namespace.
- path and type is known: cross-checking the type against what has been opened.
- path and ID are known: path is used and checked against the ID.
- path, ID and type are known: path is used and checked against ID and type of namespace.
- (path OR ID) is known, as well as PID and Starttime: additionally checks that process is still around.