The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/3396

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Signed-off-by: Christian Brauner <[email protected]>
From b1eb7453d3911644a9b6d894de7e6dedd241b17d Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Thu, 8 Jun 2017 22:01:24 +0200
Subject: [PATCH 1/3] zfs: fix container copy

Closes #3395.

Signed-off-by: Christian Brauner <[email protected]>
---
 lxd/storage_zfs.go | 47 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 45 insertions(+), 2 deletions(-)

diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 37697fe63..dbe421525 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -958,7 +958,7 @@ func (s *storageZfs) copyWithSnapshots(target container, 
source container, paren
 
        zfsSendCmd := exec.Command("zfs", args...)
        targetSnapshotDataset := fmt.Sprintf("%s/containers/%s@snapshot-%s", 
poolName, targetParentName, targetSnapOnlyName)
-       zfsRecvCmd := exec.Command("zfs", "receive", targetSnapshotDataset)
+       zfsRecvCmd := exec.Command("zfs", "receive", "-F", 
targetSnapshotDataset)
 
        zfsRecvCmd.Stdin, _ = zfsSendCmd.StdoutPipe()
        zfsRecvCmd.Stdout = os.Stdout
@@ -1019,8 +1019,9 @@ func (s *storageZfs) ContainerCopy(target container, 
source container, container
                        return err
                }
 
+               prev := ""
+               prevSnapOnlyName := ""
                for i, snap := range snapshots {
-                       prev := ""
                        if i > 0 {
                                prev = snapshots[i-1].Name()
                        }
@@ -1031,6 +1032,7 @@ func (s *storageZfs) ContainerCopy(target container, 
source container, container
                        }
 
                        _, snapOnlyName, _ := 
containerGetParentAndSnapshotName(snap.Name())
+                       prevSnapOnlyName = snapOnlyName
                        newSnapName := fmt.Sprintf("%s/%s", target.Name(), 
snapOnlyName)
                        targetSnapshot, err := containerLoadByName(s.d, 
newSnapName)
                        if err != nil {
@@ -1043,6 +1045,47 @@ func (s *storageZfs) ContainerCopy(target container, 
source container, container
                        }
                }
 
+               // send actual container
+               tmpSnapshotName := fmt.Sprintf("copy-send-%s", 
uuid.NewRandom().String())
+               err = 
s.zfsPoolVolumeSnapshotCreate(fmt.Sprintf("containers/%s", source.Name()), 
tmpSnapshotName)
+               if err != nil {
+                       return err
+               }
+
+               poolName := s.getOnDiskPoolName()
+               currentSnapshotDataset := fmt.Sprintf("%s/containers/%s@%s", 
poolName, source.Name(), tmpSnapshotName)
+               args := []string{"send", currentSnapshotDataset}
+               if prevSnapOnlyName != "" {
+                       parentSnapshotDataset := 
fmt.Sprintf("%s/containers/%s@snapshot-%s", poolName, source.Name(), 
prevSnapOnlyName)
+                       args = append(args, "-i", parentSnapshotDataset)
+               }
+
+               zfsSendCmd := exec.Command("zfs", args...)
+               targetSnapshotDataset := fmt.Sprintf("%s/containers/%s@%s", 
poolName, target.Name(), tmpSnapshotName)
+               zfsRecvCmd := exec.Command("zfs", "receive", "-F", 
targetSnapshotDataset)
+
+               zfsRecvCmd.Stdin, _ = zfsSendCmd.StdoutPipe()
+               zfsRecvCmd.Stdout = os.Stdout
+               zfsRecvCmd.Stderr = os.Stderr
+
+               err = zfsRecvCmd.Start()
+               if err != nil {
+                       return err
+               }
+
+               err = zfsSendCmd.Run()
+               if err != nil {
+                       return err
+               }
+
+               err = zfsRecvCmd.Wait()
+               if err != nil {
+                       return err
+               }
+
+               s.zfsPoolVolumeSnapshotDestroy(fmt.Sprintf("containers/%s", 
source.Name()), tmpSnapshotName)
+               s.zfsPoolVolumeSnapshotDestroy(fmt.Sprintf("containers/%s", 
target.Name()), tmpSnapshotName)
+
                fs := fmt.Sprintf("containers/%s", target.Name())
                err = s.zfsPoolVolumeSet(fs, "mountpoint", 
targetContainerMountPoint)
                if err != nil {

From 17de1869158f22d7a77e6e33f46fa51100af9d1d Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Thu, 8 Jun 2017 22:21:55 +0200
Subject: [PATCH 2/3] storage: {copy,move} bugfixes

Signed-off-by: Christian Brauner <[email protected]>
---
 lxd/migrate.go           |  2 +-
 lxd/storage_btrfs.go     | 22 ++++++++++++----------
 lxd/storage_migration.go | 33 ++++++++++++++++++---------------
 lxd/storage_zfs.go       | 27 ++++++++++++++++-----------
 4 files changed, 47 insertions(+), 37 deletions(-)

diff --git a/lxd/migrate.go b/lxd/migrate.go
index 5fa7d1db2..244ee1d73 100644
--- a/lxd/migrate.go
+++ b/lxd/migrate.go
@@ -401,7 +401,7 @@ func (s *migrationSourceWs) Do(migrateOp *operation) error {
                return err
        }
 
-       err = driver.SendWhileRunning(s.fsConn, migrateOp, bwlimit)
+       err = driver.SendWhileRunning(s.fsConn, migrateOp, bwlimit, 
s.containerOnly)
        if err != nil {
                return abort(err)
        }
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 89f49ff4f..a403b5e8e 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -1770,7 +1770,7 @@ func (s *btrfsMigrationSourceDriver) send(conn 
*websocket.Conn, btrfsPath string
        return err
 }
 
-func (s *btrfsMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn, op 
*operation, bwlimit string) error {
+func (s *btrfsMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn, op 
*operation, bwlimit string, containerOnly bool) error {
        _, containerPool := s.container.Storage().GetContainerPoolInfo()
        containerName := s.container.Name()
        containersPath := getContainerMountPoint(containerPool, "")
@@ -1806,16 +1806,18 @@ func (s *btrfsMigrationSourceDriver) 
SendWhileRunning(conn *websocket.Conn, op *
                return s.send(conn, migrationSendSnapshot, "", wrapper)
        }
 
-       for i, snap := range s.snapshots {
-               prev := ""
-               if i > 0 {
-                       prev = getSnapshotMountPoint(containerPool, 
s.snapshots[i-1].Name())
-               }
+       if !containerOnly {
+               for i, snap := range s.snapshots {
+                       prev := ""
+                       if i > 0 {
+                               prev = getSnapshotMountPoint(containerPool, 
s.snapshots[i-1].Name())
+                       }
 
-               snapMntPoint := getSnapshotMountPoint(containerPool, 
snap.Name())
-               wrapper := StorageProgressReader(op, "fs_progress", snap.Name())
-               if err := s.send(conn, snapMntPoint, prev, wrapper); err != nil 
{
-                       return err
+                       snapMntPoint := getSnapshotMountPoint(containerPool, 
snap.Name())
+                       wrapper := StorageProgressReader(op, "fs_progress", 
snap.Name())
+                       if err := s.send(conn, snapMntPoint, prev, wrapper); 
err != nil {
+                               return err
+                       }
                }
        }
 
diff --git a/lxd/storage_migration.go b/lxd/storage_migration.go
index 4f1e095c5..c49f2b373 100644
--- a/lxd/storage_migration.go
+++ b/lxd/storage_migration.go
@@ -18,7 +18,7 @@ type MigrationStorageSourceDriver interface {
        /* send any bits of the container/snapshots that are possible while the
         * container is still running.
         */
-       SendWhileRunning(conn *websocket.Conn, op *operation, bwlimit string) 
error
+       SendWhileRunning(conn *websocket.Conn, op *operation, bwlimit string, 
containerOnly bool) 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
@@ -42,22 +42,25 @@ func (s rsyncStorageSourceDriver) Snapshots() []container {
        return s.snapshots
 }
 
-func (s rsyncStorageSourceDriver) SendWhileRunning(conn *websocket.Conn, op 
*operation, bwlimit string) error {
+func (s rsyncStorageSourceDriver) SendWhileRunning(conn *websocket.Conn, op 
*operation, bwlimit string, containerOnly bool) error {
        ctName, _, _ := containerGetParentAndSnapshotName(s.container.Name())
-       for _, send := range s.snapshots {
-               ourStart, err := send.StorageStart()
-               if err != nil {
-                       return err
-               }
-               if ourStart {
-                       defer send.StorageStop()
-               }
 
-               path := send.Path()
-               wrapper := StorageProgressReader(op, "fs_progress", send.Name())
-               err = RsyncSend(ctName, shared.AddSlash(path), conn, wrapper, 
bwlimit)
-               if err != nil {
-                       return err
+       if !containerOnly {
+               for _, send := range s.snapshots {
+                       ourStart, err := send.StorageStart()
+                       if err != nil {
+                               return err
+                       }
+                       if ourStart {
+                               defer send.StorageStop()
+                       }
+
+                       path := send.Path()
+                       wrapper := StorageProgressReader(op, "fs_progress", 
send.Name())
+                       err = RsyncSend(ctName, shared.AddSlash(path), conn, 
wrapper, bwlimit)
+                       if err != nil {
+                               return err
+                       }
                }
        }
 
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index dbe421525..dea7044f5 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -2510,7 +2510,7 @@ func (s *zfsMigrationSourceDriver) send(conn 
*websocket.Conn, zfsName string, zf
        return err
 }
 
-func (s *zfsMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn, op 
*operation, bwlimit string) error {
+func (s *zfsMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn, op 
*operation, bwlimit string, containerOnly bool) error {
        if s.container.IsSnapshot() {
                _, snapOnlyName, _ := 
containerGetParentAndSnapshotName(s.container.Name())
                snapshotName := fmt.Sprintf("snapshot-%s", snapOnlyName)
@@ -2519,18 +2519,19 @@ func (s *zfsMigrationSourceDriver) 
SendWhileRunning(conn *websocket.Conn, op *op
        }
 
        lastSnap := ""
+       if !containerOnly {
+               for i, snap := range s.zfsSnapshotNames {
+                       prev := ""
+                       if i > 0 {
+                               prev = s.zfsSnapshotNames[i-1]
+                       }
 
-       for i, snap := range s.zfsSnapshotNames {
-               prev := ""
-               if i > 0 {
-                       prev = s.zfsSnapshotNames[i-1]
-               }
-
-               lastSnap = snap
+                       lastSnap = snap
 
-               wrapper := StorageProgressReader(op, "fs_progress", snap)
-               if err := s.send(conn, snap, prev, wrapper); err != nil {
-                       return err
+                       wrapper := StorageProgressReader(op, "fs_progress", 
snap)
+                       if err := s.send(conn, snap, prev, wrapper); err != nil 
{
+                               return err
+                       }
                }
        }
 
@@ -2593,6 +2594,10 @@ func (s *storageZfs) MigrationSource(ct container, 
containerOnly bool) (Migratio
                zfs:              s,
        }
 
+       if containerOnly {
+               return &driver, nil
+       }
+
        /* List all the snapshots in order of reverse creation. The idea here
        * is that we send the oldest to newest snapshot, hopefully saving on
        * xfer costs. Then, after all that, we send the container itself.

From 4263ec402833cd45b0705e5448a560f610756691 Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Thu, 8 Jun 2017 22:32:28 +0200
Subject: [PATCH 3/3] test: add more {copy,migration} tests

Signed-off-by: Christian Brauner <[email protected]>
---
 test/suites/migration.sh | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/test/suites/migration.sh b/test/suites/migration.sh
index 20b75addb..6a75cf4ec 100644
--- a/test/suites/migration.sh
+++ b/test/suites/migration.sh
@@ -128,27 +128,33 @@ migration() {
 
   # Test container only copies
   lxc init testimage cccp
+  echo "before" | lxc file push - cccp/blah
   lxc snapshot cccp
   lxc snapshot cccp
+  echo "after" | lxc file push - cccp/blah
 
   # Local container only copy.
   lxc copy cccp udssr --container-only
   [ "$(lxc info udssr | grep -c snap)" -eq 0 ]
+  [ "$(lxc file pull udssr/blah -)" = "after" ]
   lxc delete udssr
 
   # Local container with snapshots copy.
   lxc copy cccp udssr
   [ "$(lxc info udssr | grep -c snap)" -eq 2 ]
+  [ "$(lxc file pull udssr/blah -)" = "after" ]
   lxc delete udssr
 
   # Remote container only copy.
   lxc_remote copy l1:cccp l2:udssr --container-only
   [ "$(lxc_remote info l2:udssr | grep -c snap)" -eq 0 ]
+  [ "$(lxc_remote file pull l2:udssr/blah -)" = "after" ]
   lxc_remote delete l2:udssr
 
   # Remote container with snapshots copy.
   lxc_remote copy l1:cccp l2:udssr
   [ "$(lxc_remote info l2:udssr | grep -c snap)" -eq 2 ]
+  [ "$(lxc_remote file pull l2:udssr/blah -)" = "after" ]
   lxc_remote delete l2:udssr
 
   # Remote container only move.
_______________________________________________
lxc-devel mailing list
[email protected]
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to