[libvirt] [PATCH] doc: Document the Block Job API

Adam Litke agl at us.ibm.com
Fri Aug 12 15:02:40 UTC 2011


Hi DV,

This patch adds some basic documentation to the development guide for the Block
Job APIs as you requested.  Also included is a sample program that shows
end-to-end use of the BlockPull operation.  I hope this is close to what you
had in mind.

Signed-off-by: Adam Litke <agl at us.ibm.com>
---
 en-US/Guest_Domains.xml |  154 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 154 insertions(+), 0 deletions(-)

diff --git a/en-US/Guest_Domains.xml b/en-US/Guest_Domains.xml
index 0324e78..202881d 100644
--- a/en-US/Guest_Domains.xml
+++ b/en-US/Guest_Domains.xml
@@ -1219,6 +1219,160 @@ fprintf(stderr, "Device is suitable for passthrough to a guest\n");
 
     </section>
 
+    <section id="Application_Development_Guide-Live_Config-Block_Jobs">
+      <title>Block Device Jobs</title>
+
+      <para>
+        Libvirt provides a generic Block Job API that can be used to initiate
+        and manage operations on disks that belong to a domain.  Jobs are
+        started by calling the function associated with the desired operation
+        (eg.  <literal>virDomainBlockPull</literal>).  Once started, all block
+        jobs are managed in the same manner.  They can be aborted, throttled,
+        and queried.  Upon completion, an asynchronous event is issued to
+        indicate the final status.
+      </para>
+
+      <para>
+        The following block jobs can be started:
+      </para>
+      <orderedlist>
+        <listitem>
+          <para>
+	    <literal>virDomainBlockPull()</literal> starts a block pull
+            operation for the specified disk.  This operation is valid only for
+            specially configured disks.   BlockPull will populate a disk image
+            with data from its backing image.  Once all data from its backing
+            image has been pulled, the disk no longer depends on a backing
+            image.
+          </para>
+        </listitem>
+      </orderedlist>
+
+      <para>
+        A disk can be queried for active block jobs by using
+        <literal>virDomainGetBlockJobInfo()</literal>.  If found, job
+        information is reported in a structure that contains: the job type,
+        bandwidth throttling setting, and progress information.
+      </para>
+
+      <para>
+        <literal>virDomainBlockJobAbort()</literal> can be used to cancel the
+        active block job on the specified disk.
+      </para>
+
+      <para>
+        Use <literal>virDomainBlockJobSetSpeed()</literal> to limit the amount
+        of bandwidth that a block job may consume.  Bandwidth is specified in
+        units of MB/sec.
+      </para>
+
+      <para>
+        When a block job operation completes, the final status is reported using
+        an asynchronous event.  To receive this event, register a
+        <literal>virConnectDomainEventBlockJobCallback</literal> function which
+        will receive the disk, event type, and status as parameters.
+      </para>
+
+      <programlisting>
+<![CDATA[/* example blockpull-example.c */
+/* compile with: gcc -g -Wall blockpull-example.c -o blockpull-example -lvirt */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <libvirt/libvirt.h>
+
+int do_cmd(const char *cmdline)
+{
+    int status = system(cmdline);
+    if (status < 0)
+        return -1;
+    else
+        return WEXITSTATUS(status);
+}
+
+virDomainPtr make_domain(virConnectPtr conn)
+{
+    virDomainPtr dom;
+    char domxml[] = \
+       "<domain type='kvm'> \
+          <name>example</name> \
+          <memory>131072</memory> \
+          <vcpu>1</vcpu> \
+          <os> \
+            <type arch='x86_64' machine='pc-0.13'>hvm</type> \
+          </os> \
+          <devices> \
+            <disk type='file' device='disk'> \
+              <driver name='qemu' type='qed'/> \
+              <source file='/var/lib/libvirt/images/example.qed' /> \
+              <target dev='vda' bus='virtio'/> \
+            </disk> \
+          </devices> \
+        </domain>";
+
+    do_cmd("qemu-img create -f raw /var/lib/libvirt/images/backing.qed 100M");
+    do_cmd("qemu-img create -f qed -b /var/lib/libvirt/images/backing.qed \
+                /var/lib/libvirt/images/example.qed");
+
+    dom = virDomainCreateXML(conn, domxml, 0);
+    return dom;
+}
+
+int main(int argc, char *argv[])
+{
+    virConnectPtr conn;
+    virDomainPtr dom = NULL;
+    char disk[] = "/var/lib/libvirt/images/example.qed";
+
+    conn = virConnectOpen("qemu:///system");
+    if (conn == NULL) {
+        fprintf(stderr, "Failed to open connection to qemu:///system\n");
+        goto error;
+    }
+
+    dom = make_domain(conn);
+    if (dom == NULL) {
+        fprintf(stderr, "Failed to create domain\n");
+        goto error;
+    }
+
+    if ((virDomainBlockPull(dom, disk, 0, 0)) < 0) {
+        fprintf(stderr, "Failed to start block pull");
+        goto error;
+    }
+
+    while (1) {
+        virDomainBlockJobInfo info;
+        int ret = virDomainGetBlockJobInfo(dom, disk, &info, 0);
+
+        if (ret == 1) {
+            printf("BlockPull progress: %0.0f %%\n", 
+                (float)(100 * info.cur / info.end));
+        } else if (ret == 0) {
+            printf("BlockPull complete\n");
+            break;
+        } else {
+            fprintf(stderr, "Failed to query block jobs\n");
+            break;
+        }
+        usleep(100000);
+    }
+
+error:
+    unlink("/var/lib/libvirt/images/backing.qed");
+    unlink("/var/lib/libvirt/images/example.qed");
+    if (dom != NULL) {
+        virDomainDestroy(dom);
+        virDomainFree(dom);
+    }
+    if (conn != NULL)
+        virConnectClose(conn);
+    return 0;
+}]]>
+      </programlisting>
+
+    </section>
+
   </section>
 
   <section id="Application_Development_Guide-Guest_Domains-Security">
-- 
1.7.3




More information about the libvir-list mailing list