Added a picture and explanation describing the virConnectOpen processing
at a "higher" level, but with some source code references.
---
docs/internals.html.in | 102 ++++++++++++++++++++++++++++++++++--
docs/libvirt-virConnect-example.fig | 58 ++++++++++++++++++++
docs/libvirt-virConnect-example.png | Bin 0 -> 10464 bytes
3 files changed, 156 insertions(+), 4 deletions(-)
create mode 100644 docs/libvirt-virConnect-example.fig
create mode 100644 docs/libvirt-virConnect-example.png
diff --git a/docs/internals.html.in b/docs/internals.html.in
index 5689998..90143ef 100644
--- a/docs/internals.html.in
+++ b/docs/internals.html.in
@@ -9,12 +9,106 @@
</p>
<ul>
- <li>Introduction to basic rules and guidelines for <a
href="hacking.html">hacking</a>
- on libvirt code</li>
+ <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>Approach for <a href="internals/command.html">spawning
commands</a> from
- libvirt driver code</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="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 server via a virNetServerNew() call, 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>
diff --git a/docs/libvirt-virConnect-example.fig b/docs/libvirt-virConnect-example.fig
new file mode 100644
index 0000000..2936f22
--- /dev/null
+++ b/docs/libvirt-virConnect-example.fig
@@ -0,0 +1,58 @@
+#FIG 3.2 Produced by xfig version 3.2.5b
+Landscape
+Center
+Inches
+Letter
+100.00
+Single
+-2
+1200 2
+2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 450 375 4575 375 4575 1725 450 1725 450 375
+2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 1125 2475 4950 2475 4950 3600 1125 3600 1125 2475
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+ 1 0 1.00 60.00 120.00
+ 1725 1725 2175 2475
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 3150 5700 6525 5700 6525 6900 3150 6900 3150 5700
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 7875 6825 10125 6825 10125 7725 7875 7725 7875 6825
+2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 2550 4725 10350 4725 10350 7800 2550 7800 2550 4725
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 8850 1950 11550 1950 11550 3360 8850 3360 8850 1950
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+ 1 0 1.00 60.00 120.00
+ 3975 3600 5025 4425
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+ 1 0 1.00 60.00 120.00
+ 8925 3225 5400 4425
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+ 1 0 1.00 60.00 120.00
+ 5625 6900 7875 7425
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
+ 1 0 1.00 60.00 120.00
+ 11400 3375 11400 7575 10125 7575
+2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 8400 975 12450 975 12450 4125 8400 4125 8400 975
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 6
+ 1 0 1.00 60.00 120.00
+ 10125 7125 10725 7125 10725 4425 7725 4425 7725 2700 8850 2700
+4 0 0 50 -1 16 12 0.0000 4 180 2430 1350 2895 virConnectOpenReadOnly(uri)\001
+4 0 0 50 -1 16 12 0.0000 4 180 3240 1350 3090 virConnectOpenAuth(uri, auth, flags)\001
+4 0 0 50 -1 0 12 0.0000 4 165 1350 3300 5850 virConnectOpen:\001
+4 0 0 50 -1 0 12 0.0000 4 165 2070 3300 6045 virConnectOpenReadOnly:\001
+4 0 0 50 -1 0 12 0.0000 4 165 1710 3300 6240 virConnectOpenAuth:\001
+4 0 0 50 -1 0 12 0.0000 4 180 900 3975 6600 do_open():\001
+4 0 0 50 -1 0 14 0.0000 4 135 1260 8025 7125 Rremote driver\001
+4 0 0 50 -1 16 24 0.0000 4 135 630 5025 4650 libvirt\001
+4 0 0 50 -1 0 14 0.0000 4 180 1890 9000 2175 remoteDispatchOpen():\001
+4 0 0 50 -1 0 12 0.0000 4 45 270 9300 2475 ...\001
+4 0 0 50 -1 0 12 0.0000 4 180 1440 9300 2670 virConnectOpen()\001
+4 0 0 50 -1 0 12 0.0000 4 180 2160 9300 2865 virConnectOpenReadOnly()\001
+4 0 0 50 -1 0 12 0.0000 4 45 270 9300 3060 ...\001
+4 0 0 50 -1 0 12 0.0000 4 180 1080 8250 7350 remoteOpen()\001
+4 0 0 50 -1 16 16 0.0000 4 165 3240 600 1050 "virsh -c qemu:///system list
--all"\001
+4 0 0 50 -1 16 12 0.0000 4 180 1710 1350 2700 virConnectOpen(uri)\001
+4 0 0 50 -1 16 24 0.0000 4 135 720 9750 825 libvirtd\001
diff --git a/docs/libvirt-virConnect-example.png b/docs/libvirt-virConnect-example.png
new file mode 100644
index 0000000000000000000000000000000000000000..ae9c65ba01ef574c59f11d75c7d959b53a02ee2b
GIT binary patch
literal 10464
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
literal 0
HcmV?d00001
--
1.7.11.7