diff --git a/virtcontainers/factory/template/template.go b/virtcontainers/factory/template/template.go index d0c8c5650e..979e91dc66 100644 --- a/virtcontainers/factory/template/template.go +++ b/virtcontainers/factory/template/template.go @@ -25,7 +25,6 @@ type template struct { var templateProxyType = vc.KataBuiltInProxyType var templateWaitForAgent = 2 * time.Second -var templateWaitForMigration = 1 * time.Second // Fetch finds and returns a pre-built template factory. // TODO: save template metadata and fetch from storage. @@ -145,9 +144,6 @@ func (t *template) createTemplateVM(ctx context.Context) error { return err } - // qemu QMP does not wait for migration to finish... - time.Sleep(templateWaitForMigration) - return nil } diff --git a/virtcontainers/factory/template/template_test.go b/virtcontainers/factory/template/template_test.go index a5021f6107..e6ddab557f 100644 --- a/virtcontainers/factory/template/template_test.go +++ b/virtcontainers/factory/template/template_test.go @@ -20,7 +20,6 @@ import ( func TestTemplateFactory(t *testing.T) { assert := assert.New(t) - templateWaitForMigration = 1 * time.Microsecond templateWaitForAgent = 1 * time.Microsecond testDir, _ := ioutil.TempDir("", "vmfactory-tmp-") diff --git a/virtcontainers/qemu.go b/virtcontainers/qemu.go index fcaf70a838..2e6d19148d 100644 --- a/virtcontainers/qemu.go +++ b/virtcontainers/qemu.go @@ -76,6 +76,7 @@ const ( qmpCapErrMsg = "Failed to negoatiate QMP capabilities" qmpCapMigrationBypassSharedMemory = "bypass-shared-memory" qmpExecCatCmd = "exec:cat" + qmpMigrationWaitTimeout = 5 * time.Second scsiControllerID = "scsi0" rngID = "rng0" @@ -1181,6 +1182,29 @@ func (q *qemu) saveSandbox() error { return err } + t := time.NewTimer(qmpMigrationWaitTimeout) + defer t.Stop() + for { + status, err := q.qmpMonitorCh.qmp.ExecuteQueryMigration(q.qmpMonitorCh.ctx) + if err != nil { + q.Logger().WithError(err).Error("failed to query migration status") + return err + } + if status.Status == "completed" { + break + } + + select { + case <-t.C: + q.Logger().WithField("migration-status", status).Error("timeout waiting for qemu migration") + return fmt.Errorf("timed out after %d seconds waiting for qemu migration", qmpMigrationWaitTimeout) + default: + // migration in progress + q.Logger().WithField("migration-status", status).Debug("migration in progress") + time.Sleep(100 * time.Millisecond) + } + } + return nil }