diff --git a/qemu/qemu.go b/qemu/qemu.go index a360ec9213..f281d4ecba 100644 --- a/qemu/qemu.go +++ b/qemu/qemu.go @@ -1397,6 +1397,8 @@ const ( MigrationFD = 1 // MigrationExec is the migration incoming type based on commands. MigrationExec = 2 + // MigrationDefer is the defer incoming type + MigrationDefer = 3 ) // Incoming controls migration source preparation @@ -1779,6 +1781,8 @@ func (config *Config) appendIncoming() { case MigrationFD: chFDs := config.appendFDs([]*os.File{config.Incoming.FD}) uri = fmt.Sprintf("fd:%d", chFDs[0]) + case MigrationDefer: + uri = "defer" default: return } diff --git a/qemu/qemu_test.go b/qemu/qemu_test.go index 2af0ded79e..f5692f5013 100644 --- a/qemu/qemu_test.go +++ b/qemu/qemu_test.go @@ -725,6 +725,16 @@ func TestAppendIncomingExec(t *testing.T) { testAppend(source, incomingStringExec, t) } +var incomingStringDefer = "-S -incoming defer" + +func TestAppendIncomingDefer(t *testing.T) { + source := Incoming{ + MigrationType: MigrationDefer, + } + + testAppend(source, incomingStringDefer, t) +} + func TestBadName(t *testing.T) { c := &Config{} c.appendName() diff --git a/qemu/qmp.go b/qemu/qmp.go index bada7bc4e5..df2ab2ed54 100644 --- a/qemu/qmp.go +++ b/qemu/qmp.go @@ -1457,3 +1457,11 @@ func (q *QMP) ExecuteQueryMigration(ctx context.Context) (MigrationStatus, error return status, nil } + +// ExecuteMigrationIncoming start migration from incoming uri. +func (q *QMP) ExecuteMigrationIncoming(ctx context.Context, uri string) error { + args := map[string]interface{}{ + "uri": uri, + } + return q.executeCommand(ctx, "migrate-incoming", args, nil) +} diff --git a/qemu/qmp_test.go b/qemu/qmp_test.go index 5b11e94f64..0925420359 100644 --- a/qemu/qmp_test.go +++ b/qemu/qmp_test.go @@ -1349,6 +1349,23 @@ func TestExecuteVirtSerialPortAdd(t *testing.T) { <-disconnectedCh } +// Check migration incoming +func TestExecuteMigrationIncoming(t *testing.T) { + connectedCh := make(chan *QMPVersion) + disconnectedCh := make(chan struct{}) + buf := newQMPTestCommandBuffer(t) + buf.AddCommand("migrate-incoming", nil, "return", nil) + cfg := QMPConfig{Logger: qmpTestLogger{}} + q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh) + checkVersion(t, connectedCh) + err := q.ExecuteMigrationIncoming(context.Background(), "uri") + if err != nil { + t.Fatalf("Unexpected error %v", err) + } + q.Shutdown() + <-disconnectedCh +} + // Checks migration status func TestExecuteQueryMigration(t *testing.T) { connectedCh := make(chan *QMPVersion)