diff options
author | Thomas Haller <thaller@redhat.com> | 2015-04-22 16:54:53 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2015-04-22 16:54:53 +0200 |
commit | 2316d233e36d7c98e4ecad2016ed2467c853a6a0 (patch) | |
tree | b9f350017ff337eb78e914ca38e20c6e1aed9b42 | |
parent | 4526b55a516f2b7836a1879ca70d039b23dd7044 (diff) | |
parent | ea5865cf456b407e0e9627868e2af7154a574ad1 (diff) | |
download | NetworkManager-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.c | 22 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 164 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 53 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 7 | ||||
-rw-r--r-- | src/platform/tests/test-common.c | 2 |
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; } |