libnm: merge branch 'th/secret-agent-register-race'

https://bugzilla.redhat.com/show_bug.cgi?id=1781084

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/364

(cherry picked from commit 85042e7244)
This commit is contained in:
Thomas Haller
2019-12-16 18:44:41 +01:00
5 changed files with 356 additions and 184 deletions

View File

@@ -8,6 +8,7 @@
#include "c-list/src/c-list.h"
#include "nm-glib-aux/nm-ref-string.h"
#include "nm-glib-aux/nm-logging-fwd.h"
#include "nm-types.h"
#include "nm-object.h"
#include "nm-client.h"
@@ -66,6 +67,18 @@ typedef enum {
| NML_DBUS_LOG_LEVEL_WARN,
} NMLDBusLogLevel;
#undef _LOGL_TRACE
#undef _LOGL_DEBUG
#undef _LOGL_INFO
#undef _LOGL_WARN
#undef _LOGL_ERR
#define _LOGL_TRACE NML_DBUS_LOG_LEVEL_TRACE
#define _LOGL_DEBUG NML_DBUS_LOG_LEVEL_DEBUG
#define _LOGL_INFO NML_DBUS_LOG_LEVEL_INFO
#define _LOGL_WARN NML_DBUS_LOG_LEVEL_WARN
#define _LOGL_ERR NML_DBUS_LOG_LEVEL_ERR
extern volatile int _nml_dbus_log_level;
int _nml_dbus_log_level_init (void);

View File

