diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 8fdf90ca28..e0940ca179 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -9088,6 +9088,45 @@ qemuBuildTPMCommandLine(virDomainDefPtr def, return 0; } +static int +qemuBuildIncomingCheckProtocol(virQEMUCapsPtr qemuCaps, + const char *migrateFrom) +{ + if (STRPREFIX(migrateFrom, "rdma")) { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_RDMA)) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("incoming RDMA migration is not supported " + "with this QEMU binary")); + return -1; + } + } else if (!STRPREFIX(migrateFrom, "tcp") && + !STRPREFIX(migrateFrom, "exec") && + !STRPREFIX(migrateFrom, "fd") && + !STRPREFIX(migrateFrom, "unix") && + STRNEQ(migrateFrom, "stdio")) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("unknown migration protocol")); + return -1; + } + + return 0; +} + + +static char * +qemuBuildIncomingURI(const char *migrateFrom, + int migrateFd) +{ + char *uri = NULL; + + if (STREQ(migrateFrom, "stdio")) + ignore_value(virAsprintf(&uri, "fd:%d", migrateFd)); + else + ignore_value(VIR_STRDUP(uri, migrateFrom)); + + return uri; +} + qemuBuildCommandLineCallbacks buildCommandLineCallbacks = { .qemuGetSCSIDeviceSgName = virSCSIDeviceGetSgName, @@ -10937,32 +10976,20 @@ qemuBuildCommandLine(virConnectPtr conn, } if (migrateFrom) { - virCommandAddArg(cmd, "-incoming"); - if (STRPREFIX(migrateFrom, "tcp")) { - virCommandAddArg(cmd, migrateFrom); - } else if (STRPREFIX(migrateFrom, "rdma")) { - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_RDMA)) { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", - _("incoming RDMA migration is not supported " - "with this QEMU binary")); - goto error; - } - virCommandAddArg(cmd, migrateFrom); - } else if (STREQ(migrateFrom, "stdio")) { - virCommandAddArgFormat(cmd, "fd:%d", migrateFd); - virCommandPassFD(cmd, migrateFd, 0); - } else if (STRPREFIX(migrateFrom, "exec")) { - virCommandAddArg(cmd, migrateFrom); - } else if (STRPREFIX(migrateFrom, "fd")) { - virCommandAddArg(cmd, migrateFrom); - virCommandPassFD(cmd, migrateFd, 0); - } else if (STRPREFIX(migrateFrom, "unix")) { - virCommandAddArg(cmd, migrateFrom); - } else { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("unknown migration protocol")); + char *migrateURI; + + if (qemuBuildIncomingCheckProtocol(qemuCaps, migrateFrom) < 0) goto error; - } + + if (STREQ(migrateFrom, "stdio") || + STRPREFIX(migrateFrom, "fd")) + virCommandPassFD(cmd, migrateFd, 0); + + migrateURI = qemuBuildIncomingURI(migrateFrom, migrateFd); + if (!migrateURI) + goto error; + virCommandAddArgList(cmd, "-incoming", migrateURI, NULL); + VIR_FREE(migrateURI); } /* QEMU changed its default behavior to not include the virtio balloon