mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-05-01 06:50:17 +03:00
docs: Convert 'internals' to RST and move it to 'kbase/internal/overview.rst'
Note that this document was not referenced from any top level page. This patch does a straight conversion and leaves it unreferenced. Next patch will then modify it to serve as an overview (hence the new name) of how an API call happens. Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
d14ba4ff71
commit
b51afd97e5
@ -1,119 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<body>
|
|
||||||
<h1>libvirt internals</h1>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This section provides documents useful to those working on the libvirt
|
|
||||||
internals, adding new public APIs, new hypervisor drivers or extending
|
|
||||||
the libvirtd daemon code.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>Introduction to basic rules and guidelines for
|
|
||||||
<a href="hacking.html">hacking</a> on libvirt code</li>
|
|
||||||
<li>Guide to adding <a href="api_extension.html">public APIs</a></li>
|
|
||||||
<li>Insight into libvirt <a href="internals/eventloop.html">event loop and worker pool</a></li>
|
|
||||||
<li>Approach for <a href="internals/command.html">spawning commands</a>
|
|
||||||
from libvirt driver code</li>
|
|
||||||
<li>The libvirt <a href="internals/rpc.html">RPC infrastructure</a></li>
|
|
||||||
<li>The <a href="internals/locking.html">Resource Lock Manager</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>Before adding new code it will be important to get a basic understanding
|
|
||||||
of the many elements involved with making any call or change to the libvirt
|
|
||||||
code. The architecture <a href="goals.html">goals</a> must be adhered to
|
|
||||||
when submitting new code. Understanding the many places that need to be
|
|
||||||
touched and the interactions between various subsystems within libvirt
|
|
||||||
will directly correlate to the ability to be successful in getting new
|
|
||||||
code accepted.</p>
|
|
||||||
<p>The following diagram depicts code flow from a client application, in
|
|
||||||
this case the libvirt provided <code>virsh</code> command through the
|
|
||||||
various layers to elicit a response from some chosen hypervisor.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p class="image">
|
|
||||||
<img alt="virConnectOpen calling sequence"
|
|
||||||
src="images/libvirt-virConnect-example.png"/>
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>"virsh -c qemu:///system list --all"
|
|
||||||
<p>After the virsh code processes the input arguments, it eventually
|
|
||||||
will make a call to open the connection using a default set of
|
|
||||||
authentication credentials (virConnectAuthDefault). </p></li>
|
|
||||||
<li>virConnectOpenAuth()
|
|
||||||
<p>Each of the virConnectOpen APIs will first call virInitialize() and
|
|
||||||
then revector through the local "do_open():" call.</p>
|
|
||||||
<ul>
|
|
||||||
<li>virInitialize()
|
|
||||||
<p>Calls the registration API for each of the drivers with
|
|
||||||
client-side only capabilities and then call the remoteRegister()
|
|
||||||
API last. This ensures the virDriverTab[] tries local drivers
|
|
||||||
first before using the remote driver.</p></li>
|
|
||||||
<li>Loop through virDriverTab[] entries trying to call their
|
|
||||||
respective "open" entry point (in our case remoteOpen())</li>
|
|
||||||
<li>After successful return from the virDriverTab[] open()
|
|
||||||
API, attempt to find and open other drivers (network, interface,
|
|
||||||
storage, etc.)</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li>remoteOpen()
|
|
||||||
<p>After a couple of URI checks, a call to doRemoteOpen() is made</p>
|
|
||||||
<ul>
|
|
||||||
<li>Determine network transport and host/port to use from URI
|
|
||||||
<p>The transport will be either tls, unix, ssh, libssh2, ext,
|
|
||||||
or tcp with the default of tls. Decode the host/port if provided
|
|
||||||
or default to "localhost".</p></li>
|
|
||||||
<li>virNetClientRegisterAsyncIO()
|
|
||||||
<p>Register an I/O callback mechanism to get returned data via
|
|
||||||
virNetClientIncomingEvent()</p></li>
|
|
||||||
<li>"call(...REMOTE_PROC_OPEN...)"
|
|
||||||
<p>Eventually routes into virNetClientProgramCall() which will
|
|
||||||
call virNetClientSendWithReply() and eventually uses
|
|
||||||
virNetClientIO()to send the message to libvirtd and
|
|
||||||
then waits for a response using virNetClientIOEventLoop()</p></li>
|
|
||||||
<li>virNetClientIncomingEvent()
|
|
||||||
<p>Receives the returned packet and processes through
|
|
||||||
virNetClientIOUpdateCallback()</p></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li>libvirtd Daemon
|
|
||||||
<p></p>
|
|
||||||
<ul>
|
|
||||||
<li>Daemon Startup
|
|
||||||
<p>The daemon initialization processing will declare itself
|
|
||||||
as a daemon via a virNetDaemonNew() call, then creates new server
|
|
||||||
using virNetServerNew() and adds that server to the main daemon
|
|
||||||
struct with virNetDaemonAddServer() call. It will then use
|
|
||||||
virDriverLoadModule() to find/load all known drivers,
|
|
||||||
set up an RPC server program using the <code>remoteProcs[]</code>
|
|
||||||
table via a virNetServerProgramNew() call. The table is the
|
|
||||||
corollary to the <code>remote_procedure</code> enum list in
|
|
||||||
the client. It lists all the functions to be called in
|
|
||||||
the same order. Once RPC is set up, networking server sockets
|
|
||||||
are opened, the various driver state initialization routines
|
|
||||||
are run from the <code>virStateDriverTab[]</code>, the network
|
|
||||||
links are enabled, and the daemon waits for work.</p></li>
|
|
||||||
<li>RPC
|
|
||||||
<p>When a message is received, the <code>remoteProcs[]</code>
|
|
||||||
table is referenced for the 'REMOTE_PROC_OPEN' call entry.
|
|
||||||
This results in remoteDispatchOpen() being called via the
|
|
||||||
virNetServerProgramDispatchCall().</p></li>
|
|
||||||
<li>remoteDispatchOpen()
|
|
||||||
<p>The API will read the argument passed picking out the
|
|
||||||
<code>name</code> of the driver to be opened. The code
|
|
||||||
will then call virConnectOpen() or virConnectOpenReadOnly()
|
|
||||||
depending on the argument <code>flags</code>.</p></li>
|
|
||||||
<li>virConnectOpen() or virConnectOpenReadOnly()
|
|
||||||
<p>Just like the client except that upon entry the URI
|
|
||||||
is what was passed from the client and will be found
|
|
||||||
and opened to process the data.</p>
|
|
||||||
<p>The returned structure data is returned via the
|
|
||||||
virNetServer interfaces to the remote driver which then
|
|
||||||
returns it to the client application.</p></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -4,6 +4,7 @@ docs_kbase_internals_files = [
|
|||||||
'incremental-backup',
|
'incremental-backup',
|
||||||
'locking',
|
'locking',
|
||||||
'migration',
|
'migration',
|
||||||
|
'overview',
|
||||||
'rpc',
|
'rpc',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
117
docs/kbase/internals/overview.rst
Normal file
117
docs/kbase/internals/overview.rst
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
==========================
|
||||||
|
libvirt internals overview
|
||||||
|
==========================
|
||||||
|
|
||||||
|
This section provides documents useful to those working on the libvirt
|
||||||
|
internals, adding new public APIs, new hypervisor drivers or extending the
|
||||||
|
libvirtd daemon code.
|
||||||
|
|
||||||
|
- Introduction to basic rules and guidelines for `hacking <../../hacking.html>`__ on
|
||||||
|
libvirt code
|
||||||
|
- Guide to adding `public APIs <../../api_extension.html>`__
|
||||||
|
- Insight into libvirt `event loop and worker
|
||||||
|
pool <eventloop.html>`__
|
||||||
|
- Approach for `spawning commands <command.html>`__ from libvirt
|
||||||
|
driver code
|
||||||
|
- The libvirt `RPC infrastructure <rpc.html>`__
|
||||||
|
- The `Resource Lock Manager <locking.html>`__
|
||||||
|
|
||||||
|
Before adding new code it will be important to get a basic understanding of the
|
||||||
|
many elements involved with making any call or change to the libvirt code. The
|
||||||
|
architecture `goals <../../goals.html>`__ must be adhered to when submitting new code.
|
||||||
|
Understanding the many places that need to be touched and the interactions
|
||||||
|
between various subsystems within libvirt will directly correlate to the ability
|
||||||
|
to be successful in getting new code accepted.
|
||||||
|
|
||||||
|
The following diagram depicts code flow from a client application, in this case
|
||||||
|
the libvirt provided ``virsh`` command through the various layers to elicit a
|
||||||
|
response from some chosen hypervisor.
|
||||||
|
|
||||||
|
.. image:: ../../images/libvirt-virConnect-example.png
|
||||||
|
:alt: virConnectOpen calling sequence
|
||||||
|
|
||||||
|
- "virsh -c qemu:///system list --all"
|
||||||
|
|
||||||
|
After the virsh code processes the input arguments, it eventually will make a
|
||||||
|
call to open the connection using a default set of authentication credentials
|
||||||
|
(virConnectAuthDefault).
|
||||||
|
|
||||||
|
- virConnectOpenAuth()
|
||||||
|
|
||||||
|
Each of the virConnectOpen APIs will first call virInitialize() and then
|
||||||
|
revector through the local "do_open():" call.
|
||||||
|
|
||||||
|
- virInitialize()
|
||||||
|
|
||||||
|
Calls the registration API for each of the drivers with client-side only
|
||||||
|
capabilities and then call the remoteRegister() API last. This ensures the
|
||||||
|
virDriverTab[] tries local drivers first before using the remote driver.
|
||||||
|
|
||||||
|
- Loop through virDriverTab[] entries trying to call their respective "open"
|
||||||
|
entry point (in our case remoteOpen())
|
||||||
|
|
||||||
|
- After successful return from the virDriverTab[] open() API, attempt to
|
||||||
|
find and open other drivers (network, interface, storage, etc.)
|
||||||
|
|
||||||
|
- remoteOpen()
|
||||||
|
|
||||||
|
After a couple of URI checks, a call to doRemoteOpen() is made
|
||||||
|
|
||||||
|
- Determine network transport and host/port to use from URI
|
||||||
|
|
||||||
|
The transport will be either tls, unix, ssh, libssh2, ext, or tcp with the
|
||||||
|
default of tls. Decode the host/port if provided or default to
|
||||||
|
"localhost".
|
||||||
|
|
||||||
|
- virNetClientRegisterAsyncIO()
|
||||||
|
|
||||||
|
Register an I/O callback mechanism to get returned data via
|
||||||
|
virNetClientIncomingEvent()
|
||||||
|
|
||||||
|
- "call(...REMOTE_PROC_OPEN...)"
|
||||||
|
|
||||||
|
Eventually routes into virNetClientProgramCall() which will call
|
||||||
|
virNetClientSendWithReply() and eventually uses virNetClientIO()to send
|
||||||
|
the message to libvirtd and then waits for a response using
|
||||||
|
virNetClientIOEventLoop()
|
||||||
|
|
||||||
|
- virNetClientIncomingEvent()
|
||||||
|
|
||||||
|
Receives the returned packet and processes through
|
||||||
|
virNetClientIOUpdateCallback()
|
||||||
|
|
||||||
|
- libvirtd Daemon
|
||||||
|
|
||||||
|
- Daemon Startup
|
||||||
|
|
||||||
|
The daemon initialization processing will declare itself as a daemon via a
|
||||||
|
virNetDaemonNew() call, then creates new server using virNetServerNew()
|
||||||
|
and adds that server to the main daemon struct with
|
||||||
|
virNetDaemonAddServer() call. It will then use virDriverLoadModule() to
|
||||||
|
find/load all known drivers, set up an RPC server program using the
|
||||||
|
``remoteProcs[]`` table via a virNetServerProgramNew() call. The table is
|
||||||
|
the corollary to the ``remote_procedure`` enum list in the client. It
|
||||||
|
lists all the functions to be called in the same order. Once RPC is set
|
||||||
|
up, networking server sockets are opened, the various driver state
|
||||||
|
initialization routines are run from the ``virStateDriverTab[]``, the
|
||||||
|
network links are enabled, and the daemon waits for work.
|
||||||
|
|
||||||
|
- RPC
|
||||||
|
|
||||||
|
When a message is received, the ``remoteProcs[]`` table is referenced for
|
||||||
|
the 'REMOTE_PROC_OPEN' call entry. This results in remoteDispatchOpen()
|
||||||
|
being called via the virNetServerProgramDispatchCall().
|
||||||
|
|
||||||
|
- remoteDispatchOpen()
|
||||||
|
|
||||||
|
The API will read the argument passed picking out the ``name`` of the
|
||||||
|
driver to be opened. The code will then call virConnectOpen() or
|
||||||
|
virConnectOpenReadOnly() depending on the argument ``flags``.
|
||||||
|
|
||||||
|
- virConnectOpen() or virConnectOpenReadOnly()
|
||||||
|
|
||||||
|
Just like the client except that upon entry the URI is what was passed
|
||||||
|
from the client and will be found and opened to process the data.
|
||||||
|
|
||||||
|
The returned structure data is returned via the virNetServer interfaces to
|
||||||
|
the remote driver which then returns it to the client application.
|
@ -23,7 +23,6 @@ docs_html_in_files = [
|
|||||||
'formatnode',
|
'formatnode',
|
||||||
'formatnwfilter',
|
'formatnwfilter',
|
||||||
'index',
|
'index',
|
||||||
'internals',
|
|
||||||
'remote',
|
'remote',
|
||||||
'storage',
|
'storage',
|
||||||
'uri',
|
'uri',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user