The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6372
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) === Modifies MatchTypes to accept a fallback type which is used when doing cross-pool migrations on different backend drivers.
From 7629ef9b9e808fc9b89b0e7babb7bf159a7734f1 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 31 Oct 2019 11:27:01 +0000 Subject: [PATCH 1/3] lxd/migration/migration/volumes: Updates MatchTypes to accept fallback type This is used when the sender prefers a different transport method than the recipient. The fallback type specified on the recipient is then sent back to the sender and they are expected to accept it. Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/migration/migration_volumes.go | 62 ++++++++++++++++++------------ 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/lxd/migration/migration_volumes.go b/lxd/migration/migration_volumes.go index 8b504922b4..415ecac98d 100644 --- a/lxd/migration/migration_volumes.go +++ b/lxd/migration/migration_volumes.go @@ -96,44 +96,58 @@ func TypesToHeader(types ...Type) MigrationHeader { // MatchTypes attempts to find a matching migration transport type between an offered type sent // from a remote source and the types supported by a local storage pool. If a match is found then // a Type is returned containing the method and the matching optional features present in both. -func MatchTypes(offer MigrationHeader, ourTypes []Type) (Type, error) { +// The function also takes a fallback type which is used as an additional offer type preference +// in case the preferred remote type is not compatible with the local type available. +// It is expected that both sides of the migration will support the fallback type for the volume's +// content type that is being migrated. +func MatchTypes(offer MigrationHeader, fallbackType MigrationFSType, ourTypes []Type) (Type, error) { + // Generate an offer types slice from the preferred type supplied from remote and the + // fallback type supplied based on the content type of the transfer. + offeredFSTypes := []MigrationFSType{offer.GetFs(), fallbackType} + // Find first matching type. - offerFSType := offer.GetFs() for _, ourType := range ourTypes { - if offerFSType != ourType.FSType { - continue // Not a match, try the next one. - } + for _, offerFSType := range offeredFSTypes { + if offerFSType != ourType.FSType { + continue // Not a match, try the next one. + } - // We got a match, now extract the relevant offered features. - var offeredFeatures []string - if offerFSType == MigrationFSType_ZFS { - offeredFeatures = offer.GetZfsFeaturesSlice() - } else if offerFSType == MigrationFSType_RSYNC { - offeredFeatures = offer.GetRsyncFeaturesSlice() - } + // We got a match, now extract the relevant offered features. + var offeredFeatures []string + if offerFSType == MigrationFSType_ZFS { + offeredFeatures = offer.GetZfsFeaturesSlice() + } else if offerFSType == MigrationFSType_RSYNC { + offeredFeatures = offer.GetRsyncFeaturesSlice() + } - // Find common features in both our type and offered type. - commonFeatures := []string{} - for _, ourFeature := range ourType.Features { - if shared.StringInSlice(ourFeature, offeredFeatures) { - commonFeatures = append(commonFeatures, ourFeature) + // Find common features in both our type and offered type. + commonFeatures := []string{} + for _, ourFeature := range ourType.Features { + if shared.StringInSlice(ourFeature, offeredFeatures) { + commonFeatures = append(commonFeatures, ourFeature) + } } + + // Return type with combined features. + return Type{ + FSType: ourType.FSType, + Features: commonFeatures, + }, nil } + } - // Return type with combined features. - return Type{ - FSType: ourType.FSType, - Features: commonFeatures, - }, nil + // No matching transport type found, generate an error with offered types and our types. + offeredTypeStrings := make([]string, 0, len(offeredFSTypes)) + for _, offerFSType := range offeredFSTypes { + offeredTypeStrings = append(offeredTypeStrings, offerFSType.String()) } - // No matching transport type found, generate an error with offered type and our types. ourTypeStrings := make([]string, 0, len(ourTypes)) for _, ourType := range ourTypes { ourTypeStrings = append(ourTypeStrings, ourType.FSType.String()) } - return Type{}, fmt.Errorf("No matching migration type found. Offered type: %v, our types: %v", offerFSType, ourTypeStrings) + return Type{}, fmt.Errorf("No matching migration type found. Offered types: %v, our types: %v", offeredTypeStrings, ourTypeStrings) } func progressWrapperRender(op *operations.Operation, key string, description string, progressInt int64, speedInt int64) { From 512430104f75780b4b92549c2b524a7c4bfd3e44 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 31 Oct 2019 11:28:10 +0000 Subject: [PATCH 2/3] lxd/migration/storage/volumes: Updates MatchTypes usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/migrate_storage_volumes.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/migrate_storage_volumes.go b/lxd/migrate_storage_volumes.go index a6d69cafce..978d95ed88 100644 --- a/lxd/migrate_storage_volumes.go +++ b/lxd/migrate_storage_volumes.go @@ -143,7 +143,7 @@ func (s *migrationSourceWs) DoStorage(state *state.State, poolName string, volNa // Use new storage layer for migration if supported. if pool != nil { - migrationType, err := migration.MatchTypes(respHeader, poolMigrationTypes) + migrationType, err := migration.MatchTypes(respHeader, migration.MigrationFSType_RSYNC, poolMigrationTypes) if err != nil { logger.Errorf("Failed to neogotiate migration type: %v", err) s.sendControl(err) @@ -343,7 +343,7 @@ func (c *migrationSink) DoStorage(state *state.State, poolName string, req *api. // Extract the source's migration type and then match it against our pool's // supported types and features. If a match is found the combined features list // will be sent back to requester. - respType, err := migration.MatchTypes(offerHeader, pool.MigrationTypes(storageDrivers.ContentTypeFS)) + respType, err := migration.MatchTypes(offerHeader, migration.MigrationFSType_RSYNC, pool.MigrationTypes(storageDrivers.ContentTypeFS)) if err != nil { return err } From 1a6f324d905ec9ff01b31cd4a36a39adb30238ff Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 31 Oct 2019 11:28:27 +0000 Subject: [PATCH 3/3] lxd/storage/backend/lxd: Updates MatchTypes usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/backend_lxd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index 68c39a6baf..9f91ab84d9 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -340,7 +340,7 @@ func (b *lxdBackend) CreateCustomVolumeFromCopy(volName, desc string, config map // Negotiate the migration type to use. offeredTypes := srcPool.MigrationTypes(drivers.ContentTypeFS) offerHeader := migration.TypesToHeader(offeredTypes...) - migrationType, err := migration.MatchTypes(offerHeader, b.MigrationTypes(drivers.ContentTypeFS)) + migrationType, err := migration.MatchTypes(offerHeader, migration.MigrationFSType_RSYNC, b.MigrationTypes(drivers.ContentTypeFS)) if err != nil { return fmt.Errorf("Failed to neogotiate copy migration type: %v", err) }
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel