[lxc-devel] [lxd/master] Finish replacing Daemon with State also in higher-level entity APIs

freeekanayaka on Github lxc-bot at linuxcontainers.org
Tue Aug 22 22:29:35 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 676 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170822/2f7a0317/attachment.bin>
-------------- next part --------------
From 524f049836529cf7dd11d8cb3d13177096944b5e Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Fri, 18 Aug 2017 07:57:58 +0000
Subject: [PATCH] Finish replacing Daemon with State also in higher-level
 entity APIs

All higher-level entry points to entity-related functionality now
takes a State parameter as opposed to Daemon. With this commit, only
the REST-API layer is still depending direcly on Daemon, and that will
be squashed too in coming branches, effectively paving the ground for
new unit-testing possibilities.

Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
 lxd/api_internal.go          |  2 +-
 lxd/container.go             | 14 +++++++-------
 lxd/container_put.go         |  9 +++++----
 lxd/containers.go            | 14 +++++++-------
 lxd/containers_get.go        | 13 +++++++------
 lxd/containers_post.go       |  8 ++++----
 lxd/daemon.go                | 12 +++++++-----
 lxd/devices.go               | 31 ++++++++++++++++---------------
 lxd/images.go                | 13 +++++++------
 lxd/main_daemon.go           |  9 +++++----
 lxd/networks.go              | 12 ++++++------
 lxd/patches.go               | 11 ++++++-----
 lxd/profiles.go              | 21 +++++++++++----------
 lxd/profiles_utils.go        |  2 +-
 lxd/storage.go               | 18 +++++++++---------
 lxd/storage_pools.go         |  8 ++++----
 lxd/storage_pools_utils.go   | 23 ++++++++++++-----------
 lxd/storage_volumes.go       | 14 +++++++-------
 lxd/storage_volumes_utils.go | 30 +++++++++++++++---------------
 19 files changed, 137 insertions(+), 127 deletions(-)

