diff options
| author | Michael Biebl <biebl@debian.org> | 2024-12-25 20:36:29 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2024-12-25 20:36:29 +0100 |
| commit | e465722b908aa870bdc293b9a417d3c15294aa6d (patch) | |
| tree | 7c959d3b73f427d6c40522a7464eaa4531ef2f05 /docs/libnm/html/usage.html | |
| parent | 56928734cbcf1d3a02fae4f152a541df1b04e04a (diff) | |
New upstream version 1.50.1 upstream/1.50.1
Diffstat (limited to 'docs/libnm/html/usage.html')
| -rw-r--r-- | docs/libnm/html/usage.html | 276 |
1 files changed, 0 insertions, 276 deletions
diff --git a/docs/libnm/html/usage.html b/docs/libnm/html/usage.html deleted file mode 100644 index a537beeb..00000000 --- a/docs/libnm/html/usage.html +++ /dev/null @@ -1,276 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> -<title>Using libnm: libnm Reference Manual</title> -<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot"> -<link rel="home" href="index.html" title="libnm Reference Manual"> -<link rel="up" href="ref-overview.html" title="Overview"> -<link rel="prev" href="ref-overview.html" title="Overview"> -<link rel="next" href="ch02.html" title="Client Object API Reference"> -<meta name="generator" content="GTK-Doc V1.34.0 (XML mode)"> -<link rel="stylesheet" href="style.css" type="text/css"> -</head> -<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> -<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle"> -<td width="100%" align="left" class="shortcuts"></td> -<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td> -<td><a accesskey="u" href="ref-overview.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td> -<td><a accesskey="p" href="ref-overview.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td> -<td><a accesskey="n" href="ch02.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td> -</tr></table> -<div class="section"> -<div class="titlepage"><div><div><h2 class="title" style="clear: both"> -<a name="usage"></a>Using libnm</h2></div></div></div> -<div class="simplesect"> -<div class="titlepage"><div><div><h3 class="title"> -<a name="id-1.2.3.2"></a>When to use libnm</h3></div></div></div> -<p> - libnm is fairly simple to use from C. It's based on glib and GObject. - If your project uses these already you'll find integration libnm with your - project rather convenient. In fact, the <span class="command"><strong>nmcli</strong></span> tool shipped - with NetworkManager is based on libnm. - </p> -<p> - libnm should be also the way to go if your project does something non-trivial - with NetworkManager, such as manipulating the connection profiles. - That is, if you're writing a specialized networking control tool or a desktop - environment, libnm is probably the right choice. The popular desktop - environments in fact all use libnm directly or with nm-applet and - nm-connection-editor that are all based on libnm. - </p> -<p> - An alternative to use of libnm is the use of the - <a class="ulink" href="https://networkmanager.dev/docs/api/latest/spec.html" target="_top">D-Bus API</a>, - directly. This gives you larger flexibility and reduces the overhead of linking - with the libnm library. This makes sense if your task is simple and you have a good - D-Bus library at your disposal. Activating a particular connection profile - from a Python script is a good example of a task that is perfectly simple - without using libnm. - </p> -</div> -<div class="simplesect"> -<div class="titlepage"><div><div><h3 class="title"> -<a name="id-1.2.3.3"></a>How to use libnm</h3></div></div></div> -<p> - You can use the libnm's C API directly. To do so, all libnm programs need to - include <code class="filename">NetworkManager.h</code> that provides necessary definitions. - The rest of the API is documented in the reference manual. - </p> -<div class="informalexample"> - <table class="listing_frame" border="0" cellpadding="0" cellspacing="0"> - <tbody> - <tr> - <td class="listing_lines" align="right"><pre>1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12</pre></td> - <td class="listing_code"><pre class="programlisting"><span class="cp">#include</span><span class="w"> </span><span class="cpf"><glib.h></span> -<span class="cp">#include</span><span class="w"> </span><span class="cpf"><NetworkManager.h></span> - -<span class="kt">int</span> -<span class="nf">main</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">argc</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">argv</span><span class="p">[])</span> -<span class="p">{</span> -<span class="w"> </span><span class="n">NMClient</span><span class="w"> </span><span class="o">*</span><span class="n">client</span><span class="p">;</span> - -<span class="w"> </span><span class="n">client</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nm_client_new</span><span class="w"> </span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">);</span> -<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">client</span><span class="p">)</span> -<span class="w"> </span><span class="n">g_print</span><span class="w"> </span><span class="p">(</span><span class="s">"NetworkManager version: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">nm_client_get_version</span><span class="w"> </span><span class="p">(</span><span class="n">client</span><span class="p">));</span> -<span class="p">}</span></pre></td> - </tr> - </tbody> - </table> -</div> - -<p> - Use <span class="command"><strong>pkg-config</strong></span> for <code class="varname">libnm</code> to discover the necessary - compiler flags. - </p> -<pre class="screen"><code class="prompt">$ </code><strong class="userinput"><code>cc $(pkg-config --libs --cflags libnm) -o hello-nm hello-nm.c</code></strong> - <code class="prompt">$ </code><strong class="userinput"><code>./hello-nm</code></strong> - NetworkManager version: 1.50.0 - - <code class="prompt">$ </code></pre> -<p> - Utilize the <code class="varname">PKG_CHECK_MODULES</code> macro to integrate with an - autoconf-based build system. It's also recommended to use - <code class="varname">NM_VERSION_MIN_REQUIRED</code> and <code class="varname">NM_VERSION_MAX_ALLOWED</code> - macros to tell libnm headers which API version does your application need to work with. - If you use them, the compiler will warn you when you use functionality that is not - available in the versions you specified. - </p> -<div class="informalexample"> - <table class="listing_frame" border="0" cellpadding="0" cellspacing="0"> - <tbody> - <tr> - <td class="listing_lines" align="right"><pre>1 -2 -3</pre></td> - <td class="listing_code"><pre class="programlisting"><span class="n">PKG_CHECK_MODULES</span><span class="p">(</span><span class="n">LIBNM</span><span class="p">,</span><span class="w"> </span><span class="n">libnm</span><span class="w"> </span><span class="o">>=</span><span class="w"> </span><span class="mf">1.8</span><span class="p">)</span> -<span class="n">LIBNM_CFLAGS</span><span class="o">=</span><span class="s">"$LIBNM_CFLAGS -DNM_VERSION_MIN_REQUIRED=NM_VERSION_1_8"</span> -<span class="n">LIBNM_CFLAGS</span><span class="o">=</span><span class="s">"$LIBNM_CFLAGS -DNM_VERSION_MAX_ALLOWED=NM_VERSION_1_8"</span></pre></td> - </tr> - </tbody> - </table> -</div> - -<p> - You can use libnm from other languages than C with the use of GObject introspection. - This includes Perl, Python, Javascript, Lua, Ruby and more. The example below shows what the - typical libnm use in Python would look like. - </p> -<div class="informalexample"> - <table class="listing_frame" border="0" cellpadding="0" cellspacing="0"> - <tbody> - <tr> - <td class="listing_lines" align="right"><pre>1 -2 -3 -4 -5 -6</pre></td> - <td class="listing_code"><pre class="programlisting"><span class="n">import</span><span class="w"> </span><span class="n">gi</span> -<span class="n">gi</span><span class="p">.</span><span class="n">require_version</span><span class="p">(</span><span class="err">'</span><span class="n">NM</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="mf">1.0</span><span class="err">'</span><span class="p">)</span> -<span class="n">from</span><span class="w"> </span><span class="n">gi</span><span class="p">.</span><span class="n">repository</span><span class="w"> </span><span class="n">import</span><span class="w"> </span><span class="n">NM</span> - -<span class="n">client</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">NM</span><span class="p">.</span><span class="n">Client</span><span class="p">.</span><span class="n">new</span><span class="p">(</span><span class="n">None</span><span class="p">)</span> -<span class="n">print</span><span class="w"> </span><span class="p">(</span><span class="s">"NetworkManager version "</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">get_version</span><span class="p">())</span></pre></td> - </tr> - </tbody> - </table> -</div> - -<p> - There's <a class="ulink" href="https://lazka.github.io/pgi-docs/#NM-1.0" target="_top">NM-1.0 Python API Reference</a> - maintained a third party that is generated from the introspection metadata. - </p> -<p> - In general, the C API documentation applies to the use GObject introspection - from other languages, with the calling convention respecting the language's - customs. Consult the source tree for - <a class="ulink" href="https://gitlab.freedesktop.org/NetworkManager/NetworkManager/tree/main/examples" target="_top">some examples</a>. - </p> -</div> -<div class="simplesect"> -<div class="titlepage"><div><div><h3 class="title"> -<a name="sync-api"></a>Synchronous API in libnm</h3></div></div></div> -<p> - Libnm contains some synchronous API. This API basically makes a blocking - D-Bus call (g_dbus_connection_call_sync()) and is now deprecated. - </p> -<p> - Note that D-Bus is fundamentally asynchronous. Doing blocking calls - on top of D-Bus is odd, especially for libnm's NMClient. That is because - NMClient essentially is a client-side cache of the objects of the D-Bus - interface. This cache should be filled exclusively by (asynchronous) D-Bus - events. So, making a blocking D-Bus call means to wait for a response and - return it, while queuing everything that happens in between. Basically, - there are three options how a synchronous API on NMClient could behave: - </p> -<div class="orderedlist"><ol class="orderedlist" type="1"> -<li class="listitem"><p> - The call basically calls g_dbus_connection_call_sync(). This means - that libnm sends a D-Bus request via GDBusConnection, and blockingly - waits for the response. All D-Bus messages that get received in the - meantime are queued in the GMainContext that belongs to NMClient. - That means, none of these D-Bus events are processed until we - iterate the GMainContext after the call returns. The effect is, - that NMClient (and all cached objects in there) are unaffected by - the D-Bus request. - Most of the synchronous API calls in libnm are of this kind. - The problem is that the strict ordering of D-Bus events gets - violated. - For some API this is not an immediate problem. Take for example - nm_device_wifi_request_scan(). The call merely blockingly tells - NetworkManager to start scanning, but since NetworkManager's D-Bus - API does not directly expose any state that tells whether we are - currently scanning, this out of order processing of the D-Bus - request is a small issue. - The problem is more obvious for nm_client_networking_set_enabled(). - After calling it, NM_CLIENT_NETWORKING_ENABLED is still unaffected - and unchanged, because the PropertiesChanged signal from D-Bus - is not yet processed. - This means, while you make such a blocking call, NMClient's state - does not change. But usually you perform the synchronous call - to change some state. In this form, the blocking call is not useful, - because NMClient only changes the state after iterating the GMainContext, - and not after the blocking call returns. - </p></li> -<li class="listitem"><p> - Like 1), but after making the blocking g_dbus_connection_call_sync(), - update the NMClient cache artificially. This is what - nm_manager_check_connectivity() does, to "fix" bgo#784629. - This also has the problem of out-of-order events, but it kinda - solves the problem of not changing the state during the blocking - call. But it does so by hacking the state of the cache. I think - this is really wrong because the state should only be updated from - the ordered stream of D-Bus messages. When libnm decides to modify - the state, there are already D-Bus messages queued that affect this - very state. - </p></li> -<li class="listitem"><p> - Instead of calling g_dbus_connection_call_sync(), use the - asynchronous g_dbus_connection_call(). If we would use a separate - GMainContext for all D-Bus related calls, we could ensure that - while we block for the response, we iterate the internal main context. - This might be nice, because all events are processed in order and - after the blocking call returns, the NMClient state is up to date. - The are problems however: current blocking API does not do this, - so it's a significant change in behavior. Also, it might be - unexpected to the user that during the blocking call the entire - content of NMClient's cache might change and all pointers to the - cache might be invalidated. Also, of course NMClient would invoke - signals for all the changes that happen. - Another problem is that this would be more effort to implement - and it involves a small performance overhead for all D-Bus related - calls (because we have to serialize all events in an internal - GMainContext first and then invoke them on the caller's context). - Also, if the users wants this, they could implement it themself - using their own extra GMainContext and the asynchronous API. - </p></li> -</ol></div> -<p> - - See also <a class="ulink" href="https://smcv.pseudorandom.co.uk/2008/11/nonblocking/" target="_top">this blog</a> - for why blocking calls are wrong. - </p> -<p> - All possible behaviors for synchronous API have severe behavioural - issues and thus such API is deprecated. Note that "deprecated" here does not - mean that the API is going to be removed. Libnm does not break API. The - user may: - - </p> -<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> -<li class="listitem"><p> - Continue to use this API. It's deprecated, awkward and discouraged, - but if it works for you, that's fine. - </p></li> -<li class="listitem"><p> - Use asynchronous API. That's the only sensible way to use D-Bus. - If libnm lacks a certain asynchronous counterpart, it should be - added. - </p></li> -<li class="listitem"><p> - Use GDBusConnection directly. There really isn't anything wrong - with D-Bus or GDBusConnection. This deprecated API is just a wrapper - around g_dbus_connection_call_sync(). You may call it directly - without feeling dirty. - </p></li> -</ul></div> -<p> - </p> -</div> -</div> -<div class="footer"> -<hr>Generated by GTK-Doc V1.34.0</div> -</body> -</html> \ No newline at end of file |