[lxc-devel] [lxd/master] Improve cluster performance a bit

stgraber on Github lxc-bot at linuxcontainers.org
Tue Aug 7 03:33:17 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 401 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180807/5e28fec8/attachment.bin>
-------------- next part --------------
From ac0092d3efe0104c611431f50c45abe89fe5a092 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 6 Aug 2018 17:27:48 -0400
Subject: [PATCH 1/4] lxd/containers: Use internal struct values
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/container_lxc.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 05d19220dc..1ae39c1034 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -3035,7 +3035,7 @@ func (c *containerLXC) Render() (interface{}, interface{}, error) {
 			Location:        c.node,
 		}
 
-		ct.Description = c.Description()
+		ct.Description = c.description
 		ct.Architecture = architectureName
 		ct.Config = c.localConfig
 		ct.CreatedAt = c.creationDate

From e42b054dd289e6c279f21001fb1b26132f678ec6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 6 Aug 2018 17:56:53 -0400
Subject: [PATCH 2/4] networks: Ignore veth devices
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This should significantly shorten the number of interfaces we deal with
when iterating through networks.

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/networks.go       |  5 +++++
 lxd/networks_utils.go | 11 +++++++++++
 2 files changed, 16 insertions(+)

diff --git a/lxd/networks.go b/lxd/networks.go
index f4406d05eb..7b8e0a710c 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -373,6 +373,11 @@ func networkGet(d *Daemon, r *http.Request) Response {
 }
 
 func doNetworkGet(d *Daemon, name string) (api.Network, error) {
+	// Ignore veth pairs (for performance reasons)
+	if strings.HasPrefix(name, "veth") {
+		return api.Network{}, os.ErrNotExist
+	}
+
 	// Get some information
 	osInfo, _ := net.InterfaceByName(name)
 	_, dbInfo, _ := d.cluster.NetworkGet(name)
diff --git a/lxd/networks_utils.go b/lxd/networks_utils.go
index 7ee6cfd835..f2ac915651 100644
--- a/lxd/networks_utils.go
+++ b/lxd/networks_utils.go
@@ -90,6 +90,12 @@ func networkGetInterfaces(cluster *db.Cluster) ([]string, error) {
 	}
 
 	for _, iface := range ifaces {
+		// Ignore veth pairs (for performance reasons)
+		if strings.HasPrefix(iface.Name, "veth") {
+			continue
+		}
+
+		// Append to the list
 		if !shared.StringInSlice(iface.Name, networks) {
 			networks = append(networks, iface.Name)
 		}
@@ -463,6 +469,11 @@ func networkDefaultGatewaySubnetV4() (*net.IPNet, string, error) {
 }
 
 func networkValidName(value string) error {
+	// Not a veth-liked name
+	if strings.HasPrefix(value, "veth") {
+		return fmt.Errorf("Interface name cannot be prefix with veth")
+	}
+
 	// Validate the length
 	if len(value) < 2 {
 		return fmt.Errorf("Interface name is too short (minimum 2 characters)")

From 97be1fd8cb980d85dfd3e33b0efcbeffad3a356e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 6 Aug 2018 17:57:41 -0400
Subject: [PATCH 3/4] networks: Don't try listing containers for lo
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/networks.go | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/lxd/networks.go b/lxd/networks.go
index 7b8e0a710c..66b21a4c56 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -393,23 +393,6 @@ func doNetworkGet(d *Daemon, name string) (api.Network, error) {
 	n.UsedBy = []string{}
 	n.Config = map[string]string{}
 
-	// Look for containers using the interface
-	cts, err := d.cluster.ContainersList(db.CTypeRegular)
-	if err != nil {
-		return api.Network{}, err
-	}
-
-	for _, ct := range cts {
-		c, err := containerLoadByName(d.State(), ct)
-		if err != nil {
-			return api.Network{}, err
-		}
-
-		if networkIsInUse(c, n.Name) {
-			n.UsedBy = append(n.UsedBy, fmt.Sprintf("/%s/containers/%s", version.APIVersion, ct))
-		}
-	}
-
 	// Set the device type as needed
 	if osInfo != nil && shared.IsLoopback(osInfo) {
 		n.Type = "loopback"
@@ -436,6 +419,25 @@ func doNetworkGet(d *Daemon, name string) (api.Network, error) {
 		}
 	}
 
+	// Look for containers using the interface
+	if n.Type != "loopback" {
+		cts, err := d.cluster.ContainersList(db.CTypeRegular)
+		if err != nil {
+			return api.Network{}, err
+		}
+
+		for _, ct := range cts {
+			c, err := containerLoadByName(d.State(), ct)
+			if err != nil {
+				return api.Network{}, err
+			}
+
+			if networkIsInUse(c, n.Name) {
+				n.UsedBy = append(n.UsedBy, fmt.Sprintf("/%s/containers/%s", version.APIVersion, ct))
+			}
+		}
+	}
+
 	if dbInfo != nil {
 		n.Status = dbInfo.Status
 		n.Locations = dbInfo.Locations

From 9776cbd7d3c77ed188ca195957bd90c3281c4f78 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 6 Aug 2018 18:18:36 -0400
Subject: [PATCH 4/4] lxd/cluster: Only query the containers we need
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/containers.go            |  2 +-
 lxd/daemon.go                |  2 +-
 lxd/devices.go               | 13 +++++++------
 lxd/devlxd.go                |  2 +-
 lxd/logging.go               |  2 +-
 lxd/main_activateifneeded.go |  2 +-
 lxd/networks_utils.go        |  2 +-
 lxd/patches.go               | 14 +++++++-------
 lxd/storage_lvm_utils.go     |  2 +-
 9 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/lxd/containers.go b/lxd/containers.go
index aa0da82a8d..b7a171c441 100644
--- a/lxd/containers.go
+++ b/lxd/containers.go
@@ -200,7 +200,7 @@ func containersShutdown(s *state.State) error {
 	dbAvailable := true
 
 	// Get all the containers
-	results, err := s.Cluster.ContainersList(db.CTypeRegular)
+	results, err := s.Cluster.ContainersNodeList(db.CTypeRegular)
 	if err != nil {
 		// Mark database as offline
 		dbAvailable = false
diff --git a/lxd/daemon.go b/lxd/daemon.go
index 9eb6479216..354c493033 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -696,7 +696,7 @@ func (d *Daemon) Ready() error {
 }
 
 func (d *Daemon) numRunningContainers() (int, error) {
-	results, err := d.cluster.ContainersList(db.CTypeRegular)
+	results, err := d.cluster.ContainersNodeList(db.CTypeRegular)
 	if err != nil {
 		return 0, err
 	}
diff --git a/lxd/devices.go b/lxd/devices.go
index ed573980d1..fde7f1f174 100644
--- a/lxd/devices.go
+++ b/lxd/devices.go
@@ -652,11 +652,12 @@ func deviceTaskBalance(s *state.State) {
 	}
 
 	// Iterate through the containers
-	containers, err := s.Cluster.ContainersList(db.CTypeRegular)
+	containers, err := s.Cluster.ContainersNodeList(db.CTypeRegular)
 	if err != nil {
 		logger.Error("Problem loading containers list", log.Ctx{"err": err})
 		return
 	}
+
 	fixedContainers := map[int][]container{}
 	balancedContainers := map[container]int{}
 	for _, name := range containers {
@@ -778,7 +779,7 @@ func deviceNetworkPriority(s *state.State, netif string) {
 		return
 	}
 
-	containers, err := s.Cluster.ContainersList(db.CTypeRegular)
+	containers, err := s.Cluster.ContainersNodeList(db.CTypeRegular)
 	if err != nil {
 		return
 	}
@@ -809,7 +810,7 @@ func deviceNetworkPriority(s *state.State, netif string) {
 }
 
 func deviceUSBEvent(s *state.State, usb usbDevice) {
-	containers, err := s.Cluster.ContainersList(db.CTypeRegular)
+	containers, err := s.Cluster.ContainersNodeList(db.CTypeRegular)
 	if err != nil {
 		logger.Error("Problem loading containers list", log.Ctx{"err": err})
 		return
@@ -1857,7 +1858,7 @@ func deviceInotifyDirDeleteEvent(s *state.State, target *sys.InotifyTargetInfo)
 }
 
 func deviceInotifyDirRescan(s *state.State) {
-	containers, err := s.Cluster.ContainersList(db.CTypeRegular)
+	containers, err := s.Cluster.ContainersNodeList(db.CTypeRegular)
 	if err != nil {
 		logger.Errorf("Failed to load containers: %s", err)
 		return
@@ -1922,7 +1923,7 @@ func deviceInotifyDirCreateEvent(s *state.State, target *sys.InotifyTargetInfo)
 		return
 	}
 
-	containers, err := s.Cluster.ContainersList(db.CTypeRegular)
+	containers, err := s.Cluster.ContainersNodeList(db.CTypeRegular)
 	if err != nil {
 		logger.Errorf("Failed to load containers: %s", err)
 		return
@@ -2025,7 +2026,7 @@ func deviceInotifyFileEvent(s *state.State, target *sys.InotifyTargetInfo) {
 		return
 	}
 
-	containers, err := s.Cluster.ContainersList(db.CTypeRegular)
+	containers, err := s.Cluster.ContainersNodeList(db.CTypeRegular)
 	if err != nil {
 		logger.Errorf("Failed to load containers: %s", err)
 		return
diff --git a/lxd/devlxd.go b/lxd/devlxd.go
index 2a05bdaa14..cac19791e1 100644
--- a/lxd/devlxd.go
+++ b/lxd/devlxd.go
@@ -467,7 +467,7 @@ func findContainerForPid(pid int32, d *Daemon) (container, error) {
 		return nil, err
 	}
 
-	containers, err := d.cluster.ContainersList(db.CTypeRegular)
+	containers, err := d.cluster.ContainersNodeList(db.CTypeRegular)
 	if err != nil {
 		return nil, err
 	}
diff --git a/lxd/logging.go b/lxd/logging.go
index 3408cd6837..5f3d1be6c7 100644
--- a/lxd/logging.go
+++ b/lxd/logging.go
@@ -41,7 +41,7 @@ func expireLogs(ctx context.Context, state *state.State) error {
 	var containers []string
 	ch := make(chan struct{})
 	go func() {
-		containers, err = state.Cluster.ContainersList(db.CTypeRegular)
+		containers, err = state.Cluster.ContainersNodeList(db.CTypeRegular)
 		ch <- struct{}{}
 	}()
 	select {
diff --git a/lxd/main_activateifneeded.go b/lxd/main_activateifneeded.go
index b7a8927418..2f4989645a 100644
--- a/lxd/main_activateifneeded.go
+++ b/lxd/main_activateifneeded.go
@@ -105,7 +105,7 @@ func (c *cmdActivateifneeded) Run(cmd *cobra.Command, args []string) error {
 	}
 
 	d.cluster = db.ForLocalInspection(sqldb)
-	result, err := d.cluster.ContainersList(db.CTypeRegular)
+	result, err := d.cluster.ContainersNodeList(db.CTypeRegular)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/networks_utils.go b/lxd/networks_utils.go
index f2ac915651..4c63e29dd1 100644
--- a/lxd/networks_utils.go
+++ b/lxd/networks_utils.go
@@ -759,7 +759,7 @@ func networkUpdateStatic(s *state.State, networkName string) error {
 	defer networkStaticLock.Unlock()
 
 	// Get all the containers
-	containers, err := s.Cluster.ContainersList(db.CTypeRegular)
+	containers, err := s.Cluster.ContainersNodeList(db.CTypeRegular)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/patches.go b/lxd/patches.go
index bba4d9894c..2e5d740ecf 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -213,13 +213,13 @@ func patchStorageApi(name string, d *Daemon) error {
 	// Check if this LXD instace currently has any containers, snapshots, or
 	// images configured. If so, we create a default storage pool in the
 	// database. Otherwise, the user will have to run LXD init.
-	cRegular, err := d.cluster.ContainersList(db.CTypeRegular)
+	cRegular, err := d.cluster.ContainersNodeList(db.CTypeRegular)
 	if err != nil {
 		return err
 	}
 
 	// Get list of existing snapshots.
-	cSnapshots, err := d.cluster.ContainersList(db.CTypeSnapshot)
+	cSnapshots, err := d.cluster.ContainersNodeList(db.CTypeSnapshot)
 	if err != nil {
 		return err
 	}
@@ -1881,13 +1881,13 @@ func patchStorageApiV1(name string, d *Daemon) error {
 		return nil
 	}
 
-	cRegular, err := d.cluster.ContainersList(db.CTypeRegular)
+	cRegular, err := d.cluster.ContainersNodeList(db.CTypeRegular)
 	if err != nil {
 		return err
 	}
 
 	// Get list of existing snapshots.
-	cSnapshots, err := d.cluster.ContainersList(db.CTypeSnapshot)
+	cSnapshots, err := d.cluster.ContainersNodeList(db.CTypeSnapshot)
 	if err != nil {
 		return err
 	}
@@ -2651,7 +2651,7 @@ func patchStorageApiCephSizeRemove(name string, d *Daemon) error {
 }
 
 func patchDevicesNewNamingScheme(name string, d *Daemon) error {
-	cts, err := d.cluster.ContainersList(db.CTypeRegular)
+	cts, err := d.cluster.ContainersNodeList(db.CTypeRegular)
 	if err != nil {
 		logger.Errorf("Failed to retrieve containers from database")
 		return err
@@ -2978,7 +2978,7 @@ func patchUpdateFromV10(d *Daemon) error {
 }
 
 func patchUpdateFromV11(d *Daemon) error {
-	cNames, err := d.cluster.ContainersList(db.CTypeSnapshot)
+	cNames, err := d.cluster.ContainersNodeList(db.CTypeSnapshot)
 	if err != nil {
 		return err
 	}
@@ -3049,7 +3049,7 @@ func patchUpdateFromV15(d *Daemon) error {
 	// munge all LVM-backed containers' LV names to match what is
 	// required for snapshot support
 
-	cNames, err := d.cluster.ContainersList(db.CTypeRegular)
+	cNames, err := d.cluster.ContainersNodeList(db.CTypeRegular)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/storage_lvm_utils.go b/lxd/storage_lvm_utils.go
index 3231d365aa..825fb5eab6 100644
--- a/lxd/storage_lvm_utils.go
+++ b/lxd/storage_lvm_utils.go
@@ -732,7 +732,7 @@ func storageLVMThinpoolExists(vgName string, poolName string) (bool, error) {
 func storageLVMGetThinPoolUsers(s *state.State) ([]string, error) {
 	results := []string{}
 
-	cNames, err := s.Cluster.ContainersList(db.CTypeRegular)
+	cNames, err := s.Cluster.ContainersNodeList(db.CTypeRegular)
 	if err != nil {
 		return results, err
 	}


More information about the lxc-devel mailing list