[libvirt] [PATCH 1/8] save: document new public API

Eric Blake eblake at redhat.com
Thu Jul 14 14:24:28 UTC 2011


In order to choose whether to use O_DIRECT when saving a domain image
to a file, we need a new flag.  But virDomainSave was implemented
before our policy of all new APIs having a flag argument.

* include/libvirt/libvirt.h.in (virDomainSaveFlags): New prototype.
* src/libvirt.c (virDomainSaveFlags): New API.
* src/libvirt_public.syms: Export it.
* src/driver.h (virDrvDomainSaveFlags): New driver callback.
---
 include/libvirt/libvirt.h.in |   14 ++++++
 src/driver.h                 |    6 +++
 src/libvirt.c                |   94 +++++++++++++++++++++++++++++++++++++++++-
 src/libvirt_public.syms      |    5 ++
 4 files changed, 118 insertions(+), 1 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index d5a7105..d9a8694 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -659,6 +659,7 @@ typedef virDomainMemoryStatStruct *virDomainMemoryStatPtr;
 typedef enum {
     VIR_DUMP_CRASH   = (1 << 0), /* crash after dump */
     VIR_DUMP_LIVE    = (1 << 1), /* live dump */
+    VIR_DUMP_DIRECT  = (1 << 2), /* Use O_DIRECT while saving */
 } virDomainCoreDumpFlags;

 /* Domain migration flags. */
@@ -941,8 +942,21 @@ int                     virDomainResume         (virDomainPtr domain);
 /*
  * Domain save/restore
  */
+
+/**
+ * virDomainSaveFlagValues:
+ * Flags for use in virDomainSaveFlags and virDomainManagedSave.
+ */
+typedef enum {
+    VIR_DOMAIN_SAVE_DIRECT = 1 << 0,     /* Use O_DIRECT while saving */
+} virDomainSaveFlagValues;
+
 int                     virDomainSave           (virDomainPtr domain,
                                                  const char *to);
+int                     virDomainSaveFlags      (virDomainPtr domain,
+                                                 const char *to,
+                                                 const char *dxml,
+                                                 unsigned int flags);
 int                     virDomainRestore        (virConnectPtr conn,
                                                  const char *from);

diff --git a/src/driver.h b/src/driver.h
index 70ea4c2..29d4df1 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -178,6 +178,11 @@ typedef int
         (*virDrvDomainSave)		(virDomainPtr domain,
                                          const char *to);
 typedef int
+        (*virDrvDomainSaveFlags)	(virDomainPtr domain,
+                                         const char *to,
+                                         const char *dxml,
+                                         unsigned int flags);
+typedef int
         (*virDrvDomainRestore)		(virConnectPtr conn,
                                          const char *from);
 typedef int
@@ -710,6 +715,7 @@ struct _virDriver {
     virDrvDomainGetState	domainGetState;
     virDrvDomainGetControlInfo  domainGetControlInfo;
     virDrvDomainSave		domainSave;
+    virDrvDomainSaveFlags	domainSaveFlags;
     virDrvDomainRestore		domainRestore;
     virDrvDomainCoreDump        domainCoreDump;
     virDrvDomainScreenshot      domainScreenshot;
diff --git a/src/libvirt.c b/src/libvirt.c
index fc17f2b..d280eb7 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -2242,6 +2242,8 @@ error:
  * listed as running anymore (this may be a problem).
  * Use virDomainRestore() to restore a domain after saving.
  *
+ * See virDomainSaveFlags() for more control.
+ *
  * Returns 0 in case of success and -1 in case of failure.
  */
 int
@@ -2296,6 +2298,84 @@ error:
 }

 /**
+ * virDomainSaveFlags:
+ * @domain: a domain object
+ * @to: path for the output file
+ * @dxml: (optional) XML config for adjusting guest xml used on restore
+ * @flags: bitwise-OR of virDomainSaveFlagValues
+ *
+ * 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.
+ *
+ * If the hypervisor supports it, @dxml can be used to alter
+ * host-specific portions of the domain XML that will be used when
+ * restoring an image.  For example, it is possible to alter the
+ * backing filename that is associated with a disk device, in order to
+ * prepare for file renaming done as part of backing up the disk
+ * device while the domain is stopped.
+ *
+ * If @flags includes VIR_DOMAIN_SAVE_DIRECT, then libvirt will attempt
+ * to use O_DIRECT I/O while creating the file; this can allow less
+ * pressure on file system cache, but also risks slowing saves to NFS.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainSaveFlags(virDomainPtr domain, const char *to,
+                   const char *dxml, unsigned int flags)
+{
+    virConnectPtr conn;
+
+    VIR_DOMAIN_DEBUG(domain, "to=%s dxml=%s flags=%x",
+                     to, NULLSTR(dxml), flags);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        virDispatchError(NULL);
+        return -1;
+    }
+    if (domain->conn->flags & VIR_CONNECT_RO) {
+        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        goto error;
+    }
+    conn = domain->conn;
+    if (to == NULL) {
+        virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    if (conn->driver->domainSaveFlags) {
+        int ret;
+        char *absolute_to;
+
+        /* We must absolutize the file path as the save is done out of process */
+        if (virFileAbsPath(to, &absolute_to) < 0) {
+            virLibConnError(VIR_ERR_INTERNAL_ERROR,
+                            _("could not build absolute output file path"));
+            goto error;
+        }
+
+        ret = conn->driver->domainSaveFlags(domain, absolute_to, dxml, flags);
+
+        VIR_FREE(absolute_to);
+
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    virDispatchError(domain->conn);
+    return -1;
+}
+
+/**
  * virDomainRestore:
  * @conn: pointer to the hypervisor connection
  * @from: path to the input file
@@ -2362,6 +2442,14 @@ error:
  * Note that for remote Xen Daemon the file path will be interpreted in
  * the remote host.
  *
+ * If @flags includes VIR_DUMP_CRASH, then leave the guest shut off with
+ * a crashed state after the dump completes.  If @flags includes
+ * VIR_DUMP_LIVE, then make the core dump while continuing to allow
+ * the guest to run; otherwise, the guest is suspended during the dump.
+ * If @flags includes VIR_DUMP_DIRECT, then libvirt will attempt
+ * to use O_DIRECT I/O while creating the file; this can allow less
+ * pressure on file system cache, but also risks slowing saves to NFS.
+ *
  * Returns 0 in case of success and -1 in case of failure.
  */
 int
@@ -14811,7 +14899,7 @@ error:
 /**
  * virDomainManagedSave:
  * @dom: pointer to the domain
- * @flags: optional flags currently unused
+ * @flags: bitwise-OR of virDomainSaveFlagValues
  *
  * 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
@@ -14821,6 +14909,10 @@ error:
  * restarted (automatically or via an explicit libvirt call).
  * As a result any running domain is sure to not have a managed saved image.
  *
+ * If @flags includes VIR_DOMAIN_SAVE_DIRECT, then libvirt will attempt
+ * to use O_DIRECT I/O while creating the file; this can allow less
+ * pressure on file system cache, but also risks slowing saves to NFS.
+ *
  * Returns 0 in case of success or -1 in case of failure
  */
 int virDomainManagedSave(virDomainPtr dom, unsigned int flags)
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 5f2541a..0d31b94 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -466,4 +466,9 @@ LIBVIRT_0.9.3 {
         virNodeGetMemoryStats;
 } LIBVIRT_0.9.2;

+LIBVIRT_0.9.4 {
+    global:
+        virDomainSaveFlags;
+} LIBVIRT_0.9.3;
+
 # .... define new API here using predicted next version number ....
-- 
1.7.4.4




More information about the libvir-list mailing list