+#: ../src/guestfs.pod:1607
+#, no-wrap
+msgid ""
+" typedef void (*guestfs_close_cb) (guestfs_h *g, void *opaque);\n"
+" void guestfs_set_close_callback (guestfs_h *g,\n"
+" guestfs_close_cb cb,\n"
+" void *opaque);\n"
+"\n"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1612
+msgid ""
+"The callback function C<cb> will be called while the handle is being closed "
+"(synchronously from L</guestfs_close>)."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1615
+msgid ""
+"Note that libguestfs installs an L<atexit(3)> handler to try to clean up "
+"handles that are open when the program exits. This means that this callback "
+"might be called indirectly from L<exit(3)>, which can cause unexpected "
+"problems in higher-level languages (eg. if your HLL interpreter has already "
+"been cleaned up by the time this is called, and if your callback then jumps "
+"into some HLL function)."
+msgstr ""
+
+# type: =head2
+#: ../src/guestfs.pod:1623
+msgid "guestfs_set_progress_callback"
+msgstr ""
+
+# type: verbatim
+#: ../src/guestfs.pod:1625
+#, no-wrap
+msgid ""
+" typedef void (*guestfs_progress_cb) (guestfs_h *g, void *opaque,\n"
+" int proc_nr, int serial,\n"
+" uint64_t position, uint64_t total);\n"
+" void guestfs_set_progress_callback (guestfs_h *g,\n"
+" guestfs_progress_cb cb,\n"
+" void *opaque);\n"
+"\n"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1632
+msgid ""
+"Some long-running operations can generate progress messages. If this "
+"callback is registered, then it will be called each time a progress message "
+"is generated (usually two seconds after the operation started, and three "
+"times per second thereafter until it completes, although the frequency may "
+"change in future versions)."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1638
+msgid ""
+"The callback receives two numbers: C<position> and C<total>. The units of "
+"C<total> are not defined, although for some operations C<total> may relate "
+"in some way to the amount of data to be transferred (eg. in bytes or "
+"megabytes), and C<position> may be the portion which has been transferred."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1644
+msgid "The only defined and stable parts of the API are:"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1650
+msgid ""
+"The callback can display to the user some type of progress bar or indicator "
+"which shows the ratio of C<position>:C<total>."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1655
+msgid "0 E<lt>= C<position> E<lt>= C<total>"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1659
+msgid ""
+"If any progress notification is sent during a call, then a final progress "
+"notification is always sent when C<position> = C<total>."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1662
+msgid ""
+"This is to simplify caller code, so callers can easily set the progress "
+"indicator to \"100%\" at the end of the operation, without requiring special "
+"code to detect this case."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1668
+msgid ""
+"The callback also receives the procedure number and serial number of the "
+"call. These are only useful for debugging protocol issues, and the callback "
+"can normally ignore them. The callback may want to print these numbers in "
+"error messages or debugging messages."
+msgstr ""
+
+# type: =head1
+#: ../src/guestfs.pod:1673
+msgid "PRIVATE DATA AREA"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1675
+msgid ""
+"You can attach named pieces of private data to the libguestfs handle, and "
+"fetch them by name for the lifetime of the handle. This is called the "
+"private data area and is only available from the C API."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1679
+msgid "To attach a named piece of data, use the following call:"
+msgstr ""
+
+# type: verbatim
+#: ../src/guestfs.pod:1681
+#, no-wrap
+msgid ""
+" void guestfs_set_private (guestfs_h *g, const char *key, void *data);\n"
+"\n"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1683
+msgid ""
+"C<key> is the name to associate with this data, and C<data> is an arbitrary "
+"pointer (which can be C<NULL>). Any previous item with the same name is "
+"overwritten."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1687
+msgid ""
+"You can use any C<key> you want, but names beginning with an underscore "
+"character are reserved for internal libguestfs purposes (for implementing "
+"language bindings). It is recommended to prefix the name with some unique "
+"string to avoid collisions with other users."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1692
+msgid "To retrieve the pointer, use:"
+msgstr ""
+
+# type: verbatim
+#: ../src/guestfs.pod:1694
+#, no-wrap
+msgid ""
+" void *guestfs_get_private (guestfs_h *g, const char *key);\n"
+"\n"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1696
+msgid ""
+"This function returns C<NULL> if either no data is found associated with "
+"C<key>, or if the user previously set the C<key>'s C<data> pointer to "
+"C<NULL>."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1700
+msgid ""
+"Libguestfs does not try to look at or interpret the C<data> pointer in any "
+"way. As far as libguestfs is concerned, it need not be a valid pointer at "
+"all. In particular, libguestfs does I<not> try to free the data when the "
+"handle is closed. If the data must be freed, then the caller must either "
+"free it before calling L</guestfs_close> or must set up a close callback to "
+"do it (see L</guestfs_set_close_callback>, and note that only one callback "
+"can be registered for a handle)."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1708
+msgid ""
+"The private data area is implemented using a hash table, and should be "
+"reasonably efficient for moderate numbers of keys."
+msgstr ""
+
+# type: =end
+#: ../src/guestfs.pod:1711 ../src/guestfs.pod:1716
+msgid "html"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1713
+msgid ""
+"<!-- old anchor for the next section --> <a name="
+"\"state_machine_and_low_level_event_api\"/>"
+msgstr ""
+
+# type: =head1
+#: ../src/guestfs.pod:1718
+msgid "ARCHITECTURE"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1720
+msgid ""
+"Internally, libguestfs is implemented by running an appliance (a special "
+"type of small virtual machine) using L<qemu(1)>. Qemu runs as a child "
+"process of the main program."
+msgstr ""
+
+# type: verbatim
+#: ../src/guestfs.pod:1724
+#, no-wrap
+msgid ""
+" ___________________\n"
+" / \\\n"
+" | main program |\n"
+" | |\n"
+" | | child process / appliance\n"
+" | | __________________________\n"
+" | | / qemu \\\n"
+" +-------------------+ RPC | +-----------------+ |\n"
+" | libguestfs <--------------------> guestfsd | |\n"
+" | | | +-----------------+ |\n"
+" \\___________________/ | | Linux kernel | |\n"
+" | +--^--------------+ |\n"
+" \\_________|________________/\n"
+" |\n"
+" _______v______\n"
+" / \\\n"
+" | Device or |\n"
+" | disk image |\n"
+" \\______________/\n"
+"\n"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1744
+msgid ""
+"The library, linked to the main program, creates the child process and hence "
+"the appliance in the L</guestfs_launch> function."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1747
+msgid ""
+"Inside the appliance is a Linux kernel and a complete stack of userspace "
+"tools (such as LVM and ext2 programs) and a small controlling daemon called "
+"L</guestfsd>. The library talks to L</guestfsd> using remote procedure "
+"calls (RPC). There is a mostly one-to-one correspondence between libguestfs "
+"API calls and RPC calls to the daemon. Lastly the disk image(s) are "
+"attached to the qemu process which translates device access by the "
+"appliance's Linux kernel into accesses to the image."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1756
+msgid ""
+"A common misunderstanding is that the appliance \"is\" the virtual machine. "
+"Although the disk image you are attached to might also be used by some "
+"virtual machine, libguestfs doesn't know or care about this. (But you will "
+"care if both libguestfs's qemu process and your virtual machine are trying "
+"to update the disk image at the same time, since these usually results in "
+"massive disk corruption)."
+msgstr ""
+
+# type: =head1
+#: ../src/guestfs.pod:1763
+msgid "STATE MACHINE"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1765
+msgid "libguestfs uses a state machine to model the child process:"
+msgstr ""
+
+# type: verbatim
+#: ../src/guestfs.pod:1767
+#, no-wrap
+msgid ""
+" |\n"
+" guestfs_create\n"
+" |\n"
+" |\n"
+" ____V_____\n"
+" / \\\n"
+" | CONFIG |\n"
+" \\__________/\n"
+" ^ ^ ^ \\\n"
+" / | \\ \\ guestfs_launch\n"
+" / | _\\__V______\n"
+" / | / \\\n"
+" / | | LAUNCHING |\n"
+" / | \\___________/\n"
+" / | /\n"
+" / | guestfs_launch\n"
+" / | /\n"
+" ______ / __|____V\n"
+" / \\ ------> / \\\n"
+" | BUSY | | READY |\n"
+" \\______/ <------ \\________/\n"
+"\n"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1789
+msgid ""
+"The normal transitions are (1) CONFIG (when the handle is created, but there "
+"is no child process), (2) LAUNCHING (when the child process is booting up), "
+"(3) alternating between READY and BUSY as commands are issued to, and "
+"carried out by, the child process."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1794
+msgid ""
+"The guest may be killed by L</guestfs_kill_subprocess>, or may die "
+"asynchronously at any time (eg. due to some internal error), and that causes "
+"the state to transition back to CONFIG."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1798
+msgid ""
+"Configuration commands for qemu such as L</guestfs_add_drive> can only be "
+"issued when in the CONFIG state."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1801
+msgid ""
+"The API offers one call that goes from CONFIG through LAUNCHING to READY. "
+"L</guestfs_launch> blocks until the child process is READY to accept "
+"commands (or until some failure or timeout). L</guestfs_launch> internally "
+"moves the state from CONFIG to LAUNCHING while it is running."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1807
+msgid ""
+"API actions such as L</guestfs_mount> can only be issued when in the READY "
+"state. These API calls block waiting for the command to be carried out (ie. "
+"the state to transition to BUSY and then back to READY). There are no non-"
+"blocking versions, and no way to issue more than one command per handle at "
+"the same time."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1813
+msgid ""
+"Finally, the child process sends asynchronous messages back to the main "
+"program, such as kernel log messages. You can register a callback to "
+"receive these messages."
+msgstr ""
+
+# type: =head1
+#: ../src/guestfs.pod:1817
+msgid "INTERNALS"
+msgstr ""
+
+# type: =head2
+#: ../src/guestfs.pod:1819
+msgid "COMMUNICATION PROTOCOL"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1821
+msgid ""
+"Don't rely on using this protocol directly. This section documents how it "
+"currently works, but it may change at any time."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1824
+msgid ""
+"The protocol used to talk between the library and the daemon running inside "
+"the qemu virtual machine is a simple RPC mechanism built on top of XDR (RFC "
+"1014, RFC 1832, RFC 4506)."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1828
+msgid ""
+"The detailed format of structures is in C<src/guestfs_protocol.x> (note: "
+"this file is automatically generated)."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1831
+msgid ""
+"There are two broad cases, ordinary functions that don't have any C<FileIn> "
+"and C<FileOut> parameters, which are handled with very simple request/reply "
+"messages. Then there are functions that have any C<FileIn> or C<FileOut> "
+"parameters, which use the same request and reply messages, but they may also "
+"be followed by files sent using a chunked encoding."
+msgstr ""
+
+# type: =head3
+#: ../src/guestfs.pod:1838
+msgid "ORDINARY FUNCTIONS (NO FILEIN/FILEOUT PARAMS)"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1840
+msgid "For ordinary functions, the request message is:"
+msgstr ""
+
+# type: verbatim
+#: ../src/guestfs.pod:1842
+#, no-wrap
+msgid ""
+" total length (header + arguments,\n"
+" but not including the length word itself)\n"
+" struct guestfs_message_header (encoded as XDR)\n"
+" struct guestfs_<foo>_args (encoded as XDR)\n"
+"\n"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1847
+msgid ""
+"The total length field allows the daemon to allocate a fixed size buffer "
+"into which it slurps the rest of the message. As a result, the total length "
+"is limited to C<GUESTFS_MESSAGE_MAX> bytes (currently 4MB), which means the "
+"effective size of any request is limited to somewhere under this size."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1853
+msgid ""
+"Note also that many functions don't take any arguments, in which case the "
+"C<guestfs_I<foo>_args> is completely omitted."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1856
+msgid ""
+"The header contains the procedure number (C<guestfs_proc>) which is how the "
+"receiver knows what type of args structure to expect, or none at all."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1860
+msgid "The reply message for ordinary functions is:"
+msgstr ""
+
+# type: verbatim
+#: ../src/guestfs.pod:1862
+#, no-wrap
+msgid ""
+" total length (header + ret,\n"
+" but not including the length word itself)\n"
+" struct guestfs_message_header (encoded as XDR)\n"
+" struct guestfs_<foo>_ret (encoded as XDR)\n"
+"\n"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1867
+msgid ""
+"As above the C<guestfs_I<foo>_ret> structure may be completely omitted for "
+"functions that return no formal return values."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1870
+msgid ""
+"As above the total length of the reply is limited to C<GUESTFS_MESSAGE_MAX>."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1873
+msgid ""
+"In the case of an error, a flag is set in the header, and the reply message "
+"is slightly changed:"
+msgstr ""
+
+# type: verbatim
+#: ../src/guestfs.pod:1876
+#, no-wrap
+msgid ""
+" total length (header + error,\n"
+" but not including the length word itself)\n"
+" struct guestfs_message_header (encoded as XDR)\n"
+" struct guestfs_message_error (encoded as XDR)\n"
+"\n"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1881
+msgid ""
+"The C<guestfs_message_error> structure contains the error message as a "
+"string."
+msgstr ""
+
+# type: =head3
+#: ../src/guestfs.pod:1884
+msgid "FUNCTIONS THAT HAVE FILEIN PARAMETERS"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1886
+msgid ""
+"A C<FileIn> parameter indicates that we transfer a file I<into> the guest. "
+"The normal request message is sent (see above). However this is followed by "
+"a sequence of file chunks."
+msgstr ""
+
+# type: verbatim
+#: ../src/guestfs.pod:1890
+#, no-wrap
+msgid ""
+" total length (header + arguments,\n"
+" but not including the length word itself,\n"
+" and not including the chunks)\n"
+" struct guestfs_message_header (encoded as XDR)\n"
+" struct guestfs_<foo>_args (encoded as XDR)\n"
+" sequence of chunks for FileIn param #0\n"
+" sequence of chunks for FileIn param #1 etc.\n"
+"\n"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1898
+msgid "The \"sequence of chunks\" is:"
+msgstr ""
+
+# type: verbatim
+#: ../src/guestfs.pod:1900
+#, no-wrap
+msgid ""
+" length of chunk (not including length word itself)\n"
+" struct guestfs_chunk (encoded as XDR)\n"
+" length of chunk\n"
+" struct guestfs_chunk (encoded as XDR)\n"
+" ...\n"
+" length of chunk\n"
+" struct guestfs_chunk (with data.data_len == 0)\n"
+"\n"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1908
+msgid ""
+"The final chunk has the C<data_len> field set to zero. Additionally a flag "
+"is set in the final chunk to indicate either successful completion or early "
+"cancellation."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1912
+msgid ""
+"At time of writing there are no functions that have more than one FileIn "
+"parameter. However this is (theoretically) supported, by sending the "
+"sequence of chunks for each FileIn parameter one after another (from left to "
+"right)."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1917
+msgid ""
+"Both the library (sender) I<and> the daemon (receiver) may cancel the "
+"transfer. The library does this by sending a chunk with a special flag set "
+"to indicate cancellation. When the daemon sees this, it cancels the whole "
+"RPC, does I<not> send any reply, and goes back to reading the next request."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1923
+msgid ""
+"The daemon may also cancel. It does this by writing a special word "
+"C<GUESTFS_CANCEL_FLAG> to the socket. The library listens for this during "
+"the transfer, and if it gets it, it will cancel the transfer (it sends a "
+"cancel chunk). The special word is chosen so that even if cancellation "
+"happens right at the end of the transfer (after the library has finished "
+"writing and has started listening for the reply), the \"spurious\" cancel "
+"flag will not be confused with the reply message."
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1932
+msgid ""
+"This protocol allows the transfer of arbitrary sized files (no 32 bit "
+"limit), and also files where the size is not known in advance (eg. from "
+"pipes or sockets). However the chunks are rather small "
+"(C<GUESTFS_MAX_CHUNK_SIZE>), so that neither the library nor the daemon need "
+"to keep much in memory."
+msgstr ""
+
+# type: =head3
+#: ../src/guestfs.pod:1938
+msgid "FUNCTIONS THAT HAVE FILEOUT PARAMETERS"
+msgstr ""
+
+# type: textblock
+#: ../src/guestfs.pod:1940
+msgid ""
+"The protocol for FileOut parameters is exactly the same as for FileIn "
+"parameters, but with the roles of daemon and library reversed."
+msgstr ""
+
+# type: verbatim
+#: ../src/guestfs.pod:1943