This patch implements on_missing feature in qemu driver.
Upon qemu startup process an accessibility of CDROMs
and floppy disks is checked. The source might get dropped
if unavailable and on_missing is set accordingly.
No event is emit thought. Look for follow up patch.
---
src/qemu/qemu_domain.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_domain.h | 4 +++
src/qemu/qemu_process.c | 10 +++++--
3 files changed, 77 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index b202ba7..7fbdfa1 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1608,3 +1608,69 @@ qemuDomainSetFakeReboot(struct qemud_driver *driver,
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
VIR_WARN("Failed to save status on vm %s", vm->def->name);
}
+
+int
+qemuDomainCheckDiskPresence(struct qemud_driver *driver,
+ virDomainObjPtr vm,
+ bool start_with_state)
+{
+ int ret = -1;
+ int i;
+ int accessRet;
+ virDomainDiskDefPtr disk;
+ char uuid[VIR_UUID_STRING_BUFLEN] ATTRIBUTE_UNUSED;
+
+ virUUIDFormat(vm->def->uuid, uuid);
+
+ for (i = 0; i < vm->def->ndisks; i++) {
+ disk = vm->def->disks[i];
+
+ if (!disk->startupPolicy || !disk->src)
+ continue;
+
+ if ((accessRet = virFileAccessibleAs(disk->src, F_OK,
+ driver->user,
+ driver->group)) >= 0) {
+ /* disk accessible or virFileAccessibleAs()
+ * terminated with signal*/
+ continue;
+ }
+
+ switch ((enum virDomainStartupPolicy) disk->startupPolicy) {
+ case VIR_DOMAIN_STARTUP_POLICY_OPTIONAL:
+ break;
+
+ case VIR_DOMAIN_STARTUP_POLICY_MANDATORY:
+ virReportSystemError(-accessRet,
+ _("cannot access file '%s'"),
+ disk->src);
+ goto cleanup;
+ break;
+
+ case VIR_DOMAIN_STARTUP_POLICY_REQUISITE:
+ if (!start_with_state) {
+ virReportSystemError(-accessRet,
+ _("cannot access file '%s'"),
+ disk->src);
+ goto cleanup;
+ }
+ break;
+
+ case VIR_DOMAIN_STARTUP_POLICY_DEFAULT:
+ case VIR_DOMAIN_STARTUP_POLICY_LAST:
+ /* this should never happen */
+ break;
+ }
+
+ VIR_DEBUG("Droping disk '%s' on domain '%s' (UUID
'%s') "
+ "due to not accessible source '%s'",
+ disk->dst, vm->def->name, uuid, disk->src);
+
+ VIR_FREE(disk->src);
+ }
+
+ ret = 0;
+
+cleanup:
+ return ret;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index d9f323c..e8bcab3 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -280,4 +280,8 @@ void qemuDomainSetFakeReboot(struct qemud_driver *driver,
bool qemuDomainJobAllowed(qemuDomainObjPrivatePtr priv,
enum qemuDomainJob job);
+
+int qemuDomainCheckDiskPresence(struct qemud_driver *driver,
+ virDomainObjPtr vm,
+ bool start_with_state);
#endif /* __QEMU_DOMAIN_H__ */
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index c0f6fd4..5731223 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2880,6 +2880,13 @@ int qemuProcessStart(virConnectPtr conn,
NULL) < 0)
goto cleanup;
+ if (qemuAssignDeviceAliases(vm->def, priv->qemuCaps) < 0)
+ goto cleanup;
+
+ VIR_DEBUG("Checking for CDROM and floppy presence");
+ if (qemuDomainCheckDiskPresence(driver, vm, migrateFrom != NULL) < 0)
+ goto cleanup;
+
/* If you are using a SecurityDriver with dynamic labelling,
then generate a security label for isolation */
VIR_DEBUG("Generating domain security label (if required)");
@@ -3015,9 +3022,6 @@ int qemuProcessStart(virConnectPtr conn,
priv->persistentAddrs = 0;
}
- if (qemuAssignDeviceAliases(vm->def, priv->qemuCaps) < 0)
- goto cleanup;
-
VIR_DEBUG("Building emulator command line");
if (!(cmd = qemuBuildCommandLine(conn, driver, vm->def, priv->monConfig,
priv->monJSON != 0, priv->qemuCaps,
--
1.7.3.4