[lxc-devel] [lxd/master] storage: simplify backend

brauner on Github lxc-bot at linuxcontainers.org
Fri Feb 24 16:19:51 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 596 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170224/d8080a89/attachment.bin>
-------------- next part --------------
From d91d11ec20e0098b6c4cf8b365fda04359d6043e Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 24 Feb 2017 15:44:40 +0100
Subject: [PATCH 01/10] lxd/storage: simplify

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage.go | 713 ++-------------------------------------------------------
 1 file changed, 23 insertions(+), 690 deletions(-)

diff --git a/lxd/storage.go b/lxd/storage.go
index 9e7756d..9eba5dd 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -13,13 +13,9 @@ import (
 
 	"github.com/gorilla/websocket"
 
-	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/ioprogress"
-	"github.com/lxc/lxd/shared/logging"
-
-	log "gopkg.in/inconshreveable/log15.v2"
 )
 
 // lxdStorageLockMap is a hashmap that allows functions to check whether the
@@ -173,35 +169,6 @@ func storageStringToType(sName string) (storageType, error) {
 	return -1, fmt.Errorf("Invalid storage type name.")
 }
 
-type MigrationStorageSourceDriver interface {
-	/* snapshots for this container, if any */
-	Snapshots() []container
-
-	/* send any bits of the container/snapshots that are possible while the
-	 * container is still running.
-	 */
-	SendWhileRunning(conn *websocket.Conn, op *operation) error
-
-	/* send the final bits (e.g. a final delta snapshot for zfs, btrfs, or
-	 * do a final rsync) of the fs after the container has been
-	 * checkpointed. This will only be called when a container is actually
-	 * being live migrated.
-	 */
-	SendAfterCheckpoint(conn *websocket.Conn) error
-
-	/* Called after either success or failure of a migration, can be used
-	 * to clean up any temporary snapshots, etc.
-	 */
-	Cleanup()
-}
-
-type storageCoreInfo interface {
-	StorageCoreInit() (*storageCore, error)
-	GetStorageType() storageType
-	GetStorageTypeName() string
-	GetStorageTypeVersion() string
-}
-
 // FIXME(brauner): Split up this interace into sub-interfaces, that can be
 // combined into this single big interface but can also be individually
 // initialized. Suggestion:
@@ -294,9 +261,7 @@ type storage interface {
 	MigrationSink(live bool, container container, objects []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation) error
 }
 
