</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>
--- /dev/null
+#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