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

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) ===
This adds a new criu migration type "NONE" which can be used to perform mock
live migration. Any step but actually calling criu will be performed.

Closes #3798.

Signed-off-by: Christian Brauner <[email protected]>
From e9b04a39f689c1498a773f54c5f190c794b89c9c Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Wed, 27 Sep 2017 17:56:13 +0200
Subject: [PATCH 1/3] migration: stateless incremental containers

This adds a new criu migration type "NONE" which can be used to perform mock
live migration. Any step but actually calling criu will be performed.

Closes #3798.

Signed-off-by: Christian Brauner <[email protected]>
---
 lxd/migrate.go    |  27 ++++++++++++--
 lxd/migrate.pb.go | 103 +++++++++++++++++++++++++++++++++++++++++++-----------
 lxd/migrate.proto |   1 +
 3 files changed, 108 insertions(+), 23 deletions(-)

diff --git a/lxd/migrate.go b/lxd/migrate.go
index 59fa03faa..555fb0714 100644
--- a/lxd/migrate.go
+++ b/lxd/migrate.go
@@ -360,6 +360,9 @@ func (s *migrationSourceWs) Do(migrateOp *operation) error {
        criuType := CRIUType_CRIU_RSYNC.Enum()
        if !s.live {
                criuType = nil
+               if s.container.IsRunning() {
+                       criuType = CRIUType_NONE.Enum()
+               }
        }
 
        // Storage needs to start unconditionally now, since we need to
@@ -470,6 +473,7 @@ func (s *migrationSourceWs) Do(migrateOp *operation) error {
 
        restoreSuccess := make(chan bool, 1)
        dumpSuccess := make(chan error, 1)
+
        if s.live {
                if header.Criu == nil {
                        return abort(fmt.Errorf("Got no CRIU socket type for 
live migration"))
@@ -589,7 +593,9 @@ func (s *migrationSourceWs) Do(migrateOp *operation) error {
                if err != nil {
                        return abort(err)
                }
+       }
 
+       if s.live || (header.Criu != nil && *header.Criu == CRIUType_NONE) {
                err = driver.SendAfterCheckpoint(s.fsConn, bwlimit)
                if err != nil {
                        return abort(err)
@@ -827,8 +833,12 @@ func (c *migrationSink) Do(migrateOp *operation) error {
        }
 
        criuType := CRIUType_CRIU_RSYNC.Enum()
-       if !live {
-               criuType = nil
+       if header.Criu != nil && *header.Criu == CRIUType_NONE {
+               criuType = CRIUType_NONE.Enum()
+       } else {
+               if !live {
+                       criuType = nil
+               }
        }
 
        mySink := c.src.container.Storage().MigrationSink
@@ -898,7 +908,18 @@ func (c *migrationSink) Do(migrateOp *operation) error {
                                fsConn = c.src.fsConn
                        }
 
-                       err = mySink(live, c.src.container, snapshots, fsConn, 
srcIdmap, migrateOp, c.src.containerOnly)
+                       sendFinalFsDelta := false
+                       if live {
+                               sendFinalFsDelta = true
+                       }
+
+                       if criuType != nil && *criuType == CRIUType_NONE {
+                               sendFinalFsDelta = true
+                       }
+
+                       err = mySink(sendFinalFsDelta, c.src.container,
+                               snapshots, fsConn, srcIdmap, migrateOp,
+                               c.src.containerOnly)
                        if err != nil {
                                fsTransfer <- err
                                return
diff --git a/lxd/migrate.pb.go b/lxd/migrate.pb.go
index 69dafcb77..93dce20cf 100644
--- a/lxd/migrate.pb.go
+++ b/lxd/migrate.pb.go
@@ -1,6 +1,5 @@
-// Code generated by protoc-gen-go.
+// Code generated by protoc-gen-go. DO NOT EDIT.
 // source: lxd/migrate.proto
-// DO NOT EDIT!
 
 /*
 Package main is a generated protocol buffer package.
@@ -19,12 +18,20 @@ It has these top-level messages:
 package main
 
 import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
 import math "math"
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
+var _ = fmt.Errorf
 var _ = math.Inf
 
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
 type MigrationFSType int32
 
 const (
@@ -63,21 +70,25 @@ func (x *MigrationFSType) UnmarshalJSON(data []byte) error {
        *x = MigrationFSType(value)
        return nil
 }
+func (MigrationFSType) EnumDescriptor() ([]byte, []int) { return 
fileDescriptor0, []int{0} }
 
 type CRIUType int32
 
 const (
        CRIUType_CRIU_RSYNC CRIUType = 0
        CRIUType_PHAUL      CRIUType = 1
+       CRIUType_NONE       CRIUType = 2
 )
 
 var CRIUType_name = map[int32]string{
        0: "CRIU_RSYNC",
        1: "PHAUL",
+       2: "NONE",
 }
 var CRIUType_value = map[string]int32{
        "CRIU_RSYNC": 0,
        "PHAUL":      1,
+       "NONE":       2,
 }
 
 func (x CRIUType) Enum() *CRIUType {
@@ -96,6 +107,7 @@ func (x *CRIUType) UnmarshalJSON(data []byte) error {
        *x = CRIUType(value)
        return nil
 }
+func (CRIUType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, 
[]int{1} }
 
 type IDMapType struct {
        Isuid            *bool  `protobuf:"varint,1,req,name=isuid" 
json:"isuid,omitempty"`
@@ -106,9 +118,10 @@ type IDMapType struct {
        XXX_unrecognized []byte `json:"-"`
 }
 
-func (m *IDMapType) Reset()         { *m = IDMapType{} }
-func (m *IDMapType) String() string { return proto.CompactTextString(m) }
-func (*IDMapType) ProtoMessage()    {}
+func (m *IDMapType) Reset()                    { *m = IDMapType{} }
+func (m *IDMapType) String() string            { return 
proto.CompactTextString(m) }
+func (*IDMapType) ProtoMessage()               {}
+func (*IDMapType) Descriptor() ([]byte, []int) { return fileDescriptor0, 
[]int{0} }
 
 func (m *IDMapType) GetIsuid() bool {
        if m != nil && m.Isuid != nil {
@@ -151,9 +164,10 @@ type Config struct {
        XXX_unrecognized []byte  `json:"-"`
 }
 
-func (m *Config) Reset()         { *m = Config{} }
-func (m *Config) String() string { return proto.CompactTextString(m) }
-func (*Config) ProtoMessage()    {}
+func (m *Config) Reset()                    { *m = Config{} }
+func (m *Config) String() string            { return 
proto.CompactTextString(m) }
+func (*Config) ProtoMessage()               {}
+func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} 
}
 
 func (m *Config) GetKey() string {
        if m != nil && m.Key != nil {
@@ -175,9 +189,10 @@ type Device struct {
        XXX_unrecognized []byte    `json:"-"`
 }
 
-func (m *Device) Reset()         { *m = Device{} }
-func (m *Device) String() string { return proto.CompactTextString(m) }
-func (*Device) ProtoMessage()    {}
+func (m *Device) Reset()                    { *m = Device{} }
+func (m *Device) String() string            { return 
proto.CompactTextString(m) }
+func (*Device) ProtoMessage()               {}
+func (*Device) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} 
}
 
 func (m *Device) GetName() string {
        if m != nil && m.Name != nil {
@@ -204,9 +219,10 @@ type Snapshot struct {
        XXX_unrecognized []byte    `json:"-"`
 }
 
-func (m *Snapshot) Reset()         { *m = Snapshot{} }
-func (m *Snapshot) String() string { return proto.CompactTextString(m) }
-func (*Snapshot) ProtoMessage()    {}
+func (m *Snapshot) Reset()                    { *m = Snapshot{} }
+func (m *Snapshot) String() string            { return 
proto.CompactTextString(m) }
+func (*Snapshot) ProtoMessage()               {}
+func (*Snapshot) Descriptor() ([]byte, []int) { return fileDescriptor0, 
[]int{3} }
 
 func (m *Snapshot) GetName() string {
        if m != nil && m.Name != nil {
@@ -266,9 +282,10 @@ type MigrationHeader struct {
        XXX_unrecognized []byte           `json:"-"`
 }
 
-func (m *MigrationHeader) Reset()         { *m = MigrationHeader{} }
-func (m *MigrationHeader) String() string { return proto.CompactTextString(m) }
-func (*MigrationHeader) ProtoMessage()    {}
+func (m *MigrationHeader) Reset()                    { *m = MigrationHeader{} }
+func (m *MigrationHeader) String() string            { return 
proto.CompactTextString(m) }
+func (*MigrationHeader) ProtoMessage()               {}
+func (*MigrationHeader) Descriptor() ([]byte, []int) { return fileDescriptor0, 
[]int{4} }
 
 func (m *MigrationHeader) GetFs() MigrationFSType {
        if m != nil && m.Fs != nil {
@@ -312,9 +329,10 @@ type MigrationControl struct {
        XXX_unrecognized []byte  `json:"-"`
 }
 
-func (m *MigrationControl) Reset()         { *m = MigrationControl{} }
-func (m *MigrationControl) String() string { return proto.CompactTextString(m) 
}
-func (*MigrationControl) ProtoMessage()    {}
+func (m *MigrationControl) Reset()                    { *m = 
MigrationControl{} }
+func (m *MigrationControl) String() string            { return 
proto.CompactTextString(m) }
+func (*MigrationControl) ProtoMessage()               {}
+func (*MigrationControl) Descriptor() ([]byte, []int) { return 
fileDescriptor0, []int{5} }
 
 func (m *MigrationControl) GetSuccess() bool {
        if m != nil && m.Success != nil {
@@ -331,6 +349,51 @@ func (m *MigrationControl) GetMessage() string {
 }
 
 func init() {
+       proto.RegisterType((*IDMapType)(nil), "main.IDMapType")
+       proto.RegisterType((*Config)(nil), "main.Config")
+       proto.RegisterType((*Device)(nil), "main.Device")
+       proto.RegisterType((*Snapshot)(nil), "main.Snapshot")
+       proto.RegisterType((*MigrationHeader)(nil), "main.MigrationHeader")
+       proto.RegisterType((*MigrationControl)(nil), "main.MigrationControl")
        proto.RegisterEnum("main.MigrationFSType", MigrationFSType_name, 
MigrationFSType_value)
        proto.RegisterEnum("main.CRIUType", CRIUType_name, CRIUType_value)
 }
+
+func init() { proto.RegisterFile("lxd/migrate.proto", fileDescriptor0) }
+
+var fileDescriptor0 = []byte{
+       // 523 bytes of a gzipped FileDescriptorProto
+       0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x52, 
0x4d, 0x6f, 0xd3, 0x40,
+       0x10, 0xc5, 0x5f, 0xa9, 0x3d, 0x09, 0xa9, 0x59, 0x01, 0x5a, 0x21, 0x0e, 
0x91, 0xd5, 0x4a, 0x51,
+       0x85, 0xd2, 0x2a, 0x37, 0x8e, 0x24, 0x21, 0x6a, 0x25, 0x1a, 0xd0, 0xa6, 
0x3d, 0xc0, 0x05, 0xad,
+       0xec, 0x89, 0xb3, 0xc2, 0x5f, 0xf2, 0xda, 0x15, 0x3d, 0xf1, 0x33, 0xf9, 
0x2f, 0x9c, 0xd0, 0xae,
+       0x3f, 0x9a, 0x48, 0x70, 0x9b, 0xf7, 0xe6, 0x79, 0x9e, 0xe7, 0xed, 0xc0, 
0x8b, 0xe4, 0x67, 0x74,
+       0x99, 0x8a, 0xb8, 0xe4, 0x15, 0xce, 0x8a, 0x32, 0xaf, 0x72, 0x62, 0xa7, 
0x5c, 0x64, 0xc1, 0x2f,
+       0xf0, 0x6e, 0x56, 0xb7, 0xbc, 0xb8, 0x7b, 0x2c, 0x90, 0xbc, 0x04, 0x47, 
0xc8, 0x5a, 0x44, 0xd4,
+       0x98, 0x98, 0x53, 0x97, 0x35, 0xa0, 0x61, 0x63, 0x11, 0x51, 0xb3, 0x63, 
0x63, 0x11, 0x91, 0xd7,
+       0x30, 0xd8, 0xe7, 0xb2, 0x12, 0x11, 0xb5, 0x26, 0xe6, 0xd4, 0x61, 0x2d, 
0x22, 0x04, 0xec, 0x4c,
+       0x8a, 0x88, 0xda, 0x9a, 0xd5, 0x35, 0x79, 0x03, 0x6e, 0xca, 0x8b, 0x92, 
0x67, 0x31, 0x52, 0x47,
+       0xf3, 0x3d, 0x0e, 0xae, 0x60, 0xb0, 0xcc, 0xb3, 0x9d, 0x88, 0x89, 0x0f, 
0xd6, 0x0f, 0x7c, 0xd4,
+       0xde, 0x1e, 0x53, 0xa5, 0x72, 0x7e, 0xe0, 0x49, 0x8d, 0xda, 0xd9, 0x63, 
0x0d, 0x08, 0x16, 0x30,
+       0x58, 0xe1, 0x83, 0x08, 0x51, 0x7b, 0xf1, 0x14, 0xdb, 0x4f, 0x74, 0x4d, 
0xce, 0x60, 0x10, 0xea,
+       0x79, 0xd4, 0x9c, 0x58, 0xd3, 0xe1, 0x7c, 0x34, 0x53, 0x7b, 0xce, 0x1a, 
0x0f, 0xd6, 0xf6, 0x82,
+       0x3f, 0x06, 0xb8, 0xdb, 0x8c, 0x17, 0x72, 0x9f, 0x57, 0xff, 0x1c, 0x33, 
0x83, 0x61, 0x92, 0x87,
+       0x3c, 0x59, 0xfe, 0x7f, 0xd6, 0xa1, 0x40, 0xad, 0x58, 0x94, 0xf9, 0x4e, 
0x24, 0x28, 0xa9, 0x35,
+       0xb1, 0xa6, 0x1e, 0xeb, 0x31, 0x79, 0x0b, 0x1e, 0x16, 0x7b, 0x4c, 0xb1, 
0xe4, 0x89, 0xce, 0xc5,
+       0x65, 0x4f, 0x04, 0xb9, 0x82, 0x91, 0x1e, 0xd4, 0xec, 0x24, 0xa9, 0x73, 
0x68, 0xd5, 0x90, 0xec,
+       0x48, 0x41, 0x02, 0x18, 0xf1, 0x32, 0xdc, 0x8b, 0x0a, 0xc3, 0xaa, 0x2e, 
0x91, 0x0e, 0x74, 0xa4,
+       0x47, 0x9c, 0xfa, 0x1f, 0x59, 0xf1, 0x0a, 0x77, 0x75, 0x42, 0x4f, 0xb4, 
0x65, 0x8f, 0x83, 0xdf,
+       0x06, 0x9c, 0xde, 0xea, 0x5b, 0x10, 0x79, 0x76, 0x8d, 0x3c, 0xc2, 0x92, 
0x9c, 0x83, 0xb9, 0x93,
+       0x3a, 0x81, 0xf1, 0xfc, 0x55, 0xe3, 0xdd, 0x4b, 0xd6, 0x5b, 0x75, 0x1d, 
0xcc, 0xdc, 0x29, 0x6b,
+       0x3b, 0x2c, 0x45, 0x4d, 0xcd, 0x89, 0x31, 0x1d, 0xcf, 0xc7, 0x6d, 0x1e, 
0xec, 0xe6, 0x5e, 0x2b,
+       0x74, 0x8f, 0x9c, 0x83, 0x23, 0xa2, 0x94, 0x17, 0x3a, 0x87, 0xe1, 0xfc, 
0xb4, 0x11, 0xf5, 0x57,
+       0xc6, 0x9a, 0x2e, 0x39, 0x83, 0xe7, 0xb2, 0x7d, 0x81, 0x0d, 0x4f, 0x51, 
0x52, 0x5b, 0xc7, 0x76,
+       0x4c, 0x92, 0x77, 0xe0, 0x75, 0x44, 0x17, 0x4d, 0xeb, 0xda, 0x3d, 0x1f, 
0x7b, 0x12, 0x04, 0x6b,
+       0xf0, 0xfb, 0xbf, 0x5e, 0xe6, 0x59, 0x55, 0xe6, 0x09, 0xa1, 0x70, 0x22, 
0xeb, 0x30, 0x44, 0x29,
+       0xdb, 0xb3, 0xee, 0xa0, 0xea, 0xa4, 0x28, 0x25, 0x8f, 0x51, 0xef, 0xe3, 
0xb1, 0x0e, 0x5e, 0xbc,
+       0x3f, 0x08, 0xa8, 0xd9, 0x9e, 0x78, 0xe0, 0xb0, 0xed, 0xd7, 0xcd, 0xd2, 
0x7f, 0xa6, 0xca, 0xc5,
+       0x1d, 0x5b, 0x6f, 0x7d, 0x83, 0x9c, 0x80, 0xf5, 0x6d, 0xbd, 0xf5, 0x4d, 
0x55, 0xb0, 0xc5, 0xca,
+       0xb7, 0x2e, 0x2e, 0xc1, 0xed, 0xf2, 0x20, 0x63, 0x00, 0x55, 0x7f, 0x3f, 
0xf8, 0xf0, 0xcb, 0xf5,
+       0x87, 0xfb, 0x4f, 0xbe, 0x41, 0x5c, 0xb0, 0x37, 0x9f, 0x37, 0x1f, 0x7d, 
0xf3, 0x6f, 0x00, 0x00,
+       0x00, 0xff, 0xff, 0xe4, 0xf2, 0xc3, 0xd0, 0x9b, 0x03, 0x00, 0x00,
+}
diff --git a/lxd/migrate.proto b/lxd/migrate.proto
index 6cdee4eff..172a940be 100644
--- a/lxd/migrate.proto
+++ b/lxd/migrate.proto
@@ -10,6 +10,7 @@ enum MigrationFSType {
 enum CRIUType {
        CRIU_RSYNC      = 0;
        PHAUL           = 1;
+       NONE            = 2;
 }
 
 message IDMapType {

From 51de6151d7286583309bd67f9a4e125c4f43ed19 Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Wed, 27 Sep 2017 20:04:47 +0200
Subject: [PATCH 2/3] tests: add stateless live migration tests

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

diff --git a/test/suites/migration.sh b/test/suites/migration.sh
index 057346c75..16b1d0bbd 100644
--- a/test/suites/migration.sh
+++ b/test/suites/migration.sh
@@ -122,6 +122,23 @@ migration() {
   lxc_remote list l1: | grep RUNNING | grep nonlive2
   lxc_remote delete l1:nonlive2 l2:nonlive2 --force
 
+  lxc_remote launch testimage cccp
+  lxc_remote copy l1:cccp l2:udssr --stateless
+  lxc_remote delete l2:udssr --force
+  lxc_remote copy l1:cccp l2:udssr --stateless --mode=push
+  lxc_remote delete l2:udssr --force
+  lxc_remote copy l1:cccp l2:udssr --stateless --mode=relay
+  lxc_remote delete l2:udssr --force
+
+  lxc_remote move l1:cccp l2:udssr --stateless
+  lxc_remote delete l2:udssr --force
+  lxc_remote launch testimage cccp
+  lxc_remote move l1:cccp l2:udssr --stateless --mode=push
+  lxc_remote delete l2:udssr --force
+  lxc_remote launch testimage cccp
+  lxc_remote move l1:cccp l2:udssr --stateless --mode=relay
+  lxc_remote delete l2:udssr --force
+
   lxc_remote start l2:nonlive
   lxc_remote list l2: | grep RUNNING | grep nonlive
   lxc_remote delete l2:nonlive --force

From 7fd48765a83f5a82561b3cb0f4043ca73df1f60d Mon Sep 17 00:00:00 2001
From: Christian Brauner <[email protected]>
Date: Wed, 27 Sep 2017 19:33:08 +0200
Subject: [PATCH 3/3] migration: fix lvm stateful restores

Signed-off-by: Christian Brauner <[email protected]>
---
 lxd/container_lxc.go |  1 +
 lxd/storage_lvm.go   | 15 ++++++++++++---
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index a7fa9ba99..a21ef563a 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -2766,6 +2766,7 @@ func (c *containerLXC) Restore(sourceContainer container, 
stateful bool) error {
        // If the container wasn't running but was stateful, should we restore
        // it as running?
        if stateful == true {
+               logger.Errorf("0000: %s", c.StatePath())
                if !shared.PathExists(c.StatePath()) {
                        return fmt.Errorf("Stateful snapshot restore requested 
by snapshot is stateless")
                }
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index ece80e331..59514baf8 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -1293,15 +1293,24 @@ func (s *storageLvm) ContainerRestore(target container, 
source container) error
                }
 
                poolName := s.getOnDiskPoolName()
-               err = s.removeLV(poolName, 
storagePoolVolumeAPIEndpointContainers, targetLvmName)
+               err = s.removeLV(poolName,
+                       storagePoolVolumeAPIEndpointContainers, targetLvmName)
                if err != nil {
-                       logger.Errorf(fmt.Sprintf("Failed to remove \"%s\": 
%s.", targetLvmName, err))
+                       logger.Errorf("Failed to remove \"%s\": %s",
+                               targetLvmName, err)
                }
 
-               _, err = s.createSnapshotLV(poolName, sourceLvmName, 
storagePoolVolumeAPIEndpointContainers, targetLvmName, 
storagePoolVolumeAPIEndpointContainers, false, true)
+               _, err = s.createSnapshotLV(poolName, sourceLvmName,
+                       storagePoolVolumeAPIEndpointContainers, targetLvmName,
+                       storagePoolVolumeAPIEndpointContainers, false, true)
                if err != nil {
                        return fmt.Errorf("Error creating snapshot LV: %v", err)
                }
+
+               _, err = target.Storage().ContainerMount(target)
+               if err != nil {
+                       return err
+               }
        } else {
                ourMount, err := target.Storage().ContainerMount(target)
                if err != nil {
_______________________________________________
lxc-devel mailing list
[email protected]
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to