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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list