Commit graph

32 commits

Author SHA1 Message Date
Thomas Haller
ebf1c06576 exported-object: cleanup logging about properties-changed
(cherry picked from commit 46f285e3d3)
(cherry picked from commit 4f452eedab)
2016-08-31 14:25:01 +02:00
Thomas Haller
4ca20456c9 exported-object: fix source interface for PropertiesChanged D-Bus signal
nm_exported_object_notify() hooks GObject's property-change signal
and searches for the D-Bus interface to which to send the
PropertiesChanged signal.
Then it would enqueue the value encoded as GVariant in pending_notifications.
However, thereby the association between the property that changed and the
interface was lost. So later in idle_emit_properties_changed() it would
just pick the first interface with a properties-changed-id.

That is wrong. pending_notifications must be associated with the D-Bus
interface that we are going to notify. That is, each InterfaceData must
have its own separate list.

This is broken since introducing NMExportedObject and moving to gdbus.
Only now it was discovered as NMDevice itself has two D-Bus interfaces:
"Device" and "Device.Statistics".

Note that the order of the PropertiesChanged in our D-Bus API is not defined
so that later signals can reach the receiver before earlier signals.
Also, multiple change signals for one property may be combined.
That is not changed by this patch and is not considered a bug, but something
that our D-Bus API wrt. PropertiesChanged does not guarantee.

https://bugzilla.gnome.org/show_bug.cgi?id=770629
(cherry picked from commit 82e94390de)
(cherry picked from commit 8d9ea18b3d)
2016-08-31 14:25:00 +02:00
Thomas Haller
603e6dc006 exported-object: reorder includes 2016-04-01 08:58:19 +02:00
Thomas Haller
8fd3a2b893 exported-object/trivial: move code 2016-04-01 08:58:19 +02:00
Thomas Haller
61f3c9890f exported-object: static variable prefix_counters from global scope to _create_export_path() 2016-04-01 08:58:19 +02:00
Thomas Haller
d4d72e2bda exported-object: inline find_dbus_property_type() in nm_exported_object_notify()
nm_exported_object_notify() is not that large of a function. Having it
all at one place makes it clearer what it does.
2016-04-01 08:58:19 +02:00
Thomas Haller
429cc30607 exported-object: allocate temporary buffer in nm_exported_object_signal_hook() using alloca
The size of GValue is about 24 bytes. The number of arguments
for a signal is also small. No problem allocating the temporary buffer
on the stack.
2016-04-01 08:58:19 +02:00
Thomas Haller
05d4faf334 exported-object: cache signal-id for "property-changed" in InterfaceData
Instead of looking up the signal-id every time, cache it.
g_signal_lookup() requires a g_quark_try_string() and a
lock a lock on a global mutex.

Downside is that the InterfaceData structure grows.
2016-04-01 08:58:19 +02:00
Thomas Haller
6a42e18d53 exported-object: refactor list of interfaces from GSList to an array
NMExportedObject is the center of every D-Bus exported object in
NetworkManager's core. It makes sense to optimize it.

Transform the GSList of interfaces to be a array. The array is still
allocated via the slice allocator (as we expect that there are only few
types in the list). This saves the overhead to allocate a GSList item
for each entry.

Another advantage is that the interfaces list is now strongly typed
instead of an opaque data pointer.
2016-04-01 08:58:18 +02:00
Thomas Haller
efae518e3c exported-object: sort fields in emitted "property-changed" data variant
The fields of the variant should have a consistent sort order.
2016-04-01 08:58:18 +02:00
Thomas Haller
2b9462f172 exported-object: reorder fields in NMExportedObjectPrivate struct
For now, this doesn't change the overall size of the struct.
But with the next commits this ordering allows tighter packing.
2016-04-01 08:58:18 +02:00
Dan Williams
415e9441ab core: fix duplicate values in NM-specific PropertiesChanged signals
GVariantBuilder doesn't care if you give it multiple dict entries with
the same key.  But that causes duplicate dict entries in the legacy
D-Bus PropertiesChanged signals that NM emits.  So instead go back to
a hash table to ensure that any previous value is dropped in favor of
the new one.
2016-03-29 15:52:23 -05:00
Thomas Haller
8bace23beb all: cleanup includes and let "nm-default.h" include "config.h"
- All internal source files (except "examples", which are not internal)
  should include "config.h" first. As also all internal source
  files should include "nm-default.h", let "config.h" be included
  by "nm-default.h" and include "nm-default.h" as first in every
  source file.
  We already wanted to include "nm-default.h" before other headers
  because it might contains some fixes (like "nm-glib.h" compatibility)
  that is required first.

- After including "nm-default.h", we optinally allow for including the
  corresponding header file for the source file at hand. The idea
  is to ensure that each header file is self contained.

