We need to start NBD server and feed it with all non-<shared/> disks.
However, after qemuDomainObjEnterMonitorAsync the domain object
is unlocked so we cannot touch its disk definitions. Therefore,
we must prepare the list of disk IDs prior entering monitor.
---
src/qemu/qemu_migration.c | 59 +++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 57 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 5a716fd..ecb4375 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -33,6 +33,7 @@
#include "qemu_domain.h"
#include "qemu_process.h"
#include "qemu_capabilities.h"
+#include "qemu_command.h"
#include "qemu_cgroup.h"
#include "domain_audit.h"
@@ -1107,8 +1108,62 @@ qemuMigrationStartNBDServer(virQEMUDriverPtr driver
ATTRIBUTE_UNUSED,
virDomainObjPtr vm ATTRIBUTE_UNUSED,
int *nbdPort ATTRIBUTE_UNUSED)
{
- /* do nothing for now */
- return 0;
+ int ret = -1;
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ int port = qemuMigrationNextPort();
+ const char *listen = "0.0.0.0";
+ char **disks = NULL;
+ size_t i, ndisks = 0;
+
+ for (i = 0; i < vm->def->ndisks; i++) {
+ virDomainDiskDefPtr disk = vm->def->disks[i];
+
+ /* skip shared disks */
+ if (disk->shared)
+ continue;
+
+ if (VIR_REALLOC_N(disks, ndisks + 1) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (virAsprintf(&disks[ndisks++], "%s%s",
+ QEMU_DRIVE_HOST_PREFIX, disk->info.alias) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+
+ if (!ndisks) {
+ /* Hooray! Nothing to care about */
+ ret = 0;
+ goto cleanup;
+ }
+
+ if (qemuDomainObjEnterMonitorAsync(driver, vm,
+ QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
+ goto cleanup;
+
+ if (qemuMonitorNBDServerStart(priv->mon, listen, port) < 0)
+ goto endjob;
+
+ for (i = 0; i < ndisks; i++) {
+ if (qemuMonitorNBDServerAdd(priv->mon, disks[i], true) < 0) {
+ VIR_WARN("Unable to add '%s' to NDB server", disks[i]);
+ goto endjob;
+ }
+ }
+
+ *nbdPort = port;
+ ret = 0;
+
+endjob:
+ qemuDomainObjExitMonitorWithDriver(driver, vm);
+cleanup:
+ for (i = 0; i < ndisks; i++)
+ VIR_FREE(disks[i]);
+ VIR_FREE(disks);
+ return ret;
}
--
1.8.0.2