From 3cff66f487dd64611cee0f938523379fe684b145 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Fri, 26 Aug 2011 15:27:50 -0600 Subject: [PATCH] snapshot: fine-tune ability to start paused While it is nice that snapshots and saved images remember whether the domain was running or paused, sometimes the restoration phase wants to guarantee a particular state (paused to allow hot-plugging, or running without needing to call resume). This introduces new flags to allow the control, and a later patch will implement the flags for qemu. * include/libvirt/libvirt.h.in (VIR_DOMAIN_SAVE_RUNNING) (VIR_DOMAIN_SAVE_PAUSED, VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING) (VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED): New flags. * src/libvirt.c (virDomainSaveFlags, virDomainRestoreFlags) (virDomainManagedSave, virDomainSaveImageDefineXML) (virDomainRevertToSnapshot): Document their use, and enforce mutual exclusion. --- include/libvirt/libvirt.h.in | 12 ++++- src/libvirt.c | 89 ++++++++++++++++++++++++++++++++---- 2 files changed, 91 insertions(+), 10 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 4ef6ab26dc..aa64fa5948 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -960,11 +960,14 @@ int virDomainResume (virDomainPtr domain); /** * virDomainSaveRestoreFlags: - * Flags for use in virDomainSaveFlags(), virDomainManagedSave(), and - * virDomainRestoreFlags(). + * Flags for use in virDomainSaveFlags(), virDomainManagedSave(), + * virDomainRestoreFlags(), and virDomainSaveImageDefineXML(). Not all + * flags apply to all these functions. */ typedef enum { VIR_DOMAIN_SAVE_BYPASS_CACHE = 1 << 0, /* Avoid file system cache pollution */ + VIR_DOMAIN_SAVE_RUNNING = 1 << 1, /* Favor running over paused */ + VIR_DOMAIN_SAVE_PAUSED = 1 << 2, /* Favor paused over running */ } virDomainSaveRestoreFlags; int virDomainSave (virDomainPtr domain, @@ -2579,6 +2582,11 @@ int virDomainHasCurrentSnapshot(virDomainPtr domain, unsigned int flags); virDomainSnapshotPtr virDomainSnapshotCurrent(virDomainPtr domain, unsigned int flags); +typedef enum { + VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING = 1 << 0, /* Run after revert */ + VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED = 1 << 1, /* Pause after revert */ +} virDomainSnapshotRevertFlags; + /* Revert the domain to a point-in-time snapshot. The * state of the guest after this call will be the state * of the guest when the snapshot in question was taken diff --git a/src/libvirt.c b/src/libvirt.c index 13425ff852..8e569ab8bd 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -2310,7 +2310,7 @@ error: * * 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 (this may be a problem). + * listed as running anymore (this ends the life of a transient domain). * Use virDomainRestore() to restore a domain after saving. * * See virDomainSaveFlags() for more control. Also, a save file can @@ -2379,7 +2379,7 @@ error: * * 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 (this may be a problem). + * listed as running anymore (this ends the life of a transient domain). * Use virDomainRestore() to restore a domain after saving. * * If the hypervisor supports it, @dxml can be used to alter @@ -2394,6 +2394,12 @@ error: * fail if it cannot do so for the given system; this can allow less * pressure on file system cache, but also risks slowing saves to NFS. * + * Normally, the saved state file will remember whether the domain was + * running or paused, and restore defaults to the same state. + * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in + * @flags will override what state gets saved into the file. These + * two flags are mutually exclusive. + * * A save file can be inspected or modified slightly with * virDomainSaveImageGetXMLDesc() and virDomainSaveImageDefineXML(). * @@ -2425,6 +2431,12 @@ virDomainSaveFlags(virDomainPtr domain, const char *to, goto error; } + if ((flags & VIR_DOMAIN_SAVE_RUNNING) && (flags & VIR_DOMAIN_SAVE_PAUSED)) { + virLibDomainError(VIR_ERR_INVALID_ARG, + _("running and paused flags are mutually exclusive")); + goto error; + } + if (conn->driver->domainSaveFlags) { int ret; char *absolute_to; @@ -2532,6 +2544,12 @@ error: * fail if it cannot do so for the given system; this can allow less * pressure on file system cache, but also risks slowing saves to NFS. * + * Normally, the saved state file will remember whether the domain was + * running or paused, and restore defaults to the same state. + * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in + * @flags will override the default read from the file. These two + * flags are mutually exclusive. + * * Returns 0 in case of success and -1 in case of failure. */ int @@ -2557,6 +2575,12 @@ virDomainRestoreFlags(virConnectPtr conn, const char *from, const char *dxml, goto error; } + if ((flags & VIR_DOMAIN_SAVE_RUNNING) && (flags & VIR_DOMAIN_SAVE_PAUSED)) { + virLibDomainError(VIR_ERR_INVALID_ARG, + _("running and paused flags are mutually exclusive")); + goto error; + } + if (conn->driver->domainRestoreFlags) { int ret; char *absolute_from; @@ -2661,7 +2685,7 @@ error: * @conn: pointer to the hypervisor connection * @file: path to saved state file * @dxml: XML config for adjusting guest xml used on restore - * @flags: 0 for now + * @flags: bitwise-OR of virDomainSaveRestoreFlags * * This updates the definition of a domain stored in a saved state * file. @file must be a file created previously by virDomainSave() @@ -2673,6 +2697,13 @@ error: * disk device, to match renaming done as part of backing up the disk * device while the domain is stopped. * + * Normally, the saved state file will remember whether the domain was + * running or paused, and restore defaults to the same state. + * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in + * @flags will override the default saved into the file; omitting both + * leaves the file's default unchanged. These two flags are mutually + * exclusive. + * * Returns 0 in case of success and -1 in case of failure. */ int @@ -2698,6 +2729,12 @@ virDomainSaveImageDefineXML(virConnectPtr conn, const char *file, goto error; } + if ((flags & VIR_DOMAIN_SAVE_RUNNING) && (flags & VIR_DOMAIN_SAVE_PAUSED)) { + virLibDomainError(VIR_ERR_INVALID_ARG, + _("running and paused flags are mutually exclusive")); + goto error; + } + if (conn->driver->domainSaveImageDefineXML) { int ret; char *absolute_file; @@ -7018,7 +7055,9 @@ error: * @domain: pointer to a defined domain * * Launch a defined domain. If the call succeeds the domain moves from the - * defined to the running domains pools. + * defined to the running domains pools. The domain will be paused only + * if restoring from managed state created from a paused domain. For more + * control, see virDomainCreateWithFlags(). * * Returns 0 in case of success, -1 in case of error */ @@ -7064,9 +7103,12 @@ error: * Launch a defined domain. If the call succeeds the domain moves from the * defined to the running domains pools. * - * If the VIR_DOMAIN_START_PAUSED flag is set, the guest domain - * will be started, but its CPUs will remain paused. The CPUs - * can later be manually started using virDomainResume. + * If the VIR_DOMAIN_START_PAUSED flag is set, or if the guest domain + * has a managed save image that requested paused state (see + * virDomainManagedSave()) the guest domain will be started, but its + * CPUs will remain paused. The CPUs can later be manually started + * using virDomainResume(). In all other cases, the guest domain will + * be running. * * If the VIR_DOMAIN_START_AUTODESTROY flag is set, the guest * domain will be automatically destroyed when the virConnectPtr @@ -15391,6 +15433,12 @@ error: * fail if it cannot do so for the given system; this can allow less * pressure on file system cache, but also risks slowing saves to NFS. * + * Normally, the managed saved state will remember whether the domain + * was running or paused, and start will resume to the same state. + * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in + * @flags will override the default saved into the file. These two + * flags are mutually exclusive. + * * Returns 0 in case of success or -1 in case of failure */ int virDomainManagedSave(virDomainPtr dom, unsigned int flags) @@ -15413,6 +15461,12 @@ int virDomainManagedSave(virDomainPtr dom, unsigned int flags) goto error; } + if ((flags & VIR_DOMAIN_SAVE_RUNNING) && (flags & VIR_DOMAIN_SAVE_PAUSED)) { + virLibDomainError(VIR_ERR_INVALID_ARG, + _("running and paused flags are mutually exclusive")); + goto error; + } + if (conn->driver->domainManagedSave) { int ret; @@ -15844,10 +15898,22 @@ error: /** * virDomainRevertToSnapshot: * @snapshot: a domain snapshot object - * @flags: unused flag parameters; callers should pass 0 + * @flags: bitwise-OR of virDomainSnapshotRevertFlags * * Revert the domain to a given snapshot. * + * Normally, the domain will revert to the same state the domain was + * in while the snapshot was taken (whether inactive, running, or + * paused), except that disk snapshots default to reverting to + * inactive state. Including VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING in + * @flags overrides the snapshot state to guarantee a running domain + * after the revert; or including VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED in + * @flags guarantees a paused domain after the revert. These two + * flags are mutually exclusive. While a persistent domain does not + * need either flag, it is not possible to revert a transient domain + * into an inactive state, so transient domains require the use of one + * of these two flags. + * * Returns 0 if the creation is successful, -1 on error. */ int @@ -15873,6 +15939,13 @@ virDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, goto error; } + if ((flags & VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING) && + (flags & VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED)) { + virLibDomainError(VIR_ERR_INVALID_ARG, + _("running and paused flags are mutually exclusive")); + goto error; + } + if (conn->driver->domainRevertToSnapshot) { int ret = conn->driver->domainRevertToSnapshot(snapshot, flags); if (ret < 0)