Implement the domainManagedSave, domainHasManagedSaveImage, and
domainManagedSaveRemove functions in the libvirt legacy xen driver.
domainHasManagedSaveImage check the managedsave image from filesystem
everytime. This is different from qemu and libxl driver. In qemu or
libxl driver, there is a hasManagesSave flags in virDomainObjPtr which
is not used in xen legacy driver. This flag could not add into xen
driver ptr either, because the driver ptr will be release at the end of
every libvirt api calls. Meanwhile, AFAIK, xen store all the flags in
xen not in libvirt xen driver. There is no need to add this flags in xen.
Signed-off-by: Bamvor Jian Zhang <bjzhang(a)suse.com>
---
Changes since v1:
(1), add save dir in libvirt.spec.in and src/Makefile.am
(2), misc changes for return value and memory leak.
i have test the following case for this patch:
1), "virsh managedsave" save domain to /var/lib/xen/save/domain_name.save.
call xenUnifiedDomainManagedSave.
2), "virsh start": if managedsave image is exist, it should be boot from
managed save image.
call xenUnifiedDomainHasManagedSaveImage.
3), "virsh start --force-boot": fresh boot, delete the managed save image
if exists.
call xenUnifiedDomainHasManagedSaveImage,
xenUnifiedDomainManagedSaveRemove.
4), "virsh managedsave-remove": remove managed save image.
call xenUnifiedDomainManagedSaveRemove
5), "virsh undefine": undefine the domain, it will fail if mananed save
image exist.
call xenUnifiedDomainHasManagedSaveImage.
6), "virsh undefine --managed-save": undefine the domain, and remove
mananed save image.
call xenUnifiedDomainHasManagedSaveImage and
xenUnifiedDomainManagedSaveRemove.
7), "virsh list --all --with-managed-save". list domain if managed save
image exist. got nothing if non-exists.
call xenUnifiedDomainHasManagedSaveImage.
8), "virsh list --all --without-managed-save". do not list the domain if
managed save image exist.
call xenUnifiedDomainHasManagedSaveImage.
libvirt.spec.in | 3 ++
src/Makefile.am | 6 +++
src/xen/xen_driver.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++-
src/xen/xen_driver.h | 2 +
4 files changed, 118 insertions(+), 1 deletion(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 47cb087..ae18adb 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -1719,6 +1719,9 @@ rm -f $RPM_BUILD_ROOT%{_sysconfdir}/sysctl.d/libvirtd
%ghost %dir %{_localstatedir}/run/libvirt/libxl/
%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/libxl/
%endif
+%if %{with_xen}
+%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/xen/
+%endif
%if %{with_network}
%ghost %dir %{_localstatedir}/run/libvirt/network/
%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/network/
diff --git a/src/Makefile.am b/src/Makefile.am
index 01cb995..fc0d78a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1769,6 +1769,9 @@ if WITH_UML
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/uml"
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/run/libvirt/uml"
endif
+if WITH_XEN
+ $(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/xen"
+endif
if WITH_NETWORK
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/network"
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/dnsmasq"
@@ -1815,6 +1818,9 @@ if WITH_UML
rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/uml" ||:
rmdir "$(DESTDIR)$(localstatedir)/run/libvirt/uml" ||:
endif
+if WITH_XEN
+ rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/xen" ||:
+endif
if WITH_NETWORK
rm -f $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml
rm -f $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/default.xml
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index 5a40757..71ff5bd 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -65,8 +65,10 @@
#include "command.h"
#include "virnodesuspend.h"
#include "nodeinfo.h"
+#include "configmake.h"
#define VIR_FROM_THIS VIR_FROM_XEN
+#define XEN_SAVE_DIR LOCALSTATEDIR "/lib/libvirt/xen/save"
static int
xenUnifiedNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info);
@@ -267,6 +269,7 @@ xenUnifiedOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned
int flags)
{
int i, ret = VIR_DRV_OPEN_DECLINED;
xenUnifiedPrivatePtr priv;
+ char ebuf[1024];
#ifdef __sun
/*
@@ -406,6 +409,17 @@ xenUnifiedOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned
int flags)
}
#endif
+ if (virAsprintf(&priv->saveDir, "%s", XEN_SAVE_DIR) == -1) {
+ virReportOOMError();
+ goto fail;
+ }
+
+ if (virFileMakePath(priv->saveDir) < 0) {
+ VIR_ERROR(_("Failed to create save dir '%s': %s"),
priv->saveDir,
+ virStrerror(errno, ebuf, sizeof(ebuf)));
+ goto fail;
+ }
+
return VIR_DRV_OPEN_SUCCESS;
fail:
@@ -437,6 +451,7 @@ xenUnifiedClose(virConnectPtr conn)
if (priv->opened[i])
drivers[i]->xenClose(conn);
+ VIR_FREE(priv->saveDir);
virMutexDestroy(&priv->lock);
VIR_FREE(conn->privateData);
@@ -1080,6 +1095,77 @@ xenUnifiedDomainSave(virDomainPtr dom, const char *to)
return xenUnifiedDomainSaveFlags(dom, to, NULL, 0);
}
+static char *
+xenUnifiedDomainManagedSavePath(xenUnifiedPrivatePtr priv, virDomainPtr dom)
+{
+ char *ret;
+
+ if (virAsprintf(&ret, "%s/%s.save", priv->saveDir, dom->name)
< 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ VIR_DEBUG("managed save image: %s", ret);
+ return ret;
+}
+
+static int
+xenUnifiedDomainManagedSave(virDomainPtr dom, unsigned int flags)
+{
+ GET_PRIVATE(dom->conn);
+ char *name;
+ int ret = -1;
+
+ virCheckFlags(0, -1);
+
+ name = xenUnifiedDomainManagedSavePath(priv, dom);
+ if (!name)
+ goto cleanup;
+
+ if (priv->opened[XEN_UNIFIED_XEND_OFFSET])
+ ret = xenDaemonDomainSave(dom, name);
+
+cleanup:
+ VIR_FREE(name);
+ return ret;
+}
+
+static int
+xenUnifiedDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags)
+{
+ GET_PRIVATE(dom->conn);
+ char *name;
+ int ret = -1;
+
+ virCheckFlags(0, -1);
+
+ name = xenUnifiedDomainManagedSavePath(priv, dom);
+ if (!name)
+ return ret;
+
+ ret = virFileExists(name);
+ VIR_FREE(name);
+ return ret;
+}
+
+static int
+xenUnifiedDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags)
+{
+ GET_PRIVATE(dom->conn);
+ char *name;
+ int ret = -1;
+
+ virCheckFlags(0, -1);
+
+ name = xenUnifiedDomainManagedSavePath(priv, dom);
+ if (!name)
+ return ret;
+
+ ret = unlink(name);
+ VIR_FREE(name);
+ return ret;
+}
+
static int
xenUnifiedDomainRestoreFlags(virConnectPtr conn, const char *from,
const char *dxml, unsigned int flags)
@@ -1505,15 +1591,32 @@ xenUnifiedDomainCreateWithFlags(virDomainPtr dom, unsigned int
flags)
{
GET_PRIVATE(dom->conn);
int i;
+ int ret = -1;
+ char *name = NULL;
virCheckFlags(0, -1);
+ name = xenUnifiedDomainManagedSavePath(priv, dom);
+ if (!name)
+ goto cleanup;
+
+ if (virFileExists(name)) {
+ if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
+ ret = xenDaemonDomainRestore(dom->conn, name);
+ if (ret == 0)
+ unlink(name);
+ }
+ goto cleanup;
+ }
+
for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
if (priv->opened[i] && drivers[i]->xenDomainCreate &&
drivers[i]->xenDomainCreate(dom) == 0)
return 0;
- return -1;
+cleanup:
+ VIR_FREE(name);
+ return ret;
}
static int
@@ -2218,6 +2321,9 @@ static virDriver xenUnifiedDriver = {
.domainGetState = xenUnifiedDomainGetState, /* 0.9.2 */
.domainSave = xenUnifiedDomainSave, /* 0.0.3 */
.domainSaveFlags = xenUnifiedDomainSaveFlags, /* 0.9.4 */
+ .domainManagedSave = xenUnifiedDomainManagedSave, /* 1.0.1 */
+ .domainHasManagedSaveImage = xenUnifiedDomainHasManagedSaveImage, /* 1.0.1 */
+ .domainManagedSaveRemove = xenUnifiedDomainManagedSaveRemove, /* 1.0.1 */
.domainRestore = xenUnifiedDomainRestore, /* 0.0.3 */
.domainRestoreFlags = xenUnifiedDomainRestoreFlags, /* 0.9.4 */
.domainCoreDump = xenUnifiedDomainCoreDump, /* 0.1.9 */
diff --git a/src/xen/xen_driver.h b/src/xen/xen_driver.h
index b3fbcff..078980e 100644
--- a/src/xen/xen_driver.h
+++ b/src/xen/xen_driver.h
@@ -200,6 +200,8 @@ struct _xenUnifiedPrivate {
/* Location of config files, either /etc
* or /var/lib/xen */
const char *configDir;
+ /* Location of managed save dir, default /var/lib/libvirt/xen/save */
+ char *saveDir;
# if WITH_XEN_INOTIFY
/* The inotify fd */
--
1.7.12