@@ -396,15 +396,13 @@ func (d *Daemon) beginImports(ctx context.Context, cleanupInstances bool) error
396396 // This is used so that we ensure each pool in each target is checked only once for volumes in a particular project, for a particular VM OS.
397397 visitedLocations := map [string ]map [string ]map [string ]bool {}
398398 ignoredBatches := []string {}
399+ var volLock sync.Mutex
399400 err = util .RunConcurrentMap (migrationState , func (batchName string , state queue.MigrationState ) error {
400401 log := log .With (slog .String ("batch" , state .Batch .Name ))
401402 for instUUID , q := range state .QueueEntries {
402403 for _ , pool := range q .Placement .StoragePools {
404+ volLock .Lock ()
403405 // for every instance in this batch, check volumes at the corresponding target, unless we did already.
404- if visitedLocations == nil {
405- visitedLocations = map [string ]map [string ]map [string ]bool {}
406- }
407-
408406 if visitedLocations [q .Placement .TargetName ] == nil {
409407 visitedLocations [q .Placement .TargetName ] = map [string ]map [string ]bool {}
410408 }
@@ -413,18 +411,27 @@ func (d *Daemon) beginImports(ctx context.Context, cleanupInstances bool) error
413411 visitedLocations [q .Placement .TargetName ][q .Placement .TargetProject ] = map [string ]bool {}
414412 }
415413
416- if ! visitedLocations [q .Placement .TargetName ][q .Placement .TargetProject ][pool ] {
414+ shouldCreateVol := ! visitedLocations [q .Placement .TargetName ][q .Placement .TargetProject ][pool ]
415+ if shouldCreateVol {
416+ visitedLocations [q .Placement .TargetName ][q .Placement .TargetProject ][pool ] = true
417+ }
418+
419+ volLock .Unlock ()
420+
421+ if shouldCreateVol {
417422 err := d .ensureISOImagesExistInStoragePool (ctx , state .Instances [instUUID ], state .Targets [instUUID ], state .Batch , pool , q .Placement .TargetProject )
418423 if err != nil {
424+ volLock .Lock ()
425+ visitedLocations [q .Placement .TargetName ][q .Placement .TargetProject ][pool ] = false
426+ volLock .Unlock ()
427+
419428 log .Error ("Failed to validate batch" , logger .Err (err ))
420429 _ , err := d .batch .UpdateStatusByName (ctx , state .Batch .Name , api .BATCHSTATUS_ERROR , err .Error ())
421430 if err != nil {
422431 return fmt .Errorf ("Failed to set batch status to %q: %w" , api .BATCHSTATUS_ERROR , err )
423432 }
424433
425434 ignoredBatches = append (ignoredBatches , state .Batch .Name )
426- } else {
427- visitedLocations [q .Placement .TargetName ][q .Placement .TargetProject ][pool ] = true
428435 }
429436 }
430437 }
@@ -672,7 +679,32 @@ func (d *Daemon) createTargetVM(ctx context.Context, b migration.Batch, inst mig
672679 if cleanupInstances {
673680 reverter .Add (func () {
674681 slog .Error ("Cleaning up new instance after failure" , slog .String ("revert" , "instance cleanup" ), slog .Any ("error" , err ))
675- cleanup ()
682+
683+ // Instantiate a new client.
684+ it , err := target .NewTarget (t .ToAPI ())
685+ if err != nil {
686+ slog .Error ("Failed to construct target" , slog .String ("name" , t .Name ), slog .Any ("error" , err ))
687+ return
688+ }
689+
690+ timeoutCtx , cancel := context .WithTimeout (ctx , it .Timeout ())
691+ defer cancel ()
692+
693+ // Connect to the target.
694+ err = it .Connect (timeoutCtx )
695+ if err != nil {
696+ slog .Error ("Failed to connect to target" , slog .String ("name" , it .GetName ()), slog .Any ("error" , err ))
697+ return
698+ }
699+
700+ // Set the project.
701+ err = it .SetProject (q .Placement .TargetProject )
702+ if err != nil {
703+ slog .Error ("Failed to set project" , slog .String ("project" , q .Placement .TargetProject ), slog .String ("name" , it .GetName ()), slog .Any ("error" , err ))
704+ return
705+ }
706+
707+ cleanup (it )
676708 })
677709 }
678710
0 commit comments