- Don't include "config.h" or "nm-default.h" in any header file
  (except "nm-sd-adapt.h"). Public headers anyway must not include
  these headers, and internal headers are never included after
  "nm-default.h", as of the first previous point.

- Include all internal headers with quotes instead of angle brackets.
  In practice it doesn't matter, because in our public headers we must
  include other headers with angle brackets. As we use our public
  headers also to compile our interal source files, effectively the
  result must be the same. Still do it for consistency.

- Except for <config.h> itself. Include it with angle brackets as suggested by
  https://www.gnu.org/software/autoconf/manual/autoconf.html#Configuration-Headers
2016-02-19 17:53:25 +01:00
Beniamino Galvani
14c16a8b22 exported-object: set object path after skeleton creation
When exporting an object, we first set the object path and then create
GDBus interface skeletons. While doing this, a signal can be generated
[1] and then nm_exported_object_signal_hook() can trigger the failed
assertion "interface != NULL" because the object is already exported
(priv->path != NULL) but the interface has not been registered yet.

To fix this, set the object path only after skeletons have been
created.

[1] This happens here every time I disable networking and restart NM:
    #0  _g_log_abort (libglib-2.0.so.0)
    #1  g_log (libglib-2.0.so.0)
    #2  nm_exported_object_signal_hook (NetworkManager)
    #3  signal_emit_unlocked_R (libgobject-2.0.so.0)
    #4  g_signal_emit_valist (libgobject-2.0.so.0)
    #5  g_signal_emit (libgobject-2.0.so.0)
    #6  set_state (NetworkManager)
    #7  nm_manager_update_state (NetworkManager)
    #8  get_property (NetworkManager)
    #9  object_get_property (libgobject-2.0.so.0)
    #10 on_source_notify (libgobject-2.0.so.0)
    #11 g_object_bind_property_full (libgobject-2.0.so.0)
    #12 g_object_bind_property (libgobject-2.0.so.0)
    #13 nm_exported_object_skeleton_create (NetworkManager)
    #14 nm_exported_object_create_skeletons (NetworkManager)
    #15 nm_exported_object_export (NetworkManager)
    #16 nm_manager_setup (NetworkManager)
    #17 main (NetworkManager)
    #18 __libc_start_main (libc.so.6)
    #19 _start (NetworkManager)

https://mail.gnome.org/archives/networkmanager-list/2016-February/msg00041.html
2016-02-11 12:55:21 +01:00
Dan Williams
b023d0754b exported-object: add support for DBus ObjectManager interface
NMExportedObject now derives from GDBusObjectSkeleton, which is what
GDBusObjectManagerServer wants.  The main GDBusConnection and each
private server connection now gets a new GDBusObjectManagerServer,
and exported objects are registered with that instead of individually
exporting each GDBusInterfaceSkeleton.

Previously exported objects were not referenced by the BusManager,
but instead removed from the exports hash via weak references.  The
GDBusObjectManagerServer instead references exported objects, which
can make them live much longer than they did before.

Co-Authored-By: Thomas Haller <thaller@redhat.com>
2015-11-18 15:15:05 +01:00
Thomas Haller
57128494e0 exported-object: split out the creation of interface skeletons
Will be reused for ifcfg-rh plugin, which also has a skeleton,
but will not implement NMExportedObject.
2015-11-10 18:12:12 +01:00
Dan Williams
f9ee20a7b2 core: explicitly unexport objects when we're done with them
Previously most objects were implicitly unexported when they were
destroyed, but since refcounts may make the object live longer than
intended, we should explicitly unexport them when they should no
longer be present on the bus.

This means we can assume that objects will always be un-exported
already when they are destroyed, *except* when quitting where most
objects will live until exit because NM leaves interfaces up and
running on quit.
2015-11-10 18:12:12 +01:00
Thomas Haller
96f40dcdcd wifi/ap: explicitly unexport AP and refactor add/remove AP
For future use of ObjectManager, we must explicitly unexport
the AP and no longer depend on having it unexported during
deconstruction (because object manager keeps the instance alive).

Also refactor adding/removal of APs and move the export/unexport
calls to the place where we emit the signal.
2015-11-10 18:12:12 +01:00
Thomas Haller
8a8ecc46ca core: fix wrongly exporting object before instance is fully constructed
Exporting the object already in the *_init() function will later
break because the object is not yet fully initialized at that point.

Add a convenient flag so that the NMExportedObject parent implementation
automatically can export itself. This saves the derived class from
overwriting the constructed() method.

Also add an assertion to catch such bugs.
2015-11-10 18:12:12 +01:00
Thomas Haller
45f682e222 exported-object: explicitly disconnect bindings and signal handlers to GDBusInterfaceSkeleton interfaces
While an NMExportedObject is exported (i.e. registered at NMBusManager),
it has a list of GDBusInterfaceSkeleton interfaces. The properties of
the nm-object are bound to the interfaces and the signals connected.