-func storageWrapperInit(d *Daemon, poolName string, volumeName string, volumeType int) (*storageLogWrapper, error) {
-	var s storageLogWrapper
-
+func storageInit(d *Daemon, poolName string, volumeName string, volumeType int) (storage, error) {
 	// Load the storage pool.
 	poolID, pool, err := dbStoragePoolGet(d.db, poolName)
 	if err != nil {
@@ -331,84 +296,49 @@ func storageWrapperInit(d *Daemon, poolName string, volumeName string, volumeTyp
 		btrfs.pool = pool
 		btrfs.volume = volume
 		btrfs.d = d
-		s = storageLogWrapper{w: &btrfs}
-	case storageTypeZfs:
-		zfs := storageZfs{}
-		zfs.poolID = poolID
-		zfs.pool = pool
-		zfs.volume = volume
-		zfs.d = d
-		s = storageLogWrapper{w: &zfs}
-	case storageTypeLvm:
-		lvm := storageLvm{}
-		lvm.poolID = poolID
-		lvm.pool = pool
-		lvm.volume = volume
-		lvm.d = d
-		s = storageLogWrapper{w: &lvm}
+		return &btrfs, nil
 	case storageTypeDir:
 		dir := storageDir{}
 		dir.poolID = poolID
 		dir.pool = pool
 		dir.volume = volume
 		dir.d = d
-		s = storageLogWrapper{w: &dir}
+		return &dir, nil
+	case storageTypeLvm:
+		lvm := storageLvm{}
+		lvm.poolID = poolID
+		lvm.pool = pool
+		lvm.volume = volume
+		lvm.d = d
+		return &lvm, nil
 	case storageTypeMock:
 		mock := storageMock{}
 		mock.poolID = poolID
 		mock.pool = pool
 		mock.volume = volume
 		mock.d = d
-		s = storageLogWrapper{w: &mock}
+		return &mock, nil
+	case storageTypeZfs:
+		zfs := storageZfs{}
+		zfs.poolID = poolID
+		zfs.pool = pool
+		zfs.volume = volume
+		zfs.d = d
+		return &zfs, nil
 	}
 
-	return &s, nil
+	return nil, fmt.Errorf("Invalid storage type.")
 }
 
 func storagePoolInit(d *Daemon, poolName string) (storage, error) {
 	var config map[string]interface{}
 
-	wrapper, err := storageWrapperInit(d, poolName, "", -1)
+	s, err := storageInit(d, poolName, "", -1)
 	if err != nil {
 		return nil, err
 	}
 
-	storage, err := wrapper.StoragePoolInit(config)
-	if err != nil {
-		return nil, err
-	}
-
-	return storage, nil
-}
-
-func storagePoolCoreInit(poolDriver string) (*storageCore, error) {
-	sType, err := storageStringToType(poolDriver)
-	if err != nil {
-		return nil, err
-	}
-
-	var s storage
-	switch sType {
-	case storageTypeBtrfs:
-		btrfs := storageBtrfs{}
-		s = &storageLogWrapper{w: &btrfs}
-	case storageTypeZfs:
-		zfs := storageZfs{}
-		s = &storageLogWrapper{w: &zfs}
-	case storageTypeLvm:
-		lvm := storageLvm{}
-		s = &storageLogWrapper{w: &lvm}
-	case storageTypeDir:
-		dir := storageDir{}
-		s = &storageLogWrapper{w: &dir}
-	case storageTypeMock:
-		mock := storageMock{}
-		s = &storageLogWrapper{w: &mock}
-	default:
-		return nil, fmt.Errorf("Unknown storage pool driver \"%s\".", poolDriver)
-	}
-
-	return s.StorageCoreInit()
+	return s.StoragePoolInit(config)
 }
 
 func storagePoolVolumeImageInit(d *Daemon, poolName string, imageFingerprint string) (storage, error) {
@@ -433,12 +363,12 @@ func storagePoolVolumeInit(d *Daemon, poolName string, volumeName string, volume
 	var config map[string]interface{}
 
 	// No need to detect storage here, its a new container.
-	wrapper, err := storageWrapperInit(d, poolName, volumeName, volumeType)
+	s, err := storageInit(d, poolName, volumeName, volumeType)
 	if err != nil {
 		return nil, err
 	}
 
-	storage, err := wrapper.StoragePoolInit(config)
+	storage, err := s.StoragePoolInit(config)
 	if err != nil {
 		return nil, err
 	}
@@ -451,58 +381,6 @@ func storagePoolVolumeInit(d *Daemon, poolName string, volumeName string, volume
 	return storage, nil
 }
 
-type storageCore struct {
-	sType        storageType
-	sTypeName    string
-	sTypeVersion string
-	log          shared.Logger
-}
-
-func (sc *storageCore) initShared() error {
-	sc.log = logging.AddContext(
-		shared.Log,
-		log.Ctx{"driver": fmt.Sprintf("storage/%s", sc.sTypeName)},
-	)
-	return nil
-}
-
-// Return a storageCore struct that implements a storageCore interface. This
-// minimal interface only allows to retrieve basic information about the storage
-// type in question.
-func (lw *storageLogWrapper) StorageCoreInit() (*storageCore, error) {
-	sCore, err := lw.w.StorageCoreInit()
-	lw.log = logging.AddContext(
-		shared.Log,
-		log.Ctx{"driver": fmt.Sprintf("storage/%s", sCore.GetStorageTypeName())},
-	)
-
-	lw.log.Debug("StorageCoreInit")
-	return sCore, err
-}
-
-func (sc *storageCore) GetStorageType() storageType {
-	return sc.sType
-}
-
-func (sc *storageCore) GetStorageTypeName() string {
-	return sc.sTypeName
-}
-
-func (sc *storageCore) GetStorageTypeVersion() string {
-	return sc.sTypeVersion
-}
-
-type storageShared struct {
-	storageCore
-
-	d *Daemon
-
-	poolID int64
-	pool   *api.StoragePool
-
-	volume *api.StorageVolume
-}
-
 // {LXD_DIR}/storage-pools/<pool>
 func getStoragePoolMountPoint(poolName string) string {
 	return shared.VarPath("storage-pools", poolName)
@@ -664,392 +542,6 @@ func deleteSnapshotMountpoint(snapshotMountpoint string, snapshotsSymlinkTarget
 	return nil
 }
 
-func (ss *storageShared) shiftRootfs(c container) error {
-	dpath := c.Path()
-	rpath := c.RootfsPath()
-
-	shared.LogDebug("Shifting root filesystem",
-		log.Ctx{"name": c.Name(), "rootfs": rpath})
-
-	idmapset := c.IdmapSet()
-
-	if idmapset == nil {
-		return fmt.Errorf("IdmapSet of container '%s' is nil", c.Name())
-	}
-
-	err := idmapset.ShiftRootfs(rpath)
-	if err != nil {
-		shared.LogDebugf("Shift of rootfs %s failed: %s", rpath, err)
-		return err
-	}
-
-	/* Set an acl so the container root can descend the container dir */
-	// TODO: i changed this so it calls ss.setUnprivUserAcl, which does
-	// the acl change only if the container is not privileged, think thats right.
-	return ss.setUnprivUserAcl(c, dpath)
-}
-
-func (ss *storageShared) setUnprivUserAcl(c container, destPath string) error {
-	idmapset := c.IdmapSet()
-
-	// Skip for privileged containers
-	if idmapset == nil {
-		return nil
-	}
-
-	// Make sure the map is valid. Skip if container uid 0 == host uid 0
-	uid, _ := idmapset.ShiftIntoNs(0, 0)
-	switch uid {
-	case -1:
-		return fmt.Errorf("Container doesn't have a uid 0 in its map")
-	case 0:
-		return nil
-	}
-
-	// Attempt to set a POSIX ACL first. Fallback to chmod if the fs doesn't support it.
-	acl := fmt.Sprintf("%d:rx", uid)
-	_, err := exec.Command("setfacl", "-m", acl, destPath).CombinedOutput()
-	if err != nil {
-		_, err := exec.Command("chmod", "+x", destPath).CombinedOutput()
-		if err != nil {
-			return fmt.Errorf("Failed to chmod the container path: %s.", err)
-		}
-	}
-
-	return nil
-}
-
-func (ss *storageShared) createImageDbPoolVolume(fingerprint string) error {
-	// Fill in any default volume config.
-	volumeConfig := map[string]string{}
-	err := storageVolumeFillDefault(ss.pool.Name, volumeConfig, ss.pool)
-	if err != nil {
-		return err
-	}
-
-	// Create a db entry for the storage volume of the image.
-	_, err = dbStoragePoolVolumeCreate(ss.d.db, fingerprint, storagePoolVolumeTypeImage, ss.poolID, volumeConfig)
-	if err != nil {
-		// Try to delete the db entry on error.
-		dbStoragePoolVolumeDelete(ss.d.db, fingerprint, storagePoolVolumeTypeImage, ss.poolID)
-		return err
-	}
-
-	return nil
-}
-
-func (ss *storageShared) deleteImageDbPoolVolume(fingerprint string) error {
-	err := dbStoragePoolVolumeDelete(ss.d.db, fingerprint, storagePoolVolumeTypeImage, ss.poolID)
-	if err != nil {
-		return err
-	}
-
-	return nil
-}
-
-type storageLogWrapper struct {
-	w   storage
-	log shared.Logger
-}
-
-func (lw *storageLogWrapper) StoragePoolInit(config map[string]interface{}) (storage, error) {
-	_, err := lw.w.StoragePoolInit(config)
-	lw.log = logging.AddContext(
-		shared.Log,
-		log.Ctx{"driver": fmt.Sprintf("storage/%s", lw.w.GetStorageTypeName())},
-	)
-
-	lw.log.Debug("StoragePoolInit")
-	return lw, err
-}
-
-func (lw *storageLogWrapper) StoragePoolCheck() error {
-	lw.log.Debug("StoragePoolCheck")
-	return lw.w.StoragePoolCheck()
-}
-
-func (lw *storageLogWrapper) GetStorageType() storageType {
-	return lw.w.GetStorageType()
-}
-
-func (lw *storageLogWrapper) GetStorageTypeName() string {
-	return lw.w.GetStorageTypeName()
-}
-
-func (lw *storageLogWrapper) GetStorageTypeVersion() string {
-	return lw.w.GetStorageTypeVersion()
-}
-
-func (lw *storageLogWrapper) StoragePoolCreate() error {
-	lw.log.Debug("StoragePoolCreate")
-	return lw.w.StoragePoolCreate()
-}
-
-func (lw *storageLogWrapper) StoragePoolVolumeCreate() error {
-	lw.log.Debug("StoragePoolVolumeCreate")
-	return lw.w.StoragePoolVolumeCreate()
-}
-
-func (lw *storageLogWrapper) StoragePoolVolumeDelete() error {
-	lw.log.Debug("StoragePoolVolumeDelete")
-	return lw.w.StoragePoolVolumeDelete()
-}
-
-func (lw *storageLogWrapper) StoragePoolMount() (bool, error) {
-	lw.log.Debug("StoragePoolMount")
-	return lw.w.StoragePoolMount()
-}
-
-func (lw *storageLogWrapper) StoragePoolUmount() (bool, error) {
-	lw.log.Debug("StoragePoolUmount")
-	return lw.w.StoragePoolUmount()
-}
-
-func (lw *storageLogWrapper) StoragePoolVolumeMount() (bool, error) {
-	lw.log.Debug("StoragePoolVolumeMount")
-	return lw.w.StoragePoolVolumeMount()
-}
-
-func (lw *storageLogWrapper) StoragePoolVolumeUmount() (bool, error) {
-	lw.log.Debug("StoragePoolVolumeUmount")
-	return lw.w.StoragePoolVolumeUmount()
-}
-
-func (lw *storageLogWrapper) StoragePoolDelete() error {
-	lw.log.Debug("StoragePoolDelete")
-	return lw.w.StoragePoolDelete()
-}
-
-func (lw *storageLogWrapper) StoragePoolUpdate(changedConfig []string) error {
-	lw.log.Debug("StoragePoolUpdate")
-	return lw.w.StoragePoolUpdate(changedConfig)
-}
-
-func (lw *storageLogWrapper) StoragePoolVolumeUpdate(changedConfig []string) error {
-	lw.log.Debug("StoragePoolVolumeUpdate")
-	return lw.w.StoragePoolVolumeUpdate(changedConfig)
-}
-
-func (lw *storageLogWrapper) GetStoragePoolWritable() api.StoragePoolPut {
-	return lw.w.GetStoragePoolWritable()
-}
-
-func (lw *storageLogWrapper) GetStoragePoolVolumeWritable() api.StorageVolumePut {
-	return lw.w.GetStoragePoolVolumeWritable()
-}
-
-func (lw *storageLogWrapper) SetStoragePoolWritable(writable *api.StoragePoolPut) {
-	lw.w.SetStoragePoolWritable(writable)
-}
-
-func (lw *storageLogWrapper) SetStoragePoolVolumeWritable(writable *api.StorageVolumePut) {
-	lw.w.SetStoragePoolVolumeWritable(writable)
-}
-
-func (lw *storageLogWrapper) ContainerPoolGet() string {
-	return lw.w.ContainerPoolGet()
-}
-
-func (lw *storageLogWrapper) ContainerPoolIDGet() int64 {
-	return lw.w.ContainerPoolIDGet()
-}
-
-func (lw *storageLogWrapper) ContainerStorageReady(name string) bool {
-	return lw.w.ContainerStorageReady(name)
-}
-
-func (lw *storageLogWrapper) ContainerCreate(container container) error {
-	lw.log.Debug(
-		"ContainerCreate",
-		log.Ctx{
-			"name":       container.Name(),
-			"privileged": container.IsPrivileged()})
-	return lw.w.ContainerCreate(container)
-}
-
-func (lw *storageLogWrapper) ContainerCreateFromImage(
-	container container, imageFingerprint string) error {
-
-	lw.log.Debug(
-		"ContainerCreateFromImage",
-		log.Ctx{
-			"fingerprint": imageFingerprint,
-			"name":        container.Name(),
-			"privileged":  container.IsPrivileged()})
-	return lw.w.ContainerCreateFromImage(container, imageFingerprint)
-}
-
-func (lw *storageLogWrapper) ContainerCanRestore(container container, sourceContainer container) error {
-	lw.log.Debug("ContainerCanRestore", log.Ctx{"name": container.Name()})
-	return lw.w.ContainerCanRestore(container, sourceContainer)
-}
-
-func (lw *storageLogWrapper) ContainerDelete(container container) error {
-	lw.log.Debug("ContainerDelete", log.Ctx{"name": container.Name()})
-	return lw.w.ContainerDelete(container)
-}
-
-func (lw *storageLogWrapper) ContainerCopy(
-	container container, sourceContainer container) error {
-
-	lw.log.Debug(
-		"ContainerCopy",
-		log.Ctx{
-			"target": container.Name(),
-			"source": sourceContainer.Name()})
-	return lw.w.ContainerCopy(container, sourceContainer)
-}
-
-func (lw *storageLogWrapper) ContainerMount(name string, path string) (bool, error) {
-	lw.log.Debug("ContainerMount", log.Ctx{"container": name})
-	return lw.w.ContainerMount(name, path)
-}
-
-func (lw *storageLogWrapper) ContainerUmount(name string, path string) (bool, error) {
-	lw.log.Debug("ContainerUmount", log.Ctx{"name": name})
-	return lw.w.ContainerUmount(name, path)
-}
-
-func (lw *storageLogWrapper) ContainerRename(
-	container container, newName string) error {
-
-	lw.log.Debug(
-		"ContainerRename",
-		log.Ctx{
-			"oldname": container.Name(),
-			"newname": newName})
-	return lw.w.ContainerRename(container, newName)
-}
-
-func (lw *storageLogWrapper) ContainerRestore(
-	container container, sourceContainer container) error {
-
-	lw.log.Debug(
-		"ContainerRestore",
-		log.Ctx{
-			"target": container.Name(),
-			"source": sourceContainer.Name()})
-	return lw.w.ContainerRestore(container, sourceContainer)
-}
-
-func (lw *storageLogWrapper) ContainerSetQuota(
-	container container, size int64) error {
-
-	lw.log.Debug(
-		"ContainerSetQuota",
-		log.Ctx{
-			"name": container.Name(),
-			"size": size})
-	return lw.w.ContainerSetQuota(container, size)
-}
-
-func (lw *storageLogWrapper) ContainerGetUsage(
-	container container) (int64, error) {
-
-	lw.log.Debug(
-		"ContainerGetUsage",
-		log.Ctx{
-			"name": container.Name()})
-	return lw.w.ContainerGetUsage(container)
-}
-
-func (lw *storageLogWrapper) ContainerSnapshotCreate(
-	snapshotContainer container, sourceContainer container) error {
-
-	lw.log.Debug("ContainerSnapshotCreate",
-		log.Ctx{
-			"target": snapshotContainer.Name(),
-			"source": sourceContainer.Name()})
-
-	return lw.w.ContainerSnapshotCreate(snapshotContainer, sourceContainer)
-}
-
-func (lw *storageLogWrapper) ContainerSnapshotCreateEmpty(snapshotContainer container) error {
-	lw.log.Debug("ContainerSnapshotCreateEmpty",
-		log.Ctx{
-			"name": snapshotContainer.Name()})
-
-	return lw.w.ContainerSnapshotCreateEmpty(snapshotContainer)
-}
-
-func (lw *storageLogWrapper) ContainerSnapshotDelete(
-	snapshotContainer container) error {
-
-	lw.log.Debug("ContainerSnapshotDelete",
-		log.Ctx{"name": snapshotContainer.Name()})
-	return lw.w.ContainerSnapshotDelete(snapshotContainer)
-}
-
-func (lw *storageLogWrapper) ContainerSnapshotRename(
-	snapshotContainer container, newName string) error {
-
-	lw.log.Debug("ContainerSnapshotRename",
-		log.Ctx{
-			"oldname": snapshotContainer.Name(),
-			"newname": newName})
-	return lw.w.ContainerSnapshotRename(snapshotContainer, newName)
-}
-
-func (lw *storageLogWrapper) ContainerSnapshotStart(container container) error {
-	lw.log.Debug("ContainerSnapshotStart", log.Ctx{"name": container.Name()})
-	return lw.w.ContainerSnapshotStart(container)
-}
-
-func (lw *storageLogWrapper) ContainerSnapshotStop(container container) error {
-	lw.log.Debug("ContainerSnapshotStop", log.Ctx{"name": container.Name()})
-	return lw.w.ContainerSnapshotStop(container)
-}
-
-func (lw *storageLogWrapper) ImageCreate(fingerprint string) error {
-	lw.log.Debug("ImageCreate", log.Ctx{"fingerprint": fingerprint})
-	return lw.w.ImageCreate(fingerprint)
-}
-
-func (lw *storageLogWrapper) ImageDelete(fingerprint string) error {
-	lw.log.Debug("ImageDelete", log.Ctx{"fingerprint": fingerprint})
-	return lw.w.ImageDelete(fingerprint)
-}
-
-func (lw *storageLogWrapper) ImageMount(fingerprint string) (bool, error) {
-	lw.log.Debug("ImageMount", log.Ctx{"fingerprint": fingerprint})
-	return lw.w.ImageMount(fingerprint)
-}
-
-func (lw *storageLogWrapper) ImageUmount(fingerprint string) (bool, error) {
-	lw.log.Debug("ImageUmount", log.Ctx{"fingerprint": fingerprint})
-	return lw.w.ImageUmount(fingerprint)
-}
-
-func (lw *storageLogWrapper) MigrationType() MigrationFSType {
-	return lw.w.MigrationType()
-}
-
-func (lw *storageLogWrapper) PreservesInodes() bool {
-	return lw.w.PreservesInodes()
-}
-
-func (lw *storageLogWrapper) MigrationSource(container container) (MigrationStorageSourceDriver, error) {
-	lw.log.Debug("MigrationSource", log.Ctx{"name": container.Name()})
-	return lw.w.MigrationSource(container)
-}
-
-func (lw *storageLogWrapper) MigrationSink(live bool, container container, objects []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation) error {
-	objNames := []string{}
-	for _, obj := range objects {
-		objNames = append(objNames, obj.GetName())
-	}
-
-	lw.log.Debug("MigrationSink", log.Ctx{
-		"live":         live,
-		"name":         container.Name(),
-		"objects":      objNames,
-		"source idmap": *srcIdmap,
-		"op":           op,
-	})
-
-	return lw.w.MigrationSink(live, container, objects, conn, srcIdmap, op)
-}
-
 func ShiftIfNecessary(container container, srcIdmap *shared.IdmapSet) error {
 	dstIdmap := container.IdmapSet()
 	if dstIdmap == nil {
@@ -1077,165 +569,6 @@ func ShiftIfNecessary(container container, srcIdmap *shared.IdmapSet) error {
 	return nil
 }
 
-type rsyncStorageSourceDriver struct {
-	container container
-	snapshots []container
-}
-
-func (s rsyncStorageSourceDriver) Snapshots() []container {
-	return s.snapshots
-}
-
-func (s rsyncStorageSourceDriver) SendWhileRunning(conn *websocket.Conn, op *operation) error {
-	for _, send := range s.snapshots {
-		if err := send.StorageStart(); err != nil {
-			return err
-		}
-		defer send.StorageStop()
-
-		path := send.Path()
-		wrapper := StorageProgressReader(op, "fs_progress", send.Name())
-		if err := RsyncSend(shared.AddSlash(path), conn, wrapper); err != nil {
-			return err
-		}
-	}
-
-	wrapper := StorageProgressReader(op, "fs_progress", s.container.Name())
-	return RsyncSend(shared.AddSlash(s.container.Path()), conn, wrapper)
-}
-
-func (s rsyncStorageSourceDriver) SendAfterCheckpoint(conn *websocket.Conn) error {
-	/* resync anything that changed between our first send and the checkpoint */
-	return RsyncSend(shared.AddSlash(s.container.Path()), conn, nil)
-}
-
-func (s rsyncStorageSourceDriver) Cleanup() {
-	/* no-op */
-}
-
-func rsyncMigrationSource(container container) (MigrationStorageSourceDriver, error) {
-	snapshots, err := container.Snapshots()
-	if err != nil {
-		return nil, err
-	}
-
-	return rsyncStorageSourceDriver{container, snapshots}, nil
-}
-
-func snapshotProtobufToContainerArgs(containerName string, snap *Snapshot) containerArgs {
-	config := map[string]string{}
-
-	for _, ent := range snap.LocalConfig {
-		config[ent.GetKey()] = ent.GetValue()
-	}
-
-	devices := types.Devices{}
-	for _, ent := range snap.LocalDevices {
-		props := map[string]string{}
-		for _, prop := range ent.Config {
-			props[prop.GetKey()] = prop.GetValue()
-		}
-
-		devices[ent.GetName()] = props
-	}
-
-	name := containerName + shared.SnapshotDelimiter + snap.GetName()
-	return containerArgs{
-		Name:         name,
-		Ctype:        cTypeSnapshot,
-		Config:       config,
-		Profiles:     snap.Profiles,
-		Ephemeral:    snap.GetEphemeral(),
-		Devices:      devices,
-		Architecture: int(snap.GetArchitecture()),
-		Stateful:     snap.GetStateful(),
-	}
-}
-
-func rsyncMigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation) error {
-	if err := container.StorageStart(); err != nil {
-		return err
-	}
-	defer container.StorageStop()
-
-	isDirBackend := container.Storage().GetStorageType() == storageTypeDir
-	if isDirBackend {
-		for _, snap := range snapshots {
-			args := snapshotProtobufToContainerArgs(container.Name(), snap)
-			// Unset the pool of the orginal container and let
-			// containerLXCCreate figure out on which pool to  send
-			// it. Later we might make this more flexible.
-			for k, v := range args.Devices {
-				if v["type"] == "disk" && v["path"] == "/" {
-					args.Devices[k]["pool"] = ""
-				}
-			}
-			s, err := containerCreateEmptySnapshot(container.Daemon(), args)
-			if err != nil {
-				return err
-			}
-
-			wrapper := StorageProgressWriter(op, "fs_progress", s.Name())
-			if err := RsyncRecv(shared.AddSlash(s.Path()), conn, wrapper); err != nil {
-				return err
-			}
-
-			if err := ShiftIfNecessary(container, srcIdmap); err != nil {
-				return err
-			}
-		}
-
-		wrapper := StorageProgressWriter(op, "fs_progress", container.Name())
-		if err := RsyncRecv(shared.AddSlash(container.Path()), conn, wrapper); err != nil {
-			return err
-		}
-	} else {
-		for _, snap := range snapshots {
-			args := snapshotProtobufToContainerArgs(container.Name(), snap)
-			// Unset the pool of the orginal container and let
-			// containerLXCCreate figure out on which pool to  send
-			// it. Later we might make this more flexible.
-			for k, v := range args.Devices {
-				if v["type"] == "disk" && v["path"] == "/" {
-					args.Devices[k]["pool"] = ""
-				}
-			}
-			wrapper := StorageProgressWriter(op, "fs_progress", snap.GetName())
-			if err := RsyncRecv(shared.AddSlash(container.Path()), conn, wrapper); err != nil {
-				return err
-			}
-
-			if err := ShiftIfNecessary(container, srcIdmap); err != nil {
-				return err
-			}
-
-			_, err := containerCreateAsSnapshot(container.Daemon(), args, container)
-			if err != nil {
-				return err
-			}
-		}
-
-		wrapper := StorageProgressWriter(op, "fs_progress", container.Name())
-		if err := RsyncRecv(shared.AddSlash(container.Path()), conn, wrapper); err != nil {
-			return err
-		}
-	}
-
-	if live {
-		/* now receive the final sync */
-		wrapper := StorageProgressWriter(op, "fs_progress", container.Name())
-		if err := RsyncRecv(shared.AddSlash(container.Path()), conn, wrapper); err != nil {
-			return err
-		}
-	}
-
-	if err := ShiftIfNecessary(container, srcIdmap); err != nil {
-		return err
-	}
-
-	return nil
-}
-
 // Useful functions for unreliable backends
 func tryExec(name string, arg ...string) ([]byte, error) {
 	var err error

From 9ed3c873541a0391bb924ca008b5b61b54166f95 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 24 Feb 2017 15:45:25 +0100
Subject: [PATCH 02/10] lxd/storage_core: move core parts to separate file

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_core.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 lxd/storage_core.go

diff --git a/lxd/storage_core.go b/lxd/storage_core.go
new file mode 100644
index 0000000..79ebe15
--- /dev/null
+++ b/lxd/storage_core.go
@@ -0,0 +1,55 @@
+package main
+
+import (
+	"fmt"
+)
+
+type storageCoreInfo interface {
+	StorageCoreInit() (*storageCore, error)
+	GetStorageType() storageType
+	GetStorageTypeName() string
+	GetStorageTypeVersion() string
+}
+
+type storageCore struct {
+	sType        storageType
+	sTypeName    string
+	sTypeVersion string
+}
+
+func (sc *storageCore) GetStorageType() storageType {
+	return sc.sType
+}
+
+func (sc *storageCore) GetStorageTypeName() string {
+	return sc.sTypeName
+}
+
+func (sc *storageCore) GetStorageTypeVersion() string {
+	return sc.sTypeVersion
+}
+
+func storagePoolCoreInit(poolDriver string) (*storageCore, error) {
+	sType, err := storageStringToType(poolDriver)
+	if err != nil {
+		return nil, err
+	}
+
+	var s storage
+	switch sType {
+	case storageTypeBtrfs:
+		s = &storageBtrfs{}
+	case storageTypeZfs:
+		s = &storageZfs{}
+	case storageTypeLvm:
+		s = &storageLvm{}
+	case storageTypeDir:
+		s = &storageDir{}
+	case storageTypeMock:
+		s = &storageMock{}
+	default:
+		return nil, fmt.Errorf("Unknown storage pool driver \"%s\".", poolDriver)
+	}
+
+	return s.StorageCoreInit()
+}

From b9b39629d70a4956dcd66634fb0095cf12359b28 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 24 Feb 2017 15:45:52 +0100
Subject: [PATCH 03/10] lxd/storage_shared: move shared to separate file

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_shared.go | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)
 create mode 100644 lxd/storage_shared.go

diff --git a/lxd/storage_shared.go b/lxd/storage_shared.go
new file mode 100644
index 0000000..b6aa661
--- /dev/null
+++ b/lxd/storage_shared.go
@@ -0,0 +1,102 @@
+package main
+
+import (
+	"fmt"
+	"os/exec"
+
+	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/api"
+)
+
+type storageShared struct {
+	storageCore
+
+	d *Daemon
+
+	poolID int64
+	pool   *api.StoragePool
+
+	volume *api.StorageVolume
+}
+
+func (ss *storageShared) shiftRootfs(c container) error {
+	dpath := c.Path()
+	rpath := c.RootfsPath()
+
+	shared.LogDebugf("Shifting root filesystem \"%s\" for \"%s\".", rpath, c.Name())
+
+	idmapset := c.IdmapSet()
+
+	if idmapset == nil {
+		return fmt.Errorf("IdmapSet of container '%s' is nil", c.Name())
+	}
+
+	err := idmapset.ShiftRootfs(rpath)
+	if err != nil {
+		shared.LogDebugf("Shift of rootfs %s failed: %s", rpath, err)
+		return err
+	}
+
+	/* Set an acl so the container root can descend the container dir */
+	// TODO: i changed this so it calls ss.setUnprivUserAcl, which does
+	// the acl change only if the container is not privileged, think thats right.
+	return ss.setUnprivUserAcl(c, dpath)
+}
+
+func (ss *storageShared) setUnprivUserAcl(c container, destPath string) error {
+	idmapset := c.IdmapSet()
+
+	// Skip for privileged containers
+	if idmapset == nil {
+		return nil
+	}
+
+	// Make sure the map is valid. Skip if container uid 0 == host uid 0
+	uid, _ := idmapset.ShiftIntoNs(0, 0)
+	switch uid {
+	case -1:
+		return fmt.Errorf("Container doesn't have a uid 0 in its map")
+	case 0:
+		return nil
+	}
+
+	// Attempt to set a POSIX ACL first. Fallback to chmod if the fs doesn't support it.
+	acl := fmt.Sprintf("%d:rx", uid)
+	_, err := exec.Command("setfacl", "-m", acl, destPath).CombinedOutput()
+	if err != nil {
+		_, err := exec.Command("chmod", "+x", destPath).CombinedOutput()
+		if err != nil {
+			return fmt.Errorf("Failed to chmod the container path: %s.", err)
+		}
+	}
+
+	return nil
+}
+
+func (ss *storageShared) createImageDbPoolVolume(fingerprint string) error {
+	// Fill in any default volume config.
+	volumeConfig := map[string]string{}
+	err := storageVolumeFillDefault(ss.pool.Name, volumeConfig, ss.pool)
+	if err != nil {
+		return err
+	}
+
+	// Create a db entry for the storage volume of the image.
+	_, err = dbStoragePoolVolumeCreate(ss.d.db, fingerprint, storagePoolVolumeTypeImage, ss.poolID, volumeConfig)
+	if err != nil {
+		// Try to delete the db entry on error.
+		dbStoragePoolVolumeDelete(ss.d.db, fingerprint, storagePoolVolumeTypeImage, ss.poolID)
+		return err
+	}
+
+	return nil
+}
+
+func (ss *storageShared) deleteImageDbPoolVolume(fingerprint string) error {
+	err := dbStoragePoolVolumeDelete(ss.d.db, fingerprint, storagePoolVolumeTypeImage, ss.poolID)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}

From 7efaa844c7059c0b73c87a8cbf47280a626ac4f4 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 24 Feb 2017 15:46:13 +0100
Subject: [PATCH 04/10] lxd/storage_migration: move to separate file

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_migration.go | 189 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 189 insertions(+)
 create mode 100644 lxd/storage_migration.go

diff --git a/lxd/storage_migration.go b/lxd/storage_migration.go
new file mode 100644
index 0000000..35ae15d
--- /dev/null
+++ b/lxd/storage_migration.go
@@ -0,0 +1,189 @@
+package main
+
+import (
+	"github.com/gorilla/websocket"
+
+	"github.com/lxc/lxd/lxd/types"
+	"github.com/lxc/lxd/shared"
+)
+
+type MigrationStorageSourceDriver interface {
+	/* snapshots for this container, if any */
+	Snapshots() []container
+
+	/* send any bits of the container/snapshots that are possible while the
+	 * container is still running.
+	 */
+	SendWhileRunning(conn *websocket.Conn, op *operation) error
+
+	/* send the final bits (e.g. a final delta snapshot for zfs, btrfs, or
+	 * do a final rsync) of the fs after the container has been
+	 * checkpointed. This will only be called when a container is actually
+	 * being live migrated.
+	 */
+	SendAfterCheckpoint(conn *websocket.Conn) error
+
+	/* Called after either success or failure of a migration, can be used
+	 * to clean up any temporary snapshots, etc.
+	 */
+	Cleanup()
+}
+
+type rsyncStorageSourceDriver struct {
+	container container
+	snapshots []container
+}
+
+func (s rsyncStorageSourceDriver) Snapshots() []container {
+	return s.snapshots
+}
+
+func (s rsyncStorageSourceDriver) SendWhileRunning(conn *websocket.Conn, op *operation) error {
+	for _, send := range s.snapshots {
+		if err := send.StorageStart(); err != nil {
+			return err
+		}
+		defer send.StorageStop()
+
+		path := send.Path()
+		wrapper := StorageProgressReader(op, "fs_progress", send.Name())
+		if err := RsyncSend(shared.AddSlash(path), conn, wrapper); err != nil {
+			return err
+		}
+	}
+
+	wrapper := StorageProgressReader(op, "fs_progress", s.container.Name())
+	return RsyncSend(shared.AddSlash(s.container.Path()), conn, wrapper)
+}
+
+func (s rsyncStorageSourceDriver) SendAfterCheckpoint(conn *websocket.Conn) error {
+	/* resync anything that changed between our first send and the checkpoint */
+	return RsyncSend(shared.AddSlash(s.container.Path()), conn, nil)
+}
+
+func (s rsyncStorageSourceDriver) Cleanup() {
+	/* no-op */
+}
+
+func rsyncMigrationSource(container container) (MigrationStorageSourceDriver, error) {
+	snapshots, err := container.Snapshots()
+	if err != nil {
+		return nil, err
+	}
+
+	return rsyncStorageSourceDriver{container, snapshots}, nil
+}
+
+func snapshotProtobufToContainerArgs(containerName string, snap *Snapshot) containerArgs {
+	config := map[string]string{}
+
+	for _, ent := range snap.LocalConfig {
+		config[ent.GetKey()] = ent.GetValue()
+	}
+
+	devices := types.Devices{}
+	for _, ent := range snap.LocalDevices {
+		props := map[string]string{}
+		for _, prop := range ent.Config {
+			props[prop.GetKey()] = prop.GetValue()
+		}
+
+		devices[ent.GetName()] = props
+	}
+
+	name := containerName + shared.SnapshotDelimiter + snap.GetName()
+	return containerArgs{
+		Name:         name,
+		Ctype:        cTypeSnapshot,
+		Config:       config,
+		Profiles:     snap.Profiles,
+		Ephemeral:    snap.GetEphemeral(),
+		Devices:      devices,
+		Architecture: int(snap.GetArchitecture()),
+		Stateful:     snap.GetStateful(),
+	}
+}
+
+func rsyncMigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation) error {
+	if err := container.StorageStart(); err != nil {
+		return err
+	}
+	defer container.StorageStop()
+
+	isDirBackend := container.Storage().GetStorageType() == storageTypeDir
+	if isDirBackend {
+		for _, snap := range snapshots {
+			args := snapshotProtobufToContainerArgs(container.Name(), snap)
+			// Unset the pool of the orginal container and let
+			// containerLXCCreate figure out on which pool to  send
+			// it. Later we might make this more flexible.
+			for k, v := range args.Devices {
+				if v["type"] == "disk" && v["path"] == "/" {
+					args.Devices[k]["pool"] = ""
+				}
+			}
+			s, err := containerCreateEmptySnapshot(container.Daemon(), args)
+			if err != nil {
+				return err
+			}
+
+			wrapper := StorageProgressWriter(op, "fs_progress", s.Name())
+			if err := RsyncRecv(shared.AddSlash(s.Path()), conn, wrapper); err != nil {
+				return err
+			}
+
+			if err := ShiftIfNecessary(container, srcIdmap); err != nil {
+				return err
+			}
+		}
+
+		wrapper := StorageProgressWriter(op, "fs_progress", container.Name())
+		if err := RsyncRecv(shared.AddSlash(container.Path()), conn, wrapper); err != nil {
+			return err
+		}
+	} else {
+		for _, snap := range snapshots {
+			args := snapshotProtobufToContainerArgs(container.Name(), snap)
+			// Unset the pool of the orginal container and let
+			// containerLXCCreate figure out on which pool to  send
+			// it. Later we might make this more flexible.
+			for k, v := range args.Devices {
+				if v["type"] == "disk" && v["path"] == "/" {
+					args.Devices[k]["pool"] = ""
+				}
+			}
+			wrapper := StorageProgressWriter(op, "fs_progress", snap.GetName())
+			if err := RsyncRecv(shared.AddSlash(container.Path()), conn, wrapper); err != nil {
+				return err
+			}
+
+			if err := ShiftIfNecessary(container, srcIdmap); err != nil {
+				return err
+			}
+
+			_, err := containerCreateAsSnapshot(container.Daemon(), args, container)
+			if err != nil {
+				return err
+			}
+		}
+
+		wrapper := StorageProgressWriter(op, "fs_progress", container.Name())
+		if err := RsyncRecv(shared.AddSlash(container.Path()), conn, wrapper); err != nil {
+			return err
+		}
+	}
+
+	if live {
+		/* now receive the final sync */
+		wrapper := StorageProgressWriter(op, "fs_progress", container.Name())
+		if err := RsyncRecv(shared.AddSlash(container.Path()), conn, wrapper); err != nil {
+			return err
+		}
+	}
+
+	if err := ShiftIfNecessary(container, srcIdmap); err != nil {
+		return err
+	}
+
+	return nil
+}

From f3c00d45f8738d13e2bb309a03131ca831258808 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 24 Feb 2017 15:46:43 +0100
Subject: [PATCH 05/10] btrfs: adapt to new layout

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_btrfs.go | 35 ++++++++++++++---------------------
 1 file changed, 14 insertions(+), 21 deletions(-)

diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 36fa57a..6b9d750 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -18,8 +18,6 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
-
-	log "gopkg.in/inconshreveable/log15.v2"
 )
 
 var btrfsMntOptions = "user_subvol_rm_allowed"
@@ -72,10 +70,7 @@ func (s *storageBtrfs) StorageCoreInit() (*storageCore, error) {
 		return nil, fmt.Errorf("The 'btrfs' tool isn't working properly")
 	}
 
-	err = sCore.initShared()
-	if err != nil {
-		return nil, err
-	}
+	shared.LogInfof("Initializing a BTRFS driver.")
 
 	s.storageCore = sCore
 
@@ -174,10 +169,10 @@ func (s *storageBtrfs) StoragePoolCreate() error {
 		// we granted it above. So try to call btrfs filesystem show and
 		// parse it out. (I __hate__ this!)
 		if devUUID == "" {
-			s.log.Warn("Failed to detect UUID by looking at /dev/disk/by-uuid.")
+			shared.LogWarnf("Failed to detect UUID by looking at /dev/disk/by-uuid.")
 			devUUID, err1 = s.btrfsLookupFsUUID(source)
 			if err1 != nil {
-				s.log.Error("Failed to detect UUID by parsing filesystem info.")
+				shared.LogErrorf("Failed to detect UUID by parsing filesystem info.")
 				return err1
 			}
 		}
@@ -269,7 +264,7 @@ func (s *storageBtrfs) StoragePoolDelete() error {
 		} else {
 			msg = fmt.Sprintf("Failed to lookup disk device with UUID: %s: %s.", source, err)
 		}
-		s.log.Debug(msg)
+		shared.LogDebugf(msg)
 	} else {
 		var err error
 		if s.d.BackingFs == "btrfs" {
@@ -302,7 +297,7 @@ func (s *storageBtrfs) StoragePoolMount() (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[poolMountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			s.log.Warn("Received value over semaphore. This should not have happened.")
+			shared.LogWarnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in mounting the storage pool.
@@ -383,7 +378,7 @@ func (s *storageBtrfs) StoragePoolUmount() (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[poolUmountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			s.log.Warn("Received value over semaphore. This should not have happened.")
+			shared.LogWarnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in unmounting the storage pool.
@@ -587,7 +582,7 @@ func (s *storageBtrfs) ContainerCreateFromImage(container container, fingerprint
 	if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			s.log.Warn("Received value over semaphore. This should not have happened.")
+			shared.LogWarnf("Received value over semaphore. This should not have happened.")
 		}
 	} else {
 		lxdStorageOngoingOperationMap[imageStoragePoolLockID] = make(chan bool)
@@ -754,7 +749,7 @@ func (s *storageBtrfs) ContainerCopy(container container, sourceContainer contai
 		output, err := storageRsyncCopy(sourceContainerSubvolumeName, targetContainerSubvolumeName)
 		if err != nil {
 			s.ContainerDelete(container)
-			s.log.Error("ContainerCopy: rsync failed", log.Ctx{"output": string(output)})
+			shared.LogErrorf("ContainerCopy: rsync failed: %s.", string(output))
 			return fmt.Errorf("rsync failed: %s", string(output))
 		}
 	}
@@ -880,7 +875,7 @@ func (s *storageBtrfs) ContainerRestore(container container, sourceContainer con
 			output, err := storageRsyncCopy(sourceContainerSubvolumeName, targetContainerSubvolumeName)
 			if err != nil {
 				s.ContainerDelete(container)
-				s.log.Error("ContainerRestore: rsync failed", log.Ctx{"output": string(output)})
+				shared.LogErrorf("ContainerRestore: rsync failed: %s.", string(output))
 				failure = err
 			}
 		} else {
@@ -1427,9 +1422,7 @@ func (s *storageBtrfs) btrfsPoolVolumesSnapshot(source string, dest string, read
 		// also don't make subvolumes readonly.
 		readonly = false
 
-		s.log.Warn(
-			"Subvolumes detected, ignoring ro flag",
-			log.Ctx{"source": source, "dest": dest})
+		shared.LogWarnf("Subvolumes detected, ignoring ro flag.")
 	}
 
 	// First snapshot the root
@@ -1741,12 +1734,12 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 
 		output, err := ioutil.ReadAll(stderr)
 		if err != nil {
-			s.log.Debug(fmt.Sprintf("problem reading btrfs receive stderr %s", err))
+			shared.LogDebugf("Problem reading btrfs receive stderr %s.", err)
 		}
 
 		err = cmd.Wait()
 		if err != nil {
-			s.log.Error("problem with btrfs receive", log.Ctx{"output": string(output)})
+			shared.LogErrorf("Problem with btrfs receive: %s.", string(output))
 			return err
 		}
 
@@ -1758,13 +1751,13 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 			err = s.btrfsPoolVolumesSnapshot(btrfsPath, targetPath, true)
 		}
 		if err != nil {
-			s.log.Error("problem with btrfs snapshot", log.Ctx{"err": err})
+			shared.LogErrorf("Problem with btrfs snapshot: %s.", err)
 			return err
 		}
 
 		err = btrfsSubVolumesDelete(btrfsPath)
 		if err != nil {
-			s.log.Error("problem with btrfs delete", log.Ctx{"err": err})
+			shared.LogErrorf("Problem with btrfs delete: %s.", err)
 			return err
 		}
 

From cef2fad677e529589cf286f1e9c1549a21bd9dc3 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 24 Feb 2017 15:46:57 +0100
Subject: [PATCH 06/10] dir: adapt to new layout

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_dir.go | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 75793d8..fe2b582 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -28,10 +28,7 @@ func (s *storageDir) StorageCoreInit() (*storageCore, error) {
 	sCore.sTypeName = typeName
 	sCore.sTypeVersion = "1"
 
-	err = sCore.initShared()
-	if err != nil {
-		return nil, err
-	}
+	shared.LogInfof("Initializing a DIR driver.")
 
 	s.storageCore = sCore
 
@@ -507,11 +504,11 @@ func (s *storageDir) ContainerSnapshotCreate(snapshotContainer container, source
 	if sourceContainer.IsRunning() {
 		// This is done to ensure consistency when snapshotting. But we
 		// probably shouldn't fail just because of that.
-		s.log.Debug("Trying to freeze and rsync again to ensure consistency.")
+		shared.LogDebugf("Trying to freeze and rsync again to ensure consistency.")
 
 		err := sourceContainer.Freeze()
 		if err != nil {
-			s.log.Warn("Trying to freeze and rsync again failed.")
+			shared.LogWarnf("Trying to freeze and rsync again failed.")
 			return nil
 		}
 

From 283835b551f005eff3c877a230b70182357c95ba Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 24 Feb 2017 15:47:21 +0100
Subject: [PATCH 07/10] lvm: adapt to new layout

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_lvm.go | 61 +++++++++++++++++++++++++-----------------------------
 1 file changed, 28 insertions(+), 33 deletions(-)

diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index d319292..756adc7 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -13,8 +13,6 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
-
-	log "gopkg.in/inconshreveable/log15.v2"
 )
 
 func storagePVExists(pvName string) (bool, error) {
@@ -261,10 +259,7 @@ func (s *storageLvm) StorageCoreInit() (*storageCore, error) {
 		sCore.sTypeVersion += strings.TrimSpace(fields[1])
 	}
 
-	err = sCore.initShared()
-	if err != nil {
-		return nil, err
-	}
+	shared.LogInfof("Initializing an LVM driver.")
 
 	s.storageCore = sCore
 
@@ -484,7 +479,7 @@ func (s *storageLvm) StoragePoolVolumeCreate() error {
 
 	err = s.createThinLV(poolName, thinPoolName, s.volume.Name, lvFsType, lvSize, volumeType)
 	if err != nil {
-		s.log.Error("LVMCreateThinLV", log.Ctx{"err": err})
+		shared.LogErrorf("LVMCreateThinLV: %s.", err)
 		return fmt.Errorf("Error Creating LVM LV for new image: %v", err)
 	}
 	defer func() {
@@ -553,7 +548,7 @@ func (s *storageLvm) StoragePoolVolumeMount() (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[customMountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			s.log.Warn("Received value over semaphore. This should not have happened.")
+			shared.LogWarnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in mounting the storage volume.
@@ -592,7 +587,7 @@ func (s *storageLvm) StoragePoolVolumeUmount() (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[customUmountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			s.log.Warn("Received value over semaphore. This should not have happened.")
+			shared.LogWarnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in unmounting the storage volume.
@@ -777,7 +772,7 @@ func (s *storageLvm) ContainerCreateFromImage(container container, fingerprint s
 	if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			s.log.Warn("Received value over semaphore. This should not have happened.")
+			shared.LogWarnf("Received value over semaphore. This should not have happened.")
 		}
 	} else {
 		lxdStorageOngoingOperationMap[imageStoragePoolLockID] = make(chan bool)
@@ -859,7 +854,7 @@ func (s *storageLvm) ContainerCreateFromImage(container container, fingerprint s
 
 	err = container.TemplateApply("create")
 	if err != nil {
-		s.log.Error("Error in create template during ContainerCreateFromImage, continuing to unmount", log.Ctx{"err": err})
+		shared.LogErrorf("Error in create template during ContainerCreateFromImage, continuing to unmount: %s.", err)
 		return err
 	}
 
@@ -929,16 +924,16 @@ func (s *storageLvm) ContainerCopy(container container, sourceContainer containe
 	if sourceContainer.Storage().GetStorageType() == storageTypeLvm {
 		err := s.createSnapshotContainer(container, sourceContainer, false)
 		if err != nil {
-			s.log.Error("Error creating snapshot LV for copy", log.Ctx{"err": err})
+			shared.LogErrorf("Error creating snapshot LV for copy: %s.", err)
 			return err
 		}
 	} else {
 		sourceContainerName := sourceContainer.Name()
 		targetContainerName := container.Name()
-		s.log.Info("Copy from Non-LVM container", log.Ctx{"container": targetContainerName, "sourceContainer": sourceContainerName})
+		shared.LogInfof("Copy from Non-LVM container: %s -> %s.", sourceContainerName, targetContainerName)
 		err := s.ContainerCreate(container)
 		if err != nil {
-			s.log.Error("Error creating empty container", log.Ctx{"err": err})
+			shared.LogErrorf("Error creating empty container: %s.", err)
 			return err
 		}
 		defer func() {
@@ -950,7 +945,7 @@ func (s *storageLvm) ContainerCopy(container container, sourceContainer containe
 		targetContainerPath := container.Path()
 		ourSourceMount, err := s.ContainerMount(targetContainerName, targetContainerPath)
 		if err != nil {
-			s.log.Error("Error starting/mounting container", log.Ctx{"err": err, "container": targetContainerName})
+			shared.LogErrorf("Error starting/mounting container \"%s\": %s.", targetContainerName, err)
 			return err
 		}
 		if ourSourceMount {
@@ -971,7 +966,7 @@ func (s *storageLvm) ContainerCopy(container container, sourceContainer containe
 		targetContainerMntPoint := getContainerMountPoint(s.pool.Name, targetContainerName)
 		output, err := storageRsyncCopy(sourceContainerMntPoint, targetContainerMntPoint)
 		if err != nil {
-			s.log.Error("ContainerCopy: rsync failed", log.Ctx{"output": string(output)})
+			shared.LogErrorf("ContainerCopy: rsync failed: %s.", string(output))
 			s.ContainerDelete(container)
 			return fmt.Errorf("rsync failed: %s", string(output))
 		}
@@ -1000,7 +995,7 @@ func (s *storageLvm) ContainerMount(name string, path string) (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[containerMountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			s.log.Warn("Received value over semaphore. This should not have happened.")
+			shared.LogWarnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in mounting the storage volume.
@@ -1039,7 +1034,7 @@ func (s *storageLvm) ContainerUmount(name string, path string) (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[containerUmountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			s.log.Warn("Received value over semaphore. This should not have happened.")
+			shared.LogWarnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in unmounting the storage volume.
@@ -1084,7 +1079,7 @@ func (s *storageLvm) ContainerRename(container container, newContainerName strin
 
 	output, err := s.renameLV(oldLvmName, newLvmName, storagePoolVolumeApiEndpointContainers)
 	if err != nil {
-		s.log.Error("Failed to rename a container LV", log.Ctx{"oldName": oldLvmName, "newName": newLvmName, "err": err, "output": string(output)})
+		shared.LogErrorf("Failed to rename a container LV: %s -> %s: %s.", oldLvmName, newLvmName, string(output))
 		return fmt.Errorf("Failed to rename a container LV, oldName='%s', newName='%s', err='%s'", oldLvmName, newLvmName, err)
 	}
 	defer func() {
@@ -1177,7 +1172,7 @@ func (s *storageLvm) ContainerRestore(container container, sourceContainer conta
 	poolName := s.getOnDiskPoolName()
 	err = s.removeLV(poolName, storagePoolVolumeApiEndpointContainers, destName)
 	if err != nil {
-		s.log.Error(fmt.Sprintf("Failed to remove \"%s\": %s.", destName, err))
+		shared.LogErrorf(fmt.Sprintf("Failed to remove \"%s\": %s.", destName, err))
 	}
 
 	_, err = s.createSnapshotLV(poolName, srcLvName, storagePoolVolumeApiEndpointContainers, destLvName, storagePoolVolumeApiEndpointContainers, false)
@@ -1207,7 +1202,7 @@ func (s *storageLvm) createSnapshotContainer(snapshotContainer container, source
 	targetContainerName := snapshotContainer.Name()
 	sourceContainerLvmName := containerNameToLVName(sourceContainerName)
 	targetContainerLvmName := containerNameToLVName(targetContainerName)
-	s.log.Debug("Creating snapshot", log.Ctx{"srcName": sourceContainerName, "destName": targetContainerName})
+	shared.LogDebugf("Creating snapshot: %s -> %s.", sourceContainerName, targetContainerName)
 
 	poolName := s.getOnDiskPoolName()
 	_, err := s.createSnapshotLV(poolName, sourceContainerLvmName, storagePoolVolumeApiEndpointContainers, targetContainerLvmName, storagePoolVolumeApiEndpointContainers, readonly)
@@ -1262,7 +1257,7 @@ func (s *storageLvm) ContainerSnapshotRename(snapshotContainer container, newCon
 
 	output, err := s.renameLV(oldLvmName, newLvmName, storagePoolVolumeApiEndpointContainers)
 	if err != nil {
-		s.log.Error("Failed to rename a snapshot LV", log.Ctx{"oldName": oldLvmName, "newName": newLvmName, "err": err, "output": string(output)})
+		shared.LogErrorf("Failed to rename a snapshot LV: %s -> %s: %s.", oldLvmName, newLvmName, string(output))
 		return fmt.Errorf("Failed to rename a container LV, oldName='%s', newName='%s', err='%s'", oldLvmName, newLvmName, err)
 	}
 	defer func() {
@@ -1293,7 +1288,7 @@ func (s *storageLvm) ContainerSnapshotStart(container container) error {
 
 	tmpTargetLvmName := getTmpSnapshotName(targetLvmName)
 
-	s.log.Debug("Creating snapshot", log.Ctx{"srcName": sourceLvmName, "destName": targetLvmName})
+	shared.LogDebugf("Creating snapshot: %s -> %s.", sourceLvmName, targetLvmName)
 
 	poolName := s.getOnDiskPoolName()
 	lvpath, err := s.createSnapshotLV(poolName, sourceLvmName, storagePoolVolumeApiEndpointContainers, tmpTargetLvmName, storagePoolVolumeApiEndpointContainers, false)
@@ -1375,7 +1370,7 @@ func (s *storageLvm) ImageCreate(fingerprint string) error {
 
 	err = s.createThinLV(poolName, thinPoolName, fingerprint, lvFsType, lvSize, storagePoolVolumeApiEndpointImages)
 	if err != nil {
-		s.log.Error("LVMCreateThinLV", log.Ctx{"err": err})
+		shared.LogErrorf("LVMCreateThinLV: %s.", err)
 		return fmt.Errorf("Error Creating LVM LV for new image: %v", err)
 	}
 	defer func() {
@@ -1457,7 +1452,7 @@ func (s *storageLvm) ImageMount(fingerprint string) (bool, error) {
 
 	err := tryMount(lvmVolumePath, imageMntPoint, lvmFstype, 0, lvmMountOptions)
 	if err != nil {
-		s.log.Info(fmt.Sprintf("Error mounting image LV for unpacking: %s", err))
+		shared.LogInfof(fmt.Sprintf("Error mounting image LV for unpacking: %s", err))
 		return false, fmt.Errorf("Error mounting image LV: %v", err)
 	}
 
@@ -1492,7 +1487,7 @@ func (s *storageLvm) createThinLV(vgName string, thinPoolName string, lvName str
 
 		err = storageLVMValidateThinPoolName(s.d, vgName, thinPoolName)
 		if err != nil {
-			s.log.Error("Setting thin pool name", log.Ctx{"err": err})
+			shared.LogErrorf("Setting thin pool name: %s.", err)
 			return fmt.Errorf("Error setting LVM thin pool config: %v", err)
 		}
 	}
@@ -1505,7 +1500,7 @@ func (s *storageLvm) createThinLV(vgName string, thinPoolName string, lvName str
 		"-n", lvmPoolVolumeName,
 		"--virtualsize", lvSize+"B", lvmThinPoolPath)
 	if err != nil {
-		s.log.Error("Could not create LV", log.Ctx{"lvname": lvmPoolVolumeName, "output": string(output)})
+		shared.LogErrorf("Could not create LV \"%s\": %s.", lvmPoolVolumeName, string(output))
 		return fmt.Errorf("Could not create thin LV named %s", lvmPoolVolumeName)
 	}
 
@@ -1522,7 +1517,7 @@ func (s *storageLvm) createThinLV(vgName string, thinPoolName string, lvName str
 	}
 
 	if err != nil {
-		s.log.Error("Filesystem creation failed", log.Ctx{"output": string(output)})
+		shared.LogErrorf("Filesystem creation failed: %s.", string(output))
 		return fmt.Errorf("Error making filesystem on image LV: %v", err)
 	}
 
@@ -1553,7 +1548,7 @@ func (s *storageLvm) createDefaultThinPool(vgName string, thinPoolName string, l
 	}
 
 	if err != nil {
-		s.log.Error("Could not create thin pool", log.Ctx{"name": thinPoolName, "err": err, "output": string(output)})
+		shared.LogErrorf("Could not create thin pool \"%s\": %s.", thinPoolName, string(output))
 		return fmt.Errorf("Could not create LVM thin pool named %s", thinPoolName)
 	}
 
@@ -1562,7 +1557,7 @@ func (s *storageLvm) createDefaultThinPool(vgName string, thinPoolName string, l
 		output, err = tryExec("lvextend", "--alloc", "anywhere", "-l", "100%FREE", lvmThinPool)
 
 		if err != nil {
-			s.log.Error("Could not grow thin pool", log.Ctx{"name": thinPoolName, "err": err, "output": string(output)})
+			shared.LogErrorf("Could not grow thin pool: \"%s\": %s.", thinPoolName, string(output))
 			return fmt.Errorf("Could not grow LVM thin pool named %s", thinPoolName)
 		}
 	}
@@ -1575,7 +1570,7 @@ func (s *storageLvm) removeLV(vgName string, volumeType string, lvName string) e
 	output, err := tryExec("lvremove", "-f", lvmVolumePath)
 
 	if err != nil {
-		s.log.Error("Could not remove LV", log.Ctx{"lvname": lvName, "output": string(output)})
+		shared.LogErrorf("Could not remove LV \"%s\": %s.", lvName, string(output))
 		return fmt.Errorf("Could not remove LV named %s", lvName)
 	}
 
@@ -1584,7 +1579,7 @@ func (s *storageLvm) removeLV(vgName string, volumeType string, lvName string) e
 
 func (s *storageLvm) createSnapshotLV(vgName string, origLvName string, origVolumeType string, lvName string, volumeType string, readonly bool) (string, error) {
 	sourceLvmVolumePath := getLvmDevPath(vgName, origVolumeType, origLvName)
-	s.log.Debug("in createSnapshotLV:", log.Ctx{"lvname": lvName, "dev string": sourceLvmVolumePath})
+	shared.LogDebugf("in createSnapshotLV: %s.", sourceLvmVolumePath)
 	isRecent, err := s.lvmVersionIsAtLeast("2.02.99")
 	if err != nil {
 		return "", fmt.Errorf("Error checking LVM version: %v", err)
@@ -1605,7 +1600,7 @@ func (s *storageLvm) createSnapshotLV(vgName string, origLvName string, origVolu
 			"-s", sourceLvmVolumePath)
 	}
 	if err != nil {
-		s.log.Error("Could not create LV snapshot", log.Ctx{"lvname": lvName, "origlvname": origLvName, "output": string(output)})
+		shared.LogErrorf("Could not create LV snapshot: %s -> %s: %s.", origLvName, lvName, string(output))
 		return "", fmt.Errorf("Could not create snapshot LV named %s", lvName)
 	}
 

From eeb1cd10a59fd74c30f15eb1308689484df4d57a Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 24 Feb 2017 15:47:32 +0100
Subject: [PATCH 08/10] mock: adapt to new layout

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_mock.go | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index ab75689..d174134 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -22,10 +22,7 @@ func (s *storageMock) StorageCoreInit() (*storageCore, error) {
 	}
 	sCore.sTypeName = typeName
 
-	err = sCore.initShared()
-	if err != nil {
-		return nil, err
-	}
+	shared.LogInfof("Initializing a MOCK driver.")
 
 	s.storageCore = sCore
 

From 397640cac47a0d63685c3f98b776d4556ad50ced Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 24 Feb 2017 15:47:44 +0100
Subject: [PATCH 09/10] zfs: adapt to new layout

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_zfs.go | 52 ++++++++++++++++++++++++----------------------------
 1 file changed, 24 insertions(+), 28 deletions(-)

diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 6e8ed4a..c1c3574 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -18,7 +18,6 @@ import (
 	"github.com/lxc/lxd/shared/api"
 
 	"github.com/pborman/uuid"
-	log "gopkg.in/inconshreveable/log15.v2"
 )
 
 var zfsUseRefquota = "false"
@@ -74,10 +73,7 @@ func (s *storageZfs) StorageCoreInit() (*storageCore, error) {
 		return nil, err
 	}
 
-	err = sCore.initShared()
-	if err != nil {
-		return nil, err
-	}
+	shared.LogInfof("Initializing a ZFS driver.")
 
 	s.storageCore = sCore
 
@@ -212,7 +208,7 @@ func (s *storageZfs) StoragePoolVolumeMount() (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[customMountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			s.log.Warn("Received value over semaphore. This should not have happened.")
+			shared.LogWarnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in mounting the storage volume.
@@ -252,7 +248,7 @@ func (s *storageZfs) StoragePoolVolumeUmount() (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[customUmountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			s.log.Warn("Received value over semaphore. This should not have happened.")
+			shared.LogWarnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in unmounting the storage volume.
@@ -369,7 +365,7 @@ func (s *storageZfs) ContainerMount(name string, path string) (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[containerMountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			s.log.Warn("Received value over semaphore. This should not have happened.")
+			shared.LogWarnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in mounting the storage volume.
@@ -409,7 +405,7 @@ func (s *storageZfs) ContainerUmount(name string, path string) (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[containerUmountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			s.log.Warn("Received value over semaphore. This should not have happened.")
+			shared.LogWarnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in unmounting the storage volume.
@@ -500,7 +496,7 @@ func (s *storageZfs) ContainerCreateFromImage(container container, fingerprint s
 	if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			s.log.Warn("Received value over semaphore. This should not have happened.")
+			shared.LogWarnf("Received value over semaphore. This should not have happened.")
 		}
 	} else {
 		lxdStorageOngoingOperationMap[imageStoragePoolLockID] = make(chan bool)
@@ -1448,7 +1444,7 @@ func (s *storageZfs) zfsPoolCreate() error {
 						"mountpoint=none",
 						vdev).CombinedOutput()
 					if err != nil {
-						s.log.Error("zfs create failed", log.Ctx{"output": string(output)})
+						shared.LogErrorf("zfs create failed: %s.", string(output))
 						return fmt.Errorf("Failed to create ZFS filesystem: %s", output)
 					}
 				}
@@ -1525,7 +1521,7 @@ func (s *storageZfs) zfsPoolVolumeClone(source string, name string, dest string,
 		fmt.Sprintf("%s/%s@%s", poolName, source, name),
 		fmt.Sprintf("%s/%s", poolName, dest)).CombinedOutput()
 	if err != nil {
-		s.log.Error("zfs clone failed", log.Ctx{"output": string(output)})
+		shared.LogErrorf("zfs clone failed: %s.", string(output))
 		return fmt.Errorf("Failed to clone the filesystem: %s", output)
 	}
 
@@ -1555,7 +1551,7 @@ func (s *storageZfs) zfsPoolVolumeClone(source string, name string, dest string,
 			fmt.Sprintf("%s/%s@%s", poolName, sub, name),
 			fmt.Sprintf("%s/%s", poolName, destSubvol)).CombinedOutput()
 		if err != nil {
-			s.log.Error("zfs clone failed", log.Ctx{"output": string(output)})
+			shared.LogErrorf("zfs clone failed: %s.", string(output))
 			return fmt.Errorf("Failed to clone the sub-volume: %s", output)
 		}
 	}
@@ -1571,7 +1567,7 @@ func (s *storageZfs) zfsPoolVolumeCreate(path string) error {
 		"-p",
 		fmt.Sprintf("%s/%s", poolName, path)).CombinedOutput()
 	if err != nil {
-		s.log.Error("zfs create failed", log.Ctx{"output": string(output)})
+		shared.LogErrorf("zfs create failed: %s.", string(output))
 		return fmt.Errorf("Failed to create ZFS filesystem: %s", output)
 	}
 
@@ -1611,7 +1607,7 @@ func (s *storageZfs) zfsPoolVolumeDestroy(path string) error {
 	if mountpoint != "none" && shared.IsMountPoint(mountpoint) {
 		err := syscall.Unmount(mountpoint, syscall.MNT_DETACH)
 		if err != nil {
-			s.log.Error("umount failed", log.Ctx{"err": err})
+			shared.LogErrorf("umount failed: %s.", err)
 			return err
 		}
 	}
@@ -1625,7 +1621,7 @@ func (s *storageZfs) zfsPoolVolumeDestroy(path string) error {
 		fmt.Sprintf("%s/%s", poolName, path))
 
 	if err != nil {
-		s.log.Error("zfs destroy failed", log.Ctx{"output": string(output)})
+		shared.LogErrorf("zfs destroy failed: %s.", string(output))
 		return fmt.Errorf("Failed to destroy ZFS filesystem: %s", output)
 	}
 
@@ -1764,7 +1760,7 @@ func (s *storageZfs) zfsPoolVolumeRename(source string, dest string) error {
 	}
 
 	// Timeout
-	s.log.Error("zfs rename failed", log.Ctx{"output": string(output)})
+	shared.LogErrorf("zfs rename failed: %s.", string(output))
 	return fmt.Errorf("Failed to rename ZFS filesystem: %s", output)
 }
 
@@ -1776,7 +1772,7 @@ func (s *storageZfs) zfsPoolVolumeSet(path string, key string, value string) err
 		fmt.Sprintf("%s=%s", key, value),
 		fmt.Sprintf("%s/%s", poolName, path)).CombinedOutput()
 	if err != nil {
-		s.log.Error("zfs set failed", log.Ctx{"output": string(output)})
+		shared.LogErrorf("zfs set failed: %s.", string(output))
 		return fmt.Errorf("Failed to set ZFS config: %s", output)
 	}
 
@@ -1791,7 +1787,7 @@ func (s *storageZfs) zfsPoolVolumeSnapshotCreate(path string, name string) error
 		"-r",
 		fmt.Sprintf("%s/%s@%s", poolName, path, name)).CombinedOutput()
 	if err != nil {
-		s.log.Error("zfs snapshot failed", log.Ctx{"output": string(output)})
+		shared.LogErrorf("zfs snapshot failed: %s.", string(output))
 		return fmt.Errorf("Failed to create ZFS snapshot: %s", output)
 	}
 
@@ -1806,7 +1802,7 @@ func (s *storageZfs) zfsPoolVolumeSnapshotDestroy(path string, name string) erro
 		"-r",
 		fmt.Sprintf("%s/%s@%s", poolName, path, name)).CombinedOutput()
 	if err != nil {
-		s.log.Error("zfs destroy failed", log.Ctx{"output": string(output)})
+		shared.LogErrorf("zfs destroy failed: %s.", string(output))
 		return fmt.Errorf("Failed to destroy ZFS snapshot: %s", output)
 	}
 
@@ -1820,7 +1816,7 @@ func (s *storageZfs) zfsPoolVolumeSnapshotRestore(path string, name string) erro
 		"rollback",
 		fmt.Sprintf("%s/%s@%s", poolName, path, name))
 	if err != nil {
-		s.log.Error("zfs rollback failed", log.Ctx{"output": string(output)})
+		shared.LogErrorf("zfs rollback failed: %s.", string(output))
 		return fmt.Errorf("Failed to restore ZFS snapshot: %s", output)
 	}
 
@@ -1844,7 +1840,7 @@ func (s *storageZfs) zfsPoolVolumeSnapshotRestore(path string, name string) erro
 			"rollback",
 			fmt.Sprintf("%s/%s@%s", poolName, sub, name))
 		if err != nil {
-			s.log.Error("zfs rollback failed", log.Ctx{"output": string(output)})
+			shared.LogErrorf("zfs rollback failed: %s.", string(output))
 			return fmt.Errorf("Failed to restore ZFS sub-volume snapshot: %s", output)
 		}
 	}
@@ -1861,7 +1857,7 @@ func (s *storageZfs) zfsPoolVolumeSnapshotRename(path string, oldName string, ne
 		fmt.Sprintf("%s/%s@%s", poolName, path, oldName),
 		fmt.Sprintf("%s/%s@%s", poolName, path, newName)).CombinedOutput()
 	if err != nil {
-		s.log.Error("zfs snapshot rename failed", log.Ctx{"output": string(output)})
+		shared.LogErrorf("zfs snapshot rename failed: %s.", string(output))
 		return fmt.Errorf("Failed to rename ZFS snapshot: %s", output)
 	}
 
@@ -1909,7 +1905,7 @@ func (s *storageZfs) zfsPoolListSubvolumes(path string) ([]string, error) {
 		"-H",
 		"-r", path).CombinedOutput()
 	if err != nil {
-		s.log.Error("zfs list failed", log.Ctx{"output": string(output)})
+		shared.LogErrorf("zfs list failed: %s.", string(output))
 		return []string{}, fmt.Errorf("Failed to list ZFS filesystems: %s", output)
 	}
 
@@ -1948,7 +1944,7 @@ func (s *storageZfs) zfsPoolListSnapshots(path string) ([]string, error) {
 		"-s", "creation",
 		"-r", fullPath).CombinedOutput()
 	if err != nil {
-		s.log.Error("zfs list failed", log.Ctx{"output": string(output)})
+		shared.LogErrorf("zfs list failed: %s.", string(output))
 		return []string{}, fmt.Errorf("Failed to list ZFS snapshots: %s", output)
 	}
 
@@ -2225,12 +2221,12 @@ func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*
 
 		output, err := ioutil.ReadAll(stderr)
 		if err != nil {
-			s.log.Debug("problem reading zfs recv stderr %s", log.Ctx{"err": err})
+			shared.LogDebugf("problem reading zfs recv stderr %s.", err)
 		}
 
 		err = cmd.Wait()
 		if err != nil {
-			s.log.Error("problem with zfs recv", log.Ctx{"output": string(output)})
+			shared.LogErrorf("problem with zfs recv: %s.", string(output))
 		}
 		return err
 	}
@@ -2292,7 +2288,7 @@ func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*
 		/* clean up our migration-send snapshots that we got from recv. */
 		zfsSnapshots, err := s.zfsPoolListSnapshots(fmt.Sprintf("containers/%s", container.Name()))
 		if err != nil {
-			s.log.Error("failed listing snapshots post migration", log.Ctx{"err": err})
+			shared.LogErrorf("failed listing snapshots post migration: %s.", err)
 			return
 		}
 

From 371ad2036335e7c66f810698f4bbc081f186c8ff Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 24 Feb 2017 16:59:07 +0100
Subject: [PATCH 10/10] storage: add proper logging

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_btrfs.go | 76 +++++++++++++++++++++++++++++++++++++++--
 lxd/storage_dir.go   | 46 +++++++++++++++++++++++--
 lxd/storage_lvm.go   | 95 +++++++++++++++++++++++++++++++++++++++++++++++++---
 lxd/storage_mock.go  | 12 ++++---
 lxd/storage_zfs.go   | 84 ++++++++++++++++++++++++++++++++++++++++++++--
 5 files changed, 297 insertions(+), 16 deletions(-)

diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 6b9d750..c305398 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -70,10 +70,9 @@ func (s *storageBtrfs) StorageCoreInit() (*storageCore, error) {
 		return nil, fmt.Errorf("The 'btrfs' tool isn't working properly")
 	}
 
-	shared.LogInfof("Initializing a BTRFS driver.")
-
 	s.storageCore = sCore
 
+	shared.LogInfof("Initializing a BTRFS driver.")
 	return &sCore, nil
 }
 
@@ -89,10 +88,13 @@ func (s *storageBtrfs) StoragePoolInit(config map[string]interface{}) (storage,
 func (s *storageBtrfs) StoragePoolCheck() error {
 	// FIXEM(brauner): Think of something smart or useful (And then think
 	// again if it is worth implementing it. :)).
+	shared.LogInfof("Checking BTRFS storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) StoragePoolCreate() error {
+	shared.LogInfof("Creating BTRFS storage pool \"%s\".", s.pool.Name)
+
 	isBlockDev := false
 	source := s.pool.Config["source"]
 	if source == "" {
@@ -223,10 +225,13 @@ func (s *storageBtrfs) StoragePoolCreate() error {
 		return fmt.Errorf("Could not create btrfs subvolume: %s", dummyDir)
 	}
 
+	shared.LogInfof("Created BTRFS storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) StoragePoolDelete() error {
+	shared.LogInfof("Deleting BTRFS storage pool \"%s\".", s.pool.Name)
+
 	source := s.pool.Config["source"]
 	if source == "" {
 		return fmt.Errorf("No \"source\" property found for the storage pool.")
@@ -281,10 +286,13 @@ func (s *storageBtrfs) StoragePoolDelete() error {
 	// Remove the mountpoint for the storage pool.
 	os.RemoveAll(getStoragePoolMountPoint(s.pool.Name))
 
+	shared.LogInfof("Deleted BTRFS storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) StoragePoolMount() (bool, error) {
+	shared.LogInfof("Mounting BTRFS storage pool \"%s\".", s.pool.Name)
+
 	source := s.pool.Config["source"]
 	if source == "" {
 		return false, fmt.Errorf("No \"source\" property found for the storage pool.")
@@ -367,10 +375,13 @@ func (s *storageBtrfs) StoragePoolMount() (bool, error) {
 		return false, err
 	}
 
+	shared.LogInfof("Mounted BTRFS storage pool \"%s\".", s.pool.Name)
 	return true, nil
 }
 
 func (s *storageBtrfs) StoragePoolUmount() (bool, error) {
+	shared.LogInfof("Unmounting BTRFS storage pool \"%s\".", s.pool.Name)
+
 	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
 
 	poolUmountLockID := getPoolUmountLockID(s.pool.Name)
@@ -406,6 +417,7 @@ func (s *storageBtrfs) StoragePoolUmount() (bool, error) {
 		}
 	}
 
+	shared.LogInfof("Unmounted BTRFS storage pool \"%s\".", s.pool.Name)
 	return true, nil
 }
 
@@ -431,6 +443,8 @@ func (s *storageBtrfs) ContainerPoolIDGet() int64 {
 
 // Functions dealing with storage volumes.
 func (s *storageBtrfs) StoragePoolVolumeCreate() error {
+	shared.LogInfof("Creating BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	_, err := s.StoragePoolMount()
 	if err != nil {
 		return err
@@ -452,10 +466,13 @@ func (s *storageBtrfs) StoragePoolVolumeCreate() error {
 		return err
 	}
 
+	shared.LogInfof("Created BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) StoragePoolVolumeDelete() error {
+	shared.LogInfof("Deleting BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	_, err := s.StoragePoolMount()
 	if err != nil {
 		return err
@@ -476,16 +493,20 @@ func (s *storageBtrfs) StoragePoolVolumeDelete() error {
 		}
 	}
 
+	shared.LogInfof("Deleted BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) StoragePoolVolumeMount() (bool, error) {
+	shared.LogInfof("Mounting BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	// The storage pool must be mounted.
 	_, err := s.StoragePoolMount()
 	if err != nil {
 		return false, err
 	}
 
+	shared.LogInfof("Mounted BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return true, nil
 }
 
@@ -512,6 +533,8 @@ func (s *storageBtrfs) ContainerStorageReady(name string) bool {
 }
 
 func (s *storageBtrfs) ContainerCreate(container container) error {
+	shared.LogInfof("Creating empty BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	_, err := s.StoragePoolMount()
 	if err != nil {
 		return err
@@ -545,11 +568,14 @@ func (s *storageBtrfs) ContainerCreate(container container) error {
 		return err
 	}
 
+	shared.LogInfof("Created empty BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return container.TemplateApply("create")
 }
 
 // And this function is why I started hating on btrfs...
 func (s *storageBtrfs) ContainerCreateFromImage(container container, fingerprint string) error {
+	shared.LogInfof("Creating BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	source := s.pool.Config["source"]
 	if source == "" {
 		return fmt.Errorf("No \"source\" property found for the storage pool.")
@@ -629,6 +655,7 @@ func (s *storageBtrfs) ContainerCreateFromImage(container container, fingerprint
 		}
 	}
 
+	shared.LogInfof("Created BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return container.TemplateApply("create")
 }
 
@@ -637,6 +664,8 @@ func (s *storageBtrfs) ContainerCanRestore(container container, sourceContainer
 }
 
 func (s *storageBtrfs) ContainerDelete(container container) error {
+	shared.LogInfof("Deleting BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	// The storage pool needs to be mounted.
 	_, err := s.StoragePoolMount()
 	if err != nil {
@@ -675,10 +704,13 @@ func (s *storageBtrfs) ContainerDelete(container container) error {
 		}
 	}
 
+	shared.LogInfof("Deleted BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) ContainerCopy(container container, sourceContainer container) error {
+	shared.LogInfof("Copying BTRFS container storage %s -> %s.", sourceContainer.Name(), container.Name())
+
 	// The storage pool needs to be mounted.
 	_, err := s.StoragePoolMount()
 	if err != nil {
@@ -760,16 +792,20 @@ func (s *storageBtrfs) ContainerCopy(container container, sourceContainer contai
 		return err
 	}
 
+	shared.LogInfof("Copied BTRFS container storage %s -> %s.", sourceContainer.Name(), container.Name())
 	return container.TemplateApply("copy")
 }
 
 func (s *storageBtrfs) ContainerMount(name string, path string) (bool, error) {
+	shared.LogInfof("Mounting BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	// The storage pool must be mounted.
 	_, err := s.StoragePoolMount()
 	if err != nil {
 		return false, err
 	}
 
+	shared.LogInfof("Mounted BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return true, nil
 }
 
@@ -778,6 +814,8 @@ func (s *storageBtrfs) ContainerUmount(name string, path string) (bool, error) {
 }
 
 func (s *storageBtrfs) ContainerRename(container container, newName string) error {
+	shared.LogInfof("Renaming BTRFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+
 	// The storage pool must be mounted.
 	_, err := s.StoragePoolMount()
 	if err != nil {
@@ -820,10 +858,13 @@ func (s *storageBtrfs) ContainerRename(container container, newName string) erro
 		}
 	}
 
+	shared.LogInfof("Renamed BTRFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 	return nil
 }
 
 func (s *storageBtrfs) ContainerRestore(container container, sourceContainer container) error {
+	shared.LogInfof("Restoring BTRFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
+
 	// The storage pool must be mounted.
 	_, err := s.StoragePoolMount()
 	if err != nil {
@@ -899,10 +940,13 @@ func (s *storageBtrfs) ContainerRestore(container container, sourceContainer con
 		os.RemoveAll(backupTargetContainerSubvolumeName)
 	}
 
+	shared.LogInfof("Restored BTRFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
 	return failure
 }
 
 func (s *storageBtrfs) ContainerSetQuota(container container, size int64) error {
+	shared.LogInfof("Setting BTRFS quota for container \"%s\".", container.Name())
+
 	subvol := container.Path()
 
 	_, err := btrfsSubVolumeQGroup(subvol)
@@ -921,6 +965,7 @@ func (s *storageBtrfs) ContainerSetQuota(container container, size int64) error
 		return fmt.Errorf("Failed to set btrfs quota: %s", output)
 	}
 
+	shared.LogInfof("Set BTRFS quota for container \"%s\".", container.Name())
 	return nil
 }
 
@@ -929,6 +974,8 @@ func (s *storageBtrfs) ContainerGetUsage(container container) (int64, error) {
 }
 
 func (s *storageBtrfs) ContainerSnapshotCreate(snapshotContainer container, sourceContainer container) error {
+	shared.LogInfof("Creating BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	_, err := s.StoragePoolMount()
 	if err != nil {
 		return err
@@ -964,10 +1011,13 @@ func (s *storageBtrfs) ContainerSnapshotCreate(snapshotContainer container, sour
 		return err
 	}
 
+	shared.LogInfof("Created BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) ContainerSnapshotDelete(snapshotContainer container) error {
+	shared.LogInfof("Deleting BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	_, err := s.StoragePoolMount()
 	if err != nil {
 		return err
@@ -992,10 +1042,13 @@ func (s *storageBtrfs) ContainerSnapshotDelete(snapshotContainer container) erro
 		os.Remove(snapshotMntPointSymlink)
 	}
 
+	shared.LogInfof("Deleted BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) ContainerSnapshotStart(container container) error {
+	shared.LogInfof("Initializing BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	_, err := s.StoragePoolMount()
 	if err != nil {
 		return err
@@ -1017,10 +1070,13 @@ func (s *storageBtrfs) ContainerSnapshotStart(container container) error {
 		return err
 	}
 
+	shared.LogInfof("Initialized BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) ContainerSnapshotStop(container container) error {
+	shared.LogInfof("Stopping BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	_, err := s.StoragePoolMount()
 	if err != nil {
 		return err
@@ -1042,11 +1098,14 @@ func (s *storageBtrfs) ContainerSnapshotStop(container container) error {
 		return err
 	}
 
+	shared.LogInfof("Stopped BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 // ContainerSnapshotRename renames a snapshot of a container.
 func (s *storageBtrfs) ContainerSnapshotRename(snapshotContainer container, newName string) error {
+	shared.LogInfof("Renaming BTRFS storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+
 	// The storage pool must be mounted.
 	_, err := s.StoragePoolMount()
 	if err != nil {
@@ -1062,12 +1121,15 @@ func (s *storageBtrfs) ContainerSnapshotRename(snapshotContainer container, newN
 		return err
 	}
 
+	shared.LogInfof("Renamed BTRFS storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 	return nil
 }
 
 // Needed for live migration where an empty snapshot needs to be created before
 // rsyncing into it.
 func (s *storageBtrfs) ContainerSnapshotCreateEmpty(snapshotContainer container) error {
+	shared.LogInfof("Creating empty BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	// Mount the storage pool.
 	_, err := s.StoragePoolMount()
 	if err != nil {
@@ -1100,10 +1162,13 @@ func (s *storageBtrfs) ContainerSnapshotCreateEmpty(snapshotContainer container)
 		}
 	}
 
+	shared.LogInfof("Created empty BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) ImageCreate(fingerprint string) error {
+	shared.LogInfof("Creating BTRFS storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	// Create the subvolume.
 	source := s.pool.Config["source"]
 	if source == "" {
@@ -1179,10 +1244,13 @@ func (s *storageBtrfs) ImageCreate(fingerprint string) error {
 
 	undo = false
 
+	shared.LogInfof("Created BTRFS storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) ImageDelete(fingerprint string) error {
+	shared.LogInfof("Deleting BTRFS storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	_, err := s.StoragePoolMount()
 	if err != nil {
 		return err
@@ -1210,16 +1278,20 @@ func (s *storageBtrfs) ImageDelete(fingerprint string) error {
 		}
 	}
 
+	shared.LogInfof("Deleted BTRFS storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) ImageMount(fingerprint string) (bool, error) {
+	shared.LogInfof("Mounting BTRFS storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	// The storage pool must be mounted.
 	_, err := s.StoragePoolMount()
 	if err != nil {
 		return false, err
 	}
 
+	shared.LogInfof("Mounted BTRFS storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return true, nil
 }
 
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index fe2b582..a6fec42 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -28,10 +28,9 @@ func (s *storageDir) StorageCoreInit() (*storageCore, error) {
 	sCore.sTypeName = typeName
 	sCore.sTypeVersion = "1"
 
-	shared.LogInfof("Initializing a DIR driver.")
-
 	s.storageCore = sCore
 
+	shared.LogInfof("Initializing a DIR driver.")
 	return &sCore, nil
 }
 
@@ -47,10 +46,13 @@ func (s *storageDir) StoragePoolInit(config map[string]interface{}) (storage, er
 
 // Initialize a full storage interface.
 func (s *storageDir) StoragePoolCheck() error {
+	shared.LogInfof("Checking DIR storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageDir) StoragePoolCreate() error {
+	shared.LogInfof("Creating DIR storage pool \"%s\".", s.pool.Name)
+
 	source := s.pool.Config["source"]
 	if source == "" {
 		source = filepath.Join(shared.VarPath("storage-pools"), s.pool.Name)
@@ -81,10 +83,13 @@ func (s *storageDir) StoragePoolCreate() error {
 
 	revert = false
 
+	shared.LogInfof("Created DIR storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageDir) StoragePoolDelete() error {
+	shared.LogInfof("Deleting DIR storage pool \"%s\".", s.pool.Name)
+
 	source := s.pool.Config["source"]
 	if source == "" {
 		return fmt.Errorf("No \"source\" property found for the storage pool.")
@@ -110,6 +115,7 @@ func (s *storageDir) StoragePoolDelete() error {
 		}
 	}
 
+	shared.LogInfof("Deleted DIR storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
@@ -151,6 +157,8 @@ func (s *storageDir) StoragePoolUpdate(changedConfig []string) error {
 
 // Functions dealing with storage pools.
 func (s *storageDir) StoragePoolVolumeCreate() error {
+	shared.LogInfof("Creating DIR storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	source := s.pool.Config["source"]
 	if source == "" {
 		return fmt.Errorf("No \"source\" property found for the storage pool.")
@@ -162,10 +170,13 @@ func (s *storageDir) StoragePoolVolumeCreate() error {
 		return err
 	}
 
+	shared.LogInfof("Created DIR storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageDir) StoragePoolVolumeDelete() error {
+	shared.LogInfof("Deleting DIR storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	source := s.pool.Config["source"]
 	if source == "" {
 		return fmt.Errorf("No \"source\" property found for the storage pool.")
@@ -181,6 +192,7 @@ func (s *storageDir) StoragePoolVolumeDelete() error {
 		return err
 	}
 
+	shared.LogInfof("Deleted DIR storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
@@ -203,6 +215,8 @@ func (s *storageDir) ContainerStorageReady(name string) bool {
 }
 
 func (s *storageDir) ContainerCreate(container container) error {
+	shared.LogInfof("Creating empty DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	source := s.pool.Config["source"]
 	if source == "" {
 		return fmt.Errorf("No \"source\" property found for the storage pool.")
@@ -228,10 +242,13 @@ func (s *storageDir) ContainerCreate(container container) error {
 
 	revert = false
 
+	shared.LogInfof("Created empty DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageDir) ContainerCreateFromImage(container container, imageFingerprint string) error {
+	shared.LogInfof("Creating DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	source := s.pool.Config["source"]
 	if source == "" {
 		return fmt.Errorf("No \"source\" property found for the storage pool.")
@@ -272,6 +289,7 @@ func (s *storageDir) ContainerCreateFromImage(container container, imageFingerpr
 
 	revert = false
 
+	shared.LogInfof("Created DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
@@ -280,6 +298,8 @@ func (s *storageDir) ContainerCanRestore(container container, sourceContainer co
 }
 
 func (s *storageDir) ContainerDelete(container container) error {
+	shared.LogInfof("Deleting DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	source := s.pool.Config["source"]
 	if source == "" {
 		return fmt.Errorf("No \"source\" property found for the storage pool.")
@@ -324,10 +344,13 @@ func (s *storageDir) ContainerDelete(container container) error {
 		}
 	}
 
+	shared.LogInfof("Deleted DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageDir) ContainerCopy(container container, sourceContainer container) error {
+	shared.LogInfof("Copying DIR container storage %s -> %s.", sourceContainer.Name(), container.Name())
+
 	err := sourceContainer.StorageStart()
 	if err != nil {
 		return err
@@ -386,6 +409,7 @@ func (s *storageDir) ContainerCopy(container container, sourceContainer containe
 
 	revert = false
 
+	shared.LogInfof("Copied DIR container storage %s -> %s.", sourceContainer.Name(), container.Name())
 	return nil
 }
 
@@ -398,6 +422,8 @@ func (s *storageDir) ContainerUmount(name string, path string) (bool, error) {
 }
 
 func (s *storageDir) ContainerRename(container container, newName string) error {
+	shared.LogInfof("Renaming DIR storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+
 	source := s.pool.Config["source"]
 	if source == "" {
 		return fmt.Errorf("No \"source\" property found for the storage pool.")
@@ -441,10 +467,13 @@ func (s *storageDir) ContainerRename(container container, newName string) error
 		}
 	}
 
+	shared.LogInfof("Renamed DIR storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 	return nil
 }
 
 func (s *storageDir) ContainerRestore(container container, sourceContainer container) error {
+	shared.LogInfof("Restoring DIR storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
+
 	targetPath := container.Path()
 	sourcePath := sourceContainer.Path()
 
@@ -459,6 +488,7 @@ func (s *storageDir) ContainerRestore(container container, sourceContainer conta
 		return err
 	}
 
+	shared.LogInfof("Restored DIR storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
 	return nil
 }
 
@@ -471,6 +501,8 @@ func (s *storageDir) ContainerGetUsage(container container) (int64, error) {
 }
 
 func (s *storageDir) ContainerSnapshotCreate(snapshotContainer container, sourceContainer container) error {
+	shared.LogInfof("Creating DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	// Create the path for the snapshot.
 	targetContainerName := snapshotContainer.Name()
 	targetContainerMntPoint := getSnapshotMountPoint(s.pool.Name, targetContainerName)
@@ -532,10 +564,13 @@ func (s *storageDir) ContainerSnapshotCreate(snapshotContainer container, source
 		}
 	}
 
+	shared.LogInfof("Created DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageDir) ContainerSnapshotCreateEmpty(snapshotContainer container) error {
+	shared.LogInfof("Creating empty DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	// Create the path for the snapshot.
 	targetContainerName := snapshotContainer.Name()
 	targetContainerMntPoint := getSnapshotMountPoint(s.pool.Name, targetContainerName)
@@ -567,10 +602,13 @@ func (s *storageDir) ContainerSnapshotCreateEmpty(snapshotContainer container) e
 
 	revert = false
 
+	shared.LogInfof("Created empty DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageDir) ContainerSnapshotDelete(snapshotContainer container) error {
+	shared.LogInfof("Deleting DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	source := s.pool.Config["source"]
 	if source == "" {
 		return fmt.Errorf("No \"source\" property found for the storage pool.")
@@ -611,10 +649,13 @@ func (s *storageDir) ContainerSnapshotDelete(snapshotContainer container) error
 		}
 	}
 
+	shared.LogInfof("Deleted DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageDir) ContainerSnapshotRename(snapshotContainer container, newName string) error {
+	shared.LogInfof("Renaming DIR storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+
 	// Rename the mountpoint for the snapshot:
 	// ${POOL}/snapshots/<old_snapshot_name> to ${POOL}/snapshots/<new_snapshot_name>
 	oldSnapshotMntPoint := getSnapshotMountPoint(s.pool.Name, snapshotContainer.Name())
@@ -624,6 +665,7 @@ func (s *storageDir) ContainerSnapshotRename(snapshotContainer container, newNam
 		return err
 	}
 
+	shared.LogInfof("Renamed DIR storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 	return nil
 }
 
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index 756adc7..d54a39b 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -259,10 +259,9 @@ func (s *storageLvm) StorageCoreInit() (*storageCore, error) {
 		sCore.sTypeVersion += strings.TrimSpace(fields[1])
 	}
 
-	shared.LogInfof("Initializing an LVM driver.")
-
 	s.storageCore = sCore
 
+	shared.LogInfof("Initializing an LVM driver.")
 	return &sCore, nil
 }
 
@@ -302,6 +301,7 @@ func (s *storageLvm) StoragePoolInit(config map[string]interface{}) (storage, er
 }
 
 func (s *storageLvm) StoragePoolCheck() error {
+	shared.LogInfof("Checking LVM storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
@@ -348,6 +348,7 @@ func (s *storageLvm) lvmVersionIsAtLeast(versionString string) (bool, error) {
 }
 
 func (s *storageLvm) StoragePoolCreate() error {
+	shared.LogInfof("Creating LVM storage pool \"%s\".", s.pool.Name)
 	tryUndo := true
 
 	// Create the mountpoint for the storage pool.
@@ -427,10 +428,13 @@ func (s *storageLvm) StoragePoolCreate() error {
 	// Deregister cleanup.
 	tryUndo = false
 
+	shared.LogInfof("Created LVM storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) StoragePoolDelete() error {
+	shared.LogInfof("Deleting LVM storage pool \"%s\".", s.pool.Name)
+
 	source := s.pool.Config["source"]
 	if source == "" {
 		return fmt.Errorf("No \"source\" property found for the storage pool.")
@@ -450,6 +454,7 @@ func (s *storageLvm) StoragePoolDelete() error {
 		return err
 	}
 
+	shared.LogInfof("Deleted LVM storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
@@ -462,6 +467,8 @@ func (s *storageLvm) StoragePoolUmount() (bool, error) {
 }
 
 func (s *storageLvm) StoragePoolVolumeCreate() error {
+	shared.LogInfof("Creating LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	tryUndo := true
 
 	poolName := s.getOnDiskPoolName()
@@ -501,10 +508,13 @@ func (s *storageLvm) StoragePoolVolumeCreate() error {
 
 	tryUndo = false
 
+	shared.LogInfof("Created LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) StoragePoolVolumeDelete() error {
+	shared.LogInfof("Deleting LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	_, err := s.StoragePoolVolumeUmount()
 	if err != nil {
@@ -529,10 +539,13 @@ func (s *storageLvm) StoragePoolVolumeDelete() error {
 		}
 	}
 
+	shared.LogInfof("Deleted LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) StoragePoolVolumeMount() (bool, error) {
+	shared.LogInfof("Mounting LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	poolName := s.getOnDiskPoolName()
 	mountOptions := s.getLvmBlockMountOptions()
@@ -576,10 +589,13 @@ func (s *storageLvm) StoragePoolVolumeMount() (bool, error) {
 		return false, customerr
 	}
 
+	shared.LogInfof("Mounted LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return ourMount, nil
 }
 
 func (s *storageLvm) StoragePoolVolumeUmount() (bool, error) {
+	shared.LogInfof("Unmounting LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
 	customUmountLockID := getCustomUmountLockID(s.pool.Name, s.volume.Name)
@@ -615,6 +631,7 @@ func (s *storageLvm) StoragePoolVolumeUmount() (bool, error) {
 		return false, customerr
 	}
 
+	shared.LogInfof("Unmounted LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return ourUmount, nil
 }
 
@@ -643,6 +660,8 @@ func (s *storageLvm) ContainerPoolIDGet() int64 {
 }
 
 func (s *storageLvm) StoragePoolUpdate(changedConfig []string) error {
+	shared.LogInfof("Updating LVM storage pool \"%s\".", s.pool.Name)
+
 	if shared.StringInSlice("size", changedConfig) {
 		return fmt.Errorf("The \"size\" property cannot be changed.")
 	}
@@ -683,16 +702,20 @@ func (s *storageLvm) StoragePoolUpdate(changedConfig []string) error {
 		return fmt.Errorf("The \"lvm.vg_name\" property cannot be changed.")
 	}
 
+	shared.LogInfof("Updated LVM storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) StoragePoolVolumeUpdate(changedConfig []string) error {
+	shared.LogInfof("Updating LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	if shared.StringInSlice("block.mount_options", changedConfig) && len(changedConfig) == 1 {
 		// noop
 	} else {
 		return fmt.Errorf("The properties \"%v\" cannot be changed.", changedConfig)
 	}
 
+	shared.LogInfof("Updated LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
@@ -705,6 +728,8 @@ func (s *storageLvm) ContainerStorageReady(name string) bool {
 }
 
 func (s *storageLvm) ContainerCreate(container container) error {
+	shared.LogInfof("Creating empty LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	tryUndo := true
 
 	containerName := container.Name()
@@ -756,10 +781,13 @@ func (s *storageLvm) ContainerCreate(container container) error {
 
 	tryUndo = false
 
+	shared.LogInfof("Created empty LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) ContainerCreateFromImage(container container, fingerprint string) error {
+	shared.LogInfof("Creating LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	tryUndo := true
 
 	poolName := s.getOnDiskPoolName()
@@ -860,6 +888,7 @@ func (s *storageLvm) ContainerCreateFromImage(container container, fingerprint s
 
 	tryUndo = false
 
+	shared.LogInfof("Created LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
@@ -868,6 +897,8 @@ func (s *storageLvm) ContainerCanRestore(container container, sourceContainer co
 }
 
 func (s *storageLvm) ContainerDelete(container container) error {
+	shared.LogInfof("Deleting LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	containerName := container.Name()
 	containerLvmName := containerNameToLVName(containerName)
 	containerMntPoint := ""
@@ -909,10 +940,13 @@ func (s *storageLvm) ContainerDelete(container container) error {
 		}
 	}
 
+	shared.LogInfof("Deleted LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) ContainerCopy(container container, sourceContainer container) error {
+	shared.LogInfof("Copying LVM container storage %s -> %s.", sourceContainer.Name(), container.Name())
+
 	tryUndo := true
 
 	err := sourceContainer.StorageStart()
@@ -979,10 +1013,13 @@ func (s *storageLvm) ContainerCopy(container container, sourceContainer containe
 
 	tryUndo = false
 
+	shared.LogInfof("Copied LVM container storage %s -> %s.", sourceContainer.Name(), container.Name())
 	return nil
 }
 
 func (s *storageLvm) ContainerMount(name string, path string) (bool, error) {
+	shared.LogInfof("Mounting LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	containerLvmName := containerNameToLVName(name)
 	lvFsType := s.getLvmFilesystem()
 	poolName := s.getOnDiskPoolName()
@@ -1023,10 +1060,13 @@ func (s *storageLvm) ContainerMount(name string, path string) (bool, error) {
 		return false, imgerr
 	}
 
+	shared.LogInfof("Mounted LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return ourMount, nil
 }
 
 func (s *storageLvm) ContainerUmount(name string, path string) (bool, error) {
+	shared.LogInfof("Unmounting LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	containerMntPoint := getContainerMountPoint(s.pool.Name, name)
 
 	containerUmountLockID := getContainerUmountLockID(s.pool.Name, name)
@@ -1062,10 +1102,13 @@ func (s *storageLvm) ContainerUmount(name string, path string) (bool, error) {
 		return false, imgerr
 	}
 
+	shared.LogInfof("Unmounted LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return ourUmount, nil
 }
 
 func (s *storageLvm) ContainerRename(container container, newContainerName string) error {
+	shared.LogInfof("Renaming LVM storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newContainerName)
+
 	tryUndo := true
 
 	oldName := container.Name()
@@ -1141,10 +1184,13 @@ func (s *storageLvm) ContainerRename(container container, newContainerName strin
 
 	tryUndo = false
 
+	shared.LogInfof("Renamed LVM storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newContainerName)
 	return nil
 }
 
 func (s *storageLvm) ContainerRestore(container container, sourceContainer container) error {
+	shared.LogInfof("Restoring LVM storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
+
 	err := sourceContainer.StorageStart()
 	if err != nil {
 		return err
@@ -1180,6 +1226,7 @@ func (s *storageLvm) ContainerRestore(container container, sourceContainer conta
 		return fmt.Errorf("Error creating snapshot LV: %v", err)
 	}
 
+	shared.LogInfof("Restored LVM storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
 	return nil
 }
 
@@ -1192,7 +1239,15 @@ func (s *storageLvm) ContainerGetUsage(container container) (int64, error) {
 }
 
 func (s *storageLvm) ContainerSnapshotCreate(snapshotContainer container, sourceContainer container) error {
-	return s.createSnapshotContainer(snapshotContainer, sourceContainer, true)
+	shared.LogInfof("Creating LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
+	err := s.createSnapshotContainer(snapshotContainer, sourceContainer, true)
+	if err != nil {
+		return err
+	}
+
+	shared.LogInfof("Created LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	return nil
 }
 
 func (s *storageLvm) createSnapshotContainer(snapshotContainer container, sourceContainer container, readonly bool) error {
@@ -1240,15 +1295,20 @@ func (s *storageLvm) createSnapshotContainer(snapshotContainer container, source
 }
 
 func (s *storageLvm) ContainerSnapshotDelete(snapshotContainer container) error {
+	shared.LogInfof("Deleting LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	err := s.ContainerDelete(snapshotContainer)
 	if err != nil {
 		return fmt.Errorf("Error deleting snapshot %s: %s", snapshotContainer.Name(), err)
 	}
 
+	shared.LogInfof("Deleted LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) ContainerSnapshotRename(snapshotContainer container, newContainerName string) error {
+	shared.LogInfof("Renaming LVM storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newContainerName)
+
 	tryUndo := true
 
 	oldName := snapshotContainer.Name()
@@ -1275,10 +1335,13 @@ func (s *storageLvm) ContainerSnapshotRename(snapshotContainer container, newCon
 
 	tryUndo = false
 
+	shared.LogInfof("Renamed LVM storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newContainerName)
 	return nil
 }
 
 func (s *storageLvm) ContainerSnapshotStart(container container) error {
+	shared.LogInfof("Initializing LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	tryUndo := true
 
 	sourceName := container.Name()
@@ -1323,10 +1386,13 @@ func (s *storageLvm) ContainerSnapshotStart(container container) error {
 
 	tryUndo = false
 
+	shared.LogInfof("Initialized LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) ContainerSnapshotStop(container container) error {
+	shared.LogInfof("Stopping LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	name := container.Name()
 	snapshotMntPoint := getSnapshotMountPoint(s.pool.Name, name)
 
@@ -1345,14 +1411,25 @@ func (s *storageLvm) ContainerSnapshotStop(container container) error {
 		return err
 	}
 
+	shared.LogInfof("Stopped LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) ContainerSnapshotCreateEmpty(snapshotContainer container) error {
-	return s.ContainerCreate(snapshotContainer)
+	shared.LogInfof("Creating empty LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
+	err := s.ContainerCreate(snapshotContainer)
+	if err != nil {
+		return err
+	}
+
+	shared.LogInfof("Created empty LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	return nil
 }
 
 func (s *storageLvm) ImageCreate(fingerprint string) error {
+	shared.LogInfof("Creating LVM storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	tryUndo := true
 
 	poolName := s.getOnDiskPoolName()
@@ -1403,10 +1480,13 @@ func (s *storageLvm) ImageCreate(fingerprint string) error {
 
 	tryUndo = false
 
+	shared.LogInfof("Created LVM storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) ImageDelete(fingerprint string) error {
+	shared.LogInfof("Deleting LVM storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	_, err := s.ImageUmount(fingerprint)
 	if err != nil {
 		return err
@@ -1431,10 +1511,13 @@ func (s *storageLvm) ImageDelete(fingerprint string) error {
 		}
 	}
 
+	shared.LogInfof("Deleted LVM storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) ImageMount(fingerprint string) (bool, error) {
+	shared.LogInfof("Mounting LVM storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
 	if shared.IsMountPoint(imageMntPoint) {
 		return false, nil
@@ -1456,10 +1539,13 @@ func (s *storageLvm) ImageMount(fingerprint string) (bool, error) {
 		return false, fmt.Errorf("Error mounting image LV: %v", err)
 	}
 
+	shared.LogInfof("Mounted LVM storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return true, nil
 }
 
 func (s *storageLvm) ImageUmount(fingerprint string) (bool, error) {
+	shared.LogInfof("Unmounting LVM storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
 	if !shared.IsMountPoint(imageMntPoint) {
 		return false, nil
@@ -1470,6 +1556,7 @@ func (s *storageLvm) ImageUmount(fingerprint string) (bool, error) {
 		return false, err
 	}
 
+	shared.LogInfof("Unmounted LVM storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return true, nil
 }
 
diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index d174134..de637a7 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -22,10 +22,9 @@ func (s *storageMock) StorageCoreInit() (*storageCore, error) {
 	}
 	sCore.sTypeName = typeName
 
-	shared.LogInfof("Initializing a MOCK driver.")
-
 	s.storageCore = sCore
 
+	shared.LogInfof("Initializing a MOCK driver.")
 	return &sCore, nil
 }
 
@@ -39,14 +38,19 @@ func (s *storageMock) StoragePoolInit(config map[string]interface{}) (storage, e
 }
 
 func (s *storageMock) StoragePoolCheck() error {
+	shared.LogInfof("Checking MOCK storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageMock) StoragePoolCreate() error {
+	shared.LogInfof("Creating MOCK storage pool \"%s\".", s.pool.Name)
+	shared.LogInfof("Created MOCK storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageMock) StoragePoolDelete() error {
+	shared.LogInfof("Deleting MOCK storage pool \"%s\".", s.pool.Name)
+	shared.LogInfof("Deleted MOCK storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
@@ -154,9 +158,7 @@ func (s *storageMock) ContainerRestore(
 	return nil
 }
 
-func (s *storageMock) ContainerSetQuota(
-	container container, size int64) error {
-
+func (s *storageMock) ContainerSetQuota(container container, size int64) error {
 	return nil
 }
 
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index c1c3574..c51f711 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -73,10 +73,9 @@ func (s *storageZfs) StorageCoreInit() (*storageCore, error) {
 		return nil, err
 	}
 
-	shared.LogInfof("Initializing a ZFS driver.")
-
 	s.storageCore = sCore
 
+	shared.LogInfof("Initializing a ZFS driver.")
 	return &sCore, nil
 }
 
@@ -98,10 +97,14 @@ func (s *storageZfs) StoragePoolInit(config map[string]interface{}) (storage, er
 func (s *storageZfs) StoragePoolCheck() error {
 	// Make noop for now until we figure out something useful to do for all
 	// supported use cases.
+
+	shared.LogInfof("Checking ZFS storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) StoragePoolCreate() error {
+	shared.LogInfof("Creating ZFS storage pool \"%s\".", s.pool.Name)
+
 	err := s.zfsPoolCreate()
 	if err != nil {
 		return err
@@ -122,10 +125,13 @@ func (s *storageZfs) StoragePoolCreate() error {
 
 	revert = false
 
+	shared.LogInfof("Created ZFS storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) StoragePoolDelete() error {
+	shared.LogInfof("Deleting ZFS storage pool \"%s\".", s.pool.Name)
+
 	err := s.zfsFilesystemEntityDelete()
 	if err != nil {
 		return err
@@ -139,6 +145,7 @@ func (s *storageZfs) StoragePoolDelete() error {
 		}
 	}
 
+	shared.LogInfof("Deleted ZFS storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
@@ -151,6 +158,8 @@ func (s *storageZfs) StoragePoolUmount() (bool, error) {
 }
 
 func (s *storageZfs) StoragePoolVolumeCreate() error {
+	shared.LogInfof("Creating ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	fs := fmt.Sprintf("custom/%s", s.volume.Name)
 	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
@@ -177,10 +186,13 @@ func (s *storageZfs) StoragePoolVolumeCreate() error {
 
 	revert = false
 
+	shared.LogInfof("Created ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) StoragePoolVolumeDelete() error {
+	shared.LogInfof("Deleting ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	fs := fmt.Sprintf("custom/%s", s.volume.Name)
 	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
@@ -196,10 +208,13 @@ func (s *storageZfs) StoragePoolVolumeDelete() error {
 		}
 	}
 
+	shared.LogInfof("Deleted ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) StoragePoolVolumeMount() (bool, error) {
+	shared.LogInfof("Mounting ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	fs := fmt.Sprintf("custom/%s", s.volume.Name)
 	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
@@ -236,10 +251,13 @@ func (s *storageZfs) StoragePoolVolumeMount() (bool, error) {
 		return false, customerr
 	}
 
+	shared.LogInfof("Mounted ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return ourMount, nil
 }
 
 func (s *storageZfs) StoragePoolVolumeUmount() (bool, error) {
+	shared.LogInfof("Unmounting ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	fs := fmt.Sprintf("custom/%s", s.volume.Name)
 	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
@@ -276,6 +294,7 @@ func (s *storageZfs) StoragePoolVolumeUmount() (bool, error) {
 		return false, customerr
 	}
 
+	shared.LogInfof("Unmounted ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return ourUmount, nil
 }
 
@@ -304,6 +323,8 @@ func (s *storageZfs) ContainerPoolIDGet() int64 {
 }
 
 func (s *storageZfs) StoragePoolUpdate(changedConfig []string) error {
+	shared.LogInfof("Updating ZFS storage pool \"%s\".", s.pool.Name)
+
 	if shared.StringInSlice("size", changedConfig) {
 		return fmt.Errorf("The \"size\" property cannot be changed.")
 	}
@@ -336,10 +357,13 @@ func (s *storageZfs) StoragePoolUpdate(changedConfig []string) error {
 		return fmt.Errorf("The \"zfs.pool_name\" property cannot be changed.")
 	}
 
+	shared.LogInfof("Updated ZFS storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) StoragePoolVolumeUpdate(changedConfig []string) error {
+	shared.LogInfof("Updating ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	if shared.StringInSlice("block.mount_options", changedConfig) {
 		return fmt.Errorf("The \"block.mount_options\" property cannot be changed.")
 	}
@@ -352,11 +376,14 @@ func (s *storageZfs) StoragePoolVolumeUpdate(changedConfig []string) error {
 		return fmt.Errorf("The \"size\" property cannot be changed.")
 	}
 
+	shared.LogInfof("Updated ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 // Things we don't need to care about
 func (s *storageZfs) ContainerMount(name string, path string) (bool, error) {
+	shared.LogInfof("Mounting ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	fs := fmt.Sprintf("containers/%s", name)
 	containerPoolVolumeMntPoint := getContainerMountPoint(s.pool.Name, name)
 
@@ -393,10 +420,13 @@ func (s *storageZfs) ContainerMount(name string, path string) (bool, error) {
 		return false, imgerr
 	}
 
+	shared.LogInfof("Mounted ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return ourMount, nil
 }
 
 func (s *storageZfs) ContainerUmount(name string, path string) (bool, error) {
+	shared.LogInfof("Unmounting ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	fs := fmt.Sprintf("containers/%s", name)
 	containerPoolVolumeMntPoint := getContainerMountPoint(s.pool.Name, name)
 
@@ -433,6 +463,7 @@ func (s *storageZfs) ContainerUmount(name string, path string) (bool, error) {
 		return false, imgerr
 	}
 
+	shared.LogInfof("Unmounted ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return ourUmount, nil
 }
 
@@ -444,6 +475,8 @@ func (s *storageZfs) ContainerStorageReady(name string) bool {
 }
 
 func (s *storageZfs) ContainerCreate(container container) error {
+	shared.LogInfof("Creating empty ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	containerPath := container.Path()
 	containerName := container.Name()
 	fs := fmt.Sprintf("containers/%s", containerName)
@@ -480,10 +513,13 @@ func (s *storageZfs) ContainerCreate(container container) error {
 
 	revert = false
 
+	shared.LogInfof("Created empty ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) ContainerCreateFromImage(container container, fingerprint string) error {
+	shared.LogInfof("Creating ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	containerPath := container.Path()
 	containerName := container.Name()
 	fs := fmt.Sprintf("containers/%s", containerName)
@@ -551,6 +587,7 @@ func (s *storageZfs) ContainerCreateFromImage(container container, fingerprint s
 
 	revert = false
 
+	shared.LogInfof("Created ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
@@ -578,6 +615,8 @@ func (s *storageZfs) ContainerCanRestore(container container, sourceContainer co
 }
 
 func (s *storageZfs) ContainerDelete(container container) error {
+	shared.LogInfof("Deleting ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	containerName := container.Name()
 	fs := fmt.Sprintf("containers/%s", containerName)
 	containerPoolVolumeMntPoint := getContainerMountPoint(s.pool.Name, containerName)
@@ -658,10 +697,13 @@ func (s *storageZfs) ContainerDelete(container container) error {
 		}
 	}
 
+	shared.LogInfof("Deleted ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) ContainerCopy(container container, sourceContainer container) error {
+	shared.LogInfof("Copying ZFS container storage %s -> %s.", sourceContainer.Name(), container.Name())
+
 	sourceContainerName := sourceContainer.Name()
 	sourceContainerPath := sourceContainer.Path()
 
@@ -758,10 +800,13 @@ func (s *storageZfs) ContainerCopy(container container, sourceContainer containe
 
 	revert = false
 
+	shared.LogInfof("Copied ZFS container storage %s -> %s.", sourceContainer.Name(), container.Name())
 	return nil
 }
 
 func (s *storageZfs) ContainerRename(container container, newName string) error {
+	shared.LogInfof("Renaming ZFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+
 	oldName := container.Name()
 
 	// Unmount the dataset.
@@ -837,10 +882,13 @@ func (s *storageZfs) ContainerRename(container container, newName string) error
 
 	revert = false
 
+	shared.LogInfof("Renamed ZFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 	return nil
 }
 
 func (s *storageZfs) ContainerRestore(container container, sourceContainer container) error {
+	shared.LogInfof("Restoring ZFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
+
 	// Remove any needed snapshot
 	snaps, err := container.Snapshots()
 	if err != nil {
@@ -868,10 +916,13 @@ func (s *storageZfs) ContainerRestore(container container, sourceContainer conta
 		return err
 	}
 
+	shared.LogInfof("Restored ZFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
 	return nil
 }
 
 func (s *storageZfs) ContainerSetQuota(container container, size int64) error {
+	shared.LogInfof("Setting ZFS quota for container \"%s\".", container.Name())
+
 	var err error
 
 	fs := fmt.Sprintf("containers/%s", container.Name())
@@ -899,6 +950,7 @@ func (s *storageZfs) ContainerSetQuota(container container, size int64) error {
 		return err
 	}
 
+	shared.LogInfof("Set ZFS quota for container \"%s\".", container.Name())
 	return nil
 }
 
@@ -934,6 +986,8 @@ func (s *storageZfs) ContainerGetUsage(container container) (int64, error) {
 }
 
 func (s *storageZfs) ContainerSnapshotCreate(snapshotContainer container, sourceContainer container) error {
+	shared.LogInfof("Creating ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	snapshotContainerName := snapshotContainer.Name()
 	sourceContainerName := sourceContainer.Name()
 
@@ -973,10 +1027,13 @@ func (s *storageZfs) ContainerSnapshotCreate(snapshotContainer container, source
 
 	revert = false
 
+	shared.LogInfof("Created ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) ContainerSnapshotDelete(snapshotContainer container) error {
+	shared.LogInfof("Deleting ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	fields := strings.SplitN(snapshotContainer.Name(), shared.SnapshotDelimiter, 2)
 	sourceContainerName := fields[0]
 	snapName := fmt.Sprintf("snapshot-%s", fields[1])
@@ -1047,10 +1104,13 @@ func (s *storageZfs) ContainerSnapshotDelete(snapshotContainer container) error
 		}
 	}
 
+	shared.LogInfof("Deleted ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) ContainerSnapshotRename(snapshotContainer container, newName string) error {
+	shared.LogInfof("Renaming ZFS storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+
 	oldName := snapshotContainer.Name()
 
 	oldFields := strings.SplitN(snapshotContainer.Name(), shared.SnapshotDelimiter, 2)
@@ -1109,10 +1169,13 @@ func (s *storageZfs) ContainerSnapshotRename(snapshotContainer container, newNam
 
 	revert = false
 
+	shared.LogInfof("Renamed ZFS storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 	return nil
 }
 
 func (s *storageZfs) ContainerSnapshotStart(container container) error {
+	shared.LogInfof("Initializing ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	fields := strings.SplitN(container.Name(), shared.SnapshotDelimiter, 2)
 	if len(fields) < 2 {
 		return fmt.Errorf("Invalid snapshot name: %s", container.Name())
@@ -1130,10 +1193,13 @@ func (s *storageZfs) ContainerSnapshotStart(container container) error {
 		return err
 	}
 
+	shared.LogInfof("Initialized ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) ContainerSnapshotStop(container container) error {
+	shared.LogInfof("Stopping ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	fields := strings.SplitN(container.Name(), shared.SnapshotDelimiter, 2)
 	if len(fields) < 2 {
 		return fmt.Errorf("Invalid snapshot name: %s", container.Name())
@@ -1149,7 +1215,13 @@ func (s *storageZfs) ContainerSnapshotStop(container container) error {
 
 	/* zfs creates this directory on clone (start), so we need to clean it
 	 * up on stop */
-	return os.RemoveAll(container.Path())
+	shared.LogInfof("Stopped ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	err = os.RemoveAll(container.Path())
+	if err != nil {
+		return err
+	}
+
+	return nil
 }
 
 func (s *storageZfs) ContainerSnapshotCreateEmpty(snapshotContainer container) error {
@@ -1165,6 +1237,8 @@ func (s *storageZfs) ContainerSnapshotCreateEmpty(snapshotContainer container) e
 // - remove mountpoint property from zfs volume images/<fingerprint>
 // - create read-write snapshot from zfs volume images/<fingerprint>
 func (s *storageZfs) ImageCreate(fingerprint string) error {
+	shared.LogInfof("Creating ZFS storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
 	fs := fmt.Sprintf("images/%s", fingerprint)
 	revert := true
@@ -1283,10 +1357,13 @@ func (s *storageZfs) ImageCreate(fingerprint string) error {
 
 	revert = false
 
+	shared.LogInfof("Created ZFS storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) ImageDelete(fingerprint string) error {
+	shared.LogInfof("Deleting ZFS storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+
 	fs := fmt.Sprintf("images/%s", fingerprint)
 
 	if s.zfsFilesystemEntityExists(fs, true) {
@@ -1333,6 +1410,7 @@ func (s *storageZfs) ImageDelete(fingerprint string) error {
 		}
 	}
 
+	shared.LogInfof("Deleted ZFS storage volume for image \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 


More information about the lxc-devel mailing list