Univention Bugzilla – Attachment 2784 Details for
Bug 19172
Suspend/Resume von virtuellen Maschinen
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
managedSuspend-Support für Xen in libvirt
19172_libvirt-xen-suspend.diff (text/plain), 13.54 KB, created by
Philipp Hahn
on 2010-11-01 16:12:50 CET
(
hide
)
Description:
managedSuspend-Support für Xen in libvirt
Filename:
MIME Type:
Creator:
Philipp Hahn
Created:
2010-11-01 16:12:50 CET
Size:
13.54 KB
patch
obsolete
>diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c >index 66e8518..8f98219 100644 >--- a/src/xen/xen_driver.c >+++ b/src/xen/xen_driver.c >@@ -564,24 +564,28 @@ xenUnifiedListDomains (virConnectPtr conn, int *ids, int maxids) > /* Try xenstore. */ > if (priv->opened[XEN_UNIFIED_XS_OFFSET]) { > ret = xenStoreListDomains (conn, ids, maxids); >+ DEBUG("xenStoreListDomains: %d", ret); > if (ret >= 0) return ret; > } > > /* Try HV. */ > if (priv->opened[XEN_UNIFIED_HYPERVISOR_OFFSET]) { > ret = xenHypervisorListDomains (conn, ids, maxids); >+ DEBUG("xenHypervisorListDomains: %d", ret); > if (ret >= 0) return ret; > } > > /* Try xend. */ > if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) { > ret = xenDaemonListDomains (conn, ids, maxids); >+ DEBUG("xenDaemonListDomains: %d", ret); > if (ret >= 0) return ret; > } > > /* Try proxy. */ > if (priv->opened[XEN_UNIFIED_PROXY_OFFSET]) { > ret = xenProxyListDomains (conn, ids, maxids); >+ DEBUG("xenProxyListDomains: %d", ret); > if (ret >= 0) return ret; > } > return -1; >@@ -1979,6 +1983,52 @@ out: > return ret; > } > >+static int >+xenUnifiedDomainManagedSave(virDomainPtr dom, unsigned int flags) >+{ >+ GET_PRIVATE(dom->conn); >+ int i; >+ >+ for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) >+ if (priv->opened[i] && >+ drivers[i]->domainManagedSave && >+ drivers[i]->domainManagedSave(dom, flags) == 0) >+ return 0; >+ >+ return -1; >+} >+ >+static int >+xenUnifiedDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) >+{ >+ GET_PRIVATE(dom->conn); >+ int i; >+ >+ for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) >+ if (priv->opened[i] && >+ drivers[i]->domainHasManagedSaveImage && >+ drivers[i]->domainHasManagedSaveImage(dom, flags) == 0) >+ return 0; >+ >+ return -1; >+} >+ >+static int >+xenUnifiedDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags) >+{ >+ GET_PRIVATE(dom->conn); >+ int i; >+ >+ for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) >+ if (priv->opened[i] && >+ drivers[i]->domainManagedSaveRemove && >+ drivers[i]->domainManagedSaveRemove(dom, flags) == 0) >+ return 0; >+ >+ return -1; >+} >+ >+ > > /*----- Register with libvirt.c, and initialize Xen drivers. -----*/ > >@@ -2072,9 +2122,9 @@ static virDriver xenUnifiedDriver = { > NULL, /* domainMigrateSetMaxDowntime */ > xenUnifiedDomainEventRegisterAny, /* domainEventRegisterAny */ > xenUnifiedDomainEventDeregisterAny, /* domainEventDeregisterAny */ >- NULL, /* domainManagedSave */ >- NULL, /* domainHasManagedSaveImage */ >- NULL, /* domainManagedSaveRemove */ >+ xenUnifiedDomainManagedSave, /* domainManagedSave */ >+ xenUnifiedDomainHasManagedSaveImage, /* domainHasManagedSaveImage */ >+ xenUnifiedDomainManagedSaveRemove, /* domainManagedSaveRemove */ > NULL, /* domainSnapshotCreateXML */ > NULL, /* domainSnapshotDumpXML */ > NULL, /* domainSnapshotNum */ >diff --git a/src/xen/xen_driver.h b/src/xen/xen_driver.h >index 53f97d4..59276eb 100644 >--- a/src/xen/xen_driver.h >+++ b/src/xen/xen_driver.h >@@ -99,6 +99,9 @@ struct xenUnifiedDriver { > virDrvDomainGetSchedulerType domainGetSchedulerType; > virDrvDomainGetSchedulerParameters domainGetSchedulerParameters; > virDrvDomainSetSchedulerParameters domainSetSchedulerParameters; >+ virDrvDomainManagedSave domainManagedSave; >+ virDrvDomainHasManagedSaveImage domainHasManagedSaveImage; >+ virDrvDomainManagedSaveRemove domainManagedSaveRemove; > }; > > typedef struct xenXMConfCache *xenXMConfCachePtr; >diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c >index b90c331..245384f 100644 >--- a/src/xen/xend_internal.c >+++ b/src/xen/xend_internal.c >@@ -952,7 +952,7 @@ xenDaemonListDomainsOld(virConnectPtr xend) > * @xend: A xend instance > * @sexpr: An S-Expr description of the domain. > * >- * This method will create a domain based the passed in description. The >+ * This method will create a domain based on the passed in description. The > * domain will be paused after creation and must be unpaused with > * xenDaemonResumeDomain() to begin execution. > * This method may be deprecated once switching to XML-RPC based communcations >@@ -2680,6 +2680,20 @@ error: > } > #endif /* !PROXY */ > >+static char * >+xenDaemonDomainManagedSavePath(virDomainPtr dom) { >+ char *ret; >+ char uuidstr[VIR_UUID_STRING_BUFLEN]; >+ >+ virUUIDFormat(dom->uuid, uuidstr); >+ if (virAsprintf(&ret, "%s/%s/checkpoint.chk", XEND_DOMAINS_DIR, uuidstr) < 0) { >+ virReportOOMError(); >+ return(NULL); >+ } >+ >+ return(ret); >+} >+ > /***************************************************************** > ****** > ****** >@@ -4656,8 +4670,10 @@ virDomainPtr xenDaemonDomainDefineXML(virConnectPtr conn, const char *xmlDesc) { > virDomainDefFree(def); > return (NULL); > } >+ > int xenDaemonDomainCreate(virDomainPtr domain) > { >+ char *managed_save; > xenUnifiedPrivatePtr priv; > int ret; > virDomainPtr tmp; >@@ -4672,6 +4688,22 @@ int xenDaemonDomainCreate(virDomainPtr domain) > if (priv->xendConfigVersion < 3) > return(-1); > >+ /* >+ * If there is a managed saved state restore it instead of starting >+ * from scratch. In any case the old state is removed. >+ */ >+ managed_save = xenDaemonDomainManagedSavePath(domain); >+ if ((managed_save) && (virFileExists(managed_save))) { >+ ret = xend_op(domain->conn, domain->name, "op", "resume", NULL); >+ >+ if (unlink(managed_save) < 0) { >+ VIR_WARN("Failed to remove the managed state %s", managed_save); >+ } >+ >+ if (ret == 0) >+ goto cleanup; >+ } >+ > ret = xend_op(domain->conn, domain->name, "op", "start", NULL); > > if (ret != -1) { >@@ -4682,6 +4714,9 @@ int xenDaemonDomainCreate(virDomainPtr domain) > virDomainFree(tmp); > } > } >+ >+cleanup: >+ VIR_FREE(managed_save); > return ret; > } > >@@ -4737,6 +4772,19 @@ xenDaemonNumOfDefinedDomains(virConnectPtr conn) > ret++; > } > >+ sexpr_free(root); >+ >+ root = sexpr_get(conn, "/xend/domain?state=suspended"); >+ if (root == NULL) >+ goto error; >+ >+ for (_for_i = root, node = root->u.s.car; _for_i->kind == SEXPR_CONS; >+ _for_i = _for_i->u.s.cdr, node = _for_i->u.s.car) { >+ if (node->kind != SEXPR_VALUE) >+ continue; >+ ret++; >+ } >+ > error: > sexpr_free(root); > return(ret); >@@ -4777,6 +4825,26 @@ xenDaemonListDefinedDomains(virConnectPtr conn, char **const names, int maxnames > break; > } > >+ sexpr_free(root); >+ >+ root = sexpr_get(conn, "/xend/domain?state=suspended"); >+ if (root == NULL) >+ goto error; >+ >+ for (_for_i = root, node = root->u.s.car; _for_i->kind == SEXPR_CONS; >+ _for_i = _for_i->u.s.cdr, node = _for_i->u.s.car) { >+ if (node->kind != SEXPR_VALUE) >+ continue; >+ >+ if ((names[ret++] = strdup(node->u.value)) == NULL) { >+ virReportOOMError(); >+ goto error; >+ } >+ >+ if (ret >= maxnames) >+ break; >+ } >+ > cleanup: > sexpr_free(root); > return(ret); >@@ -5071,7 +5139,7 @@ error: > > /** > * xenDaemonDomainBlockPeek: >- * @dom: domain object >+ * @domain: domain object > * @path: path to the file or device > * @offset: offset > * @size: size >@@ -5159,6 +5227,124 @@ xenDaemonDomainBlockPeek (virDomainPtr domain, const char *path, > return ret; > } > >+/** >+ * xenDaemonDomainManagedSave: >+ * @domain: pointer to the domain >+ * @flags: optional flags currently unused >+ * >+ * This method will suspend a domain and save its memory contents to >+ * a file on disk. After the call, if successful, the domain is not >+ * listed as running anymore. >+ * The difference from virDomainSave() is that libvirt is keeping track of >+ * the saved state itself, and will reuse it once the domain is being >+ * restarted (automatically or via an explicit libvirt call). >+ * As a result any running domain is sure to not have a managed saved image. >+ * >+ * Returns 0 in case of success or -1 in case of failure >+ */ >+int >+xenDaemonDomainManagedSave(virDomainPtr domain, unsigned int flags) >+{ >+ if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) { >+ virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__); >+ return(-1); >+ } >+ >+ if (domain->id < 0) { >+ virXendError(VIR_ERR_OPERATION_INVALID, >+ _("Domain %s isn't running."), domain->name); >+ return(-1); >+ } >+ >+ /* We can't save the state of Domain-0, that would mean stopping it too */ >+ if (domain->id == 0) { >+ return(-1); >+ } >+ >+ virCheckFlags(0, -1); >+ >+ return xend_op(domain->conn, domain->name, "op", "suspend", NULL); >+} >+ >+/** >+ * xenDaemonDomainHasManagedSaveImage: >+ * @domain: pointer to the domain >+ * @flags: optional flags currently unused >+ * >+ * Check if a domain has a managed save image as created by >+ * virDomainManagedSave(). Note that any running domain should not have >+ * such an image, as it should have been removed on restart. >+ * >+ * Returns 0 if no image is present, 1 if an image is present, and >+ * -1 in case of error >+ */ >+int >+xenDaemonDomainHasManagedSaveImage(virDomainPtr domain, unsigned int flags) >+{ >+ char *name = NULL; >+ int ret = -1; >+ >+ if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) { >+ virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__); >+ return(-1); >+ } >+ >+ /* We can't save the state of Domain-0, that would mean stopping it too */ >+ if (domain->id == 0) { >+ return(-1); >+ } >+ >+ virCheckFlags(0, -1); >+ >+ name = xenDaemonDomainManagedSavePath(domain); >+ if (name == NULL) >+ goto cleanup; >+ >+ ret = virFileExists(name); >+ >+cleanup: >+ VIR_FREE(name); >+ return ret; >+} >+ >+/** >+ * xenDaemonDomainManagedSaveRemove: >+ * @domain: pointer to the domain >+ * @flags: optional flags currently unused >+ * >+ * Remove any managed save image for this domain. >+ * >+ * Returns 0 in case of success, and -1 in case of error >+ */ >+int >+xenDaemonDomainManagedSaveRemove(virDomainPtr domain, unsigned int flags) >+{ >+ char *name = NULL; >+ int ret = -1; >+ >+ if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) { >+ virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__); >+ return(-1); >+ } >+ >+ /* We can't save the state of Domain-0, that would mean stopping it too */ >+ if (domain->id == 0) { >+ return(-1); >+ } >+ >+ virCheckFlags(0, -1); >+ >+ name = xenDaemonDomainManagedSavePath(domain); >+ if (name == NULL) >+ goto cleanup; >+ >+ ret = unlink(name); >+ >+cleanup: >+ VIR_FREE(name); >+ return ret; >+} >+ > struct xenUnifiedDriver xenDaemonDriver = { > xenDaemonOpen, /* open */ > xenDaemonClose, /* close */ >@@ -5197,6 +5383,9 @@ struct xenUnifiedDriver xenDaemonDriver = { > xenDaemonGetSchedulerType, /* domainGetSchedulerType */ > xenDaemonGetSchedulerParameters, /* domainGetSchedulerParameters */ > xenDaemonSetSchedulerParameters, /* domainSetSchedulerParameters */ >+ xenDaemonDomainManagedSave, /* domainManagedSave */ >+ xenDaemonDomainHasManagedSaveImage, /* domainHasManagedSaveImage */ >+ xenDaemonDomainManagedSaveRemove, /* domainManagedSaveRemove */ > }; > > /************************************************************************ >diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h >index 53f5d2c..af97b88 100644 >--- a/src/xen/xend_internal.h >+++ b/src/xen/xend_internal.h >@@ -144,6 +144,9 @@ int xenDaemonDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info); > char *xenDaemonDomainDumpXML(virDomainPtr domain, int flags, const char *cpus); > unsigned long xenDaemonDomainGetMaxMemory(virDomainPtr domain); > char **xenDaemonListDomainsOld(virConnectPtr xend); >+int xenDaemonDomainManagedSave(virDomainPtr dom, unsigned int flags); >+int xenDaemonDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags); >+int xenDaemonDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags); > > virDomainPtr xenDaemonDomainDefineXML(virConnectPtr xend, const char *sexpr); > int xenDaemonDomainCreate(virDomainPtr domain); >diff --git a/tools/Makefile.am b/tools/Makefile.am >index bfe4455..9ee9363 100644 >--- a/tools/Makefile.am >+++ b/tools/Makefile.am >@@ -38,6 +38,7 @@ virt-pki-validate.1: virt-pki-validate > > virsh_SOURCES = \ > console.c console.h \ >+ @top_srcdir@/daemon/event.c \ > virsh.c > > virsh_LDFLAGS = $(WARN_LDFLAGS) $(COVERAGE_LDFLAGS) >@@ -52,6 +53,7 @@ virsh_CFLAGS = \ > -I../include -I$(top_srcdir)/include \ > -I$(top_srcdir)/src \ > -I$(top_srcdir)/src/util \ >+ -I$(top_srcdir) \ > -DGETTEXT_PACKAGE=\"$(PACKAGE)\" \ > -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ > $(WARN_CFLAGS) \ >diff --git a/tools/virsh.c b/tools/virsh.c >index 3e37b06..9cea612 100644 >--- a/tools/virsh.c >+++ b/tools/virsh.c >@@ -50,6 +50,7 @@ > #include "util.h" > #include "memory.h" > #include "xml.h" >+#include "daemon/event.h" > > static char *progname; > >@@ -11068,6 +11069,13 @@ vshInit(vshControl *ctl) > /* set up the signals handlers to catch disconnections */ > vshSetupSignals(); > >+ virEventRegisterImpl(virEventAddHandleImpl, >+ virEventUpdateHandleImpl, >+ virEventRemoveHandleImpl, >+ virEventAddTimeoutImpl, >+ virEventUpdateTimeoutImpl, >+ virEventRemoveTimeoutImpl); >+ > ctl->conn = virConnectOpenAuth(ctl->name, > virConnectAuthPtrDefault, > ctl->readonly ? VIR_CONNECT_RO : 0);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 19172
:
2783
| 2784