commit 501bfad194140fe385704a01aa6c6125c6aba9dc
Author: Bamvor Jian Zhang <bjzhang@suse.com>
Date:   Tue Dec 4 18:00:02 2012 +0800

    implement managedsave in libvirt xen legacy driver
    
    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 flag 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 released at the end of
    every libvirt api call. Meanwhile, AFAIK, xen store all the flags in
    xen not in libvirt xen driver. There is no need to add this flag in xen.
    
    Signed-off-by: Bamvor Jian Zhang <bjzhang@suse.com>

Index: libvirt-0.9.6/libvirt.spec.in
===================================================================
--- libvirt-0.9.6.orig/libvirt.spec.in
+++ libvirt-0.9.6/libvirt.spec.in
@@ -1013,6 +1013,9 @@ fi
 %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}
 %dir %{_localstatedir}/run/libvirt/network/
 %dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/network/
Index: libvirt-0.9.6/src/Makefile.am
===================================================================
--- libvirt-0.9.6.orig/src/Makefile.am
+++ libvirt-0.9.6/src/Makefile.am
@@ -1487,6 +1487,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"
@@ -1532,6 +1535,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
Index: libvirt-0.9.6/src/xen/xen_driver.c
===================================================================
--- libvirt-0.9.6.orig/src/xen/xen_driver.c
+++ libvirt-0.9.6/src/xen/xen_driver.c
@@ -51,8 +51,10 @@
 #include "fdstream.h"
 #include "virfile.h"
 #include "command.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);
@@ -253,6 +255,7 @@ xenUnifiedOpen (virConnectPtr conn, virC
     int i, ret = VIR_DRV_OPEN_DECLINED;
     xenUnifiedPrivatePtr priv;
     virDomainEventCallbackListPtr cbList;
+    char ebuf[1024];
 
 #ifdef __sun
     /*
@@ -407,6 +410,17 @@ xenUnifiedOpen (virConnectPtr conn, virC
     }
 #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:
@@ -438,6 +452,7 @@ xenUnifiedClose (virConnectPtr conn)
         if (priv->opened[i])
             drivers[i]->xenClose(conn);
 
+    VIR_FREE(priv->saveDir);
     virMutexDestroy(&priv->lock);
     VIR_FREE(conn->privateData);
 
@@ -1065,6 +1080,77 @@ xenUnifiedDomainSave(virDomainPtr dom, c
     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)
@@ -1490,15 +1576,35 @@ xenUnifiedDomainCreateWithFlags (virDoma
 {
     GET_PRIVATE(dom->conn);
     int i;
+    int ret = -1;
+    char *name = NULL;
 
     virCheckFlags(0, -1);
 
-    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
+    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;
+            drivers[i]->xenDomainCreate(dom) == 0) {
+            ret = 0;
+            goto cleanup;
+        }
+    }
 
-    return -1;
+cleanup:
+    VIR_FREE(name);
+    return ret;
 }
 
 static int
@@ -2207,6 +2313,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 */
Index: libvirt-0.9.6/src/xen/xen_driver.h
===================================================================
--- libvirt-0.9.6.orig/src/xen/xen_driver.h
+++ libvirt-0.9.6/src/xen/xen_driver.h
@@ -190,6 +190,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 */
