Module: HrrRbLxns

Includes:
Constants
Defined in:
lib/hrr_rb_lxns.rb,
lib/hrr_rb_lxns/files.rb,
lib/hrr_rb_lxns/version.rb,
lib/hrr_rb_lxns/files/file.rb,
ext/hrr_rb_lxns/hrr_rb_lxns.c

Overview

Utilities working with Linux namespaces for CRuby.

Defined Under Namespace

Modules: Constants Classes: Files

Constant Summary collapse

VERSION =
"0.3.0"
@@namespaces =
Hash.new

Constants included from Constants

Constants::BOOTTIME, Constants::MONOTONIC, Constants::NEWCGROUP, Constants::NEWIPC, Constants::NEWNET, Constants::NEWNS, Constants::NEWPID, Constants::NEWTIME, Constants::NEWUSER, Constants::NEWUTS

Class Method Summary collapse

Class Method Details

.__setns__(fd, nstype) ⇒ Integer

A primitive wrapper around setns(2) system call. Associates the caller with the corresponding namespace of the given fd.

Examples:

pid = fork do
  File.readlink "/proc/self/ns/uts"       # => uts:[xxx]
  HrrRbLxns.__unshare__ HrrRbLxns::NEWUTS # => 0
  File.readlink "/proc/self/ns/uts"       # => uts:[yyy]
  sleep
end
File.readlink "/proc/self/ns/uts"                  # => uts:[xxx]
fd = File.open "/proc/#{pid}/ns/uts", File::RDONLY
HrrRbLxns.__setns__ fd.fileno, HrrRbLxns::NEWUTS   # => 0
fd.close
File.readlink "/proc/self/ns/uts"                  # => uts:[yyy]

Parameters:

  • fd (Integer)

    The file descriptor number to associate.

  • nstype (Integer)

    Represents the namespace to associate.

Returns:

  • (Integer)

    0.

Raises:

  • (TypeError)

    In case the given fd cannot be converted to integer or the given nstype cannot be converted to integer.

  • (Errno::EXXX)

    In case setns(2) system call failed.


64
65
66
67
68
69
70
71
# File 'ext/hrr_rb_lxns/hrr_rb_lxns.c', line 64

VALUE
hrr_rb_lxns_setns(VALUE self, VALUE fd, VALUE nstype)
{
  if (setns(NUM2INT(fd), NUM2INT(nstype)) < 0)
    rb_sys_fail("setns");

  return INT2FIX(0);
}

.__unshare__(flags) ⇒ Integer

A primitive wrapper around unshare(2) system call. Disassociates parts of the caller process's execution context.

Examples:

# Disassociates uts namespace
File.readlink "/proc/self/ns/uts"       # => uts:[aaa]
HrrRbLxns.__unshare__ HrrRbLxns::NEWUTS # => 0
File.readlink "/proc/self/ns/uts"       # => uts:[xxx]

# Disassociates uts and mount namespaces
File.readlink "/proc/self/ns/uts"                          # => uts:[aaa]
File.readlink "/proc/self/ns/mnt"                          # => mnt:[bbb]
HrrRbLxns.__unshare__ HrrRbLxns::NEWUTS | HrrRbLxns::NEWNS # => 0
File.readlink "/proc/self/ns/uts"                          # => uts:[xxx]
File.readlink "/proc/self/ns/mnt"                          # => mnt:[yyy]

Parameters:

  • flags (Integer)

    Represents the namespaces to disassociate.

Returns:

  • (Integer)

    0.

Raises:

  • (TypeError)

    In case the given flags cannot be converted to integer.

  • (Errno::EXXX)

    In case unshare(2) system call failed.


32
33
34
35
36
37
38
39
# File 'ext/hrr_rb_lxns/hrr_rb_lxns.c', line 32

VALUE
hrr_rb_lxns_unshare(VALUE self, VALUE flags)
{
  if (unshare(NUM2INT(flags)) < 0)
    rb_sys_fail("unshare");

  return INT2FIX(0);
}

.files(pid = "self") ⇒ HrrRbLxns::Files

Collects namespace files information in /proc/PID/ns/ directory of a process.

Examples:

# Collects the caller process's or a specific process's namespace files information
files = HrrRbLxns.files
files = HrrRbLxns.files 12345
files.uts.path # => "/proc/12345/ns/uts"

Parameters:

  • pid (Integer, String) (defaults to: "self")

    The pid of a process to collect namespace files information. If nil, assumes that it is the caller process.

Returns:


34
35
36
# File 'lib/hrr_rb_lxns.rb', line 34

def self.files pid="self"
  Files.new pid
end

.setns(flags, pid, options = {}) ⇒ Integer

A wrapper around setns(2) system call.

Examples:

pid = fork do
  # Disassociates uts namespace
  File.readlink "/proc/self/ns/uts"    # => uts:[xxx]
  HrrRbLxns.unshare HrrRbLxns::NEWUTS  # => 0
  File.readlink "/proc/self/ns/uts"    # => uts:[yyy]
  sleep
end
# Aassociates uts namespace
File.readlink "/proc/self/ns/uts"      # => uts:[xxx]
HrrRbLxns.setns HrrRbLxns::NEWUTS, pid # => 0
File.readlink "/proc/self/ns/uts"      # => uts:[yyy]

