[lxc-devel] [lxd/master] storage: fix copy + move

brauner on Github lxc-bot at linuxcontainers.org
Wed Mar 8 15:41:36 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170308/5ec0487c/attachment.bin>
-------------- next part --------------
From 89f43c9035f1750d7725a6944c0efac149b1c3f8 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 8 Mar 2017 15:19:07 +0100
Subject: [PATCH 1/4] migration: actually unset the storage pool

Closes #3036.

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

diff --git a/lxd/containers_post.go b/lxd/containers_post.go
index 65de36e..2db5f17 100644
--- a/lxd/containers_post.go
+++ b/lxd/containers_post.go
@@ -200,6 +200,9 @@ func createFromMigration(d *Daemon, req *api.ContainersPost) Response {
 		_, err := dbStoragePoolGetID(d.db, storagePool)
 		if err == NoSuchObjectError {
 			storagePool = ""
+			// Unset the local root disk device storage pool if not
+			// found.
+			localRootDiskDevice["pool"] = ""
 		}
 	}
 

From 33b26a9bc19976eef0269fd40f373ff89c1c7109 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 8 Mar 2017 15:19:31 +0100
Subject: [PATCH 2/4] storage_migration: ensure correct pool for snaps

Ensure that snapshot and parent container have the same storage pool in their
local root disk device. If the root disk device for the snapshot comes from a
profile on the new instance as well we don't need to do anything.

Closes #3036.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_migration.go | 51 ++++++++++++++++++++++++++++++++++++------------
 1 file changed, 39 insertions(+), 12 deletions(-)

