portable

package
v0.27.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 14, 2023 License: Apache-2.0 Imports: 7 Imported by: 1

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL