We need to start NBD server and feed it with all non-shared/,
RW and source-full disks. Moreover, with new virPortAllocator we
must ensure the borrowed port for NBD server will be returned if
either migration completes or qemu process is teared down.
---
src/qemu/qemu_migration.c | 76 ++-
src/qemu/qemu_process.c | 5
2 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 0acc1ac..f572034 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -35,6 +35,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
@@ -1088,6 +1089,72 @@ error:
return NULL;
}
+/**
+ * qemuMigrationStartNBDServer:
+ * @driver: qemu driver
+ * @vm: domain
+ *
+ * Starts NBD server. This is a newer method to copy
+ * storage during migration than using 'blk' and 'inc'
+ * arguments in 'migrate' monitor command.
+ * Error is reported here.
+ *
+ * Returns 0 on success, -1 otherwise.
+ */
+static int
+qemuMigrationStartNBDServer(virQEMUDriverPtr driver,
+virDomainObjPtr vm)
+{
+int ret = -1;
+qemuDomainObjPrivatePtr priv = vm-privateData;
+unsigned short port = 0;
+const char *listenAddr = 0.0.0.0;
+char *diskAlias = NULL;
+size_t i;
+
+for (i = 0; i vm-def-ndisks; i++) {
+virDomainDiskDefPtr disk = vm-def-disks[i];
+
+/* skip shared, RO and source-less disks */
+if (disk-shared || disk-readonly || !disk-src)
+continue;
+
+VIR_FREE(diskAlias);
+if (virAsprintf(diskAlias, %s%s,
+QEMU_DRIVE_HOST_PREFIX, disk-info.alias) 0) {
+virReportOOMError();
+goto cleanup;
+}
+
+if (qemuDomainObjEnterMonitorAsync(driver, vm,
+ QEMU_ASYNC_JOB_MIGRATION_IN) 0)
+goto cleanup;
+
+if (!port
+((virPortAllocatorAcquire(driver-remotePorts, port) 0) ||
+ (qemuMonitorNBDServerStart(priv-mon, listenAddr, port) 0))) {
+qemuDomainObjExitMonitor(driver, vm);
+goto cleanup;
+}
+
+if (qemuMonitorNBDServerAdd(priv-mon, diskAlias, true) 0) {
+qemuDomainObjExitMonitor(driver, vm);
+goto cleanup;
+}
+qemuDomainObjExitMonitor(driver, vm);
+}
+
+priv-nbdPort = port;
+ret = 0;
+
+cleanup:
+VIR_FREE(diskAlias);
+if ((ret 0) port)
+virPortAllocatorRelease(driver-remotePorts, port);
+return ret;
+}
+
+
/* Validate whether the domain is safe to migrate. If vm is NULL,
* then this is being run in the v2 Prepare stage on the destination
* (where we only have the target xml); if vm is provided, then this
@@ -1814,8 +1881,11 @@ done:
if (flags VIR_MIGRATE_TUNNELLED)
VIR_DEBUG(NBD in tunnelled migration is currently not supported);
else {
+if (qemuMigrationStartNBDServer(driver, vm) 0) {
+/* error already reported */
+goto endjob;
+}
cookieFlags |= QEMU_MIGRATION_COOKIE_NBD;
-priv-nbdPort = 0;
}
}
@@ -1862,6 +1932,10 @@ cleanup:
virObjectUnlock(vm);
else
qemuDomainRemoveInactive(driver, vm);
+if (ret 0 priv-nbdPort) {
+virPortAllocatorRelease(driver-remotePorts, priv-nbdPort);
+priv-nbdPort = 0;
+}
}
if (event)
qemuDomainEventQueue(driver, event);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 476e3ed..030c143 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4197,6 +4197,11 @@ void qemuProcessStop(virQEMUDriverPtr driver,
}
}
+if (priv-nbdPort) {
+virPortAllocatorRelease(driver-remotePorts, priv-nbdPort);
+priv-nbdPort = 0;
+}
+
if (priv-agent) {
qemuAgentClose(priv-agent);
priv-agent = NULL;
--
1.8.1.2
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list