This patch adds new hvparam "lxc_devices" to the LXC hypervisor.
This parameter specifies the access control list for direct device
access from inside the LXC container.
The default value of this parameter was hardcoded, but making this
parameter as a hvparam is worth for users customizability.

Signed-off-by: Yuto KAWAMURA(kawamuray) <[email protected]>
---
 lib/hypervisor/hv_lxc.py | 18 ++++--------------
 man/gnt-instance.rst     | 23 +++++++++++++++++++++++
 src/Ganeti/Constants.hs  | 20 ++++++++++++++++++++
 3 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/lib/hypervisor/hv_lxc.py b/lib/hypervisor/hv_lxc.py
index 8594628..9d1f12a 100644
--- a/lib/hypervisor/hv_lxc.py
+++ b/lib/hypervisor/hv_lxc.py
@@ -70,18 +70,6 @@ class LXCHypervisor(hv_base.BaseHypervisor):
     "lxc-wait",
     ]
 
-  _DEVS = [
-    "c 1:3",   # /dev/null
-    "c 1:5",   # /dev/zero
-    "c 1:7",   # /dev/full
-    "c 1:8",   # /dev/random
-    "c 1:9",   # /dev/urandom
-    "c 1:10",  # /dev/aio
-    "c 5:0",   # /dev/tty
-    "c 5:1",   # /dev/console
-    "c 5:2",   # /dev/ptmx
-    "c 136:*", # first block of Unix98 PTY slaves
-    ]
   _DIR_MODE = 0755
   _UNIQ_SUFFIX = ".conf"
   _STASH_KEY_ALLOCATED_LOOP_DEV = "allocated_loopdev"
@@ -89,6 +77,7 @@ class LXCHypervisor(hv_base.BaseHypervisor):
   PARAMETERS = {
     constants.HV_CPU_MASK: hv_base.OPT_CPU_MASK_CHECK,
     constants.HV_LXC_CGROUP_USE: hv_base.NO_CHECK,
+    constants.HV_LXC_DEVICES: hv_base.NO_CHECK,
     constants.HV_LXC_DROP_CAPABILITIES: hv_base.NO_CHECK,
     constants.HV_LXC_STARTUP_WAIT: hv_base.OPT_NONNEGATIVE_INT_CHECK,
     }
@@ -513,8 +502,9 @@ class LXCHypervisor(hv_base.BaseHypervisor):
     # Device control
     # deny direct device access
     out.append("lxc.cgroup.devices.deny = a")
-    for devinfo in self._DEVS:
-      out.append("lxc.cgroup.devices.allow = %s rw" % devinfo)
+    dev_specs = instance.hvparams[constants.HV_LXC_DEVICES]
+    for dev_spec in dev_specs.split(","):
+      out.append("lxc.cgroup.devices.allow = %s" % dev_spec)
 
     # Networking
     for idx, nic in enumerate(instance.nics):
diff --git a/man/gnt-instance.rst b/man/gnt-instance.rst
index 45b708b..1e00a54 100644
--- a/man/gnt-instance.rst
+++ b/man/gnt-instance.rst
@@ -918,6 +918,29 @@ lxc\_drop\_capabilities
 
     It is set to ``mac_override,sys_boot,sys_module,sys_time`` by default.
 
+lxc\_devices
+    Valid for the LXC hypervisor.
+
+    This option specifies the list of devices should be allowed to be
+    accessed from the inside of the LXC container.
+    The each value of this option must be in the form as same as the
+    lxc.cgroup.devices.allow configuration parameter of the
+    **lxc.container.conf**\(5). It is consisted from the type(a: all,
+    b: block, c: character), the major-minor pair, and the access type
+    sequence(r: read, w: write, m: mknod) which is like: "c 1:3 rw".
+    If you'd like to allow the LXC container to access /dev/null and
+    /dev/zero with read-write access, you can set this parameter as:
+    "c 1:3 rw,c 1:5 rw".
+    The LXC hypervisor drops all direct device access by default, so
+    if you want to allow the LXC container to access an additional
+    device which is not included in the default value of this
+    parameter, you have to set this parameter manually.
+
+    By default, this parameter contains (/dev/null, /dev/zero,
+    /dev/full, /dev/random, /dev/urandom, /dev/aio, /dev/tty,
+    /dev/console, /dev/ptmx and first block of Unix98 PTY slaves) with
+    read-writable(rw) access.
+
 The ``-O (--os-parameters)`` option allows customisation of the OS
 parameters. The actual parameter names and values depend on the OS being
 used, but the syntax is the same key=value. For example, setting a
diff --git a/src/Ganeti/Constants.hs b/src/Ganeti/Constants.hs
index d317361..4d8d420 100644
--- a/src/Ganeti/Constants.hs
+++ b/src/Ganeti/Constants.hs
@@ -520,6 +520,21 @@ socatUseEscape :: Bool
 socatUseEscape = AutoConf.socatUseEscape
 
 -- * LXC
+-- If you are trying to change the value of these default constants, you also
+-- need to edit the default value declaration in man/gnt-instance.rst.
+lxcDevicesDefault :: String
+lxcDevicesDefault =
+     "c 1:3 rw"     -- /dev/null
+  ++ ",c 1:5 rw"    -- /dev/zero
+  ++ ",c 1:7 rw"    -- /dev/full
+  ++ ",c 1:8 rw"    -- /dev/random
+  ++ ",c 1:9 rw"    -- /dev/urandom
+  ++ ",c 1:10 rw"   -- /dev/aio
+  ++ ",c 5:0 rw"    -- /dev/tty
+  ++ ",c 5:1 rw"    -- /dev/console
+  ++ ",c 5:2 rw"    -- /dev/ptmx
+  ++ ",c 136:* rw"  -- first block of Unix98 PTY slaves
+
 lxcDropCapabilitiesDefault :: String
 lxcDropCapabilitiesDefault =
      "mac_override" -- Allow MAC configuration or state changes
@@ -1677,6 +1692,9 @@ hvLxcStartupWait = "lxc_startup_wait"
 hvLxcCgroupUse :: String
 hvLxcCgroupUse = "lxc_cgroup_use"
 
+hvLxcDevices :: String
+hvLxcDevices = "lxc_devices"
+
 hvLxcDropCapabilities :: String
 hvLxcDropCapabilities = "lxc_drop_capabilities"
 
@@ -1843,6 +1861,7 @@ hvsParameterTypes = Map.fromList
   , (hvKvmUseChroot,                    VTypeBool)
   , (hvKvmUserShutdown,                 VTypeBool)
   , (hvLxcCgroupUse,                    VTypeString)
+  , (hvLxcDevices,                      VTypeString)
   , (hvLxcDropCapabilities,             VTypeString)
   , (hvLxcStartupWait,                  VTypeInt)
   , (hvMemPath,                         VTypeString)
@@ -3926,6 +3945,7 @@ hvcDefaults =
   , (Lxc, Map.fromList
           [ (hvCpuMask,             PyValueEx "")
           , (hvLxcCgroupUse,        PyValueEx "")
+          , (hvLxcDevices,          PyValueEx lxcDevicesDefault)
           , (hvLxcDropCapabilities, PyValueEx lxcDropCapabilitiesDefault)
           , (hvLxcStartupWait,      PyValueEx (30 :: Int))
           ])
-- 
2.0.4

Reply via email to