diff --git a/lxd/api_internal.go b/lxd/api_internal.go
index 371385f60..65ce3375b 100644
--- a/lxd/api_internal.go
+++ b/lxd/api_internal.go
@@ -205,7 +205,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 
 	if poolErr == db.NoSuchObjectError {
 		// Create the storage pool db entry if it doesn't exist.
-		err := storagePoolDBCreate(d, containerPoolName, "", backup.Pool.Driver, backup.Pool.Config)
+		err := storagePoolDBCreate(d.State(), containerPoolName, "", backup.Pool.Driver, backup.Pool.Config)
 		if err != nil {
 			return SmartError(err)
 		}
diff --git a/lxd/container.go b/lxd/container.go
index bcbfcf7dc..295d1c579 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -540,9 +540,9 @@ func containerCreateEmptySnapshot(s *state.State, args db.ContainerArgs) (contai
 	return c, nil
 }
 
-func containerCreateFromImage(d *Daemon, args db.ContainerArgs, hash string) (container, error) {
+func containerCreateFromImage(s *state.State, args db.ContainerArgs, hash string) (container, error) {
 	// Get the image properties
-	_, img, err := db.ImageGet(d.db, hash, false, false)
+	_, img, err := db.ImageGet(s.DB, hash, false, false)
 	if err != nil {
 		return nil, err
 	}
@@ -558,12 +558,12 @@ func containerCreateFromImage(d *Daemon, args db.ContainerArgs, hash string) (co
 	args.BaseImage = hash
 
 	// Create the container
-	c, err := containerCreateInternal(d.State(), args)
+	c, err := containerCreateInternal(s, args)
 	if err != nil {
 		return nil, err
 	}
 
-	if err := db.ImageLastAccessUpdate(d.db, hash, time.Now().UTC()); err != nil {
+	if err := db.ImageLastAccessUpdate(s.DB, hash, time.Now().UTC()); err != nil {
 		return nil, fmt.Errorf("Error updating image last use date: %s", err)
 	}
 
@@ -583,9 +583,9 @@ func containerCreateFromImage(d *Daemon, args db.ContainerArgs, hash string) (co
 	return c, nil
 }
 
-func containerCreateAsCopy(d *Daemon, args db.ContainerArgs, sourceContainer container, containerOnly bool) (container, error) {
+func containerCreateAsCopy(s *state.State, args db.ContainerArgs, sourceContainer container, containerOnly bool) (container, error) {
 	// Create the container.
-	ct, err := containerCreateInternal(d.State(), args)
+	ct, err := containerCreateInternal(s, args)
 	if err != nil {
 		return nil, err
 	}
@@ -612,7 +612,7 @@ func containerCreateAsCopy(d *Daemon, args db.ContainerArgs, sourceContainer con
 			}
 
 			// Create the snapshots.
-			cs, err := containerCreateInternal(d.State(), csArgs)
+			cs, err := containerCreateInternal(s, csArgs)
 			if err != nil {
 				return nil, err
 			}
diff --git a/lxd/container_put.go b/lxd/container_put.go
index af0ded606..c208a4ca7 100644
--- a/lxd/container_put.go
+++ b/lxd/container_put.go
@@ -9,6 +9,7 @@ import (
 	"github.com/gorilla/mux"
 
 	"github.com/lxc/lxd/lxd/db"
+	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
@@ -68,7 +69,7 @@ func containerPut(d *Daemon, r *http.Request) Response {
 	} else {
 		// Snapshot Restore
 		do = func(op *operation) error {
-			return containerSnapRestore(d, name, configRaw.Restore, configRaw.Stateful)
+			return containerSnapRestore(d.State(), name, configRaw.Restore, configRaw.Stateful)
 		}
 	}
 
@@ -83,18 +84,18 @@ func containerPut(d *Daemon, r *http.Request) Response {
 	return OperationResponse(op)
 }
 
-func containerSnapRestore(d *Daemon, name string, snap string, stateful bool) error {
+func containerSnapRestore(s *state.State, name string, snap string, stateful bool) error {
 	// normalize snapshot name
 	if !shared.IsSnapshot(snap) {
 		snap = name + shared.SnapshotDelimiter + snap
 	}
 
-	c, err := containerLoadByName(d.State(), name)
+	c, err := containerLoadByName(s, name)
 	if err != nil {
 		return err
 	}
 
-	source, err := containerLoadByName(d.State(), snap)
+	source, err := containerLoadByName(s, snap)
 	if err != nil {
 		switch err {
 		case sql.ErrNoRows:
diff --git a/lxd/containers.go b/lxd/containers.go
index 38774dc76..7544ac0b8 100644
--- a/lxd/containers.go
+++ b/lxd/containers.go
@@ -97,9 +97,9 @@ func (slice containerAutostartList) Swap(i, j int) {
 	slice[i], slice[j] = slice[j], slice[i]
 }
 
-func containersRestart(d *Daemon) error {
+func containersRestart(s *state.State) error {
 	// Get all the containers
-	result, err := db.ContainersList(d.db, db.CTypeRegular)
+	result, err := db.ContainersList(s.DB, db.CTypeRegular)
 	if err != nil {
 		return err
 	}
@@ -107,7 +107,7 @@ func containersRestart(d *Daemon) error {
 	containers := []container{}
 
 	for _, name := range result {
-		c, err := containerLoadByName(d.State(), name)
+		c, err := containerLoadByName(s, name)
 		if err != nil {
 			return err
 		}
@@ -142,24 +142,24 @@ func containersRestart(d *Daemon) error {
 	return nil
 }
 
-func containersShutdown(d *Daemon) error {
+func containersShutdown(s *state.State) error {
 	var wg sync.WaitGroup
 
 	// Get all the containers
-	results, err := db.ContainersList(d.db, db.CTypeRegular)
+	results, err := db.ContainersList(s.DB, db.CTypeRegular)
 	if err != nil {
 		return err
 	}
 
 	// Reset all container states
-	_, err = db.Exec(d.db, "DELETE FROM containers_config WHERE key='volatile.last_state.power'")
+	_, err = db.Exec(s.DB, "DELETE FROM containers_config WHERE key='volatile.last_state.power'")
 	if err != nil {
 		return err
 	}
 
 	for _, r := range results {
 		// Load the container
-		c, err := containerLoadByName(d.State(), r)
+		c, err := containerLoadByName(s, r)
 		if err != nil {
 			return err
 		}
diff --git a/lxd/containers_get.go b/lxd/containers_get.go
index a704adaa6..53759464d 100644
--- a/lxd/containers_get.go
+++ b/lxd/containers_get.go
@@ -6,6 +6,7 @@ import (
 	"time"
 
 	"github.com/lxc/lxd/lxd/db"
+	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
@@ -14,7 +15,7 @@ import (
 
 func containersGet(d *Daemon, r *http.Request) Response {
 	for i := 0; i < 100; i++ {
-		result, err := doContainersGet(d, util.IsRecursionRequest(r))
+		result, err := doContainersGet(d.State(), util.IsRecursionRequest(r))
 		if err == nil {
 			return SyncResponse(true, result)
 		}
@@ -32,8 +33,8 @@ func containersGet(d *Daemon, r *http.Request) Response {
 	return InternalError(fmt.Errorf("DB is locked"))
 }
 
-func doContainersGet(d *Daemon, recursion bool) (interface{}, error) {
-	result, err := db.ContainersList(d.db, db.CTypeRegular)
+func doContainersGet(s *state.State, recursion bool) (interface{}, error) {
+	result, err := db.ContainersList(s.DB, db.CTypeRegular)
 	if err != nil {
 		return nil, err
 	}
@@ -49,7 +50,7 @@ func doContainersGet(d *Daemon, recursion bool) (interface{}, error) {
 			url := fmt.Sprintf("/%s/containers/%s", version.APIVersion, container)
 			resultString = append(resultString, url)
 		} else {
-			c, err := doContainerGet(d, container)
+			c, err := doContainerGet(s, container)
 			if err != nil {
 				c = &api.Container{
 					Name:       container,
@@ -67,8 +68,8 @@ func doContainersGet(d *Daemon, recursion bool) (interface{}, error) {
 	return resultList, nil
 }
 
-func doContainerGet(d *Daemon, cname string) (*api.Container, error) {
-	c, err := containerLoadByName(d.State(), cname)
+func doContainerGet(s *state.State, cname string) (*api.Container, error) {
+	c, err := containerLoadByName(s, cname)
 	if err != nil {
 		return nil, err
 	}
diff --git a/lxd/containers_post.go b/lxd/containers_post.go
index c7920bca5..0427b20bd 100644
--- a/lxd/containers_post.go
+++ b/lxd/containers_post.go
@@ -114,7 +114,7 @@ func createFromImage(d *Daemon, req *api.ContainersPost) Response {
 			return err
 		}
 
-		_, err = containerCreateFromImage(d, args, info.Fingerprint)
+		_, err = containerCreateFromImage(d.State(), args, info.Fingerprint)
 		return err
 	}
 
@@ -311,13 +311,13 @@ func createFromMigration(d *Daemon, req *api.ContainersPost) Response {
 
 		storagePool = rootDiskDevice["pool"]
 
-		ps, err := storagePoolInit(d, storagePool)
+		ps, err := storagePoolInit(d.State(), storagePool)
 		if err != nil {
 			return InternalError(err)
 		}
 
 		if ps.MigrationType() == MigrationFSType_RSYNC {
-			c, err = containerCreateFromImage(d, args, req.Source.BaseImage)
+			c, err = containerCreateFromImage(d.State(), args, req.Source.BaseImage)
 			if err != nil {
 				return InternalError(err)
 			}
@@ -486,7 +486,7 @@ func createFromCopy(d *Daemon, req *api.ContainersPost) Response {
 	}
 
 	run := func(op *operation) error {
-		_, err := containerCreateAsCopy(d, args, source, req.Source.ContainerOnly)
+		_, err := containerCreateAsCopy(d.State(), args, source, req.Source.ContainerOnly)
 		if err != nil {
 			return err
 		}
diff --git a/lxd/daemon.go b/lxd/daemon.go
index 321ac7d26..7cbcc853f 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -545,7 +545,7 @@ func (d *Daemon) Init() error {
 
 	if !d.os.MockMode {
 		/* Read the storage pools */
-		err = SetupStorageDriver(d, false)
+		err = SetupStorageDriver(d.State(), false)
 		if err != nil {
 			return err
 		}
@@ -557,7 +557,7 @@ func (d *Daemon) Init() error {
 		}
 
 		/* Setup the networks */
-		err = networkStartup(d)
+		err = networkStartup(d.State())
 		if err != nil {
 			return err
 		}
@@ -617,7 +617,7 @@ func (d *Daemon) Init() error {
 
 	if !d.os.MockMode {
 		/* Start the scheduler */
-		go deviceEventListener(d)
+		go deviceEventListener(d.State())
 
 		/* Setup the TLS authentication */
 		certf, keyf, err := readMyCert()
@@ -853,11 +853,13 @@ func (d *Daemon) Ready() error {
 		}
 	}()
 
+	s := d.State()
+
 	/* Restore containers */
-	containersRestart(d)
+	containersRestart(s)
 
 	/* Re-balance in case things changed while LXD was down */
-	deviceTaskBalance(d)
+	deviceTaskBalance(s)
 
 	close(d.readyChan)
 
diff --git a/lxd/devices.go b/lxd/devices.go
index 1f270d1b8..05cbf0f90 100644
--- a/lxd/devices.go
+++ b/lxd/devices.go
@@ -20,6 +20,7 @@ import (
 	_ "github.com/mattn/go-sqlite3"
 
 	"github.com/lxc/lxd/lxd/db"
+	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
@@ -520,7 +521,7 @@ func parseCpuset(cpu string) ([]int, error) {
 	return cpus, nil
 }
 
-func deviceTaskBalance(d *Daemon) {
+func deviceTaskBalance(s *state.State) {
 	min := func(x, y int) int {
 		if x < y {
 			return x
@@ -591,7 +592,7 @@ func deviceTaskBalance(d *Daemon) {
 	}
 
 	// Iterate through the containers
-	containers, err := db.ContainersList(d.db, db.CTypeRegular)
+	containers, err := db.ContainersList(s.DB, db.CTypeRegular)
 	if err != nil {
 		logger.Error("problem loading containers list", log.Ctx{"err": err})
 		return
@@ -599,7 +600,7 @@ func deviceTaskBalance(d *Daemon) {
 	fixedContainers := map[int][]container{}
 	balancedContainers := map[container]int{}
 	for _, name := range containers {
-		c, err := containerLoadByName(d.State(), name)
+		c, err := containerLoadByName(s, name)
 		if err != nil {
 			continue
 		}
@@ -711,20 +712,20 @@ func deviceTaskBalance(d *Daemon) {
 	}
 }
 
-func deviceNetworkPriority(d *Daemon, netif string) {
+func deviceNetworkPriority(s *state.State, netif string) {
 	// Don't bother running when CGroup support isn't there
 	if !cgNetPrioController {
 		return
 	}
 
-	containers, err := db.ContainersList(d.db, db.CTypeRegular)
+	containers, err := db.ContainersList(s.DB, db.CTypeRegular)
 	if err != nil {
 		return
 	}
 
 	for _, name := range containers {
 		// Get the container struct
-		c, err := containerLoadByName(d.State(), name)
+		c, err := containerLoadByName(s, name)
 		if err != nil {
 			continue
 		}
@@ -747,15 +748,15 @@ func deviceNetworkPriority(d *Daemon, netif string) {
 	return
 }
 
-func deviceUSBEvent(d *Daemon, usb usbDevice) {
-	containers, err := db.ContainersList(d.db, db.CTypeRegular)
+func deviceUSBEvent(s *state.State, usb usbDevice) {
+	containers, err := db.ContainersList(s.DB, db.CTypeRegular)
 	if err != nil {
 		logger.Error("problem loading containers list", log.Ctx{"err": err})
 		return
 	}
 
 	for _, name := range containers {
-		containerIf, err := containerLoadByName(d.State(), name)
+		containerIf, err := containerLoadByName(s, name)
 		if err != nil {
 			continue
 		}
@@ -801,7 +802,7 @@ func deviceUSBEvent(d *Daemon, usb usbDevice) {
 	}
 }
 
-func deviceEventListener(d *Daemon) {
+func deviceEventListener(s *state.State) {
 	chNetlinkCPU, chNetlinkNetwork, chUSB, err := deviceNetlinkListener()
 	if err != nil {
 		logger.Errorf("scheduler: couldn't setup netlink listener")
@@ -821,7 +822,7 @@ func deviceEventListener(d *Daemon) {
 			}
 
 			logger.Debugf("Scheduler: cpu: %s is now %s: re-balancing", e[0], e[1])
-			deviceTaskBalance(d)
+			deviceTaskBalance(s)
 		case e := <-chNetlinkNetwork:
 			if len(e) != 2 {
 				logger.Errorf("Scheduler: received an invalid network hotplug event")
@@ -833,10 +834,10 @@ func deviceEventListener(d *Daemon) {
 			}
 
 			logger.Debugf("Scheduler: network: %s has been added: updating network priorities", e[0])
-			deviceNetworkPriority(d, e[0])
-			networkAutoAttach(d.db, e[0])
+			deviceNetworkPriority(s, e[0])
+			networkAutoAttach(s.DB, e[0])
 		case e := <-chUSB:
-			deviceUSBEvent(d, e)
+			deviceUSBEvent(s, e)
 		case e := <-deviceSchedRebalance:
 			if len(e) != 3 {
 				logger.Errorf("Scheduler: received an invalid rebalance event")
@@ -848,7 +849,7 @@ func deviceEventListener(d *Daemon) {
 			}
 
 			logger.Debugf("Scheduler: %s %s %s: re-balancing", e[0], e[1], e[2])
-			deviceTaskBalance(d)
+			deviceTaskBalance(s)
 		}
 	}
 }
diff --git a/lxd/images.go b/lxd/images.go
index 7520db603..3b2f1881d 100644
--- a/lxd/images.go
+++ b/lxd/images.go
@@ -24,6 +24,7 @@ import (
 	"gopkg.in/yaml.v2"
 
 	"github.com/lxc/lxd/lxd/db"
+	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
@@ -635,7 +636,7 @@ func imageCreateInPool(d *Daemon, info *api.Image, storagePool string) error {
 	}
 
 	// Initialize a new storage interface.
-	s, err := storagePoolInit(d, storagePool)
+	s, err := storagePoolInit(d.State(), storagePool)
 	if err != nil {
 		return err
 	}
@@ -963,7 +964,7 @@ func autoUpdateImage(d *Daemon, op *operation, id int, info *api.Image) error {
 		// If we do have optimized pools, make sure we remove
 		// the volumes associated with the image.
 		if poolName != "" {
-			err = doDeleteImageFromPool(d, fingerprint, poolName)
+			err = doDeleteImageFromPool(d.State(), fingerprint, poolName)
 			if err != nil {
 				logger.Error("Error deleting image from pool", log.Ctx{"err": err, "fp": fingerprint})
 			}
@@ -1030,7 +1031,7 @@ func pruneExpiredImages(d *Daemon) {
 		}
 
 		for _, pool := range poolNames {
-			err := doDeleteImageFromPool(d, fp, pool)
+			err := doDeleteImageFromPool(d.State(), fp, pool)
 			if err != nil {
 				logger.Debugf("Error deleting image %s from storage pool %: %s", fp, pool, err)
 				continue
@@ -1069,9 +1070,9 @@ func pruneExpiredImages(d *Daemon) {
 	logger.Infof("Done pruning expired images")
 }
 
-func doDeleteImageFromPool(d *Daemon, fingerprint string, storagePool string) error {
+func doDeleteImageFromPool(state *state.State, fingerprint string, storagePool string) error {
 	// Initialize a new storage interface.
-	s, err := storagePoolVolumeImageInit(d, storagePool, fingerprint)
+	s, err := storagePoolVolumeImageInit(state, storagePool, fingerprint)
 	if err != nil {
 		return err
 	}
@@ -1107,7 +1108,7 @@ func imageDelete(d *Daemon, r *http.Request) Response {
 		}
 
 		for _, pool := range pools {
-			err := doDeleteImageFromPool(d, imgInfo.Fingerprint, pool)
+			err := doDeleteImageFromPool(d.State(), imgInfo.Fingerprint, pool)
 			if err != nil {
 				return err
 			}
diff --git a/lxd/main_daemon.go b/lxd/main_daemon.go
index 37ee5b5f4..3aea04740 100644
--- a/lxd/main_daemon.go
+++ b/lxd/main_daemon.go
@@ -67,21 +67,22 @@ func cmdDaemon() error {
 	signal.Notify(ch, syscall.SIGQUIT)
 	signal.Notify(ch, syscall.SIGTERM)
 
+	s := d.State()
 	select {
 	case sig := <-ch:
 
 		if sig == syscall.SIGPWR {
 			logger.Infof("Received '%s signal', shutting down containers.", sig)
-			containersShutdown(d)
-			networkShutdown(d)
+			containersShutdown(s)
+			networkShutdown(s)
 		} else {
 			logger.Infof("Received '%s signal', exiting.", sig)
 		}
 
 	case <-d.shutdownChan:
 		logger.Infof("Asked to shutdown by API, shutting down containers.")
-		containersShutdown(d)
-		networkShutdown(d)
+		containersShutdown(s)
+		networkShutdown(s)
 	}
 
 	return d.Stop()
diff --git a/lxd/networks.go b/lxd/networks.go
index 648b2aa3b..aa5ba2e68 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -402,16 +402,16 @@ func networkLoadByName(s *state.State, name string) (*network, error) {
 	return &n, nil
 }
 
-func networkStartup(d *Daemon) error {
+func networkStartup(s *state.State) error {
 	// Get a list of managed networks
-	networks, err := db.Networks(d.db)
+	networks, err := db.Networks(s.DB)
 	if err != nil {
 		return err
 	}
 
 	// Bring them all up
 	for _, name := range networks {
-		n, err := networkLoadByName(d.State(), name)
+		n, err := networkLoadByName(s, name)
 		if err != nil {
 			return err
 		}
@@ -426,16 +426,16 @@ func networkStartup(d *Daemon) error {
 	return nil
 }
 
-func networkShutdown(d *Daemon) error {
+func networkShutdown(s *state.State) error {
 	// Get a list of managed networks
-	networks, err := db.Networks(d.db)
+	networks, err := db.Networks(s.DB)
 	if err != nil {
 		return err
 	}
 
 	// Bring them all up
 	for _, name := range networks {
-		n, err := networkLoadByName(d.State(), name)
+		n, err := networkLoadByName(s, name)
 		if err != nil {
 			return err
 		}
diff --git a/lxd/patches.go b/lxd/patches.go
index 88db01422..c35e9fac0 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -283,7 +283,7 @@ func patchStorageApi(name string, d *Daemon) error {
 	daemonConfig["storage.zfs_remove_snapshots"].Set(d, "")
 	daemonConfig["storage.zfs_use_refquota"].Set(d, "")
 
-	return SetupStorageDriver(d, true)
+	return SetupStorageDriver(d.State(), true)
 }
 
 func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string, defaultStorageTypeName string, cRegular []string, cSnapshots []string, imgPublic []string, imgPrivate []string) error {
@@ -335,7 +335,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 		}
 		poolID = tmp
 
-		s, err := storagePoolInit(d, defaultPoolName)
+		s, err := storagePoolInit(d.State(), defaultPoolName)
 		if err != nil {
 			return err
 		}
@@ -632,7 +632,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 		}
 		poolID = tmp
 
-		s, err := storagePoolInit(d, defaultPoolName)
+		s, err := storagePoolInit(d.State(), defaultPoolName)
 		if err != nil {
 			return err
 		}
@@ -2416,8 +2416,9 @@ func patchUpdateFromV10(d *Daemon) error {
 		}
 
 		logger.Debugf("Restarting all the containers following directory rename")
-		containersShutdown(d)
-		containersRestart(d)
+		s := d.State()
+		containersShutdown(s)
+		containersRestart(s)
 	}
 
 	return nil
diff --git a/lxd/profiles.go b/lxd/profiles.go
index de4a52e7f..fe0134075 100644
--- a/lxd/profiles.go
+++ b/lxd/profiles.go
@@ -12,6 +12,7 @@ import (
 	_ "github.com/mattn/go-sqlite3"
 
 	"github.com/lxc/lxd/lxd/db"
+	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
@@ -38,7 +39,7 @@ func profilesGet(d *Daemon, r *http.Request) Response {
 			url := fmt.Sprintf("/%s/profiles/%s", version.APIVersion, name)
 			resultString[i] = url
 		} else {
-			profile, err := doProfileGet(d, name)
+			profile, err := doProfileGet(d.State(), name)
 			if err != nil {
 				logger.Error("Failed to get profile", log.Ctx{"profile": name})
 				continue
@@ -104,13 +105,13 @@ var profilesCmd = Command{
 	get:  profilesGet,
 	post: profilesPost}
 
-func doProfileGet(d *Daemon, name string) (*api.Profile, error) {
-	_, profile, err := db.ProfileGet(d.db, name)
+func doProfileGet(s *state.State, name string) (*api.Profile, error) {
+	_, profile, err := db.ProfileGet(s.DB, name)
 	if err != nil {
 		return nil, err
 	}
 
-	cts, err := db.ProfileContainersGet(d.db, name)
+	cts, err := db.ProfileContainersGet(s.DB, name)
 	if err != nil {
 		return nil, err
 	}
@@ -127,7 +128,7 @@ func doProfileGet(d *Daemon, name string) (*api.Profile, error) {
 func profileGet(d *Daemon, r *http.Request) Response {
 	name := mux.Vars(r)["name"]
 
-	resp, err := doProfileGet(d, name)
+	resp, err := doProfileGet(d.State(), name)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -136,16 +137,16 @@ func profileGet(d *Daemon, r *http.Request) Response {
 	return SyncResponseETag(true, resp, etag)
 }
 
-func getContainersWithProfile(d *Daemon, profile string) []container {
+func getContainersWithProfile(s *state.State, profile string) []container {
 	results := []container{}
 
-	output, err := db.ProfileContainersGet(d.db, profile)
+	output, err := db.ProfileContainersGet(s.DB, profile)
 	if err != nil {
 		return results
 	}
 
 	for _, name := range output {
-		c, err := containerLoadByName(d.State(), name)
+		c, err := containerLoadByName(s, name)
 		if err != nil {
 			logger.Error("Failed opening container", log.Ctx{"container": name})
 			continue
@@ -285,12 +286,12 @@ func profilePost(d *Daemon, r *http.Request) Response {
 func profileDelete(d *Daemon, r *http.Request) Response {
 	name := mux.Vars(r)["name"]
 
-	_, err := doProfileGet(d, name)
+	_, err := doProfileGet(d.State(), name)
 	if err != nil {
 		return SmartError(err)
 	}
 
-	clist := getContainersWithProfile(d, name)
+	clist := getContainersWithProfile(d.State(), name)
 	if len(clist) != 0 {
 		return BadRequest(fmt.Errorf("Profile is currently in use"))
 	}
diff --git a/lxd/profiles_utils.go b/lxd/profiles_utils.go
index dab566c86..5cab0b6d9 100644
--- a/lxd/profiles_utils.go
+++ b/lxd/profiles_utils.go
@@ -20,7 +20,7 @@ func doProfileUpdate(d *Daemon, name string, id int64, profile *api.Profile, req
 		return BadRequest(err)
 	}
 
-	containers := getContainersWithProfile(d, name)
+	containers := getContainersWithProfile(d.State(), name)
 
 	// Check if the root device is supposed to be changed or removed.
 	oldProfileRootDiskDeviceKey, oldProfileRootDiskDevice, _ := containerGetRootDiskDevice(profile.Devices)
diff --git a/lxd/storage.go b/lxd/storage.go
index a02892275..ddc680c20 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -379,8 +379,8 @@ func storageInit(s *state.State, poolName string, volumeName string, volumeType
 	return nil, fmt.Errorf("invalid storage type")
 }
 
-func storagePoolInit(d *Daemon, poolName string) (storage, error) {
-	return storageInit(d.State(), poolName, "", -1)
+func storagePoolInit(s *state.State, poolName string) (storage, error) {
+	return storageInit(s, poolName, "", -1)
 }
 
 func storagePoolVolumeAttachInit(s *state.State, poolName string, volumeName string, volumeType int, c container) (storage, error) {
@@ -526,8 +526,8 @@ func storagePoolVolumeInit(s *state.State, poolName string, volumeName string, v
 	return storageInit(s, poolName, volumeName, volumeType)
 }
 
-func storagePoolVolumeImageInit(d *Daemon, poolName string, imageFingerprint string) (storage, error) {
-	return storagePoolVolumeInit(d.State(), poolName, imageFingerprint, storagePoolVolumeTypeImage)
+func storagePoolVolumeImageInit(s *state.State, poolName string, imageFingerprint string) (storage, error) {
+	return storagePoolVolumeInit(s, poolName, imageFingerprint, storagePoolVolumeTypeImage)
 }
 
 func storagePoolVolumeContainerCreateInit(s *state.State, poolName string, containerName string) (storage, error) {
@@ -801,8 +801,8 @@ func StorageProgressWriter(op *operation, key string, description string) func(i
 	}
 }
 
-func SetupStorageDriver(d *Daemon, forceCheck bool) error {
-	pools, err := db.StoragePools(d.db)
+func SetupStorageDriver(s *state.State, forceCheck bool) error {
+	pools, err := db.StoragePools(s.DB)
 	if err != nil {
 		if err == db.NoSuchObjectError {
 			logger.Debugf("No existing storage pools detected.")
@@ -819,7 +819,7 @@ func SetupStorageDriver(d *Daemon, forceCheck bool) error {
 	// but the upgrade somehow got messed up then there will be no
 	// "storage_api" entry in the db.
 	if len(pools) > 0 && !forceCheck {
-		appliedPatches, err := db.Patches(d.db)
+		appliedPatches, err := db.Patches(s.DB)
 		if err != nil {
 			return err
 		}
@@ -833,7 +833,7 @@ func SetupStorageDriver(d *Daemon, forceCheck bool) error {
 
 	for _, pool := range pools {
 		logger.Debugf("Initializing and checking storage pool \"%s\".", pool)
-		s, err := storagePoolInit(d, pool)
+		s, err := storagePoolInit(s, pool)
 		if err != nil {
 			logger.Errorf("Error initializing storage pool \"%s\": %s. Correct functionality of the storage pool cannot be guaranteed.", pool, err)
 			continue
@@ -855,7 +855,7 @@ func SetupStorageDriver(d *Daemon, forceCheck bool) error {
 	// appropriate. (Should be cheaper then querying the db all the time,
 	// especially if we keep adding more storage drivers.)
 	if !storagePoolDriversCacheInitialized {
-		tmp, err := db.StoragePoolsGetDrivers(d.db)
+		tmp, err := db.StoragePoolsGetDrivers(s.DB)
 		if err != nil && err != db.NoSuchObjectError {
 			return nil
 		}
diff --git a/lxd/storage_pools.go b/lxd/storage_pools.go
index a616566a5..991dfc59e 100644
--- a/lxd/storage_pools.go
+++ b/lxd/storage_pools.go
@@ -77,7 +77,7 @@ func storagePoolsPost(d *Daemon, r *http.Request) Response {
 		return BadRequest(fmt.Errorf("No driver provided"))
 	}
 
-	err = storagePoolCreateInternal(d, req.Name, req.Description, req.Driver, req.Config)
+	err = storagePoolCreateInternal(d.State(), req.Name, req.Description, req.Driver, req.Config)
 	if err != nil {
 		return InternalError(err)
 	}
@@ -140,7 +140,7 @@ func storagePoolPut(d *Daemon, r *http.Request) Response {
 		return BadRequest(err)
 	}
 
-	err = storagePoolUpdate(d, poolName, req.Description, req.Config)
+	err = storagePoolUpdate(d.State(), poolName, req.Description, req.Config)
 	if err != nil {
 		return InternalError(err)
 	}
@@ -190,7 +190,7 @@ func storagePoolPatch(d *Daemon, r *http.Request) Response {
 		return BadRequest(err)
 	}
 
-	err = storagePoolUpdate(d, poolName, req.Description, req.Config)
+	err = storagePoolUpdate(d.State(), poolName, req.Description, req.Config)
 	if err != nil {
 		return InternalError(fmt.Errorf("failed to update the storage pool configuration"))
 	}
@@ -224,7 +224,7 @@ func storagePoolDelete(d *Daemon, r *http.Request) Response {
 		return BadRequest(fmt.Errorf("Storage pool \"%s\" has profiles using it:\n%s", poolName, strings.Join(profiles, "\n")))
 	}
 
-	s, err := storagePoolInit(d, poolName)
+	s, err := storagePoolInit(d.State(), poolName)
 	if err != nil {
 		return InternalError(err)
 	}
diff --git a/lxd/storage_pools_utils.go b/lxd/storage_pools_utils.go
index 26da7c3b5..501cafa63 100644
--- a/lxd/storage_pools_utils.go
+++ b/lxd/storage_pools_utils.go
@@ -6,12 +6,13 @@ import (
 	"strings"
 
 	"github.com/lxc/lxd/lxd/db"
+	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/version"
 )
 
-func storagePoolUpdate(d *Daemon, name, newDescription string, newConfig map[string]string) error {
-	s, err := storagePoolInit(d, name)
+func storagePoolUpdate(state *state.State, name, newDescription string, newConfig map[string]string) error {
+	s, err := storagePoolInit(state, name)
 	if err != nil {
 		return err
 	}
@@ -62,7 +63,7 @@ func storagePoolUpdate(d *Daemon, name, newDescription string, newConfig map[str
 
 	// Update the database if something changed
 	if len(changedConfig) != 0 || newDescription != oldDescription {
-		err = db.StoragePoolUpdate(d.db, name, newDescription, newConfig)
+		err = db.StoragePoolUpdate(state.DB, name, newDescription, newConfig)
 		if err != nil {
 			return err
 		}
@@ -156,7 +157,7 @@ func profilesUsingPoolGetNames(dbOb *sql.DB, poolName string) ([]string, error)
 	return usedBy, nil
 }
 
-func storagePoolDBCreate(d *Daemon, poolName, poolDescription string, driver string, config map[string]string) error {
+func storagePoolDBCreate(s *state.State, poolName, poolDescription string, driver string, config map[string]string) error {
 	// Check if the storage pool name is valid.
 	err := storageValidName(poolName)
 	if err != nil {
@@ -164,7 +165,7 @@ func storagePoolDBCreate(d *Daemon, poolName, poolDescription string, driver str
 	}
 
 	// Check that the storage pool does not already exist.
-	_, err = db.StoragePoolGetID(d.db, poolName)
+	_, err = db.StoragePoolGetID(s.DB, poolName)
 	if err == nil {
 		return fmt.Errorf("The storage pool already exists")
 	}
@@ -187,7 +188,7 @@ func storagePoolDBCreate(d *Daemon, poolName, poolDescription string, driver str
 	}
 
 	// Create the database entry for the storage pool.
-	_, err = dbStoragePoolCreateAndUpdateCache(d.db, poolName, poolDescription, driver, config)
+	_, err = dbStoragePoolCreateAndUpdateCache(s.DB, poolName, poolDescription, driver, config)
 	if err != nil {
 		return fmt.Errorf("Error inserting %s into database: %s", poolName, err)
 	}
@@ -195,8 +196,8 @@ func storagePoolDBCreate(d *Daemon, poolName, poolDescription string, driver str
 	return nil
 }
 
-func storagePoolCreateInternal(d *Daemon, poolName, poolDescription string, driver string, config map[string]string) error {
-	err := storagePoolDBCreate(d, poolName, poolDescription, driver, config)
+func storagePoolCreateInternal(state *state.State, poolName, poolDescription string, driver string, config map[string]string) error {
+	err := storagePoolDBCreate(state, poolName, poolDescription, driver, config)
 	if err != nil {
 		return err
 	}
@@ -209,10 +210,10 @@ func storagePoolCreateInternal(d *Daemon, poolName, poolDescription string, driv
 		if !tryUndo {
 			return
 		}
-		dbStoragePoolDeleteAndUpdateCache(d.db, poolName)
+		dbStoragePoolDeleteAndUpdateCache(state.DB, poolName)
 	}()
 
-	s, err := storagePoolInit(d, poolName)
+	s, err := storagePoolInit(state, poolName)
 	if err != nil {
 		return err
 	}
@@ -238,7 +239,7 @@ func storagePoolCreateInternal(d *Daemon, poolName, poolDescription string, driv
 	configDiff, _ := storageConfigDiff(config, postCreateConfig)
 	if len(configDiff) > 0 {
 		// Create the database entry for the storage pool.
-		err = db.StoragePoolUpdate(d.db, poolName, poolDescription, postCreateConfig)
+		err = db.StoragePoolUpdate(state.DB, poolName, poolDescription, postCreateConfig)
 		if err != nil {
 			return fmt.Errorf("Error inserting %s into database: %s", poolName, err)
 		}
diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index 711d4d4b7..ba2233d2f 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -49,7 +49,7 @@ func storagePoolVolumesGet(d *Daemon, r *http.Request) Response {
 		if recursion == 0 {
 			resultString = append(resultString, fmt.Sprintf("/%s/storage-pools/%s/volumes/%s/%s", version.APIVersion, poolName, apiEndpoint, volume.Name))
 		} else {
-			volumeUsedBy, err := storagePoolVolumeUsedByGet(d, volume.Name, volume.Type)
+			volumeUsedBy, err := storagePoolVolumeUsedByGet(d.State(), volume.Name, volume.Type)
 			if err != nil {
 				return InternalError(err)
 			}
@@ -121,7 +121,7 @@ func storagePoolVolumesTypeGet(d *Daemon, r *http.Request) Response {
 				continue
 			}
 
-			volumeUsedBy, err := storagePoolVolumeUsedByGet(d, vol.Name, vol.Type)
+			volumeUsedBy, err := storagePoolVolumeUsedByGet(d.State(), vol.Name, vol.Type)
 			if err != nil {
 				return SmartError(err)
 			}
@@ -164,7 +164,7 @@ func storagePoolVolumesTypePost(d *Daemon, r *http.Request) Response {
 	// volume is supposed to be created.
 	poolName := mux.Vars(r)["name"]
 
-	err = storagePoolVolumeCreateInternal(d, poolName, req.Name, req.Description, req.Type, req.Config)
+	err = storagePoolVolumeCreateInternal(d.State(), poolName, req.Name, req.Description, req.Type, req.Config)
 	if err != nil {
 		return InternalError(err)
 	}
@@ -215,7 +215,7 @@ func storagePoolVolumeTypeGet(d *Daemon, r *http.Request) Response {
 		return SmartError(err)
 	}
 
-	volumeUsedBy, err := storagePoolVolumeUsedByGet(d, volume.Name, volume.Type)
+	volumeUsedBy, err := storagePoolVolumeUsedByGet(d.State(), volume.Name, volume.Type)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -278,7 +278,7 @@ func storagePoolVolumeTypePut(d *Daemon, r *http.Request) Response {
 		return BadRequest(err)
 	}
 
-	err = storagePoolVolumeUpdate(d, poolName, volumeName, volumeType, req.Description, req.Config)
+	err = storagePoolVolumeUpdate(d.State(), poolName, volumeName, volumeType, req.Description, req.Config)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -351,7 +351,7 @@ func storagePoolVolumeTypePatch(d *Daemon, r *http.Request) Response {
 		return BadRequest(err)
 	}
 
-	err = storagePoolVolumeUpdate(d, poolName, volumeName, volumeType, req.Description, req.Config)
+	err = storagePoolVolumeUpdate(d.State(), poolName, volumeName, volumeType, req.Description, req.Config)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -390,7 +390,7 @@ func storagePoolVolumeTypeDelete(d *Daemon, r *http.Request) Response {
 		return BadRequest(fmt.Errorf("storage volumes of type \"%s\" cannot be deleted with the storage api", volumeTypeName))
 	}
 
-	volumeUsedBy, err := storagePoolVolumeUsedByGet(d, volumeName, volumeTypeName)
+	volumeUsedBy, err := storagePoolVolumeUsedByGet(d.State(), volumeName, volumeTypeName)
 	if err != nil {
 		return SmartError(err)
 	}
diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index 975ab904e..d4e4bc221 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -80,8 +80,8 @@ func storagePoolVolumeTypeToAPIEndpoint(volumeType int) (string, error) {
 	return "", fmt.Errorf("invalid storage volume type")
 }
 
-func storagePoolVolumeUpdate(d *Daemon, poolName string, volumeName string, volumeType int, newDescription string, newConfig map[string]string) error {
-	s, err := storagePoolVolumeInit(d.State(), poolName, volumeName, volumeType)
+func storagePoolVolumeUpdate(state *state.State, poolName string, volumeName string, volumeType int, newDescription string, newConfig map[string]string) error {
+	s, err := storagePoolVolumeInit(state, poolName, volumeName, volumeType)
 	if err != nil {
 		return err
 	}
@@ -152,14 +152,14 @@ func storagePoolVolumeUpdate(d *Daemon, poolName string, volumeName string, volu
 		s.SetStoragePoolVolumeWritable(&newWritable)
 	}
 
-	poolID, err := db.StoragePoolGetID(d.db, poolName)
+	poolID, err := db.StoragePoolGetID(state.DB, poolName)
 	if err != nil {
 		return err
 	}
 
 	// Update the database if something changed
 	if len(changedConfig) != 0 || newDescription != oldDescription {
-		err = db.StoragePoolVolumeUpdate(d.db, volumeName, volumeType, poolID, newDescription, newConfig)
+		err = db.StoragePoolVolumeUpdate(state.DB, volumeName, volumeType, poolID, newDescription, newConfig)
 		if err != nil {
 			return err
 		}
@@ -204,7 +204,7 @@ func storagePoolVolumeUsedByContainersGet(s *state.State, volumeName string,
 }
 
 // volumeUsedBy = append(volumeUsedBy, fmt.Sprintf("/%s/containers/%s", version.APIVersion, ct))
-func storagePoolVolumeUsedByGet(d *Daemon, volumeName string, volumeTypeName string) ([]string, error) {
+func storagePoolVolumeUsedByGet(s *state.State, volumeName string, volumeTypeName string) ([]string, error) {
 	// Handle container volumes
 	if volumeTypeName == "container" {
 		cName, sName, snap := containerGetParentAndSnapshotName(volumeName)
@@ -222,7 +222,7 @@ func storagePoolVolumeUsedByGet(d *Daemon, volumeName string, volumeTypeName str
 	}
 
 	// Look for containers using this volume
-	ctsUsingVolume, err := storagePoolVolumeUsedByContainersGet(d.State(),
+	ctsUsingVolume, err := storagePoolVolumeUsedByContainersGet(s,
 		volumeName, volumeTypeName)
 	if err != nil {
 		return []string{}, err
@@ -234,7 +234,7 @@ func storagePoolVolumeUsedByGet(d *Daemon, volumeName string, volumeTypeName str
 			fmt.Sprintf("/%s/containers/%s", version.APIVersion, ct))
 	}
 
-	profiles, err := profilesUsingPoolVolumeGetNames(d.db, volumeName, volumeTypeName)
+	profiles, err := profilesUsingPoolVolumeGetNames(s.DB, volumeName, volumeTypeName)
 	if err != nil {
 		return []string{}, err
 	}
@@ -288,7 +288,7 @@ func profilesUsingPoolVolumeGetNames(dbObj *sql.DB, volumeName string, volumeTyp
 	return usedBy, nil
 }
 
-func storagePoolVolumeDBCreate(d *Daemon, poolName string, volumeName, volumeDescription string, volumeTypeName string, volumeConfig map[string]string) error {
+func storagePoolVolumeDBCreate(s *state.State, poolName string, volumeName, volumeDescription string, volumeTypeName string, volumeConfig map[string]string) error {
 	// Check that the name of the new storage volume is valid. (For example.
 	// zfs pools cannot contain "/" in their names.)
 	err := storageValidName(volumeName)
@@ -310,14 +310,14 @@ func storagePoolVolumeDBCreate(d *Daemon, poolName string, volumeName, volumeDes
 	}
 
 	// Load storage pool the volume will be attached to.
-	poolID, poolStruct, err := db.StoragePoolGet(d.db, poolName)
+	poolID, poolStruct, err := db.StoragePoolGet(s.DB, poolName)
 	if err != nil {
 		return err
 	}
 
 	// Check that a storage volume of the same storage volume type does not
 	// already exist.
-	volumeID, _ := db.StoragePoolVolumeGetTypeID(d.db, volumeName, volumeType, poolID)
+	volumeID, _ := db.StoragePoolVolumeGetTypeID(s.DB, volumeName, volumeType, poolID)
 	if volumeID > 0 {
 		return fmt.Errorf("a storage volume of type %s does already exist", volumeTypeName)
 	}
@@ -339,7 +339,7 @@ func storagePoolVolumeDBCreate(d *Daemon, poolName string, volumeName, volumeDes
 	}
 
 	// Create the database entry for the storage volume.
-	_, err = db.StoragePoolVolumeCreate(d.db, volumeName, volumeDescription, volumeType, poolID, volumeConfig)
+	_, err = db.StoragePoolVolumeCreate(s.DB, volumeName, volumeDescription, volumeType, poolID, volumeConfig)
 	if err != nil {
 		return fmt.Errorf("Error inserting %s of type %s into database: %s", poolName, volumeTypeName, err)
 	}
@@ -347,8 +347,8 @@ func storagePoolVolumeDBCreate(d *Daemon, poolName string, volumeName, volumeDes
 	return nil
 }
 
-func storagePoolVolumeCreateInternal(d *Daemon, poolName string, volumeName, volumeDescription string, volumeTypeName string, volumeConfig map[string]string) error {
-	err := storagePoolVolumeDBCreate(d, poolName, volumeName, volumeDescription, volumeTypeName, volumeConfig)
+func storagePoolVolumeCreateInternal(state *state.State, poolName string, volumeName, volumeDescription string, volumeTypeName string, volumeConfig map[string]string) error {
+	err := storagePoolVolumeDBCreate(state, poolName, volumeName, volumeDescription, volumeTypeName, volumeConfig)
 	if err != nil {
 		return err
 	}
@@ -359,7 +359,7 @@ func storagePoolVolumeCreateInternal(d *Daemon, poolName string, volumeName, vol
 		return err
 	}
 
-	s, err := storagePoolVolumeInit(d.State(), poolName, volumeName, volumeType)
+	s, err := storagePoolVolumeInit(state, poolName, volumeName, volumeType)
 	if err != nil {
 		return err
 	}
@@ -369,7 +369,7 @@ func storagePoolVolumeCreateInternal(d *Daemon, poolName string, volumeName, vol
 	// Create storage volume.
 	err = s.StoragePoolVolumeCreate()
 	if err != nil {
-		db.StoragePoolVolumeDelete(d.db, volumeName, volumeType, poolID)
+		db.StoragePoolVolumeDelete(state.DB, volumeName, volumeType, poolID)
 		return err
 	}
 


More information about the lxc-devel mailing list