Previously, when unexporting the NMExportedObject, we would only unref
the interfaces, but not explicitly disconnect. As there is no guarantee
that the lifetime of the interfaces is shorter then the lifetime of the
nm-object, hence, explicitly disconnect.
2015-09-18 18:01:55 +02:00
Thomas Haller
d20948647c exported-object: fix type of @interface variables to be GDBusInterfaceSkeleton 2015-09-17 16:59:16 +02:00
Thomas Haller
a33fc00239 core: refactor setting of D-Bus properties via NMManager
- Also if the target object is the NMManager instance itself,
  re-fetch the manager via nm_bus_manager_get_registered_object().
  This way, we only set the property on the manager, if
  it's also exported according to the bus-manager. Also,
  we don't treat the manager instance special.

- Move fetching the object (nm_bus_manager_get_registered_object())
  from do_set_property_check() to prop_set_auth_done_cb(). Otherwise,
  we fetch the object first, but there is no guarantee that the object
  is still exported after the asynchronous authentication succeeds.
2015-09-16 16:36:46 +02:00
Thomas Haller
a55c87a2c0 core: refactor NMBusManager to hold reference to NMExportedObject directly
Previously, nm_bus_manager_register_object() would take various D-Bus
skeleton objects that were associated with one NMExportedObject.
This was confusing, in that these skeleton objects are all for the
same NMObject but correspond to different D-Bus interfaces.

Also, setting the D-Bus property "Managed" of a Device is broken
because we might retrieve the wrong skeleton.

Now, the NMBusManager has a reference to the exported object directly.
The skeleton interface instances instead are now exposed by the NMExportedObject.
2015-09-16 16:25:02 +02:00
Thomas Haller
d9c4411402 core: fix leaking @properties in nm_exported_object_create_skeletons()
Fixes: 073991f5a8
2015-08-18 14:44:25 +02:00
Thomas Haller
e828bae171 core: fix memleak in nm_exported_object_notify()
g_dbus_gvalue_to_gvariant() returns a non-floating ref.

Fixes: 073991f5a8
2015-08-18 14:18:37 +02:00
Thomas Haller
cad5406417 core: avoid assertion "signal_id != 0" on unexported object
When unexporting an object, we might have a notification
pending. When the notification is finally processed, it
would find no "priv->interfaces" and raise an assertion

  "idle_emit_properties_changed: assertion 'signal_id != 0' failed"

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

Fixes: 073991f5a8
2015-08-13 17:20:07 +02:00
Thomas Haller
514059aa62 core: fix memleak in nm_exported_object_class_add_interface()
Fixes: 073991f5a8
2015-08-12 11:10:05 +02:00
Dan Winship
073991f5a8 core: port NMExportedObject to gdbus
Port NMExportedObject to gdbus, and make
nm_exported_object_class_add_interface() deal with generating D-Bus
skeleton objects and attaching signal handlers and property bindings
as needed to properly handle methods, signals, and properties.
2015-08-10 09:41:26 -04:00
Thomas Haller
19c3ea948a all: make use of new header file "nm-default.h" 2015-08-05 15:32:40 +02:00
Dan Winship
02370be7f3 core: rename NMDBusManager to NMBusManager
Our gdbus generated types use the same names as their corresponding
"real" types, but with "NM" changed to "NMDBus".

Unfortunately, that means that introspection/nmdbus-manager.c (the
generated type for src/nm-manager.c) uses the same type name as the
entirely unrelated src/nm-dbus-manager.c.

Fix this by removing the "d" from src/nm-dbus-manager.c. (We could
rename the generated type instead, but then it becomes inconsistent
with all the other generated types, and we're already using it as
"NMDBusManager" in libnm/nm-manager.c.)
2015-07-24 13:25:48 -04:00
Dan Winship
c1dd3b6eed core: move D-Bus export/unexport into NMExportedObject
Move D-Bus export/unexport handling into NMExportedObject and remove
type-specific export/get_path methods (export paths are now specified
at the class level, and NMExportedObject handles the counters for all
exported types automatically).

Since all exportable objects now use the same get_path() method, we
can also add some helper methods to simplify get_property()
implementations for object-path and object-path-array properties.
2015-07-24 13:25:47 -04:00
Dan Winship
6fcc1deee0 core: add an NMExportedObject base class
Add NMExportedObject, make it the base class of all D-Bus-exported
types, and move the nm-properties-changed-signal logic into it. (Also,
make NMSettings use the same properties-changed code as everything
else, which it was not previously doing, presumably for historical
reasons).

(This is mostly just shuffling code around at this point, but
NMExportedObject will be more important in the gdbus port, since
gdbus-codegen doesn't do a very good job of supporting objects that
export multiple interfaces [as each NMDevice subclass does, for
example], so we will need more glue/helper code in NMExportedObject
then.)
2015-07-24 13:25:47 -04:00