From: =?utf-8?q?Guido_G=C3=BCnther?= <agx@sigxcpu.org>
Date: Wed, 8 Oct 2025 13:51:02 +0200
Subject: mm-manager: Get MM version early
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit

If we do it later in the async call chain it might deadlock. Do
it early as this will go away eventually anyway.

The hang looked like:

    syscall () at ../sysdeps/unix/sysv/linux/aarch64/syscall.S:38
    (gdb) #0  syscall () at ../sysdeps/unix/sysv/linux/aarch64/syscall.S:38
    #1  0x0000ffff83181834 in g_mutex_lock_slowpath (mutex=0xaaaac4832210) at ../../../glib/gthread-posix.c:939
    #2  0x0000ffff831821b4 in g_mutex_lock_impl (mutex=<optimized out>) at ../../../glib/gthread-posix.c:968
    #3  0x0000ffff83465538 in g_dbus_object_manager_client_get_name (manager=0xaaaac48322a0 [MMManager])
        at ../../../gio/gdbusobjectmanagerclient.c:945
    #4  0x0000ffff8346580c in g_dbus_object_manager_client_get_property
        (_object=0xaaaac48322a0 [MMManager], prop_id=5, value=0xffffc6c9b5b0, pspec=<optimized out>)
        at ../../../gio/gdbusobjectmanagerclient.c:271
    #5  0x0000ffff832a39a4 in object_get_property
        (object=0xaaaac48322a0 [MMManager], pspec=0xaaaac4834ad0 [GParamString], value=0xffffc6c9b5b0)
        at ../../../gobject/gobject.c:2161
    #6  g_object_get_valist
        (object=object@entry=0xaaaac48322a0 [MMManager], first_property_name=first_property_name@entry=0xffff8303d4b8 "name", var_args=...) at ../../../gobject/gobject.c:3292
    #7  0x0000ffff832a3f60 in g_object_get (_object=0xaaaac48322a0, first_property_name=0xffff8303d4b8 "name")
        at ../../../gobject/gobject.c:3389
    #8  0x0000ffff82fca0b8 in ??? () at /lib/aarch64-linux-gnu/libmm-glib.so.0
    #9  0x0000ffff82fca90c in mm_manager_get_version () at /lib/aarch64-linux-gnu/libmm-glib.so.0
    #10 0x0000aaaaad22fbc4 in is_cbm_support_blacklisted (self=0xaaaac4824480 [CbdMmManager]) at ../src/cbd-mm-manager.c:59
    #11 on_cell_broadcast_n_items_changed (self=0xaaaac4824480 [CbdMmManager]) at ../src/cbd-mm-manager.c:80
    #16 0x0000ffff832b62e0 in <emit signal 'notify:n-items or notify' on instance 0xaaaac4826490 [GListStore]>
        (instance=instance@entry=0xaaaac4826490, signal_id=signal_id@entry=1, detail=<optimized out>)
        at ../../../gobject/gsignal.c:3597
        #12 0x0000ffff83298904 in g_closure_invoke
        (closure=0xaaaac4826560, return_value=0x0, n_param_values=2, param_values=0xffffc6c9ba50, invocation_hint=0xffffc6c9b980) at ../../../gobject/gclosure.c:833
        #13 0x0000ffff832af2d0 in signal_emit_unlocked_R
        (node=node@entry=0xffffc6c9bb48, detail=detail@entry=289, instance=instance@entry=0xaaaac4826490, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0xffffc6c9ba50)
        at ../../../gobject/gsignal.c:3902
        #14 0x0000ffff832b07a8 in signal_emit_valist_unlocked
        (instance=instance@entry=0xaaaac4826490, signal_id=signal_id@entry=1, detail=detail@entry=289, var_args=...)
        at ../../../gobject/gsignal.c:3534
        #15 0x0000ffff832b6238 in g_signal_emit_valist (instance=0xaaaac4826490, signal_id=1, detail=289, var_args=...)
        at ../../../gobject/gsignal.c:3277
    #17 0x0000ffff8329d620 in g_object_dispatch_properties_changed
        (object=0xaaaac4826490 [GListStore], n_pspecs=<optimized out>, pspecs=<optimized out>)
        at ../../../gobject/gobject.c:1851
    #18 0x0000ffff832a1b74 in g_object_notify_by_spec_internal
        (object=0xaaaac4826490 [GListStore], pspec=0xaaaac4824020 [GParamUInt]) at ../../../gobject/gobject.c:1956
    #19 g_object_notify_by_pspec (object=0xaaaac4826490 [GListStore], pspec=0xaaaac4824020 [GParamUInt])
        at ../../../gobject/gobject.c:2062
    #20 0x0000ffff833f4678 in g_list_store_items_changed
        (position=<optimized out>, removed=0, added=1, store=<optimized out>) at ../../../gio/gliststore.c:84
    #21 0x0000aaaaad22f920 in modem_init_cellbroadcast
        (self=0xaaaac4824480 [CbdMmManager], object=0xffff700056a0 [MMObject]) at ../src/cbd-mm-manager.c:294
    #25 0x0000ffff832b64d0 in <emit signal '0xffff834acdd8 "interface-added" or interface-added' on instance 0xffff700056a0 [MMObject]>
        (instance=instance@entry=0xffff700056a0, detailed_signal=detailed_signal@entry=0xffff834acdd8 "interface-added")
        at ../../../gobject/gsignal.c:3638
        #22 0x0000ffff83298904 in g_closure_invoke
        (closure=0xaaaac482c230, return_value=0x0, n_param_values=2, param_values=0xffffc6c9c0a0, invocation_hint=0xffffc6c9bfd0) at ../../../gobject/gclosure.c:833
        #23 0x0000ffff832af2d0 in signal_emit_unlocked_R
        (node=node@entry=0xffffc6c9c198, detail=detail@entry=0, instance=instance@entry=0xffff700056a0, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0xffffc6c9c0a0) at ../../../gobject/gsignal.c:3902
        #24 0x0000ffff832b07a8 in signal_emit_valist_unlocked
        (instance=instance@entry=0xffff700056a0, signal_id=signal_id@entry=46, detail=<optimized out>, var_args=...)
        at ../../../gobject/gsignal.c:3534
    #26 0x0000ffff83462554 in _g_dbus_object_proxy_add_interface
        (proxy=proxy@entry=0xffff700056a0 [MMObject], interface_proxy=interface_proxy@entry=0xaaaac484e380 [MMModemCellBroadcast]) at ../../../gio/gdbusobjectproxy.c:316
    #27 0x0000ffff83463118 in add_interfaces
        (manager=manager@entry=0xaaaac48322a0 [MMManager], object_path=0xaaaac484d390 "/org/freedesktop/ModemManager1/Modem/0", ifaces_and_properties=<optimized out>, name_owner=0xffff700027f0 ":1.25")
        at ../../../gio/gdbusobjectmanagerclient.c:1625
    #28 0x0000ffff8346339c in on_control_proxy_g_signal
        (proxy=<optimized out>, sender_name=<optimized out>, signal_name=0xaaaac4840230 "InterfacesAdded", parameters=0xffff7800aff0, user_data=<optimized out>) at ../../../gio/gdbusobjectmanagerclient.c:1767
    #33 0x0000ffff832b62e0 in <emit signal 'g-signal' on instance 0xffff700013b0 [GDBusProxy]>
        (instance=instance@entry=0xffff700013b0, signal_id=signal_id@entry=21, detail=<optimized out>)
        at ../../../gobject/gsignal.c:3597
        #29 0x0000ffff83298904 in g_closure_invoke
        (closure=0xffff70002680, return_value=0x0, n_param_values=4, param_values=0xffffc6c9c8f0, invocation_hint=0xffffc6c9c820) at ../../../gobject/gclosure.c:833
        #30 0x0000ffff832af2d0 in signal_emit_unlocked_R
        (node=node@entry=0xffffc6c9ca18, detail=detail@entry=0, instance=instance@entry=0xffff700013b0, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0xffffc6c9c8f0) at ../../../gobject/gsignal.c:3902
        #31 0x0000ffff832b07a8 in signal_emit_valist_unlocked
        (instance=instance@entry=0xffff700013b0, signal_id=signal_id@entry=21, detail=detail@entry=0, var_args=...)
        at ../../../gobject/gsignal.c:3534
        #32 0x0000ffff832b6238 in g_signal_emit_valist (instance=0xffff700013b0, signal_id=21, detail=0, var_args=...)
        at ../../../gobject/gsignal.c:3277
    #34 0x0000ffff83450f4c in on_signal_received
        (connection=<optimized out>, sender_name=0xffff78004030 ":1.25", object_path=<optimized out>, interface_name=<optimized out>, signal_name=0xffff78009700 "InterfacesAdded", parameters=0xffff7800aff0, user_data=<optimized out>)
        at ../../../gio/gdbusproxy.c:876
    #35 0x0000ffff8343aad4 in emit_signal_instance_in_idle_cb (data=0xffff7800ec40) at ../../../gio/gdbusconnection.c:4207
    #36 0x0000ffff8314e234 in g_main_dispatch (context=context@entry=0xaaaac4802f00) at ../../../glib/gmain.c:3398
    #37 0x0000ffff831506fc in g_main_context_dispatch_unlocked (context=0xaaaac4802f00) at ../../../glib/gmain.c:4249
    #38 g_main_context_iterate_unlocked
        (context=context@entry=0xaaaac4802f00, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>)
        at ../../../glib/gmain.c:4314
    #39 0x0000ffff83150fa4 in g_main_context_iteration (context=context@entry=0xaaaac4802f00, may_block=may_block@entry=1)
        at ../../../glib/gmain.c:4379
    #40 0x0000ffff8340f74c in g_application_run
        (application=application@entry=0xaaaac4800070 [CbdDaemon], argc=argc@entry=1, argv=argv@entry=0xffffc6c9d0b8)
        at ../../../gio/gapplication.c:2715
    #41 0x0000aaaaad2288ec in main (argc=1, argv=0xffffc6c9d0b8) at ../src/cbd.c:18