Parameters:

  • flags (Integer)

    An integer value that represents namespaces to associate.

  • flags (String)

    A string that represents namespaces. The mapping of charactors and flags are:
    “i” : NEWIPC
    “m” : NEWNS
    “n” : NEWNET
    “p” : NEWPID
    “u” : NEWUTS
    “U” : NEWUSER
    “C” : NEWCGROUP
    “T” : NEWTIME

  • pid (Integer)

    Specifies a target process('s namespace) which the caller is to associate with. The paths specifying namespaces specified by pid are:
    /proc/pid/ns/mnt : mount namespace
    /proc/pid/ns/uts : uts namespace
    /proc/pid/ns/ipc : ipc namespace
    /proc/pid/ns/net : network namespace
    /proc/pid/ns/pid : pid namespace
    /proc/pid/ns/user : user namespace
    /proc/pid/ns/cgroup : cgroup namespace
    /proc/pid/ns/time : time namespace

  • options (Hash) (defaults to: {})

    Optional arguments.

Options Hash (options):

  • :mount (String)

    A file which specifies the mount namespace to associate with.

  • :uts (String)

    A file which specifies the uts namespace to associate with.

  • :ipc (String)

    A file which specifies the ipc namespace to associate with.

  • :network (String)

    A file which specifies the network namespace to associate with.

  • :pid (String)

    A file which specifies the pid namespace to associate with.

  • :user (String)

    A file which specifies the user namespace to associate with.

  • :cgroup (String)

    A file which specifies the cgroup namespace to associate with.

  • :time (String)

    A file which specifies the time namespace to associate with.

Returns:

  • (Integer)

    0.

Raises:

  • (ArgumentError)

    When given flags argument is not appropriate or when given pid and/or options are not appropriate for the given flags.

  • (Errno::EXXX)

    In case setns(2) system call failed.


142
143
144
145
146
147
# File 'lib/hrr_rb_lxns.rb', line 142

def self.setns flags, pid, options={}
  _flags = interpret_flags flags
  nstype_file_h = get_nstype_file_h _flags, pid, options
  do_setns nstype_file_h
  return 0
end

.unshare(flags, options = {}) ⇒ Integer?

A wrapper around unshare(2) system call.

Examples:

# Disassociates uts namespace
File.readlink "/proc/self/ns/uts"   # => uts:[aaa]
HrrRbLxns.unshare HrrRbLxns::NEWUTS # => 0
File.readlink "/proc/self/ns/uts"   # => uts:[xxx]

# Disassociates uts and mount namespaces
File.readlink "/proc/self/ns/uts"   # => uts:[aaa]
File.readlink "/proc/self/ns/mnt"   # => mnt:[bbb]
HrrRbLxns.unshare "um"              # => 0
File.readlink "/proc/self/ns/uts"   # => uts:[xxx]
File.readlink "/proc/self/ns/mnt"   # => mnt:[yyy]

Parameters:

  • flags (Integer)

    An integer value that represents namespaces to disassociate.

  • flags (String)

    A string that represents namespaces. The mapping of charactors and flags are:
    “i” : NEWIPC
    “m” : NEWNS
    “n” : NEWNET
    “p” : NEWPID
    “u” : NEWUTS
    “U” : NEWUSER
    “C” : NEWCGROUP
    “T” : NEWTIME

  • options (Hash) (defaults to: {})

    Optional arguments.

Options Hash (options):

  • :mount (String)

    A persistent mount namespace to be created by bind mount.

  • :uts (String)

    A persistent uts namespace to be created by bind mount.

  • :ipc (String)

    A persistent ipc namespace to be created by bind mount.

  • :network (String)

    A persistent network namespace to be created by bind mount.

  • :pid (String)

    A persistent pid namespace to be created by bind mount.

  • :user (String)

    A persistent user namespace to be created by bind mount.

  • :cgroup (String)

    A persistent cgroup namespace to be created by bind mount.

  • :time (String)

    A persistent time namespace to be created by bind mount.

  • :fork (Boolean)

    If specified, the caller process forks after unshare.

  • :map_uid (String, Array<String>, Array<#to_i>, Array<Array<#to_i>>)

    If specified, the caller process writes UID map in /proc/PID/uid_map.

  • :map_gid (String, Array<String>, Array<#to_i>, Array<Array<#to_i>>)

    If specified, the caller process writes deny in /proc/PID/setgroups and GID map in /proc/PID/gid_map.

  • :monotonic (Numeric, String)

    If specified, writes monotonic offset in /proc/PID/timens_offsets.

  • :boottime (Numeric, String)

    If specified, writes boottime offset in /proc/PID/timens_offsets.

Returns:

  • (Integer, nil)

    Usually 0. If :fork is specified in options, then PID of the child process in parent, nil in child (as same as Kernel.#fork).

Raises:

  • (ArgumentError)

    When given flags argument is not appropriate.

  • (TypeError)

    When map_uid and/or map_gid value is not appropriate.

  • (Errno::EXXX)

    In case unshare(2) system call failed.


81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/hrr_rb_lxns.rb', line 81

def self.unshare flags, options={}
  _flags = interpret_flags flags
  bind_ns_files_from_child(_flags, options) do
    ret = nil
    map_uid_gid_from_child(_flags, options) do
      ret = __unshare__ _flags
      set_timens_offsets(_flags, options)
    end
    if fork?(options)
      ret = fork
    end
    ret
  end
end