@@ -7,16 +7,20 @@
#include "nm-secret-agent-old.h"
#include "c-list/src/c-list.h"
#include "nm-core-internal.h"
#include "nm-dbus-helpers.h"
#include "nm-dbus-interface.h"
#include "nm-enum-types.h"
#include "nm-dbus-helpers.h"
#include "nm-glib-aux/nm-dbus-aux.h"
#include "nm-glib-aux/nm-time-utils.h"
#include "nm-simple-connection.h"
#include "nm-core-internal.h"
#include "c-list/src/c-list.h"
#include "introspection/org.freedesktop.NetworkManager.SecretAgent.h"
#include "introspection/org.freedesktop.NetworkManager.AgentManager.h"
#define REGISTER_RETRY_TIMEOUT_MSEC 2000
/*****************************************************************************/
typedef struct {
@@ -45,8 +49,10 @@ typedef struct {
NMSecretAgentCapabilities capabilities;
gint64 registering_timeout_msec;
guint registering_try_count;
bool registered:1;
bool registering:1;
bool session_bus:1;
bool auto_register:1;
bool suppress_auto:1;
@@ -64,6 +70,20 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMSecretAgentOld, nm_secret_agent_old, G_TYPE_
/*****************************************************************************/
#define _NMLOG(level, ...) \
NML_DBUS_LOG((level), \
"secret-agent["NM_HASH_OBFUSCATE_PTR_FMT"]: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
NM_HASH_OBFUSCATE_PTR (self) \
_NM_UTILS_MACRO_REST (__VA_ARGS__))
/*****************************************************************************/
static void _register_call_cb (GObject *proxy,
GAsyncResult *result,
gpointer user_data);
/*****************************************************************************/
static void
_internal_unregister (NMSecretAgentOld *self)
{
@@ -72,7 +92,7 @@ _internal_unregister (NMSecretAgentOld *self)
if (priv->registered) {
g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent));
priv->registered = FALSE;
priv->registering = FALSE;
priv->registering_timeout_msec = 0;
_notify (self, PROP_REGISTERED);
}
}
@@ -97,7 +117,7 @@ should_auto_register (NMSecretAgentOld *self)
return ( priv->auto_register
&& !priv->suppress_auto
&& !priv->registered
&& !priv->registering);
&& priv->registering_timeout_msec == 0);
}
static void
@@ -111,6 +131,9 @@ name_owner_changed (GObject *proxy,
GetSecretsInfo *info;
owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (proxy));
_LOGT ("name owner changed: %s%s%s", NM_PRINT_FMT_QUOTE_STRING (owner));
if (owner) {
if (should_auto_register (self))
nm_secret_agent_old_register_async (self, NULL, NULL, NULL);
@@ -455,6 +478,23 @@ check_nm_running (NMSecretAgentOld *self, GError **error)
/*****************************************************************************/
static gboolean
_register_should_retry (NMSecretAgentOldPrivate *priv,
guint *out_timeout_msec)
{
guint timeout_msec;
if (priv->registering_try_count++ == 0)
timeout_msec = 0;
else if (nm_utils_get_monotonic_timestamp_ms () < priv->registering_timeout_msec)
timeout_msec = 1ULL * (1ULL << NM_MIN (7, priv->registering_try_count));
else
return FALSE;
*out_timeout_msec = timeout_msec;
return TRUE;
}
/**
* nm_secret_agent_old_register:
* @self: a #NMSecretAgentOld
@@ -483,7 +523,7 @@ nm_secret_agent_old_register (NMSecretAgentOld *self,
priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
g_return_val_if_fail (priv->registered == FALSE, FALSE);
g_return_val_if_fail (priv->registering == FALSE, FALSE);
g_return_val_if_fail (priv->registering_timeout_msec == 0, FALSE);
g_return_val_if_fail (priv->bus != NULL, FALSE);
g_return_val_if_fail (priv->manager_proxy != NULL, FALSE);
@@ -505,98 +545,178 @@ nm_secret_agent_old_register (NMSecretAgentOld *self,
error))
return FALSE;
priv->registering = TRUE;
if (nmdbus_agent_manager_call_register_with_capabilities_sync (priv->manager_proxy,
priv->registering_timeout_msec = nm_utils_get_monotonic_timestamp_ms () + REGISTER_RETRY_TIMEOUT_MSEC;
priv->registering_try_count = 0;
while (TRUE) {
gs_free_error GError *local = NULL;
gs_free char *dbus_error = NULL;
nmdbus_agent_manager_call_register_with_capabilities_sync (priv->manager_proxy,
priv->identifier,
priv->capabilities,
cancellable, NULL))
goto success;
cancellable,
&local);
if (nm_dbus_error_is (local, NM_DBUS_ERROR_NAME_UNKNOWN_METHOD)) {
guint timeout_msec;
/* Might be an old NetworkManager that doesn't support capabilities;
* fall back to old Register() method instead.
*/
if (nmdbus_agent_manager_call_register_sync (priv->manager_proxy,
priv->identifier,
cancellable, error))
goto success;
if (_register_should_retry (priv, &timeout_msec)) {
if (timeout_msec > 0)
g_usleep (timeout_msec * 1000LU);
continue;
}
}
/* Failure */
priv->registering = FALSE;
priv->registering_timeout_msec = 0;
if (local) {
g_dbus_error_strip_remote_error (local);
g_propagate_error (error, g_steal_pointer (&local));
_internal_unregister (self);
return FALSE;
}
success:
priv->registering = FALSE;
priv->registered = TRUE;
_notify (self, PROP_REGISTERED);
return TRUE;
}
}
/*****************************************************************************/
typedef struct {
GCancellable *cancellable;
GSource *timeout_source;
gulong cancellable_signal_id;
} RegisterData;
static void
reg_result (NMSecretAgentOld *self, GSimpleAsyncResult *simple, GError *error)
_register_data_free (RegisterData *register_data)
{
NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
_nm_unused gs_unref_object GSimpleAsyncResult *simple_free = simple;
priv->registering = FALSE;
if (error) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
/* If registration failed we shouldn't expose ourselves on the bus */
_internal_unregister (self);
} else {
priv->registered = TRUE;
_notify (self, PROP_REGISTERED);
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
g_simple_async_result_complete (simple);
nm_clear_g_cancellable_disconnect (register_data->cancellable, &register_data->cancellable_signal_id);
nm_clear_g_source_inst (&register_data->timeout_source);
g_clear_object (&register_data->cancellable);
nm_g_slice_free (register_data);
}
static gboolean
_register_retry_cb (gpointer user_data)
{
gs_unref_object GTask *task = user_data;
NMSecretAgentOld *self = g_task_get_source_object (task);
NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
GCancellable *cancellable;
_LOGT ("register: retry registration...");
g_task_set_task_data (task, NULL, NULL);
cancellable = g_task_get_cancellable (task);
nmdbus_agent_manager_call_register_with_capabilities (priv->manager_proxy,
priv->identifier,
priv->capabilities,
cancellable,
_register_call_cb,
g_steal_pointer (&task));
return G_SOURCE_REMOVE;
}
static void
reg_request_cb (GObject *proxy,
GAsyncResult *result,
_register_cancelled_cb (GCancellable *cancellable,
gpointer user_data)
{
GSimpleAsyncResult *simple = user_data;
NMSecretAgentOld *self;
gs_unref_object GTask *task = user_data;
NMSecretAgentOld *self = g_task_get_source_object (task);
RegisterData *register_data = g_task_get_task_data (task);
GError *error = NULL;
self = NM_SECRET_AGENT_OLD (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
g_object_unref (self); /* drop extra ref added by get_source_object() */
nm_clear_g_signal_handler (register_data->cancellable, &register_data->cancellable_signal_id);
g_task_set_task_data (task, NULL, NULL);
if (!nmdbus_agent_manager_call_register_finish (NMDBUS_AGENT_MANAGER (proxy), result, &error))
g_dbus_error_strip_remote_error (error);
reg_result (self, simple, error);
_LOGT ("register: registration cancelled. Stop waiting...");
nm_utils_error_set_cancelled (&error, FALSE, NULL);
g_task_return_error (task, error);
}
static void
reg_with_caps_cb (GObject *proxy,
_register_call_cb (GObject *proxy,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *simple = user_data;
NMSecretAgentOld *self;
NMSecretAgentOldPrivate *priv;
gs_unref_object GTask *task = user_data;
NMSecretAgentOld *self = g_task_get_source_object (task);
NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
gs_free_error GError *error = NULL;
self = NM_SECRET_AGENT_OLD (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
g_object_unref (self); /* drop extra ref added by get_source_object() */
nmdbus_agent_manager_call_register_with_capabilities_finish (NMDBUS_AGENT_MANAGER (proxy), result, &error);
priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
if (nm_utils_error_is_cancelled (error, FALSE)) {
/* FIXME: we should unregister right away. For now, don't do that, likely the
* application is anyway about to exit. */
} else if (nm_dbus_error_is (error, NM_DBUS_ERROR_NAME_UNKNOWN_METHOD)) {
gboolean already_cancelled = FALSE;
RegisterData *register_data;
guint timeout_msec;
if (nmdbus_agent_manager_call_register_with_capabilities_finish (NMDBUS_AGENT_MANAGER (proxy), result, NULL)) {
reg_result (self, simple, NULL);
if (!_register_should_retry (priv, &timeout_msec))
goto done;
_LOGT ("register: registration failed with error \"%s\". Retry in %u msec...", error->message, timeout_msec);
nm_assert (G_IS_TASK (task));
nm_assert (!g_task_get_task_data (task));
register_data = g_slice_new (RegisterData);
*register_data = (RegisterData) {
.cancellable = nm_g_object_ref (g_task_get_cancellable (task)),
};
g_task_set_task_data (task,
register_data,
(GDestroyNotify) _register_data_free);
if (register_data->cancellable) {
register_data->cancellable_signal_id = g_cancellable_connect (register_data->cancellable,
G_CALLBACK (_register_cancelled_cb),
task,
NULL);
if (register_data->cancellable_signal_id == 0)
already_cancelled = TRUE;
}
if (!already_cancelled) {
register_data->timeout_source = nm_g_source_attach (nm_g_timeout_source_new (timeout_msec,
g_task_get_priority (task),
_register_retry_cb,
task,
NULL),
g_task_get_context (task));
}
/* The reference of the task is owned by the _register_cancelled_cb and _register_retry_cb actions.
* Whichever completes first, will consume it. */
g_steal_pointer (&task);
return;
}
/* Might be an old NetworkManager that doesn't support capabilities;
* fall back to old Register() method instead.
*/
nmdbus_agent_manager_call_register (priv->manager_proxy,
priv->identifier,
NULL, reg_request_cb, simple);
done:
priv->registering_timeout_msec = 0;
if (error) {
_LOGT ("register: registration failed with error \"%s\"", error->message);
g_dbus_error_strip_remote_error (error);
_internal_unregister (self);
g_task_return_error (task, g_steal_pointer (&error));
return;
}
_LOGT ("register: registration succeeded");
priv->registered = TRUE;
_notify (self, PROP_REGISTERED);
g_task_return_boolean (task, TRUE);
}
/**
@@ -621,15 +741,15 @@ nm_secret_agent_old_register_async (NMSecretAgentOld *self,
{
NMSecretAgentOldPrivate *priv;
NMSecretAgentOldClass *class;
gs_unref_object GSimpleAsyncResult *simple = NULL;
GError *error = NULL;
gs_unref_object GTask *task = NULL;
gs_free_error GError *error = NULL;
g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
g_return_if_fail (priv->registered == FALSE);
g_return_if_fail (priv->registering == FALSE);
g_return_if_fail (priv->registering_timeout_msec == 0);
g_return_if_fail (priv->bus != NULL);
g_return_if_fail (priv->manager_proxy != NULL);
@@ -639,14 +759,11 @@ nm_secret_agent_old_register_async (NMSecretAgentOld *self,
g_return_if_fail (class->save_secrets != NULL);
g_return_if_fail (class->delete_secrets != NULL);
simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
nm_secret_agent_old_register_async);
if (cancellable)
g_simple_async_result_set_check_cancellable (simple, cancellable);
task = nm_g_task_new (self, cancellable, nm_secret_agent_old_register_async, callback, user_data);
if (!check_nm_running (self, &error)) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete_in_idle (simple);
_LOGT ("register: failed because NetworkManager is not running");
g_task_return_error (task, g_steal_pointer (&error));
return;
}
@@ -655,20 +772,22 @@ nm_secret_agent_old_register_async (NMSecretAgentOld *self,
priv->bus,
NM_DBUS_PATH_SECRET_AGENT,
&error)) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete_in_idle (simple);
_LOGT ("register: failed to export D-Bus service: %s", error->message);
g_task_return_error (task, g_steal_pointer (&error));
return;
}
priv->suppress_auto = FALSE;
priv->registering = TRUE;
priv->registering_timeout_msec = nm_utils_get_monotonic_timestamp_ms () + REGISTER_RETRY_TIMEOUT_MSEC;
priv->registering_try_count = 0;
_LOGT ("register: starting asynchronous registration...");
nmdbus_agent_manager_call_register_with_capabilities (priv->manager_proxy,
priv->identifier,
priv->capabilities,
NULL,
reg_with_caps_cb,
g_steal_pointer (&simple));
cancellable,
_register_call_cb,
g_steal_pointer (&task));
}
/**
@@ -686,12 +805,10 @@ nm_secret_agent_old_register_finish (NMSecretAgentOld *self,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), nm_secret_agent_old_register_async), FALSE);
g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE);
g_return_val_if_fail (nm_g_task_is_valid (result, self, nm_secret_agent_old_register_async), FALSE);
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
return FALSE;
else
return TRUE;
return g_task_propagate_boolean (G_TASK (result), error);
}
/**
@@ -734,24 +851,21 @@ nm_secret_agent_old_unregister (NMSecretAgentOld *self,
static void
unregister_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
{
gs_unref_object GSimpleAsyncResult *simple = user_data;
NMSecretAgentOld *self;
GError *error = NULL;
self = NM_SECRET_AGENT_OLD (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
g_object_unref (self); /* drop extra ref added by get_source_object() */
gs_unref_object GTask *task = user_data;
NMSecretAgentOld *self = g_task_get_source_object (task);
gs_free_error GError *error = NULL;
_internal_unregister (self);
if (nmdbus_agent_manager_call_unregister_finish (NMDBUS_AGENT_MANAGER (proxy),
result, &error))
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
else {
if (!nmdbus_agent_manager_call_unregister_finish (NMDBUS_AGENT_MANAGER (proxy),
result,
&error)) {
g_dbus_error_strip_remote_error (error);
g_simple_async_result_take_error (simple, error);
g_task_return_error (task, g_steal_pointer (&error));
return;
}
g_simple_async_result_complete (simple);
g_task_return_boolean (task, TRUE);
}
/**
@@ -772,8 +886,8 @@ nm_secret_agent_old_unregister_async (NMSecretAgentOld *self,
gpointer user_data)
{
NMSecretAgentOldPrivate *priv;
gs_unref_object GSimpleAsyncResult *simple = NULL;
GError *error = NULL;
gs_unref_object GTask *task = NULL;
gs_free_error GError *error = NULL;
g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
@@ -782,14 +896,10 @@ nm_secret_agent_old_unregister_async (NMSecretAgentOld *self,
g_return_if_fail (priv->bus != NULL);
g_return_if_fail (priv->manager_proxy != NULL);
simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
nm_secret_agent_old_unregister_async);
if (cancellable)
g_simple_async_result_set_check_cancellable (simple, cancellable);
task = nm_g_task_new (self, cancellable, nm_secret_agent_old_unregister_async, callback, user_data);
if (!check_nm_running (self, &error)) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete_in_idle (simple);
g_task_return_error (task, g_steal_pointer (&error));
return;
}
@@ -798,7 +908,7 @@ nm_secret_agent_old_unregister_async (NMSecretAgentOld *self,
nmdbus_agent_manager_call_unregister (priv->manager_proxy,
cancellable,
unregister_cb,
g_steal_pointer (&simple));
g_steal_pointer (&task));
}
/**
@@ -816,12 +926,10 @@ nm_secret_agent_old_unregister_finish (NMSecretAgentOld *self,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), nm_secret_agent_old_unregister_async), FALSE);
g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE);
g_return_val_if_fail (nm_g_task_is_valid (result, self, nm_secret_agent_old_unregister_async), FALSE);
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
return FALSE;
else
return TRUE;
return g_task_propagate_boolean (G_TASK (result), error);
}
/**
@@ -1112,6 +1220,8 @@ nm_secret_agent_old_init (NMSecretAgentOld *self)
{
NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
_LOGT ("create new instance");
c_list_init (&priv->gsi_lst_head);
priv->dbus_secret_agent = nmdbus_secret_agent_skeleton_new ();
_nm_dbus_bind_properties (self, priv->dbus_secret_agent);
@@ -1129,6 +1239,8 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable);
NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
_LOGT ("init-sync");
priv->bus = g_bus_get_sync (_nm_dbus_bus_type (), cancellable, error);
if (!priv->bus)
return FALSE;
@@ -1156,9 +1268,12 @@ init_async (GAsyncInitable *initable, int io_priority,
GCancellable *cancellable, GAsyncReadyCallback callback,
gpointer user_data)
{
NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable);
GTask *task;
task = g_task_new (initable, cancellable, callback, user_data);
_LOGT ("init-async starting...");
task = g_task_new (self, cancellable, callback, user_data);
g_task_set_priority (task, io_priority);
g_bus_get (_nm_dbus_bus_type (),
@@ -1174,6 +1289,8 @@ dispose (GObject *object)
NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
GetSecretsInfo *info;
_LOGT ("disposing");
if (priv->registered) {
priv->registered = FALSE;
nm_secret_agent_old_unregister_async (self, NULL, NULL, NULL);

View File

@@ -341,3 +341,26 @@ nm_dbus_connection_call_finish_variant_strip_dbus_error_cb (GObject *source,
{
_call_finish_cb (source, result, user_data, FALSE, TRUE);
}
/*****************************************************************************/
gboolean
_nm_dbus_error_is (GError *error, ...)
{
gs_free char *dbus_error = NULL;
const char *name;
va_list ap;
dbus_error = g_dbus_error_get_remote_error (error);
if (!dbus_error)
return FALSE;
va_start (ap, error);
while ((name = va_arg (ap, const char *))) {
if (nm_streq (dbus_error, name))
return TRUE;
}
va_end (ap);
return FALSE;
}

View File

@@ -192,4 +192,17 @@ void nm_dbus_connection_call_finish_variant_strip_dbus_error_cb (GObject *source
/*****************************************************************************/
gboolean _nm_dbus_error_is (GError *error, ...) G_GNUC_NULL_TERMINATED;
#define nm_dbus_error_is(error, ...) \
({ \
GError *const _error = (error); \
\
_error && _nm_dbus_error_is (_error, __VA_ARGS__, NULL); \
})
#define NM_DBUS_ERROR_NAME_UNKNOWN_METHOD "org.freedesktop.DBus.Error.UnknownMethod"
/*****************************************************************************/
#endif /* __NM_DBUS_AUX_H__ */

View File

@@ -137,39 +137,45 @@ extern void _nm_utils_monotonic_timestamp_initialized (const struct timespec *tp
/*****************************************************************************/
#define _LOGL_TRACE LOGL_TRACE
#define _LOGL_DEBUG LOGL_DEBUG
#define _LOGL_INFO LOGL_INFO
#define _LOGL_WARN LOGL_WARN
#define _LOGL_ERR LOGL_ERR
/* This is the default definition of _NMLOG_ENABLED(). Special implementations
* might want to undef this and redefine it. */
#define _NMLOG_ENABLED(level) ( nm_logging_enabled ((level), (_NMLOG_DOMAIN)) )
#define _LOGT(...) _NMLOG (LOGL_TRACE, __VA_ARGS__)
#define _LOGD(...) _NMLOG (LOGL_DEBUG, __VA_ARGS__)
#define _LOGI(...) _NMLOG (LOGL_INFO , __VA_ARGS__)
#define _LOGW(...) _NMLOG (LOGL_WARN , __VA_ARGS__)
#define _LOGE(...) _NMLOG (LOGL_ERR , __VA_ARGS__)
#define _LOGT(...) _NMLOG (_LOGL_TRACE, __VA_ARGS__)
#define _LOGD(...) _NMLOG (_LOGL_DEBUG, __VA_ARGS__)
#define _LOGI(...) _NMLOG (_LOGL_INFO , __VA_ARGS__)
#define _LOGW(...) _NMLOG (_LOGL_WARN , __VA_ARGS__)
#define _LOGE(...) _NMLOG (_LOGL_ERR , __VA_ARGS__)
#define _LOGT_ENABLED(...) _NMLOG_ENABLED (LOGL_TRACE, ##__VA_ARGS__)
#define _LOGD_ENABLED(...) _NMLOG_ENABLED (LOGL_DEBUG, ##__VA_ARGS__)
#define _LOGI_ENABLED(...) _NMLOG_ENABLED (LOGL_INFO , ##__VA_ARGS__)
#define _LOGW_ENABLED(...) _NMLOG_ENABLED (LOGL_WARN , ##__VA_ARGS__)
#define _LOGE_ENABLED(...) _NMLOG_ENABLED (LOGL_ERR , ##__VA_ARGS__)
#define _LOGT_ENABLED(...) _NMLOG_ENABLED (_LOGL_TRACE, ##__VA_ARGS__)
#define _LOGD_ENABLED(...) _NMLOG_ENABLED (_LOGL_DEBUG, ##__VA_ARGS__)
#define _LOGI_ENABLED(...) _NMLOG_ENABLED (_LOGL_INFO , ##__VA_ARGS__)
#define _LOGW_ENABLED(...) _NMLOG_ENABLED (_LOGL_WARN , ##__VA_ARGS__)
#define _LOGE_ENABLED(...) _NMLOG_ENABLED (_LOGL_ERR , ##__VA_ARGS__)
#define _LOGT_err(errsv, ...) _NMLOG_err (errsv, LOGL_TRACE, __VA_ARGS__)
#define _LOGD_err(errsv, ...) _NMLOG_err (errsv, LOGL_DEBUG, __VA_ARGS__)
#define _LOGI_err(errsv, ...) _NMLOG_err (errsv, LOGL_INFO , __VA_ARGS__)
#define _LOGW_err(errsv, ...) _NMLOG_err (errsv, LOGL_WARN , __VA_ARGS__)
#define _LOGE_err(errsv, ...) _NMLOG_err (errsv, LOGL_ERR , __VA_ARGS__)
#define _LOGT_err(errsv, ...) _NMLOG_err (errsv, _LOGL_TRACE, __VA_ARGS__)
#define _LOGD_err(errsv, ...) _NMLOG_err (errsv, _LOGL_DEBUG, __VA_ARGS__)
#define _LOGI_err(errsv, ...) _NMLOG_err (errsv, _LOGL_INFO , __VA_ARGS__)
#define _LOGW_err(errsv, ...) _NMLOG_err (errsv, _LOGL_WARN , __VA_ARGS__)
#define _LOGE_err(errsv, ...) _NMLOG_err (errsv, _LOGL_ERR , __VA_ARGS__)
/* _LOGT() and _LOGt() both log with level TRACE, but the latter is disabled by default,
* unless building with --with-more-logging. */
#if NM_MORE_LOGGING
#define _LOGt_ENABLED(...) _NMLOG_ENABLED (LOGL_TRACE, ##__VA_ARGS__)
#define _LOGt(...) _NMLOG (LOGL_TRACE, __VA_ARGS__)
#define _LOGt_err(errsv, ...) _NMLOG_err (errsv, LOGL_TRACE, __VA_ARGS__)
#define _LOGt_ENABLED(...) _NMLOG_ENABLED (_LOGL_TRACE, ##__VA_ARGS__)
#define _LOGt(...) _NMLOG (_LOGL_TRACE, __VA_ARGS__)
#define _LOGt_err(errsv, ...) _NMLOG_err (errsv, _LOGL_TRACE, __VA_ARGS__)
#else
/* still call the logging macros to get compile time checks, but they will be optimized out. */
#define _LOGt_ENABLED(...) ( FALSE && (_NMLOG_ENABLED (LOGL_TRACE, ##__VA_ARGS__)) )
#define _LOGt(...) G_STMT_START { if (FALSE) { _NMLOG (LOGL_TRACE, __VA_ARGS__); } } G_STMT_END
#define _LOGt_err(errsv, ...) G_STMT_START { if (FALSE) { _NMLOG_err (errsv, LOGL_TRACE, __VA_ARGS__); } } G_STMT_END
#define _LOGt_ENABLED(...) ( FALSE && (_NMLOG_ENABLED (_LOGL_TRACE, ##__VA_ARGS__)) )
#define _LOGt(...) G_STMT_START { if (FALSE) { _NMLOG (_LOGL_TRACE, __VA_ARGS__); } } G_STMT_END
#define _LOGt_err(errsv, ...) G_STMT_START { if (FALSE) { _NMLOG_err (errsv, _LOGL_TRACE, __VA_ARGS__); } } G_STMT_END
#endif
/*****************************************************************************/
@@ -183,64 +189,64 @@ extern void _nm_utils_monotonic_timestamp_initialized (const struct timespec *tp
#define _NMLOG2_ENABLED(level) ( nm_logging_enabled ((level), (_NMLOG2_DOMAIN)) )
#define _LOG2T(...) _NMLOG2 (LOGL_TRACE, __VA_ARGS__)
#define _LOG2D(...) _NMLOG2 (LOGL_DEBUG, __VA_ARGS__)
#define _LOG2I(...) _NMLOG2 (LOGL_INFO , __VA_ARGS__)
#define _LOG2W(...) _NMLOG2 (LOGL_WARN , __VA_ARGS__)
#define _LOG2E(...) _NMLOG2 (LOGL_ERR , __VA_ARGS__)
#define _LOG2T(...) _NMLOG2 (_LOGL_TRACE, __VA_ARGS__)
#define _LOG2D(...) _NMLOG2 (_LOGL_DEBUG, __VA_ARGS__)
#define _LOG2I(...) _NMLOG2 (_LOGL_INFO , __VA_ARGS__)
#define _LOG2W(...) _NMLOG2 (_LOGL_WARN , __VA_ARGS__)
#define _LOG2E(...) _NMLOG2 (_LOGL_ERR , __VA_ARGS__)
#define _LOG2T_ENABLED(...) _NMLOG2_ENABLED (LOGL_TRACE, ##__VA_ARGS__)
#define _LOG2D_ENABLED(...) _NMLOG2_ENABLED (LOGL_DEBUG, ##__VA_ARGS__)
#define _LOG2I_ENABLED(...) _NMLOG2_ENABLED (LOGL_INFO , ##__VA_ARGS__)
#define _LOG2W_ENABLED(...) _NMLOG2_ENABLED (LOGL_WARN , ##__VA_ARGS__)
#define _LOG2E_ENABLED(...) _NMLOG2_ENABLED (LOGL_ERR , ##__VA_ARGS__)
#define _LOG2T_ENABLED(...) _NMLOG2_ENABLED (_LOGL_TRACE, ##__VA_ARGS__)
#define _LOG2D_ENABLED(...) _NMLOG2_ENABLED (_LOGL_DEBUG, ##__VA_ARGS__)
#define _LOG2I_ENABLED(...) _NMLOG2_ENABLED (_LOGL_INFO , ##__VA_ARGS__)
#define _LOG2W_ENABLED(...) _NMLOG2_ENABLED (_LOGL_WARN , ##__VA_ARGS__)
#define _LOG2E_ENABLED(...) _NMLOG2_ENABLED (_LOGL_ERR , ##__VA_ARGS__)
#define _LOG2T_err(errsv, ...) _NMLOG2_err (errsv, LOGL_TRACE, __VA_ARGS__)
#define _LOG2D_err(errsv, ...) _NMLOG2_err (errsv, LOGL_DEBUG, __VA_ARGS__)
#define _LOG2I_err(errsv, ...) _NMLOG2_err (errsv, LOGL_INFO , __VA_ARGS__)
#define _LOG2W_err(errsv, ...) _NMLOG2_err (errsv, LOGL_WARN , __VA_ARGS__)
#define _LOG2E_err(errsv, ...) _NMLOG2_err (errsv, LOGL_ERR , __VA_ARGS__)
#define _LOG2T_err(errsv, ...) _NMLOG2_err (errsv, _LOGL_TRACE, __VA_ARGS__)
#define _LOG2D_err(errsv, ...) _NMLOG2_err (errsv, _LOGL_DEBUG, __VA_ARGS__)
#define _LOG2I_err(errsv, ...) _NMLOG2_err (errsv, _LOGL_INFO , __VA_ARGS__)
#define _LOG2W_err(errsv, ...) _NMLOG2_err (errsv, _LOGL_WARN , __VA_ARGS__)
#define _LOG2E_err(errsv, ...) _NMLOG2_err (errsv, _LOGL_ERR , __VA_ARGS__)
#if NM_MORE_LOGGING
#define _LOG2t_ENABLED(...) _NMLOG2_ENABLED (LOGL_TRACE, ##__VA_ARGS__)
#define _LOG2t(...) _NMLOG2 (LOGL_TRACE, __VA_ARGS__)
#define _LOG2t_err(errsv, ...) _NMLOG2_err (errsv, LOGL_TRACE, __VA_ARGS__)
#define _LOG2t_ENABLED(...) _NMLOG2_ENABLED (_LOGL_TRACE, ##__VA_ARGS__)
#define _LOG2t(...) _NMLOG2 (_LOGL_TRACE, __VA_ARGS__)
#define _LOG2t_err(errsv, ...) _NMLOG2_err (errsv, _LOGL_TRACE, __VA_ARGS__)
#else
/* still call the logging macros to get compile time checks, but they will be optimized out. */
#define _LOG2t_ENABLED(...) ( FALSE && (_NMLOG2_ENABLED (LOGL_TRACE, ##__VA_ARGS__)) )
#define _LOG2t(...) G_STMT_START { if (FALSE) { _NMLOG2 (LOGL_TRACE, __VA_ARGS__); } } G_STMT_END
#define _LOG2t_err(errsv, ...) G_STMT_START { if (FALSE) { _NMLOG2_err (errsv, LOGL_TRACE, __VA_ARGS__); } } G_STMT_END
#define _LOG2t_ENABLED(...) ( FALSE && (_NMLOG2_ENABLED (_LOGL_TRACE, ##__VA_ARGS__)) )
#define _LOG2t(...) G_STMT_START { if (FALSE) { _NMLOG2 (_LOGL_TRACE, __VA_ARGS__); } } G_STMT_END
#define _LOG2t_err(errsv, ...) G_STMT_START { if (FALSE) { _NMLOG2_err (errsv, _LOGL_TRACE, __VA_ARGS__); } } G_STMT_END
#endif
#define _NMLOG3_ENABLED(level) ( nm_logging_enabled ((level), (_NMLOG3_DOMAIN)) )
#define _LOG3T(...) _NMLOG3 (LOGL_TRACE, __VA_ARGS__)
#define _LOG3D(...) _NMLOG3 (LOGL_DEBUG, __VA_ARGS__)
#define _LOG3I(...) _NMLOG3 (LOGL_INFO , __VA_ARGS__)
#define _LOG3W(...) _NMLOG3 (LOGL_WARN , __VA_ARGS__)
#define _LOG3E(...) _NMLOG3 (LOGL_ERR , __VA_ARGS__)
#define _LOG3T(...) _NMLOG3 (_LOGL_TRACE, __VA_ARGS__)
#define _LOG3D(...) _NMLOG3 (_LOGL_DEBUG, __VA_ARGS__)
#define _LOG3I(...) _NMLOG3 (_LOGL_INFO , __VA_ARGS__)
#define _LOG3W(...) _NMLOG3 (_LOGL_WARN , __VA_ARGS__)
#define _LOG3E(...) _NMLOG3 (_LOGL_ERR , __VA_ARGS__)
#define _LOG3T_ENABLED(...) _NMLOG3_ENABLED (LOGL_TRACE, ##__VA_ARGS__)
#define _LOG3D_ENABLED(...) _NMLOG3_ENABLED (LOGL_DEBUG, ##__VA_ARGS__)
#define _LOG3I_ENABLED(...) _NMLOG3_ENABLED (LOGL_INFO , ##__VA_ARGS__)
#define _LOG3W_ENABLED(...) _NMLOG3_ENABLED (LOGL_WARN , ##__VA_ARGS__)
#define _LOG3E_ENABLED(...) _NMLOG3_ENABLED (LOGL_ERR , ##__VA_ARGS__)
#define _LOG3T_ENABLED(...) _NMLOG3_ENABLED (_LOGL_TRACE, ##__VA_ARGS__)
#define _LOG3D_ENABLED(...) _NMLOG3_ENABLED (_LOGL_DEBUG, ##__VA_ARGS__)
#define _LOG3I_ENABLED(...) _NMLOG3_ENABLED (_LOGL_INFO , ##__VA_ARGS__)
#define _LOG3W_ENABLED(...) _NMLOG3_ENABLED (_LOGL_WARN , ##__VA_ARGS__)
#define _LOG3E_ENABLED(...) _NMLOG3_ENABLED (_LOGL_ERR , ##__VA_ARGS__)
#define _LOG3T_err(errsv, ...) _NMLOG3_err (errsv, LOGL_TRACE, __VA_ARGS__)
#define _LOG3D_err(errsv, ...) _NMLOG3_err (errsv, LOGL_DEBUG, __VA_ARGS__)
#define _LOG3I_err(errsv, ...) _NMLOG3_err (errsv, LOGL_INFO , __VA_ARGS__)
#define _LOG3W_err(errsv, ...) _NMLOG3_err (errsv, LOGL_WARN , __VA_ARGS__)
#define _LOG3E_err(errsv, ...) _NMLOG3_err (errsv, LOGL_ERR , __VA_ARGS__)
#define _LOG3T_err(errsv, ...) _NMLOG3_err (errsv, _LOGL_TRACE, __VA_ARGS__)
#define _LOG3D_err(errsv, ...) _NMLOG3_err (errsv, _LOGL_DEBUG, __VA_ARGS__)
#define _LOG3I_err(errsv, ...) _NMLOG3_err (errsv, _LOGL_INFO , __VA_ARGS__)
#define _LOG3W_err(errsv, ...) _NMLOG3_err (errsv, _LOGL_WARN , __VA_ARGS__)
#define _LOG3E_err(errsv, ...) _NMLOG3_err (errsv, _LOGL_ERR , __VA_ARGS__)
#if NM_MORE_LOGGING
#define _LOG3t_ENABLED(...) _NMLOG3_ENABLED (LOGL_TRACE, ##__VA_ARGS__)
#define _LOG3t(...) _NMLOG3 (LOGL_TRACE, __VA_ARGS__)
#define _LOG3t_err(errsv, ...) _NMLOG3_err (errsv, LOGL_TRACE, __VA_ARGS__)
#define _LOG3t_ENABLED(...) _NMLOG3_ENABLED (_LOGL_TRACE, ##__VA_ARGS__)
#define _LOG3t(...) _NMLOG3 (_LOGL_TRACE, __VA_ARGS__)
#define _LOG3t_err(errsv, ...) _NMLOG3_err (errsv, _LOGL_TRACE, __VA_ARGS__)
#else
/* still call the logging macros to get compile time checks, but they will be optimized out. */
#define _LOG3t_ENABLED(...) ( FALSE && (_NMLOG3_ENABLED (LOGL_TRACE, ##__VA_ARGS__)) )
#define _LOG3t(...) G_STMT_START { if (FALSE) { _NMLOG3 (LOGL_TRACE, __VA_ARGS__); } } G_STMT_END
#define _LOG3t_err(errsv, ...) G_STMT_START { if (FALSE) { _NMLOG3_err (errsv, LOGL_TRACE, __VA_ARGS__); } } G_STMT_END
#define _LOG3t_ENABLED(...) ( FALSE && (_NMLOG3_ENABLED (_LOGL_TRACE, ##__VA_ARGS__)) )
#define _LOG3t(...) G_STMT_START { if (FALSE) { _NMLOG3 (_LOGL_TRACE, __VA_ARGS__); } } G_STMT_END
#define _LOG3t_err(errsv, ...) G_STMT_START { if (FALSE) { _NMLOG3_err (errsv, _LOGL_TRACE, __VA_ARGS__); } } G_STMT_END
#endif
/*****************************************************************************/