Forwarded: https://gitlab.freedesktop.org/devrtz/cellbroadcastd/-/merge_requests/49
Signed-off-by: Guido Günther <agx@sigxcpu.org>
---
 src/cbd-mm-manager.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/cbd-mm-manager.c b/src/cbd-mm-manager.c
index 918141a..8141f8e 100644
--- a/src/cbd-mm-manager.c
+++ b/src/cbd-mm-manager.c
@@ -37,6 +37,7 @@ typedef struct _CbdMmManager {
   guint           watch_id;
   GCancellable   *cancellable;
   MMManager      *mm;
+  char           *mm_version;
 
   CbdChannelManager *channel_manager;
   GListModel        *modems;
@@ -51,19 +52,15 @@ G_DEFINE_FINAL_TYPE (CbdMmManager, cbd_mm_manager, G_TYPE_OBJECT);
 static gboolean
 is_cbm_support_blocklisted (CbdMmManager *self)
 {
-  const char *version;
-
   if (!self->mm)
     return TRUE;
 
-  version = mm_manager_get_version (self->mm);
-
   /* MM 1.24 has CBM support but doesn't support SetChannel and QMI.
    * Since older versions will never expose a CellBroadcast interface
    * and 1.25 already supports both SetChannel and QMI we only need to
    * blocklist that single version in order to make sure users don't
    * think they're all set */
-  if (g_str_has_prefix (version, "1.24."))
+  if (g_str_has_prefix (self->mm_version, "1.24."))
     return TRUE;
 
   return FALSE;
@@ -445,6 +442,8 @@ on_new_mm_manager (GDBusConnection *connection,
     return;
   }
 
+  self->mm_version = g_strdup (mm_manager_get_version (self->mm));
+
   g_signal_connect_swapped (self->mm,
                             "object-added",
                             G_CALLBACK (on_mm_object_added), self);
@@ -527,6 +526,8 @@ cbd_mm_manager_dispose (GObject *object)
   g_clear_object (&self->cancellable);
   g_clear_object (&self->mm);
 
+  g_clear_pointer (&self->mm_version, g_free);
+
   G_OBJECT_CLASS (cbd_mm_manager_parent_class)->dispose (object);
 }
 