diff --git a/lxd/storage_migration.go b/lxd/storage_migration.go
index 35ae15d..b565ac3 100644
--- a/lxd/storage_migration.go
+++ b/lxd/storage_migration.go
@@ -1,6 +1,8 @@
 package main
 
 import (
+	"fmt"
+
 	"github.com/gorilla/websocket"
 
 	"github.com/lxc/lxd/lxd/types"
@@ -110,18 +112,38 @@ func rsyncMigrationSink(live bool, container container, snapshots []*Snapshot, c
 	}
 	defer container.StorageStop()
 
+	// At this point we have already figured out the parent
+	// container's root disk device so we can simply
+	// retrieve it from the expanded devices.
+	parentStoragePool := ""
+	parentExpandedDevices := container.ExpandedDevices()
+	parentLocalRootDiskDeviceKey, parentLocalRootDiskDevice, _ := containerGetRootDiskDevice(parentExpandedDevices)
+	if parentLocalRootDiskDeviceKey != "" {
+		parentStoragePool = parentLocalRootDiskDevice["pool"]
+	}
+
+	// A little neuroticism.
+	if parentStoragePool == "" {
+		return fmt.Errorf("The container's root device is missing the pool property.")
+	}
+
 	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"] = ""
+
+			// Ensure that snapshot and parent container have the
+			// same storage pool in their local root disk device.
+			// If the root disk device for the snapshot comes from a
+			// profile on the new instance as well we don't need to
+			// do anything.
+			if args.Devices != nil {
+				snapLocalRootDiskDeviceKey, _, _ := containerGetRootDiskDevice(args.Devices)
+				if snapLocalRootDiskDeviceKey != "" {
+					args.Devices[snapLocalRootDiskDeviceKey]["pool"] = parentStoragePool
 				}
 			}
+
 			s, err := containerCreateEmptySnapshot(container.Daemon(), args)
 			if err != nil {
 				return err
@@ -144,14 +166,19 @@ func rsyncMigrationSink(live bool, container container, snapshots []*Snapshot, c
 	} 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"] = ""
+
+			// Ensure that snapshot and parent container have the
+			// same storage pool in their local root disk device.
+			// If the root disk device for the snapshot comes from a
+			// profile on the new instance as well we don't need to
+			// do anything.
+			if args.Devices != nil {
+				snapLocalRootDiskDeviceKey, _, _ := containerGetRootDiskDevice(args.Devices)
+				if snapLocalRootDiskDeviceKey != "" {
+					args.Devices[snapLocalRootDiskDeviceKey]["pool"] = parentStoragePool
 				}
 			}
+
 			wrapper := StorageProgressWriter(op, "fs_progress", snap.GetName())
 			if err := RsyncRecv(shared.AddSlash(container.Path()), conn, wrapper); err != nil {
 				return err

From ad907a84be94e838c020c874e72b1feb27776944 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 8 Mar 2017 15:51:30 +0100
Subject: [PATCH 3/4] migration: set correct pool propert for btrfs

Closes #3036.

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

diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 33abab6..abb1599 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -1904,16 +1904,36 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 		}
 	}
 
+	// At this point we have already figured out the parent
+	// container's root disk device so we can simply
+	// retrieve it from the expanded devices.
+	parentStoragePool := ""
+	parentExpandedDevices := container.ExpandedDevices()
+	parentLocalRootDiskDeviceKey, parentLocalRootDiskDevice, _ := containerGetRootDiskDevice(parentExpandedDevices)
+	if parentLocalRootDiskDeviceKey != "" {
+		parentStoragePool = parentLocalRootDiskDevice["pool"]
+	}
+
+	// A little neuroticism.
+	if parentStoragePool == "" {
+		return fmt.Errorf("Detected that the container's root device is missing the pool property during BTRFS migration.")
+	}
+
 	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"] = ""
+
+		// Ensure that snapshot and parent container have the
+		// same storage pool in their local root disk device.
+		// If the root disk device for the snapshot comes from a
+		// profile on the new instance as well we don't need to
+		// do anything.
+		if args.Devices != nil {
+			snapLocalRootDiskDeviceKey, _, _ := containerGetRootDiskDevice(args.Devices)
+			if snapLocalRootDiskDeviceKey != "" {
+				args.Devices[snapLocalRootDiskDeviceKey]["pool"] = parentStoragePool
 			}
 		}
+
 		containerMntPoint := getSnapshotMountPoint(containerPool, args.Name)
 		_, err := containerCreateEmptySnapshot(container.Daemon(), args)
 		if err != nil {

From d9c2cf4bd236bb84ee6f98f33877c0a890f0349a Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 8 Mar 2017 15:59:21 +0100
Subject: [PATCH 4/4] migration: set correct pool propert for zfs

Closes #3036.

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

diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index e521b5b..c76cc07 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -2375,14 +2375,33 @@ func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*
 		}
 	}
 
+	// At this point we have already figured out the parent
+	// container's root disk device so we can simply
+	// retrieve it from the expanded devices.
+	parentStoragePool := ""
+	parentExpandedDevices := container.ExpandedDevices()
+	parentLocalRootDiskDeviceKey, parentLocalRootDiskDevice, _ := containerGetRootDiskDevice(parentExpandedDevices)
+	if parentLocalRootDiskDeviceKey != "" {
+		parentStoragePool = parentLocalRootDiskDevice["pool"]
+	}
+
+	// A little neuroticism.
+	if parentStoragePool == "" {
+		return fmt.Errorf("Detected that the container's root device is missing the pool property during BTRFS migration.")
+	}
+
 	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"] = ""
+
+		// Ensure that snapshot and parent container have the
+		// same storage pool in their local root disk device.
+		// If the root disk device for the snapshot comes from a
+		// profile on the new instance as well we don't need to
+		// do anything.
+		if args.Devices != nil {
+			snapLocalRootDiskDeviceKey, _, _ := containerGetRootDiskDevice(args.Devices)
+			if snapLocalRootDiskDeviceKey != "" {
+				args.Devices[snapLocalRootDiskDeviceKey]["pool"] = parentStoragePool
 			}
 		}
 		_, err := containerCreateEmptySnapshot(container.Daemon(), args)


More information about the lxc-devel mailing list