mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
libxl: adds managed save and restore support
Based on the equivalent qemu driver code * src/libxl/libxl_driver.c: refactor the Start save and restore routines of the driver and adds the new entry points for managed saves handling
This commit is contained in:
parent
47370d5a0b
commit
5b6c961ef2
@ -66,7 +66,6 @@ static int
|
|||||||
libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
|
libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
|
||||||
bool start_paused, int restore_fd);
|
bool start_paused, int restore_fd);
|
||||||
|
|
||||||
|
|
||||||
/* Function definitions */
|
/* Function definitions */
|
||||||
static void
|
static void
|
||||||
libxlDriverLock(libxlDriverPrivatePtr driver)
|
libxlDriverLock(libxlDriverPrivatePtr driver)
|
||||||
@ -219,6 +218,87 @@ libxlDoNodeGetInfo(libxlDriverPrivatePtr driver, virNodeInfoPtr info)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
libxlDomainManagedSavePath(libxlDriverPrivatePtr driver, virDomainObjPtr vm) {
|
||||||
|
char *ret;
|
||||||
|
|
||||||
|
if (virAsprintf(&ret, "%s/%s.save", driver->saveDir, vm->def->name) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This internal function expects the driver lock to already be held on
|
||||||
|
* entry. */
|
||||||
|
static int ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4)
|
||||||
|
libxlSaveImageOpen(libxlDriverPrivatePtr driver, const char *from,
|
||||||
|
virDomainDefPtr *ret_def, libxlSavefileHeaderPtr ret_hdr)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
virDomainDefPtr def = NULL;
|
||||||
|
libxlSavefileHeader hdr;
|
||||||
|
char *xml = NULL;
|
||||||
|
|
||||||
|
if ((fd = virFileOpenAs(from, O_RDONLY, 0, getuid(), getgid(), 0)) < 0) {
|
||||||
|
libxlError(VIR_ERR_OPERATION_FAILED,
|
||||||
|
"%s", _("cannot read domain image"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saferead(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
|
||||||
|
libxlError(VIR_ERR_OPERATION_FAILED,
|
||||||
|
"%s", _("failed to read libxl header"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(hdr.magic, LIBXL_SAVE_MAGIC, sizeof(hdr.magic))) {
|
||||||
|
libxlError(VIR_ERR_INVALID_ARG, "%s", _("image magic is incorrect"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hdr.version > LIBXL_SAVE_VERSION) {
|
||||||
|
libxlError(VIR_ERR_OPERATION_FAILED,
|
||||||
|
_("image version is not supported (%d > %d)"),
|
||||||
|
hdr.version, LIBXL_SAVE_VERSION);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hdr.xmlLen <= 0) {
|
||||||
|
libxlError(VIR_ERR_OPERATION_FAILED,
|
||||||
|
_("invalid XML length: %d"), hdr.xmlLen);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_ALLOC_N(xml, hdr.xmlLen) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saferead(fd, xml, hdr.xmlLen) != hdr.xmlLen) {
|
||||||
|
libxlError(VIR_ERR_OPERATION_FAILED, "%s", _("failed to read XML"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(def = virDomainDefParseString(driver->caps, xml,
|
||||||
|
VIR_DOMAIN_XML_INACTIVE)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
VIR_FREE(xml);
|
||||||
|
|
||||||
|
*ret_def = def;
|
||||||
|
*ret_hdr = hdr;
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
error:
|
||||||
|
VIR_FREE(xml);
|
||||||
|
virDomainDefFree(def);
|
||||||
|
VIR_FORCE_CLOSE(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cleanup function for domain that has reached shutoff state.
|
* Cleanup function for domain that has reached shutoff state.
|
||||||
*
|
*
|
||||||
@ -546,17 +626,53 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
|
|||||||
bool start_paused, int restore_fd)
|
bool start_paused, int restore_fd)
|
||||||
{
|
{
|
||||||
libxl_domain_config d_config;
|
libxl_domain_config d_config;
|
||||||
virDomainDefPtr def = vm->def;
|
virDomainDefPtr def = NULL;
|
||||||
virDomainEventPtr event = NULL;
|
virDomainEventPtr event = NULL;
|
||||||
|
libxlSavefileHeader hdr;
|
||||||
int ret;
|
int ret;
|
||||||
uint32_t domid = 0;
|
uint32_t domid = 0;
|
||||||
char *dom_xml = NULL;
|
char *dom_xml = NULL;
|
||||||
|
char *managed_save = NULL;
|
||||||
pid_t child_console_pid = -1;
|
pid_t child_console_pid = -1;
|
||||||
libxlDomainObjPrivatePtr priv = vm->privateData;
|
libxlDomainObjPrivatePtr priv = vm->privateData;
|
||||||
|
|
||||||
|
/* If there is a managed saved state restore it instead of starting
|
||||||
|
* from scratch. The old state is removed once the restoring succeeded. */
|
||||||
|
if (restore_fd < 0) {
|
||||||
|
managed_save = libxlDomainManagedSavePath(driver, vm);
|
||||||
|
if (managed_save == NULL)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (virFileExists(managed_save)) {
|
||||||
|
|
||||||
|
restore_fd = libxlSaveImageOpen(driver, managed_save, &def, &hdr);
|
||||||
|
if (restore_fd < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (STRNEQ(vm->def->name, def->name) ||
|
||||||
|
memcmp(vm->def->uuid, def->uuid, VIR_UUID_BUFLEN)) {
|
||||||
|
char vm_uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
|
char def_uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
|
virUUIDFormat(vm->def->uuid, vm_uuidstr);
|
||||||
|
virUUIDFormat(def->uuid, def_uuidstr);
|
||||||
|
libxlError(VIR_ERR_OPERATION_FAILED,
|
||||||
|
_("cannot restore domain '%s' uuid %s from a file"
|
||||||
|
" which belongs to domain '%s' uuid %s"),
|
||||||
|
vm->def->name, vm_uuidstr, def->name, def_uuidstr);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
virDomainObjAssignDef(vm, def, true);
|
||||||
|
def = NULL;
|
||||||
|
|
||||||
|
if (unlink(managed_save) < 0)
|
||||||
|
VIR_WARN("Failed to remove the managed state %s", managed_save);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
memset(&d_config, 0, sizeof(d_config));
|
memset(&d_config, 0, sizeof(d_config));
|
||||||
|
|
||||||
if (libxlBuildDomainConfig(driver, def, &d_config) < 0 )
|
if (libxlBuildDomainConfig(driver, vm->def, &d_config) < 0 )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (libxlFreeMem(priv, &d_config) < 0) {
|
if (libxlFreeMem(priv, &d_config) < 0) {
|
||||||
@ -586,8 +702,8 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
def->id = domid;
|
vm->def->id = domid;
|
||||||
if ((dom_xml = virDomainDefFormat(def, 0)) == NULL)
|
if ((dom_xml = virDomainDefFormat(vm->def, 0)) == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (libxl_userdata_store(&priv->ctx, domid, "libvirt-xml",
|
if (libxl_userdata_store(&priv->ctx, domid, "libvirt-xml",
|
||||||
@ -627,11 +743,14 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
|
|||||||
error:
|
error:
|
||||||
if (domid > 0) {
|
if (domid > 0) {
|
||||||
libxl_domain_destroy(&priv->ctx, domid, 0);
|
libxl_domain_destroy(&priv->ctx, domid, 0);
|
||||||
def->id = -1;
|
vm->def->id = -1;
|
||||||
virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_FAILED);
|
virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_FAILED);
|
||||||
}
|
}
|
||||||
libxl_domain_config_destroy(&d_config);
|
libxl_domain_config_destroy(&d_config);
|
||||||
VIR_FREE(dom_xml);
|
VIR_FREE(dom_xml);
|
||||||
|
VIR_FREE(managed_save);
|
||||||
|
virDomainDefFree(def);
|
||||||
|
VIR_FORCE_CLOSE(restore_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1692,12 +1811,13 @@ libxlDomainGetState(virDomainPtr dom,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This internal function expects the driver lock to already be held on
|
||||||
|
* entry and the vm must be active. */
|
||||||
static int
|
static int
|
||||||
libxlDomainSave(virDomainPtr dom, const char *to)
|
libxlDoDomainSave(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
|
||||||
|
const char *to)
|
||||||
{
|
{
|
||||||
libxlDriverPrivatePtr driver = dom->conn->privateData;
|
libxlDomainObjPrivatePtr priv = vm->privateData;
|
||||||
virDomainObjPtr vm;
|
|
||||||
libxlDomainObjPrivatePtr priv;
|
|
||||||
libxlSavefileHeader hdr;
|
libxlSavefileHeader hdr;
|
||||||
virDomainEventPtr event = NULL;
|
virDomainEventPtr event = NULL;
|
||||||
char *xml = NULL;
|
char *xml = NULL;
|
||||||
@ -1705,28 +1825,10 @@ libxlDomainSave(virDomainPtr dom, const char *to)
|
|||||||
int fd;
|
int fd;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
libxlDriverLock(driver);
|
|
||||||
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
|
||||||
|
|
||||||
if (!vm) {
|
|
||||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
||||||
virUUIDFormat(dom->uuid, uuidstr);
|
|
||||||
libxlError(VIR_ERR_NO_DOMAIN,
|
|
||||||
_("No domain with matching uuid '%s'"), uuidstr);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!virDomainObjIsActive(vm)) {
|
|
||||||
libxlError(VIR_ERR_OPERATION_INVALID, "%s", _("Domain is not running"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv = vm->privateData;
|
|
||||||
|
|
||||||
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) {
|
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) {
|
||||||
libxlError(VIR_ERR_OPERATION_INVALID,
|
libxlError(VIR_ERR_OPERATION_INVALID,
|
||||||
_("Domain '%d' has to be running because libxenlight will"
|
_("Domain '%d' has to be running because libxenlight will"
|
||||||
" suspend it"), dom->id);
|
" suspend it"), vm->def->id);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1758,10 +1860,10 @@ libxlDomainSave(virDomainPtr dom, const char *to)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (libxl_domain_suspend(&priv->ctx, NULL, dom->id, fd) != 0) {
|
if (libxl_domain_suspend(&priv->ctx, NULL, vm->def->id, fd) != 0) {
|
||||||
libxlError(VIR_ERR_INTERNAL_ERROR,
|
libxlError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Failed to save domain '%d' with libxenlight"),
|
_("Failed to save domain '%d' with libxenlight"),
|
||||||
dom->id);
|
vm->def->id);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1770,7 +1872,7 @@ libxlDomainSave(virDomainPtr dom, const char *to)
|
|||||||
|
|
||||||
if (libxlVmReap(driver, vm, 1, VIR_DOMAIN_SHUTOFF_SAVED) != 0) {
|
if (libxlVmReap(driver, vm, 1, VIR_DOMAIN_SHUTOFF_SAVED) != 0) {
|
||||||
libxlError(VIR_ERR_INTERNAL_ERROR,
|
libxlError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Failed to destroy domain '%d'"), dom->id);
|
_("Failed to destroy domain '%d'"), vm->def->id);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1785,10 +1887,39 @@ cleanup:
|
|||||||
VIR_FREE(xml);
|
VIR_FREE(xml);
|
||||||
if (VIR_CLOSE(fd) < 0)
|
if (VIR_CLOSE(fd) < 0)
|
||||||
virReportSystemError(errno, "%s", _("cannot close file"));
|
virReportSystemError(errno, "%s", _("cannot close file"));
|
||||||
if (vm)
|
|
||||||
virDomainObjUnlock(vm);
|
|
||||||
if (event)
|
if (event)
|
||||||
libxlDomainEventQueue(driver, event);
|
libxlDomainEventQueue(driver, event);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
libxlDomainSave(virDomainPtr dom, const char *to)
|
||||||
|
{
|
||||||
|
libxlDriverPrivatePtr driver = dom->conn->privateData;
|
||||||
|
virDomainObjPtr vm;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
libxlDriverLock(driver);
|
||||||
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
||||||
|
|
||||||
|
if (!vm) {
|
||||||
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
|
virUUIDFormat(dom->uuid, uuidstr);
|
||||||
|
libxlError(VIR_ERR_NO_DOMAIN,
|
||||||
|
_("No domain with matching uuid '%s'"), uuidstr);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!virDomainObjIsActive(vm)) {
|
||||||
|
libxlError(VIR_ERR_OPERATION_INVALID, "%s", _("Domain is not running"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = libxlDoDomainSave(driver, vm, to);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (vm)
|
||||||
|
virDomainObjUnlock(vm);
|
||||||
libxlDriverUnlock(driver);
|
libxlDriverUnlock(driver);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1797,57 +1928,16 @@ static int
|
|||||||
libxlDomainRestore(virConnectPtr conn, const char *from)
|
libxlDomainRestore(virConnectPtr conn, const char *from)
|
||||||
{
|
{
|
||||||
libxlDriverPrivatePtr driver = conn->privateData;
|
libxlDriverPrivatePtr driver = conn->privateData;
|
||||||
virDomainDefPtr def = NULL;
|
|
||||||
virDomainObjPtr vm = NULL;
|
virDomainObjPtr vm = NULL;
|
||||||
|
virDomainDefPtr def = NULL;
|
||||||
libxlSavefileHeader hdr;
|
libxlSavefileHeader hdr;
|
||||||
char *xml = NULL;
|
int fd = -1;
|
||||||
int fd;
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
libxlDriverLock(driver);
|
libxlDriverLock(driver);
|
||||||
|
|
||||||
if ((fd = virFileOpenAs(from, O_RDONLY, 0, getuid(), getgid(), 0)) < 0) {
|
fd = libxlSaveImageOpen(driver, from, &def, &hdr);
|
||||||
libxlError(VIR_ERR_OPERATION_FAILED,
|
if (fd < 0)
|
||||||
"%s", _("cannot read domain image"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (saferead(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
|
|
||||||
libxlError(VIR_ERR_OPERATION_FAILED,
|
|
||||||
"%s", _("failed to read libxl header"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (memcmp(hdr.magic, LIBXL_SAVE_MAGIC, sizeof(hdr.magic))) {
|
|
||||||
libxlError(VIR_ERR_INVALID_ARG, "%s", _("image magic is incorrect"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hdr.version > LIBXL_SAVE_VERSION) {
|
|
||||||
libxlError(VIR_ERR_OPERATION_FAILED,
|
|
||||||
_("image version is not supported (%d > %d)"),
|
|
||||||
hdr.version, LIBXL_SAVE_VERSION);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hdr.xmlLen <= 0) {
|
|
||||||
libxlError(VIR_ERR_OPERATION_FAILED,
|
|
||||||
_("invalid XML length: %d"), hdr.xmlLen);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (VIR_ALLOC_N(xml, hdr.xmlLen) < 0) {
|
|
||||||
virReportOOMError();
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (saferead(fd, xml, hdr.xmlLen) != hdr.xmlLen) {
|
|
||||||
libxlError(VIR_ERR_OPERATION_FAILED, "%s", _("failed to read XML"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(def = virDomainDefParseString(driver->caps, xml,
|
|
||||||
VIR_DOMAIN_XML_INACTIVE)))
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
|
if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
|
||||||
@ -1865,10 +1955,7 @@ libxlDomainRestore(virConnectPtr conn, const char *from)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(xml);
|
|
||||||
virDomainDefFree(def);
|
virDomainDefFree(def);
|
||||||
if (VIR_CLOSE(fd) < 0)
|
|
||||||
virReportSystemError(errno, "%s", _("cannot close file"));
|
|
||||||
if (vm)
|
if (vm)
|
||||||
virDomainObjUnlock(vm);
|
virDomainObjUnlock(vm);
|
||||||
libxlDriverUnlock(driver);
|
libxlDriverUnlock(driver);
|
||||||
@ -1969,6 +2056,115 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
libxlDomainManagedSave(virDomainPtr dom, unsigned int flags)
|
||||||
|
{
|
||||||
|
libxlDriverPrivatePtr driver = dom->conn->privateData;
|
||||||
|
virDomainObjPtr vm = NULL;
|
||||||
|
char *name = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
virCheckFlags(0, -1);
|
||||||
|
|
||||||
|
libxlDriverLock(driver);
|
||||||
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
||||||
|
if (!vm) {
|
||||||
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
|
virUUIDFormat(dom->uuid, uuidstr);
|
||||||
|
libxlError(VIR_ERR_NO_DOMAIN,
|
||||||
|
_("No domain with matching uuid '%s'"), uuidstr);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!virDomainObjIsActive(vm)) {
|
||||||
|
libxlError(VIR_ERR_OPERATION_INVALID, "%s", _("Domain is not running"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = libxlDomainManagedSavePath(driver, vm);
|
||||||
|
if (name == NULL)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
VIR_INFO("Saving state to %s", name);
|
||||||
|
|
||||||
|
ret = libxlDoDomainSave(driver, vm, name);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (vm)
|
||||||
|
virDomainObjUnlock(vm);
|
||||||
|
libxlDriverUnlock(driver);
|
||||||
|
VIR_FREE(name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
libxlDriverLock(driver);
|
||||||
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
||||||
|
if (!vm) {
|
||||||
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
|
virUUIDFormat(dom->uuid, uuidstr);
|
||||||
|
libxlError(VIR_ERR_NO_DOMAIN,
|
||||||
|
_("No domain with matching uuid '%s'"), uuidstr);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = libxlDomainManagedSavePath(driver, vm);
|
||||||
|
if (name == NULL)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = virFileExists(name);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(name);
|
||||||
|
if (vm)
|
||||||
|
virDomainObjUnlock(vm);
|
||||||
|
libxlDriverUnlock(driver);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
libxlDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags)
|
||||||
|
{
|
||||||
|
libxlDriverPrivatePtr driver = dom->conn->privateData;
|
||||||
|
virDomainObjPtr vm = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
char *name = NULL;
|
||||||
|
|
||||||
|
virCheckFlags(0, -1);
|
||||||
|
|
||||||
|
libxlDriverLock(driver);
|
||||||
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
||||||
|
if (!vm) {
|
||||||
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
|
virUUIDFormat(dom->uuid, uuidstr);
|
||||||
|
libxlError(VIR_ERR_NO_DOMAIN,
|
||||||
|
_("No domain with matching uuid '%s'"), uuidstr);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = libxlDomainManagedSavePath(driver, vm);
|
||||||
|
if (name == NULL)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = unlink(name);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(name);
|
||||||
|
if (vm)
|
||||||
|
virDomainObjUnlock(vm);
|
||||||
|
libxlDriverUnlock(driver);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
|
libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
@ -3634,6 +3830,9 @@ static virDriver libxlDriver = {
|
|||||||
.nodeGetFreeMemory = libxlNodeGetFreeMemory, /* 0.9.0 */
|
.nodeGetFreeMemory = libxlNodeGetFreeMemory, /* 0.9.0 */
|
||||||
.domainEventRegister = libxlDomainEventRegister, /* 0.9.0 */
|
.domainEventRegister = libxlDomainEventRegister, /* 0.9.0 */
|
||||||
.domainEventDeregister = libxlDomainEventDeregister, /* 0.9.0 */
|
.domainEventDeregister = libxlDomainEventDeregister, /* 0.9.0 */
|
||||||
|
.domainManagedSave = libxlDomainManagedSave, /* 0.9.3 */
|
||||||
|
.domainHasManagedSaveImage = libxlDomainHasManagedSaveImage, /* 0.9.3 */
|
||||||
|
.domainManagedSaveRemove = libxlDomainManagedSaveRemove, /* 0.9.3 */
|
||||||
.domainIsActive = libxlDomainIsActive, /* 0.9.0 */
|
.domainIsActive = libxlDomainIsActive, /* 0.9.0 */
|
||||||
.domainIsPersistent = libxlDomainIsPersistent, /* 0.9.0 */
|
.domainIsPersistent = libxlDomainIsPersistent, /* 0.9.0 */
|
||||||
.domainIsUpdated = libxlDomainIsUpdated, /* 0.9.0 */
|
.domainIsUpdated = libxlDomainIsUpdated, /* 0.9.0 */
|
||||||
|
Loading…
Reference in New Issue
Block a user