[libvirt] [Patch 1/1] enable --checkpoint option in 'virsh save'

Matt McCowan libvirt at rpsmetocean.com
Tue Feb 24 09:25:22 UTC 2009


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);




More information about the libvir-list mailing list