While the content is slightly outdated it's still a good primer on how an API call traverses through the client library and to the remote driver. To make the page useful, this commit: - removes the paragraphs which were intended to serve as a directory page for the 'internals' subdirectory - adds a note saying that some facts might not be up to date - adds linking to this page from the kbase directory page - adds more monospace formatting around function names Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- docs/kbase/index.rst | 4 + docs/kbase/internals/overview.rst | 121 +++++++++++++----------------- 2 files changed, 57 insertions(+), 68 deletions(-) diff --git a/docs/kbase/index.rst b/docs/kbase/index.rst index 31711d908b..0848467d51 100644 --- a/docs/kbase/index.rst +++ b/docs/kbase/index.rst @@ -86,6 +86,10 @@ Internals VM migration implementation details, complementing the info in `migration <../migration.html>`__ +`API call flow overview <internals/overview.html>`__ + Overview of how an API call is handled by the ``libvirt`` library and passed + over RPC to the daemon. + `Spawning commands <internals/command.html>`__ Spawning commands from libvirt driver code diff --git a/docs/kbase/internals/overview.rst b/docs/kbase/internals/overview.rst index 84ea7858db..7887e16667 100644 --- a/docs/kbase/internals/overview.rst +++ b/docs/kbase/internals/overview.rst @@ -1,117 +1,102 @@ -========================== -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. +========================= +libvirt API call overview +========================= 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. +**Note:** Some aspects of this document may be outdated. + .. image:: ../../images/libvirt-virConnect-example.png :alt: virConnectOpen calling sequence -- "virsh -c qemu:///system list --all" +- ``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). + (``virConnectAuthDefault``). -- virConnectOpenAuth() +- ``virConnectOpenAuth()`` - Each of the virConnectOpen APIs will first call virInitialize() and then - revector through the local "do_open():" call. + Each of the ``virConnectOpen`` APIs will first call ``virInitialize()`` and + then revector through the local "``do_open()``" call. - - virInitialize() + - ``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. + 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()) + - 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.) + - After successful return from the ``virDriverTab[]`` ``open()`` API, + attempt to find and open other drivers (network, interface, storage, etc.) -- remoteOpen() +- ``remoteOpen()`` - After a couple of URI checks, a call to doRemoteOpen() is made + 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". + 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() + - ``virNetClientRegisterAsyncIO()`` Register an I/O callback mechanism to get returned data via - virNetClientIncomingEvent() + ``virNetClientIncomingEvent()`` - - "call(...REMOTE_PROC_OPEN...)" + - ``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() + 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() + - ``virNetClientIncomingEvent()`` Receives the returned packet and processes through - virNetClientIOUpdateCallback() + ``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. + ``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(). + the ``REMOTE_PROC_OPEN`` call entry. This results in + ``remoteDispatchOpen()`` being called via the + ``virNetServerProgramDispatchCall()``. - - remoteDispatchOpen() + - ``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``. + driver to be opened. The code will then call ``virConnectOpen()`` or + ``virConnectOpenReadOnly()`` depending on the argument ``flags``. - - virConnectOpen() or virConnectOpenReadOnly() + - ``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. + The returned structure data is returned via the ``virNetServer`` + interfaces to the remote driver which then returns it to the client + application. -- 2.35.1