diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d627ad82e8..88674eb830 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1817,6 +1817,8 @@ struct _virDomainObj { virDomainSnapshotObjList snapshots; virDomainSnapshotObjPtr current_snapshot; + bool hasManagedSave; + void *privateData; void (*privateDataFreeFunc)(void *); diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 500d51b4ba..0520ce988e 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -59,6 +59,11 @@ /* Number of Xen scheduler parameters */ #define XEN_SCHED_CREDIT_NPARAM 2 +static void libxlDomainManagedSaveLoad(void *payload, + const void *n ATTRIBUTE_UNUSED, + void *opaque); + + static libxlDriverPrivatePtr libxl_driver = NULL; /* Function declarations */ @@ -647,6 +652,7 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, VIR_WARN("Failed to remove the managed state %s", managed_save_path); } + vm->hasManagedSave = false; } VIR_FREE(managed_save_path); } @@ -983,6 +989,9 @@ libxlStartup(int privileged) { virHashForEach(libxl_driver->domains.objs, libxlAutostartDomain, libxl_driver); + virHashForEach(libxl_driver->domains.objs, libxlDomainManagedSaveLoad, + libxl_driver); + libxlDriverUnlock(libxl_driver); return 0; @@ -1868,6 +1877,8 @@ libxlDoDomainSave(libxlDriverPrivatePtr driver, virDomainObjPtr vm, goto cleanup; } + vm->hasManagedSave = true; + if (!vm->persistent) { virDomainRemoveInactive(&driver->domains, vm); vm = NULL; @@ -2124,13 +2135,33 @@ cleanup: return ret; } +static void +libxlDomainManagedSaveLoad(void *payload, + const void *n ATTRIBUTE_UNUSED, + void *opaque) +{ + virDomainObjPtr vm = payload; + libxlDriverPrivatePtr driver = opaque; + char *name; + + virDomainObjLock(vm); + + if (!(name = libxlDomainManagedSavePath(driver, vm))) + goto cleanup; + + vm->hasManagedSave = virFileExists(name); + +cleanup: + virDomainObjUnlock(vm); + VIR_FREE(name); +} + static int libxlDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) { libxlDriverPrivatePtr driver = dom->conn->privateData; virDomainObjPtr vm = NULL; int ret = -1; - char *name = NULL; virCheckFlags(0, -1); @@ -2144,14 +2175,9 @@ libxlDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) goto cleanup; } - name = libxlDomainManagedSavePath(driver, vm); - if (name == NULL) - goto cleanup; - - ret = virFileExists(name); + ret = vm->hasManagedSave; cleanup: - VIR_FREE(name); if (vm) virDomainObjUnlock(vm); libxlDriverUnlock(driver); @@ -2183,6 +2209,7 @@ libxlDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags) goto cleanup; ret = unlink(name); + vm->hasManagedSave = false; cleanup: VIR_FREE(name); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 32819c383b..3fd9803812 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -139,6 +139,11 @@ static int qemuDomainObjStart(virConnectPtr conn, static int qemudDomainGetMaxVcpus(virDomainPtr dom); +static void qemuDomainManagedSaveLoad(void *payload, + const void *n ATTRIBUTE_UNUSED, + void *opaque); + + struct qemud_driver *qemu_driver = NULL; @@ -734,6 +739,9 @@ qemudStartup(int privileged) { virHashForEach(qemu_driver->domains.objs, qemuDomainSnapshotLoad, qemu_driver->snapshotDir); + virHashForEach(qemu_driver->domains.objs, qemuDomainManagedSaveLoad, + qemu_driver); + qemu_driver->workerPool = virThreadPoolNew(0, 1, 0, processWatchdogEvent, qemu_driver); if (!qemu_driver->workerPool) goto error; @@ -2729,6 +2737,7 @@ qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom, } ret = 0; + vm->hasManagedSave = true; /* Shut it down */ qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_SAVED, 0); @@ -2918,13 +2927,33 @@ cleanup: return ret; } +static void +qemuDomainManagedSaveLoad(void *payload, + const void *n ATTRIBUTE_UNUSED, + void *opaque) +{ + virDomainObjPtr vm = payload; + struct qemud_driver *driver = opaque; + char *name; + + virDomainObjLock(vm); + + if (!(name = qemuDomainManagedSavePath(driver, vm))) + goto cleanup; + + vm->hasManagedSave = virFileExists(name); + +cleanup: + virDomainObjUnlock(vm); + VIR_FREE(name); +} + static int qemuDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) { struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm = NULL; int ret = -1; - char *name = NULL; virCheckFlags(0, -1); @@ -2938,14 +2967,9 @@ qemuDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) goto cleanup; } - name = qemuDomainManagedSavePath(driver, vm); - if (name == NULL) - goto cleanup; - - ret = virFileExists(name); + ret = vm->hasManagedSave; cleanup: - VIR_FREE(name); if (vm) virDomainObjUnlock(vm); qemuDriverUnlock(driver); @@ -2977,6 +3001,7 @@ qemuDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags) goto cleanup; ret = unlink(name); + vm->hasManagedSave = false; cleanup: VIR_FREE(name); @@ -4820,8 +4845,13 @@ qemuDomainObjStart(virConnectPtr conn, ret = qemuDomainObjRestore(conn, driver, vm, managed_save, start_paused, bypass_cache); - if (ret == 0 && unlink(managed_save) < 0) - VIR_WARN("Failed to remove the managed state %s", managed_save); + if (ret == 0) { + if (unlink(managed_save) < 0) + VIR_WARN("Failed to remove the managed state %s", managed_save); + else + vm->hasManagedSave = false; + } + if (ret > 0) VIR_WARN("Ignoring incomplete managed state %s", managed_save); else