We call these functions a lot. A GSList is just the wrong tool for the
job. Refactor the code to use instead a sorted array everywhere.
This means, we malloc() one array for all connections instead
slice-allocate a GSList item for each. Also, sorting an array
is faster then sorting a GSList.
Technically, the GSList implementation had the same big-O runtime
complexity, but using an array is still faster. That is, sorting
an array and a GSList is both O(n*log(n)).
Actually, nm_settings_get_connections_sorted() used
g_slist_insert_sorted() instead of g_slist_sort(). That results
in O(n^2). That could have been fixed to have O(n*log(n)), but
instead refactor the code to use an array.
nm_settings_get_best_connections() has only one caller: to create
the hidden-SSID list.
Instead of having a highly specialised function (that accepts 3 ways for
filtering -- one of them broken, has one hard-coded way of sorting, and
a @max_requested argument), add a more generic nm_settings_get_connections_clone()
function.
Also invert nm_settings_sort_connections(). The two callers want
to sort descending, not ascending.
Have a proper cmp() function and a wrapper *_p_with_data() that can be
used for g_qsort_with_data().
Thus, establish a naming scheme (*_p_with_data()) for these compare
wrappers that we need all over the place. Note, we also have
nm_strcmp_p_with_data() for the same reason and later more such
functions will follow.
scan_request_cb() handles the answer from the D-Bus "Scan" method.
At that point, the scan is not yet done, it merely started. It is
wrong to already signal SCAN_DONE.
The only place where we want to signal SCAN_DONE is when we actually
receive the "ScanDone" D-Bus signal.
In the SCAN_DONE handler, NMDeviceWifi resets the flag that indicates
that a current scan request is pending. We need to first obtain the
new APs (NEW_BSS) before signalling SCAN_DONE.
Cache the value for accessing the GObject property
NM_DEVICE_WIFI_SCANNING.
Re-evaluating the property every time by checking the
supplicant interface is ugly because it might change
under the hood. It should only change if (and only if)
we emit a notify changed signal.
Also, avoid accessing
nm_supplicant_interface_get_scanning (priv->sup_iface)
without checking whether priv->sup_iface is not NULL.
When we dump a list of APs, determine one timestamp for "now",
instead of re-evaluating it every time.
This ensures that all APs are printed with the same understanding
of the current timestamp.
LOGD_WIFI_SCAN is there to avoid flodding the log with continous scan
results. It should not be used for messages related to scheduling scan
requests.
This is especially important, because LOGD_WIFI_SCAN domain is not
included in LOGD_DEFAULT.
The _LOGD() macros of NMDeviceWifi print a logging context for each
line, that is, they add a prefix with the device name.
Replace nm_wifi_ap_dump() by nm_wifi_ap_to_string() and let device
log a message about the AP.
Also, update the format for printing the AP. Now, all fields are
separated by space.
- no longer bother clearing .state and .reason when the .id
field is unset. The fields just don't matter and no user
accesses these fields when the glib source id is not set.
- unify logging and give them all a prefix "queue-state[%s, %s, %u]: ".
- drop nm_device_queued_state_peek(), it only had one caller,
thus inline the trivial check.
- make nm_device_queued_state_clear() a static function
queued_state_clear()
- rename queued_set_state() to queued_state_set().
Reorder code to be like in other source files:
- first includes and generic defines
- then various helper structs
- then GObject related declarations, with first signal and property
enums, then the private data, then the G_DEFINE_TYPE() itself.
- finally, forward declarations for functions.
We don't want to waste a full "int" size to store the @hw_addr_type
in NMDevicePrivate. Previously, that was hacked around by using guint8.
Now, instead use a bitfield which has the right type.
These two structs are only used at exactly one place: as the type
for a field in NMDevicePrivate.
Having additional structs (that are only used at one place) only
add noise. Also, there are already prior-acts of using unnamed
structs in NMDevicePrivate in case of structs that only serve
to group/namespace a set of fields.
All callers either use a static @action argument or keep a clone
of the string that lives as long as the action is pending. So,
save cloning the string.
While we still recheck-available, we want to queue a pending action to block
startup-complete. However, we have to queue that before removing the pending
action for "wait for supplicant".
<debug> [...] device[0x563abbcca400] (wlp2s0): remove_pending_action (0): 'waiting for supplicant'
<info> [...] manager: startup complete
<debug> [...] device[0x563abbcca400] (wlp2s0): add_pending_action (1): 'queued state change to disconnected'
Startup-complete means that all devices have settled in a state
and no further activation is pending. When we have a recheck-available
scheduled, we clearly should not yet declare startup-complete.
Add a new pending-action "recheck-available" to avoid:
<info> [1485520408.3920] device (wlp2s0): supplicant interface state: starting -> ready
<debug> [1485520408.3920] device[0x563abbcca400] (wlp2s0): remove_pending_action (0): 'waiting for supplicant'
<info> [1485520408.3920] manager: startup complete
<debug> [1485520408.3924] device[0x563abbcca400] (wlp2s0): add_pending_action (1): 'queued state change to disconnected'
grep-ing for '\<scanning\>' yields 42 hits under src. But only 2 are actual
references to the "scanning" GObject property of NMDeviceWifi.
Use a #define with a unique name where we mean NMDeviceWifi's property.
I think NM_CACHED_QUARK_FCN() is better because:
- the implementation is in our hand, meaning it is clear that
putting a "static" before NM_CACHED_QUARK_FCN() is guaranteed to
work -- without relying on G_DEFINE_QUARK() to be defined in a way
that this works (in fact, we currently never do that and instead
make all functions non-static).
- it does not construct function names by appending "_quark".
Thus you can grep for the entire function name and finding
the place where it is implemented.
- same with the stings, where the new macro doesn't stringify the
argument, which is less surpising. Again, now you can grep
for the string including the double quoting.
(yes, I really use grep to understand the source-code)
NM_CACHED_QUARK_FCN() is a replacement for G_DEFINE_QUARK().
G_DEFINE_QUARK() is mostly used to define GError quarks. As
such, it always appends _quark() to the function name, which
is unfavorable because it makes it harder to grep for the
definition of the function.
In general I think that macros that defined symbols by concatenating
something should be avoided because that makes it harder to locate
where the symbol was defined.
`nm` is used by "tools/create-exports-NetworkManager.sh" script.
Alloc configuring an explicit path during configure.
BINUTILS_NM=/usr/bin/nm ./configure
ip4_addr_subnets_is_secondary() should fill the list of addresses in
the same subnet also when returning FALSE, because
nm_platform_ip4_address_sync() uses it.
Fixes: 2f68a50041
_return() assigns the return value @retval and asserts that
currently no return-value is assigned -- in order not to overwrite
a once set value.
That requires, that we call _return() and exit the main-loop right
away, without possibility to call _return() again.
However, during client_properties_changed() we easily might
receive the "notify" signal multiple times, and thus call
quit_if_connected() and _return() multiple times. That would
lead to a wrong assertion failure.
Avoid that, by disconnecting the signal handler once we reach
_return().
Fixes: f7875a42b0
- use gs_free attribute
- move printing the logging cache warning inside the place
where we actuall add a new item to the cache.
It's really a minor cleanup of stuff that come to my mind reviewing the
function.
We no longer use wpa_supplicant for MAC address randomization. Instead, NetworkManager
handles it on it's own. It is actually important that supplicant does not interfere
when setting the MAC address of the device.
The code was only in effect when supplicant has a PreassocMacAddr property.
As this is a recent feature, the left-over code wasn't noticed until now.
https://mail.gnome.org/archives/networkmanager-list/2017-February/msg00003.html
Fixes: 767abfa690
libnm-core/nm-setting-bond.c:502:1: error: ‘static’ is not at beginning of declaration [-Werror=old-style-declaration]
const static struct {
^~~~~
In file included from clients/cli/common.c:32:0:
./clients/common/nm-vpn-helpers.h:27:1: error: ‘typedef’ is not at beginning of declaration [-Werror=old-style-declaration]
} typedef VpnPasswordName;
^
./src/nm-config-data.h:163:1: error: 'const' type qualifier on return type has no effect [-Werror,-Wignored-qualifiers]
const guint nm_config_data_get_connectivity_interval (const NMConfigData *config_data);
^~~~~~
Fix it by converting the macro to an inline function. It's anyway
nicer.
$ make src/src_libNetworkManagerBase_la-main-utils.lo
CC src/src_libNetworkManagerBase_la-main-utils.lo
In file included from ./shared/nm-utils/nm-macros-internal.h:29:0,
from ./shared/nm-default.h:178,
from src/main-utils.c:22:
src/main-utils.c: In function ‘nm_main_utils_setup_signals’:
./shared/nm-utils/nm-glib.h:144:36: error: comparison of unsigned expression >= 0 is always true [-Werror=type-limits]
&& glib_micro_version >= (micro))))
^
src/main-utils.c:82:6: note: in expansion of macro ‘nm_glib_check_version’
if (nm_glib_check_version (2, 36, 0)) {
^~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
Makefile:12312: recipe for target 'src/src_libNetworkManagerBase_la-main-utils.lo' failed
priv->path_cost and priv->priority can only be set as GObject properties,
which already does the same range check. Hence, the checks are never reached.
This also avoids a compiler warning:
libnm-core/nm-setting-bridge-port.c: In function ‘verify’:
libnm-core/nm-setting-bridge-port.c:132:22: error: comparison is always false due to limited range of data type [-Werror=type-limits]
if (priv->path_cost > BR_MAX_PATH_COST) {
^
The warning seems questionable and overly strict.
For now, just disable it to allow building with gcc7.
src/systemd/src/basic/time-util.c: In function ‘format_timespan’:
src/systemd/src/basic/time-util.c:509:46: error: ‘%0*lu’ directive output between 1 and 2147483648 bytes may cause result to exceed ‘INT_MAX’ [-Werror=format-truncation=]
"%s"USEC_FMT".%0*"PRI_USEC"%s",
^~~~
src/systemd/src/basic/time-util.c:509:60: note: format string is defined here
"%s"USEC_FMT".%0*"PRI_USEC"%s",
src/systemd/src/basic/time-util.c:509:46: note: directive argument in the range [0, 18446744073709551614]
"%s"USEC_FMT".%0*"PRI_USEC"%s",
^~~~
https://mail.gnome.org/archives/networkmanager-list/2017-February/msg00001.html