[lxc-devel] [lxd/master] Device Interface PoC

tomponline on Github lxc-bot at linuxcontainers.org
Tue Jul 2 10:03:49 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 408 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190702/4221b62e/attachment-0001.bin>
-------------- next part --------------
From 69aece765e1bae31a67187adf198bc278a8ba2ad Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 2 Jul 2019 11:01:57 +0100
Subject: [PATCH 1/2] device: Adds new device interface and PoC physical
 implementation

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/device/device.go          | 71 +++++++++++++++++++++++++++++++++++
 lxd/device/device_physical.go | 27 +++++++++++++
 2 files changed, 98 insertions(+)
 create mode 100644 lxd/device/device.go
 create mode 100644 lxd/device/device_physical.go

diff --git a/lxd/device/device.go b/lxd/device/device.go
new file mode 100644
index 0000000000..dfa90b1b5b
--- /dev/null
+++ b/lxd/device/device.go
@@ -0,0 +1,71 @@
+package device
+
+import (
+	"fmt"
+)
+
+// ErrUnsupportedDevType is the error that occurs when an unsupported device type is created.
+var ErrUnsupportedDevType = fmt.Errorf("Unsupported device type")
+
+// Config represents user defined persistent config for a device.
+type Config map[string]string
+
+// VolatileConfig represents LXD defined persistent config for a device.
+type VolatileConfig map[string]string
+
+// RunConfig represents LXD defined run-time config used for device setup.
+type RunConfig map[string]string
+
+// Device represents a device that can be added to an instance.
+type Device interface {
+	// SetConfig checks the contents of DeviceConfig for correctness and stores in device.
+	SetConfig(string, Config) error
+
+	// Start peforms any host-side configuration required to setup the device for the instance.
+	// This can be when a device is plugged into a running instance or the instance is starting.
+	// VolatileConfig from previous instantiations of this device is required.
+	// It returns run-time configuration neccessary for configuring the instance with the new
+	// device and any changes to VolatileConfig that need to be persisted.
+	Start(VolatileConfig) (RunConfig, VolatileConfig, error)
+
+	// Stop performs any host-side cleanup required when a device is removed from an instance,
+	// either due to unplugging it from a running instance or instance is being shutdown.
+	// VolatileConfig from previous instantiations of this device is required.
+	// It return sany changes to VolatileConfig that need to be persisted.
+	Stop(VolatileConfig) (VolatileConfig, error)
+}
+
+// deviceCommon represents the common struct for all devices.
+type deviceCommon struct {
+	instanceType string
+	config       map[string]string
+}
+
+// SetConfig validates the supplied config and stores inside the device.
+func (d *deviceCommon) SetConfig(instanceType string, conf Config) error {
+	d.instanceType = instanceType
+	d.config = conf
+	return nil
+}
+
+// New instantiates a new device struct, validates the supplied config and sets it into the device.
+func New(instanceType string, devConfig Config) (Device, error) {
+	var d Device
+	if devConfig["type"] == "nic" {
+		switch devConfig["nictype"] {
+		case "physical":
+			d = &devicePhysical{}
+		default:
+			return d, ErrUnsupportedDevType
+		}
+	} else {
+		return d, ErrUnsupportedDevType
+	}
+
+	err := d.SetConfig(instanceType, devConfig)
+	if err != nil {
+		return d, err
+	}
+
+	return d, nil
+}
diff --git a/lxd/device/device_physical.go b/lxd/device/device_physical.go
new file mode 100644
index 0000000000..f46cc37de8
--- /dev/null
+++ b/lxd/device/device_physical.go
@@ -0,0 +1,27 @@
+package device
+
+import (
+	"github.com/lxc/lxd/shared/logger"
+)
+
+type devicePhysical struct {
+	deviceCommon
+}
+
+func (d *devicePhysical) Start(v VolatileConfig) (RunConfig, VolatileConfig, error) {
+	runConf := make(RunConfig)
+	volatileSave := make(VolatileConfig)
+	logger.Errorf("Physical nic started: %v %v", d.config, v)
+
+	runConf["type"] = "phys"
+	runConf["flags"] = "up"
+	runConf["link"] = d.config["parent"]
+	runConf["name"] = d.config["name"]
+
+	return runConf, volatileSave, nil
+}
+
+func (d *devicePhysical) Stop(v VolatileConfig) (VolatileConfig, error) {
+	volatileSave := make(VolatileConfig)
+	return volatileSave, nil
+}

From 90957bc7f9b4fa7f57c53bdabd20c9795de0903e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 2 Jul 2019 11:02:26 +0100
Subject: [PATCH 2/2] container/lxc: Wires up physical device interface to LXC

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/container_lxc.go | 45 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 42 insertions(+), 3 deletions(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index fce12c64f8..03ae25e728 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -30,6 +30,7 @@ import (
 	"github.com/lxc/lxd/lxd/cluster"
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/db/query"
+	"github.com/lxc/lxd/lxd/device"
 	"github.com/lxc/lxd/lxd/maas"
 	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/lxd/template"
@@ -1646,15 +1647,41 @@ func (c *containerLXC) initLXC(config bool) error {
 				return err
 			}
 		} else if m["type"] == "nic" || m["type"] == "infiniband" {
+			networkKeyPrefix := "lxc.net"
+			if !util.RuntimeLiblxcVersionAtLeast(2, 1, 0) {
+				networkKeyPrefix = "lxc.network"
+			}
+
 			// Fill in some fields from volatile
 			m, err = c.fillNetworkDevice(k, m)
 			if err != nil {
 				return err
 			}
 
-			networkKeyPrefix := "lxc.net"
-			if !util.RuntimeLiblxcVersionAtLeast(2, 1, 0) {
-				networkKeyPrefix = "lxc.network"
+			d, err := device.New("ct", m)
+			if err != nil && err != device.ErrUnsupportedDevType {
+				return err
+			}
+
+			if err != device.ErrUnsupportedDevType {
+				runConfig, saveVolatile, err := d.Start(c.deviceVolatile(k))
+				if err != nil {
+					return err
+				}
+
+				err = c.VolatileSet(saveVolatile)
+				if err != nil {
+					return err
+				}
+
+				for dk, dv := range runConfig {
+					err = lxcSetConfigItem(cc, fmt.Sprintf("%s.%d.%s", networkKeyPrefix, networkidx, dk), dv)
+					if err != nil {
+						return err
+					}
+				}
+
+				continue
 			}
 
 			// Interface type specific configuration
@@ -1897,6 +1924,17 @@ func (c *containerLXC) initLXC(config bool) error {
 	return nil
 }
 
+func (c *containerLXC) deviceVolatile(devName string) map[string]string {
+	volatile := make(map[string]string)
+	prefix := fmt.Sprintf("volatile.%s.", devName)
+	for k, v := range c.localConfig {
+		if strings.HasPrefix(k, prefix) {
+			volatile[strings.TrimPrefix(k, prefix)] = v
+		}
+	}
+	return volatile
+}
+
 // initLXCIPVLAN runs as part of initLXC function and initialises liblxc with the IPVLAN config.
 func (c *containerLXC) initLXCIPVLAN(cc *lxc.Container, networkKeyPrefix string, networkidx int, m map[string]string) error {
 	err := c.checkIPVLANSupport()
@@ -2421,6 +2459,7 @@ func (c *containerLXC) startCommon() (string, error) {
 			}
 		} else if m["type"] == "nic" || m["type"] == "infiniband" {
 			var err error
+
 			var infiniband map[string]IBF
 			if m["type"] == "infiniband" {
 				infiniband, err = deviceLoadInfiniband()


More information about the lxc-devel mailing list