diff --git a/libvirt.spec.in b/libvirt.spec.in index 5b3f4e4775..ec6fc8b735 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 54e9611383..1a2f94f790 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1771,6 +1771,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" @@ -1817,6 +1820,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 15e760d606..3786176db1 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); @@ -269,6 +271,7 @@ xenUnifiedOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags) { int i, ret = VIR_DRV_OPEN_DECLINED; xenUnifiedPrivatePtr priv; + char ebuf[1024]; #ifdef __sun /* @@ -408,6 +411,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: @@ -439,6 +453,7 @@ xenUnifiedClose(virConnectPtr conn) if (priv->opened[i]) drivers[i]->xenClose(conn); + VIR_FREE(priv->saveDir); virMutexDestroy(&priv->lock); VIR_FREE(conn->privateData); @@ -1082,6 +1097,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) @@ -1507,15 +1593,35 @@ xenUnifiedDomainCreateWithFlags(virDomainPtr dom, unsigned int flags) { GET_PRIVATE(dom->conn); int i; + int ret = -1; + char *name = NULL; virCheckFlags(0, -1); - for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) - if (priv->opened[i] && drivers[i]->xenDomainCreate && - drivers[i]->xenDomainCreate(dom) == 0) - return 0; + name = xenUnifiedDomainManagedSavePath(priv, dom); + if (!name) + goto cleanup; - return -1; + 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) { + ret = 0; + goto cleanup; + } + } + +cleanup: + VIR_FREE(name); + return ret; } static int @@ -2220,6 +2326,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 b3fbcff557..078980e3e7 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 */