[PATCH 07/10] mmcli: new '--report-kernel-event-udev' to report kernel events based on udev
Aleksander Morgado
aleksander at aleksander.es
Sat Aug 6 13:03:35 UTC 2016
This new mmcli command automatically reports kernel events from the info
gathered from udev. E.g. can be used when the ModemManager daemon was launched
with '--no-auto-scan'.
---
cli/Makefile.am | 5 +++
cli/mmcli-manager.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 100 insertions(+), 1 deletion(-)
diff --git a/cli/Makefile.am b/cli/Makefile.am
index d2573db..6c2d791 100644
--- a/cli/Makefile.am
+++ b/cli/Makefile.am
@@ -38,6 +38,11 @@ mmcli_LDADD = \
$(top_builddir)/libmm-glib/libmm-glib.la \
$(NULL)
+if WITH_UDEV
+mmcli_CPPFLAGS += $(GUDEV_CFLAGS)
+mmcli_LDADD += $(GUDEV_LIBS)
+endif
+
completiondir = $(datadir)/bash-completion/completions
install-data-hook:
diff --git a/cli/mmcli-manager.c b/cli/mmcli-manager.c
index d78734f..4818b3d 100644
--- a/cli/mmcli-manager.c
+++ b/cli/mmcli-manager.c
@@ -15,8 +15,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
- * Copyright (C) 2011 Aleksander Morgado <aleksander at gnu.org>
* Copyright (C) 2011 Google, Inc.
+ * Copyright (C) 2011-2016 Aleksander Morgado <aleksander at aleksander.es>
*/
#include "config.h"
@@ -29,6 +29,10 @@
#include <glib.h>
#include <gio/gio.h>
+#if WITH_UDEV
+# include <gudev/gudev.h>
+#endif
+
#define _LIBMM_INSIDE_MMCLI
#include "libmm-glib.h"
@@ -39,6 +43,9 @@
typedef struct {
MMManager *manager;
GCancellable *cancellable;
+#if WITH_UDEV
+ GUdevClient *udev;
+#endif
} Context;
static Context *ctx;
@@ -49,6 +56,10 @@ static gboolean scan_modems_flag;
static gchar *set_logging_str;
static gchar *report_kernel_event_str;
+#if WITH_UDEV
+static gboolean report_kernel_event_udev;
+#endif
+
static GOptionEntry entries[] = {
{ "set-logging", 'G', 0, G_OPTION_ARG_STRING, &set_logging_str,
"Set logging level in the ModemManager daemon",
@@ -70,6 +81,12 @@ static GOptionEntry entries[] = {
"Report kernel event",
"[\"key=value,...\"]"
},
+#if WITH_UDEV
+ { "report-kernel-event-udev", 0, 0, G_OPTION_ARG_NONE, &report_kernel_event_udev,
+ "Automatically report kernel events based on udev notifications",
+ NULL
+ },
+#endif
{ NULL }
};
@@ -104,6 +121,10 @@ mmcli_manager_options_enabled (void)
!!set_logging_str +
!!report_kernel_event_str);
+#if WITH_UDEV
+ n_actions += report_kernel_event_udev;
+#endif
+
if (n_actions > 1) {
g_printerr ("error: too many manager actions requested\n");
exit (EXIT_FAILURE);
@@ -112,6 +133,11 @@ mmcli_manager_options_enabled (void)
if (monitor_modems_flag)
mmcli_force_async_operation ();
+#if WITH_UDEV
+ if (report_kernel_event_udev)
+ mmcli_force_async_operation ();
+#endif
+
checked = TRUE;
return !!n_actions;
}
@@ -122,6 +148,11 @@ context_free (Context *ctx)
if (!ctx)
return;
+#if WITH_UDEV
+ if (ctx->udev)
+ g_object_unref (ctx->udev);
+#endif
+
if (ctx->manager)
g_object_unref (ctx->manager);
if (ctx->cancellable)
@@ -294,6 +325,26 @@ cancelled (GCancellable *cancellable)
mmcli_async_operation_done ();
}
+#if WITH_UDEV
+
+static void
+handle_uevent (GUdevClient *client,
+ const char *action,
+ GUdevDevice *device,
+ gpointer none)
+{
+ MMKernelEventProperties *properties;
+
+ properties = mm_kernel_event_properties_new ();
+ mm_kernel_event_properties_set_action (properties, action);
+ mm_kernel_event_properties_set_subsystem (properties, g_udev_device_get_subsystem (device));
+ mm_kernel_event_properties_set_name (properties, g_udev_device_get_name (device));
+ mm_manager_report_kernel_event (ctx->manager, properties, NULL, NULL, NULL);
+ g_object_unref (properties);
+}
+
+#endif
+
static void
get_manager_ready (GObject *source,
GAsyncResult *result,
@@ -337,6 +388,42 @@ get_manager_ready (GObject *source,
return;
}
+#if WITH_UDEV
+ if (report_kernel_event_udev) {
+ const gchar *subsys[] = { "tty", "usbmisc", "net", NULL };
+ guint i;
+
+ ctx->udev = g_udev_client_new (subsys);
+ g_signal_connect (ctx->udev, "uevent", G_CALLBACK (handle_uevent), NULL);
+
+ for (i = 0; subsys[i]; i++) {
+ GList *list, *iter;
+
+ list = g_udev_client_query_by_subsystem (ctx->udev, subsys[i]);
+ for (iter = list; iter; iter = g_list_next (iter)) {
+ MMKernelEventProperties *properties;
+ GUdevDevice *device;
+
+ device = G_UDEV_DEVICE (iter->data);
+ properties = mm_kernel_event_properties_new ();
+ mm_kernel_event_properties_set_action (properties, "add");
+ mm_kernel_event_properties_set_subsystem (properties, subsys[i]);
+ mm_kernel_event_properties_set_name (properties, g_udev_device_get_name (device));
+ mm_manager_report_kernel_event (ctx->manager, properties, NULL, NULL, NULL);
+ g_object_unref (properties);
+ }
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+ }
+
+ /* If we get cancelled, operation done */
+ g_cancellable_connect (ctx->cancellable,
+ G_CALLBACK (cancelled),
+ NULL,
+ NULL);
+ return;
+ }
+#endif
+
/* Request to monitor modems? */
if (monitor_modems_flag) {
g_signal_connect (ctx->manager,
@@ -393,6 +480,13 @@ mmcli_manager_run_synchronous (GDBusConnection *connection)
exit (EXIT_FAILURE);
}
+#if WITH_UDEV
+ if (report_kernel_event_udev) {
+ g_printerr ("error: monitoring udev events cannot be done synchronously\n");
+ exit (EXIT_FAILURE);
+ }
+#endif
+
/* Initialize context */
ctx = g_new0 (Context, 1);
ctx->manager = mmcli_get_manager_sync (connection);
--
2.9.0
More information about the ModemManager-devel
mailing list