summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-04-22 16:54:53 +0200
committerThomas Haller <thaller@redhat.com>2015-04-22 16:54:53 +0200
commit2316d233e36d7c98e4ecad2016ed2467c853a6a0 (patch)
treeb9f350017ff337eb78e914ca38e20c6e1aed9b42
parent4526b55a516f2b7836a1879ca70d039b23dd7044 (diff)
parentea5865cf456b407e0e9627868e2af7154a574ad1 (diff)
downloadNetworkManager-2316d233e36d7c98e4ecad2016ed2467c853a6a0.tar.gz
platform: merge branch 'th/platform-div-bgo748131'
https://bugzilla.gnome.org/show_bug.cgi?id=748131
-rw-r--r--src/platform/nm-fake-platform.c22
-rw-r--r--src/platform/nm-linux-platform.c164
-rw-r--r--src/platform/nm-platform.c53
-rw-r--r--src/platform/nm-platform.h7
-rw-r--r--src/platform/tests/test-common.c2
5 files changed, 140 insertions, 108 deletions
diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c
index 09e1d37cc7..c9785b0035 100644
--- a/src/platform/nm-fake-platform.c
+++ b/src/platform/nm-fake-platform.c
@@ -60,14 +60,6 @@ G_DEFINE_TYPE (NMFakePlatform, nm_fake_platform, NM_TYPE_PLATFORM)
/******************************************************************/
-void
-nm_fake_platform_setup (void)
-{
- nm_platform_setup (NM_TYPE_FAKE_PLATFORM);
-}
-
-/******************************************************************/
-
static gboolean
sysctl_set (NMPlatform *platform, const char *path, const char *value)
{
@@ -1336,9 +1328,15 @@ nm_fake_platform_init (NMFakePlatform *fake_platform)
priv->ip6_routes = g_array_new (TRUE, TRUE, sizeof (NMPlatformIP6Route));
}
-static gboolean
-setup (NMPlatform *platform)
+void
+nm_fake_platform_setup (void)
{
+ NMPlatform *platform;
+
+ platform = g_object_new (NM_TYPE_FAKE_PLATFORM, NULL);
+
+ nm_platform_setup (platform);
+
/* skip zero element */
link_add (platform, NULL, NM_LINK_TYPE_NONE, NULL, 0);
@@ -1349,8 +1347,6 @@ setup (NMPlatform *platform)
link_add (platform, "eth0", NM_LINK_TYPE_ETHERNET, NULL, 0);
link_add (platform, "eth1", NM_LINK_TYPE_ETHERNET, NULL, 0);
link_add (platform, "eth2", NM_LINK_TYPE_ETHERNET, NULL, 0);
-
- return TRUE;
}
static void
@@ -1386,8 +1382,6 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass)
/* virtual methods */
object_class->finalize = nm_fake_platform_finalize;
- platform_class->setup = setup;
-
platform_class->sysctl_set = sysctl_set;
platform_class->sysctl_get = sysctl_get;
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index f3d25e2532..da804804d8 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -67,9 +67,51 @@
/* This is only included for the translation of VLAN flags */
#include "nm-setting-vlan.h"
-#define debug(...) nm_log_dbg (LOGD_PLATFORM, __VA_ARGS__)
-#define warning(...) nm_log_warn (LOGD_PLATFORM, __VA_ARGS__)
-#define error(...) nm_log_err (LOGD_PLATFORM, __VA_ARGS__)
+/*********************************************************************************************/
+
+#define _LOG_DOMAIN LOGD_PLATFORM
+#define _LOG_PREFIX_NAME "platform-linux"
+
+#define _LOG(level, domain, self, ...) \
+ G_STMT_START { \
+ const NMLogLevel __level = (level); \
+ const NMLogDomain __domain = (domain); \
+ \
+ if (nm_logging_enabled (__level, __domain)) { \
+ char __prefix[32]; \
+ const char *__p_prefix = _LOG_PREFIX_NAME; \
+ const void *const __self = (self); \
+ \
+ if (__self && __self != nm_platform_try_get ()) { \
+ g_snprintf (__prefix, sizeof (__prefix), "%s[%p]", _LOG_PREFIX_NAME, __self); \
+ __p_prefix = __prefix; \
+ } \
+ _nm_log (__level, __domain, 0, \
+ "%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
+ __p_prefix _NM_UTILS_MACRO_REST (__VA_ARGS__)); \
+ } \
+ } G_STMT_END
+#define _LOG_LEVEL_ENABLED(level, domain) \
+ ( nm_logging_enabled ((level), (domain)) )
+
+#ifdef NM_MORE_LOGGING
+#define _LOGT_ENABLED() _LOG_LEVEL_ENABLED (LOGL_TRACE, _LOG_DOMAIN)
+#define _LOGT(...) _LOG (LOGL_TRACE, _LOG_DOMAIN, platform, __VA_ARGS__)
+#else
+#define _LOGT_ENABLED() FALSE
+#define _LOGT(...) G_STMT_START { (void) 0; } G_STMT_END
+#endif
+
+#define _LOGD(...) _LOG (LOGL_DEBUG, _LOG_DOMAIN, platform, __VA_ARGS__)
+#define _LOGI(...) _LOG (LOGL_INFO , _LOG_DOMAIN, platform, __VA_ARGS__)
+#define _LOGW(...) _LOG (LOGL_WARN , _LOG_DOMAIN, platform, __VA_ARGS__)
+#define _LOGE(...) _LOG (LOGL_ERR , _LOG_DOMAIN, platform, __VA_ARGS__)
+
+#define debug(...) _LOG (LOGL_DEBUG, _LOG_DOMAIN, NULL, __VA_ARGS__)
+#define warning(...) _LOG (LOGL_WARN , _LOG_DOMAIN, NULL, __VA_ARGS__)
+#define error(...) _LOG (LOGL_ERR , _LOG_DOMAIN, NULL, __VA_ARGS__)
+
+/******************************************************************/
#define return_type(t, name) \
G_STMT_START { \
@@ -286,6 +328,47 @@ _rtnl_addr_hack_lifetimes_rel_to_abs (struct rtnl_addr *rtnladdr)
rtnl_addr_set_preferred_lifetime (rtnladdr, _get_expiry (now, a_preferred));
}
+/******************************************************************/
+
+#if HAVE_LIBNL_INET6_ADDR_GEN_MODE
+static int _support_user_ipv6ll = 0;
+#endif
+
+static gboolean
+_support_user_ipv6ll_get ()
+{
+#if HAVE_LIBNL_INET6_ADDR_GEN_MODE
+ if (G_UNLIKELY (_support_user_ipv6ll == 0)) {
+ _support_user_ipv6ll = -1;
+ nm_log_warn (LOGD_PLATFORM, "kernel support for IFLA_INET6_ADDR_GEN_MODE %s", "failed to detect; assume no support");
+ } else
+ return _support_user_ipv6ll > 0;
+#endif
+
+ return FALSE;
+}
+
+static void
+_support_user_ipv6ll_detect (const struct rtnl_link *rtnl_link)
+{
+#if HAVE_LIBNL_INET6_ADDR_GEN_MODE
+ /* If we ever see a link with valid IPv6 link-local address
+ * generation modes, the kernel supports it.
+ */
+ if (G_UNLIKELY (_support_user_ipv6ll == 0)) {
+ uint8_t mode;
+
+ if (rtnl_link_inet6_get_addr_gen_mode ((struct rtnl_link *) rtnl_link, &mode) == 0) {
+ _support_user_ipv6ll = 1;
+ nm_log_dbg (LOGD_PLATFORM, "kernel support for IFLA_INET6_ADDR_GEN_MODE %s", "detected");
+ } else {
+ _support_user_ipv6ll = -1;
+ nm_log_dbg (LOGD_PLATFORM, "kernel support for IFLA_INET6_ADDR_GEN_MODE %s", "not detected");
+ }
+ }
+#endif
+}
+
/******************************************************************
* ethtool
******************************************************************/
@@ -474,7 +557,6 @@ typedef struct {
GHashTable *wifi_data;
int support_kernel_extended_ifa_flags;
- int support_user_ipv6ll;
} NMLinuxPlatformPrivate;
#define NM_LINUX_PLATFORM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_LINUX_PLATFORM, NMLinuxPlatformPrivate))
@@ -488,7 +570,7 @@ static gboolean _route_match (struct rtnl_route *rtnlroute, int family, int ifin
void
nm_linux_platform_setup (void)
{
- nm_platform_setup (NM_TYPE_LINUX_PLATFORM);
+ nm_platform_setup (g_object_new (NM_TYPE_LINUX_PLATFORM, NULL));
}
/******************************************************************/
@@ -583,6 +665,7 @@ get_kernel_object (struct nl_sock *sock, struct nl_object *needle)
nle = rtnl_link_get_kernel (sock, ifindex, name, (struct rtnl_link **) &object);
switch (nle) {
case -NLE_SUCCESS:
+ _support_user_ipv6ll_detect ((struct rtnl_link *) object);
if (nm_logging_enabled (LOGL_DEBUG, LOGD_PLATFORM)) {
name = rtnl_link_get_name ((struct rtnl_link *) object);
debug ("get_kernel_object for link: %s (%d, family %d)",
@@ -787,21 +870,11 @@ check_support_kernel_extended_ifa_flags (NMPlatform *platform)
static gboolean
check_support_user_ipv6ll (NMPlatform *platform)
{
- NMLinuxPlatformPrivate *priv;
-
g_return_val_if_fail (NM_IS_LINUX_PLATFORM (platform), FALSE);
- priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
-
- if (priv->support_user_ipv6ll == 0) {
- nm_log_warn (LOGD_PLATFORM, "Unable to detect kernel support for IFLA_INET6_ADDR_GEN_MODE. Assume no kernel support.");
- priv->support_user_ipv6ll = -1;
- }
-
- return priv->support_user_ipv6ll > 0;
+ return _support_user_ipv6ll_get ();
}
-
/* Object type specific utilities */
static const char *
@@ -1541,18 +1614,6 @@ announce_object (NMPlatform *platform, const struct nl_object *object, NMPlatfor
struct rtnl_link *rtnl_link = (struct rtnl_link *) object;
NMPlatformLink device;
-#if HAVE_LIBNL_INET6_ADDR_GEN_MODE
- /* If we ever see a link with valid IPv6 link-local address
- * generation modes, the kernel supports it.
- */
- if (priv->support_user_ipv6ll == 0) {
- uint8_t mode;
-
- if (rtnl_link_inet6_get_addr_gen_mode (rtnl_link, &mode) == 0)
- priv->support_user_ipv6ll = 1;
- }
-#endif
-
if (!init_link (platform, &device, rtnl_link))
return;
@@ -1956,10 +2017,14 @@ event_notification (struct nl_msg *msg, gpointer user_data)
}
nl_msg_parse (msg, ref_object, &object);
- g_return_val_if_fail (object, NL_OK);
+ if (!object)
+ return NL_OK;
type = _nlo_get_object_type (object);
+ if (type == OBJECT_TYPE_LINK)
+ _support_user_ipv6ll_detect ((struct rtnl_link *) object);
+
if (nm_logging_enabled (LOGL_DEBUG, LOGD_PLATFORM)) {
if (type == OBJECT_TYPE_LINK) {
const char *name = rtnl_link_get_name ((struct rtnl_link *) object);
@@ -2541,9 +2606,7 @@ static gboolean
link_get_user_ipv6ll_enabled (NMPlatform *platform, int ifindex)
{
#if HAVE_LIBNL_INET6_ADDR_GEN_MODE
- NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
-
- if (priv->support_user_ipv6ll > 0) {
+ if (_support_user_ipv6ll_get ()) {
auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex);
uint8_t mode = 0;
@@ -2563,7 +2626,7 @@ static gboolean
link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enabled)
{
#if HAVE_LIBNL_INET6_ADDR_GEN_MODE
- if (check_support_user_ipv6ll (platform)) {
+ if (_support_user_ipv6ll_get ()) {
auto_nl_object struct rtnl_link *change = _nm_rtnl_link_alloc (ifindex, NULL);
guint8 mode = enabled ? IN6_ADDR_GEN_MODE_NONE : IN6_ADDR_GEN_MODE_EUI64;
char buf[32];
@@ -4476,9 +4539,10 @@ nm_linux_platform_init (NMLinuxPlatform *platform)
{
}
-static gboolean
-setup (NMPlatform *platform)
+static void
+constructed (GObject *_object)
{
+ NMPlatform *platform = NM_PLATFORM (_object);
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
const char *udev_subsys[] = { "net", NULL };
GUdevEnumerator *enumerator;
@@ -4486,9 +4550,6 @@ setup (NMPlatform *platform)
int channel_flags;
gboolean status;
int nle;
-#if HAVE_LIBNL_INET6_ADDR_GEN_MODE
- struct nl_object *object;
-#endif
/* Initialize netlink socket for requests */
priv->nlh = setup_socket (FALSE, platform);
@@ -4527,21 +4588,17 @@ setup (NMPlatform *platform)
cache_repopulate_all (platform);
#if HAVE_LIBNL_INET6_ADDR_GEN_MODE
- /* Initial check for user IPv6LL support once the link cache is allocated
- * and filled. If there are no links in the cache yet then we'll check
- * when a new link shows up in announce_object().
- */
- object = nl_cache_get_first (priv->link_cache);
- if (object) {
- uint8_t mode;
+ if (G_UNLIKELY (_support_user_ipv6ll == 0)) {
+ struct nl_object *object;
- if (rtnl_link_inet6_get_addr_gen_mode ((struct rtnl_link *) object, &mode) == 0)
- priv->support_user_ipv6ll = 1;
- else
- priv->support_user_ipv6ll = -1;
+ /* Initial check for user IPv6LL support once the link cache is allocated
+ * and filled. If there are no links in the cache yet then we'll check
+ * when a new link shows up in announce_object().
+ */
+ object = nl_cache_get_first (priv->link_cache);
+ if (object)
+ _support_user_ipv6ll_detect ((struct rtnl_link *) object);
}
-#else
- priv->support_user_ipv6ll = -1;
#endif
/* Set up udev monitoring */
@@ -4575,7 +4632,7 @@ setup (NMPlatform *platform)
priv->wifi_data = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) wifi_utils_deinit);
- return TRUE;
+ G_OBJECT_CLASS (nm_linux_platform_parent_class)->constructed (_object);
}
static void
@@ -4610,10 +4667,9 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
g_type_class_add_private (klass, sizeof (NMLinuxPlatformPrivate));
/* virtual methods */
+ object_class->constructed = constructed;
object_class->finalize = nm_linux_platform_finalize;
- platform_class->setup = setup;
-
platform_class->sysctl_set = sysctl_set;
platform_class->sysctl_get = sysctl_get;
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 1bc907b667..1a7b9bc182 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -58,7 +58,9 @@ static guint signals[LAST_SIGNAL] = { 0 };
/******************************************************************/
/* Singleton NMPlatform subclass instance and cached class object */
-static NMPlatform *singleton_instance = NULL;
+NM_DEFINE_SINGLETON_INSTANCE (NMPlatform);
+
+NM_DEFINE_SINGLETON_WEAK_REF (NMPlatform);
/* Just always initialize a @klass instance. NM_PLATFORM_GET_CLASS()
* is only a plain read on the self instance, which the compiler
@@ -82,11 +84,7 @@ static NMPlatform *singleton_instance = NULL;
/**
* nm_platform_setup:
- * @type: The #GType for a subclass of #NMPlatform
- *
- * Do not use this function directly, it is intended to be called by
- * NMPlatform subclasses. For the linux platform initialization use
- * nm_linux_platform_setup() instead.
+ * @instance: the #NMPlatform instance
*
* Failing to set up #NMPlatform singleton results in a fatal error,
* as well as trying to initialize it multiple times without freeing
@@ -94,39 +92,19 @@ static NMPlatform *singleton_instance = NULL;
*
* NetworkManager will typically use only one platform object during
* its run. Test programs might want to switch platform implementations,
- * though. This is done with a combination of nm_platform_free() and
- * nm_*_platform_setup().
+ * though.
*/
void
-nm_platform_setup (GType type)
+nm_platform_setup (NMPlatform *instance)
{
- gboolean status;
- NMPlatformClass *klass;
-
- g_assert (singleton_instance == NULL);
+ g_return_if_fail (NM_IS_PLATFORM (instance));
+ g_return_if_fail (!singleton_instance);
- singleton_instance = g_object_new (type, NULL);
- g_assert (NM_IS_PLATFORM (singleton_instance));
+ singleton_instance = instance;
- klass = NM_PLATFORM_GET_CLASS (singleton_instance);
- g_assert (klass->setup);
+ nm_singleton_instance_weak_ref_register ();
- status = klass->setup (singleton_instance);
- g_assert (status);
-}
-
-/**
- * nm_platform_free:
- *
- * Free #NMPlatform singleton created by nm_*_platform_setup().
- */
-void
-nm_platform_free (void)
-{
- g_assert (singleton_instance);
-
- g_object_unref (singleton_instance);
- singleton_instance = NULL;
+ nm_log_dbg (LOGD_CORE, "setup NMPlatform singleton (%p, %s)", instance, G_OBJECT_TYPE_NAME (instance));
}
/**
@@ -134,8 +112,7 @@ nm_platform_free (void)
* @self: platform instance
*
* Retrieve #NMPlatform singleton. Use this whenever you want to connect to
- * #NMPlatform signals. It is an error to call it before nm_*_platform_setup()
- * or after nm_platform_free().
+ * #NMPlatform signals. It is an error to call it before nm_platform_setup().
*
* Returns: (transfer none): The #NMPlatform singleton reference.
*/
@@ -147,6 +124,12 @@ nm_platform_get ()
return singleton_instance;
}
+NMPlatform *
+nm_platform_try_get (void)
+{
+ return singleton_instance;
+}
+
/******************************************************************/
/**
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index aee1ee8160..5cd5ae8e0c 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -97,6 +97,7 @@ struct _NMPlatformLink {
};
typedef enum {
+ NM_PLATFORM_SIGNAL_NONE,
NM_PLATFORM_SIGNAL_ADDED,
NM_PLATFORM_SIGNAL_CHANGED,
NM_PLATFORM_SIGNAL_REMOVED,
@@ -357,8 +358,6 @@ struct _NMPlatform {
typedef struct {
GObjectClass parent;
- gboolean (*setup) (NMPlatform *);
-
gboolean (*sysctl_set) (NMPlatform *, const char *path, const char *value);
char * (*sysctl_get) (NMPlatform *, const char *path);
@@ -490,9 +489,9 @@ typedef struct {
GType nm_platform_get_type (void);
-void nm_platform_setup (GType type);
+void nm_platform_setup (NMPlatform *instance);
NMPlatform *nm_platform_get (void);
-void nm_platform_free (void);
+NMPlatform *nm_platform_try_get (void);
#define NM_PLATFORM_GET (nm_platform_get ())
diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c
index cedbc518e6..d1627058e9 100644
--- a/src/platform/tests/test-common.c
+++ b/src/platform/tests/test-common.c
@@ -287,6 +287,6 @@ main (int argc, char **argv)
nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME));
- nm_platform_free ();
+ g_object_unref (nm_platform_get ());
return result;
}