diff -ur libvirt.orig/docs/libvirt-api.xml libvirt/docs/libvirt-api.xml --- libvirt.orig/docs/libvirt-api.xml 2009-01-31 20:46:29.000000000 +0900 +++ libvirt/docs/libvirt-api.xml 2009-02-24 18:12:34.000000000 +0900 @@ -40,6 +40,7 @@ <exports symbol='VIR_CRED_NOECHOPROMPT' type='enum'/> <exports symbol='VIR_DOMAIN_EVENT_UNDEFINED' type='enum'/> <exports symbol='VIR_MIGRATE_LIVE' type='enum'/> + <exports symbol='VIR_SAVE_CHECKPOINT' type='enum'/> <exports symbol='VIR_DOMAIN_EVENT_STOPPED_DESTROYED' type='enum'/> <exports symbol='VIR_DOMAIN_EVENT_DEFINED_ADDED' type='enum'/> <exports symbol='VIR_DOMAIN_EVENT_STARTED_MIGRATED' type='enum'/> @@ -593,6 +594,7 @@ <enum name='VIR_FROM_XML' file='virterror' value='5' type='virErrorDomain' info='Error in the XML code'/> <enum name='VIR_MEMORY_VIRTUAL' file='libvirt' value='1' type='virDomainMemoryFlags' info=' addresses are virtual addresses'/> <enum name='VIR_MIGRATE_LIVE' file='libvirt' value='1' type='virDomainMigrateFlags' info=' live migration'/> + <enum name='VIR_SAVE_CHECKPOINT' file='libvirt' value='1' type='virDomainSaveFlags' info=' checkpoint save'/> <enum name='VIR_STORAGE_POOL_BUILDING' file='libvirt' value='1' type='virStoragePoolState' info='Initializing pool, not available'/> <enum name='VIR_STORAGE_POOL_BUILD_NEW' file='libvirt' value='0' type='virStoragePoolBuildFlags' info='Regular build from scratch'/> <enum name='VIR_STORAGE_POOL_BUILD_REPAIR' file='libvirt' value='1' type='virStoragePoolBuildFlags' info='Repair / reinitialize'/> @@ -1207,9 +1209,10 @@ <arg name='domain' type='virDomainPtr' info='a domain object'/> </function> <function name='virDomainSave' file='libvirt' module='libvirt'> - <info>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). Use virDomainRestore() to restore a domain after saving.</info> + <info>This method will suspend a domain and save its memory contents to a file on disk. Flags may be one of more of the following: VIR_SAVE_CHECKPOINT. After the call, if successful, the domain may be suspended (CHECKPOINT) or not listed as running anymore (this may be a problem). Use virDomainRestore() to restore a domain after saving.</info> <return type='int' info='0 in case of success and -1 in case of failure.'/> <arg name='domain' type='virDomainPtr' info='a domain object'/> + <arg name='flags' type='unsigned long' info='save flags'/> <arg name='to' type='const char *' info='path for the output file'/> </function> <function name='virDomainSetAutostart' file='libvirt' module='libvirt'> diff -ur libvirt.orig/docs/libvirt-refs.xml libvirt/docs/libvirt-refs.xml --- libvirt.orig/docs/libvirt-refs.xml 2009-01-31 20:46:29.000000000 +0900 +++ libvirt/docs/libvirt-refs.xml 2009-02-24 13:09:07.000000000 +0900 @@ -2875,6 +2875,9 @@ <ref name='virConnectListDefinedStoragePools'/> <ref name='virConnectListStoragePools'/> </word> + <word name='checkpoint'> + <ref name='virDomainSave'/> + </word> <word name='choose'> <ref name='virDomainMigrate'/> </word> diff -ur libvirt.orig/include/libvirt/libvirt.h.in libvirt/include/libvirt/libvirt.h.in --- libvirt.orig/include/libvirt/libvirt.h.in 2009-01-20 21:14:03.000000000 +0900 +++ libvirt/include/libvirt/libvirt.h.in 2009-02-24 13:09:07.000000000 +0900 @@ -463,10 +463,16 @@ int virDomainSuspend (virDomainPtr domain); int virDomainResume (virDomainPtr domain); +/* Domain save flags. */ +typedef enum { + VIR_SAVE_CHECKPOINT = 1, /* checkpoint save */ +} virDomainSaveFlags; + /* * Domain save/restore */ int virDomainSave (virDomainPtr domain, + unsigned long flags, const char *to); int virDomainRestore (virConnectPtr conn, const char *from); diff -ur libvirt.orig/qemud/remote.c libvirt/qemud/remote.c --- libvirt.orig/qemud/remote.c 2009-02-06 01:28:30.000000000 +0900 +++ libvirt/qemud/remote.c 2009-02-24 13:09:07.000000000 +0900 @@ -1861,7 +1861,7 @@ return -1; } - if (virDomainSave (dom, args->to) == -1) { + if (virDomainSave (dom, args->flags, args->to) == -1) { virDomainFree(dom); remoteDispatchConnError(rerr, conn); return -1; diff -ur libvirt.orig/qemud/remote_protocol.c libvirt/qemud/remote_protocol.c --- libvirt.orig/qemud/remote_protocol.c 2009-01-29 06:33:56.000000000 +0900 +++ libvirt/qemud/remote_protocol.c 2009-02-24 13:09:07.000000000 +0900 @@ -855,6 +855,8 @@ if (!xdr_remote_nonnull_domain (xdrs, &objp->dom)) return FALSE; + if (!xdr_uint64_t (xdrs, &objp->flags)) + return FALSE; if (!xdr_remote_nonnull_string (xdrs, &objp->to)) return FALSE; return TRUE; diff -ur libvirt.orig/qemud/remote_protocol.h libvirt/qemud/remote_protocol.h --- libvirt.orig/qemud/remote_protocol.h 2009-01-29 06:33:56.000000000 +0900 +++ libvirt/qemud/remote_protocol.h 2009-02-24 13:09:07.000000000 +0900 @@ -446,6 +446,7 @@ struct remote_domain_save_args { remote_nonnull_domain dom; + uint64_t flags; remote_nonnull_string to; }; typedef struct remote_domain_save_args remote_domain_save_args; diff -ur libvirt.orig/qemud/remote_protocol.x libvirt/qemud/remote_protocol.x --- libvirt.orig/qemud/remote_protocol.x 2008-12-18 02:23:21.000000000 +0900 +++ libvirt/qemud/remote_protocol.x 2009-02-24 13:09:07.000000000 +0900 @@ -480,6 +480,7 @@ struct remote_domain_save_args { remote_nonnull_domain dom; + unsigned hyper flags; remote_nonnull_string to; }; diff -ur libvirt.orig/src/driver.h libvirt/src/driver.h --- libvirt.orig/src/driver.h 2008-12-18 06:48:20.000000000 +0900 +++ libvirt/src/driver.h 2009-02-24 13:09:07.000000000 +0900 @@ -140,6 +140,7 @@ virDomainInfoPtr info); typedef int (*virDrvDomainSave) (virDomainPtr domain, + unsigned long flags, const char *to); typedef int (*virDrvDomainRestore) (virConnectPtr conn, diff -ur libvirt.orig/src/libvirt.c libvirt/src/libvirt.c --- libvirt.orig/src/libvirt.c 2009-02-17 19:33:41.000000000 +0900 +++ libvirt/src/libvirt.c 2009-02-24 13:09:07.000000000 +0900 @@ -1937,21 +1937,25 @@ /** * virDomainSave: * @domain: a domain object + * @flags: flags * @to: path for the output file * * 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). * Use virDomainRestore() to restore a domain after saving. + * Flags may be one of more of the following: + * VIR_SAVE_CHECKPOINT Don't exit after save * * Returns 0 in case of success and -1 in case of failure. */ int -virDomainSave(virDomainPtr domain, const char *to) +virDomainSave(virDomainPtr domain, unsigned long flags, + const char *to) { char filepath[4096]; virConnectPtr conn; - DEBUG("domain=%p, to=%s", domain, to); + DEBUG("domain=%p, flags=%lu, to=%s", domain, flags, to); virResetLastError(); @@ -1991,7 +1995,7 @@ if (conn->driver->domainSave) { int ret; - ret = conn->driver->domainSave (domain, to); + ret = conn->driver->domainSave (domain, flags, to); if (ret < 0) goto error; return ret; diff -ur libvirt.orig/src/qemu_driver.c libvirt/src/qemu_driver.c --- libvirt.orig/src/qemu_driver.c 2009-02-19 17:18:31.000000000 +0900 +++ libvirt/src/qemu_driver.c 2009-02-24 13:09:07.000000000 +0900 @@ -2393,6 +2393,7 @@ }; static int qemudDomainSave(virDomainPtr dom, + unsigned long flags ATTRIBUTE_UNUSED, const char *path) { struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm; @@ -2504,15 +2505,17 @@ goto cleanup; } - /* Shut it down */ - qemudShutdownVMDaemon(dom->conn, driver, vm); - event = virDomainEventNewFromObj(vm, + if (!(flags & VIR_SAVE_CHECKPOINT)) { + /* Shut it down */ + qemudShutdownVMDaemon(dom->conn, driver, vm); + event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_SAVED); - if (!vm->persistent) { - virDomainRemoveInactive(&driver->domains, + if (!vm->persistent) { + virDomainRemoveInactive(&driver->domains, vm); - vm = NULL; + vm = NULL; + } } ret = 0; diff -ur libvirt.orig/src/remote_internal.c libvirt/src/remote_internal.c --- libvirt.orig/src/remote_internal.c 2009-02-17 18:44:18.000000000 +0900 +++ libvirt/src/remote_internal.c 2009-02-24 13:09:07.000000000 +0900 @@ -2065,7 +2065,7 @@ } static int -remoteDomainSave (virDomainPtr domain, const char *to) +remoteDomainSave (virDomainPtr domain, unsigned long flags, const char *to) { int rv = -1; remote_domain_save_args args; @@ -2075,6 +2075,7 @@ make_nonnull_domain (&args.dom, domain); args.to = (char *) to; + args.flags = flags; if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SAVE, (xdrproc_t) xdr_remote_domain_save_args, (char *) &args, diff -ur libvirt.orig/src/test.c libvirt/src/test.c --- libvirt.orig/src/test.c 2009-02-14 03:11:03.000000000 +0900 +++ libvirt/src/test.c 2009-02-24 13:09:07.000000000 +0900 @@ -1176,7 +1176,7 @@ #define TEST_SAVE_MAGIC "TestGuestMagic" -static int testDomainSave(virDomainPtr domain, +static int testDomainSave(virDomainPtr domain, unsigned long flags, const char *path) { testConnPtr privconn = domain->conn->privateData; @@ -1206,34 +1206,34 @@ if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) { virReportSystemError(domain->conn, errno, - _("saving domain '%s' to '%s': open failed"), - domain->name, path); + _("saving domain '%s' with '%lu' to '%s': open failed"), + domain->name, flags, path); goto cleanup; } len = strlen(xml); if (safewrite(fd, TEST_SAVE_MAGIC, sizeof(TEST_SAVE_MAGIC)) < 0) { virReportSystemError(domain->conn, errno, - _("saving domain '%s' to '%s': write failed"), - domain->name, path); + _("saving domain '%s' with '%lu' to '%s': write failed"), + domain->name, flags, path); goto cleanup; } if (safewrite(fd, (char*)&len, sizeof(len)) < 0) { virReportSystemError(domain->conn, errno, - _("saving domain '%s' to '%s': write failed"), - domain->name, path); + _("saving domain '%s' with '%lu' to '%s': write failed"), + domain->name, flags, path); goto cleanup; } if (safewrite(fd, xml, len) < 0) { virReportSystemError(domain->conn, errno, - _("saving domain '%s' to '%s': write failed"), - domain->name, path); + _("saving domain '%s' with '%lu' to '%s': write failed"), + domain->name, flags, path); goto cleanup; } if (close(fd) < 0) { virReportSystemError(domain->conn, errno, - _("saving domain '%s' to '%s': write failed"), - domain->name, path); + _("saving domain '%s' with '%lu' to '%s': write failed"), + domain->name, flags, path); goto cleanup; } fd = -1; diff -ur libvirt.orig/src/virsh.c libvirt/src/virsh.c --- libvirt.orig/src/virsh.c 2009-02-17 07:51:31.000000000 +0900 +++ libvirt/src/virsh.c 2009-02-24 18:09:30.000000000 +0900 @@ -1067,11 +1067,12 @@ */ static const vshCmdInfo info_save[] = { {"help", gettext_noop("save a domain state to a file")}, - {"desc", gettext_noop("Save a running domain.")}, + {"desc", gettext_noop("Save a running domain. Add --checkpoint to not quit")}, {NULL, NULL} }; static const vshCmdOptDef opts_save[] = { + {"checkpoint", VSH_OT_BOOL, 0, gettext_noop("checkpoint save")}, {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")}, {"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("where to save the data")}, {NULL, 0, 0, NULL} @@ -1083,6 +1084,7 @@ virDomainPtr dom; char *name; char *to; + long unsigned int flags = 0; int ret = TRUE; if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) @@ -1094,10 +1096,14 @@ if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) return FALSE; - if (virDomainSave(dom, to) == 0) { + if (vshCommandOptBool (cmd, "checkpoint")) + flags |= VIR_SAVE_CHECKPOINT; + + if (virDomainSave(dom, flags, to) == 0) { vshPrint(ctl, _("Domain %s saved to %s\n"), name, to); } else { - vshError(ctl, FALSE, _("Failed to save domain %s to %s"), name, to); + vshError(ctl, FALSE, + _("Failed to save domain %s with %lu to %s"), name, flags, to); ret = FALSE; } diff -ur libvirt.orig/src/xen_unified.c libvirt/src/xen_unified.c --- libvirt.orig/src/xen_unified.c 2009-02-06 01:03:11.000000000 +0900 +++ libvirt/src/xen_unified.c 2009-02-24 13:09:07.000000000 +0900 @@ -899,7 +899,7 @@ } static int -xenUnifiedDomainSave (virDomainPtr dom, const char *to) +xenUnifiedDomainSave (virDomainPtr dom, unsigned long flags, const char *to) { GET_PRIVATE(dom->conn); int i; diff -ur libvirt.orig/src/xend_internal.c libvirt/src/xend_internal.c --- libvirt.orig/src/xend_internal.c 2009-02-14 03:23:23.000000000 +0900 +++ libvirt/src/xend_internal.c 2009-02-24 13:09:07.000000000 +0900 @@ -2999,6 +2999,7 @@ /** * xenDaemonDomainSave: * @domain: pointer to the Domain block + * @flags: flags * @filename: path for the output file * * This method will suspend a domain and save its memory contents to @@ -3010,7 +3011,9 @@ * Returns 0 in case of success, -1 (with errno) in case of error. */ int -xenDaemonDomainSave(virDomainPtr domain, const char *filename) +xenDaemonDomainSave(virDomainPtr domain, + unsigned long flags ATTRIBUTE_UNUSED, + const char *filename) { if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) || (filename == NULL)) { diff -ur libvirt.orig/src/xend_internal.h libvirt/src/xend_internal.h --- libvirt.orig/src/xend_internal.h 2008-12-18 06:26:16.000000000 +0900 +++ libvirt/src/xend_internal.h 2009-02-24 13:09:07.000000000 +0900 @@ -140,7 +140,8 @@ int xenDaemonDomainShutdown(virDomainPtr domain); int xenDaemonDomainReboot(virDomainPtr domain, unsigned int flags); int xenDaemonDomainDestroy(virDomainPtr domain); -int xenDaemonDomainSave(virDomainPtr domain, const char *filename); +int xenDaemonDomainSave(virDomainPtr domain, unsigned long flags, + const char *filename); int xenDaemonDomainRestore(virConnectPtr conn, const char *filename); int xenDaemonDomainSetMemory(virDomainPtr domain, unsigned long memory); int xenDaemonDomainSetMaxMemory(virDomainPtr domain, unsigned long memory); -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list