linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* D-BUS patch for udev-008
@ 2003-12-07 23:01 David Zeuthen
  2003-12-08  0:34 ` Rob Love
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: David Zeuthen @ 2003-12-07 23:01 UTC (permalink / raw)
  To: linux-hotplug

[-- Attachment #1: Type: text/plain, Size: 1705 bytes --]

Hi,

Attached is a patch against udev-008 to send out a D-BUS message when a
device node is added or removed.

Using D-BUS lingo, udev acquires the org.kernel.udev service and sends
out a NodeCreated or NodeDeleted signal on the
org.kernel.udev.NodeMonitor interface. Each signal carries two
parameters: the node in question and the corresponding sysfs path.

[Note: the D-BUS concepts of service, interface, object can be a bit
confusing at first glance]

An example program listening for these messages looks like this

#!/usr/bin/python
 
import dbus
import gtk
 
def udev_signal_received(dbus_iface, member, service, object_path,
message):
    [filename, sysfs_path] = message.get_args_list()
    if member=='NodeCreated':
        print 'Node %s created for %s'%(filename, sysfs_path)
    elif member=='NodeDeleted':
        print 'Node %s deleted for %s'%(filename, sysfs_path)
 
def main():
    bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
    bus.add_signal_receiver(udev_signal_received,
                            'org.kernel.udev.NodeMonitor',  # interface
                            'org.kernel.udev',              # service
                            '/org/kernel/udev/NodeMonitor') # object
 
    gtk.mainloop()
 
if __name__ == '__main__':
    main()

and this is the output when hot-plugging some usb-storage.

[david@laptop udev-008]$ ~/node_monitor.py
Node /udev/sda created for /block/sda
Node /udev/sda1 created for /block/sda/sda1
Node /udev/sda1 deleted for /block/sda/sda1
Node /udev/sda deleted for /block/sda

The patch requires D-BUS 0.20 or later while the python example program
requires D-BUS from CVS as I only recently applied a patch against the
python bindings.
 
Cheers,
David

[-- Attachment #2: udev-008_add_dbus_signals_dze.patch --]
[-- Type: text/x-patch, Size: 9910 bytes --]

diff -Nru ../orig/udev-008/Makefile ./Makefile
--- ../orig/udev-008/Makefile	2003-12-03 22:57:27.000000000 +0100
+++ ./Makefile	2003-12-07 23:27:28.670247544 +0100
@@ -20,6 +20,10 @@
 # Leave this set to `false' for production use.
 DEBUG = false
 
+# Set the following to `true' to make udev emit a D-BUS signal when a
+# new node is created.
+USE_DBUS = true
+
 
 ROOT =		udev
 VERSION =	008
@@ -34,6 +38,7 @@
 sbindir =	${exec_prefix}/sbin
 mandir =	${prefix}/usr/share/man
 hotplugdir =	${etcdir}/hotplug.d/default
+dbusdir =	${etcdir}/dbus-1/system.d
 configdir =	${etcdir}/udev/
 srcdir = .
 
@@ -133,6 +138,13 @@
 	LDFLAGS = --static 
 endif
 
+ifeq ($(USE_DBUS), true)
+	CFLAGS += -DUSE_DBUS
+	CFLAGS += $(shell pkg-config --cflags dbus-1)
+	LIB_OBJS += $(shell pkg-config --libs-only-l dbus-1)
+endif
+
+
 all: $(ROOT)
 
 $(ROOT): $(LIBC)
@@ -225,7 +237,20 @@
 	@echo "Built $(RELEASE_NAME).tar.gz"
 
 
-install: all
+ifeq ($(USE_DBUS), true)
+install-dbus-policy:
+	$(INSTALL) -d $(DESTDIR)$(dbusdir)
+	$(INSTALL_DATA) udev_sysbus_policy.conf $(DESTDIR)$(dbusdir)
+uninstall-dbus-policy:
+	- rm $(DESTDIR)$(dbusdir)/udev_sysbus_policy.conf
+else
+install-dbus-policy:
+	-
+uninstall-dbus-policy:
+	-
+endif
+
+install: install-dbus-policy all
 	$(INSTALL) -d $(DESTDIR)$(udevdir)
 	$(INSTALL) -d $(DESTDIR)$(configdir)
 	$(INSTALL) -d $(DESTDIR)$(hotplugdir)
@@ -237,7 +262,7 @@
 	- rm -f $(DESTDIR)$(hotplugdir)/udev.hotplug
 	- ln -s $(sbindir)/$(ROOT) $(DESTDIR)$(hotplugdir)/udev.hotplug
 
-uninstall:
+uninstall: uninstall-dbus-policy
 	- rm $(hotplugdir)/udev.hotplug
 	- rm $(configdir)/udev.permissions
 	- rm $(configdir)/udev.rules
diff -Nru ../orig/udev-008/TODO ./TODO
--- ../orig/udev-008/TODO	2003-12-03 09:17:53.000000000 +0100
+++ ./TODO	2003-12-07 23:31:20.114062736 +0100
@@ -21,7 +21,6 @@
   will have an upgrade path.
 - do early boot logic (putting udev into initramfs, handle pivot-root,
   etc.)
-- add hooks to call D-BUS when new node is created or removed
 - lots of other stuff...
 - actually use the BUS= value to determine where the LABEL rule should look
   (right now it's ignored, and we only look in the current sysfs directory.)
diff -Nru ../orig/udev-008/udev-add.c ./udev-add.c
--- ../orig/udev-008/udev-add.c	2003-11-24 14:52:18.000000000 +0100
+++ ./udev-add.c	2003-12-07 23:18:12.547791008 +0100
@@ -72,6 +72,42 @@
 	return retval;
 }
 
+#ifdef USE_DBUS
+/** Send out a signal that a device node is created
+ *
+ *  @param  dev                 udevice object
+ *  @param  path                Sysfs path of device
+ */
+static void sysbus_send_create(struct udevice *dev, const char *path)
+{
+        char filename[255];
+        DBusMessage* message;
+        DBusMessageIter iter;
+
+        if (sysbus_connection == NULL)
+                return;
+
+        strncpy(filename, udev_root, sizeof(filename));
+        strncat(filename, dev->name, sizeof(filename));
+
+        /* object, interface, member */
+        message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", 
+                                          "org.kernel.udev.NodeMonitor",
+                                          "NodeCreated");
+        
+        dbus_message_iter_init(message, &iter);
+        dbus_message_iter_append_string(&iter, filename);
+        dbus_message_iter_append_string(&iter, path);
+
+        if ( !dbus_connection_send(sysbus_connection, message, NULL) )
+                dbg("error sending d-bus signal");
+
+        dbus_message_unref(message);
+        
+        dbus_connection_flush(sysbus_connection);
+}
+#endif /* USE_DBUS */
+
 /*
  * we possibly want to add some symlinks here
  * only numeric owner/group id's are supported
@@ -278,6 +314,12 @@
 	dbg("name='%s'", dev.name);
 	retval = create_node(&dev);
 
+#ifdef USE_DBUS
+        if (retval == 0) {
+                sysbus_send_create(&dev, path);
+        }
+#endif /* USE_DBUS */
+
 exit:
 	if (class_dev)
 		sysfs_close_class_device(class_dev);
diff -Nru ../orig/udev-008/udev.c ./udev.c
--- ../orig/udev-008/udev.c	2003-12-03 08:39:47.000000000 +0100
+++ ./udev.c	2003-12-07 23:17:50.984069192 +0100
@@ -63,6 +63,60 @@
 	return seqnum;
 }
 
+#ifdef USE_DBUS
+
+/** Global variable for the connection the to system message bus or #NULL
+ *  if we cannot connect or acquire the org.kernel.udev service
+ */
+DBusConnection* sysbus_connection;
+
+/** Disconnect from the system message bus */
+static void sysbus_disconnect()
+{
+        if (sysbus_connection == NULL)
+                return;
+
+        dbus_connection_disconnect(sysbus_connection);
+        sysbus_connection = NULL;
+}
+
+/** Connect to the system message bus */
+static void sysbus_connect()
+{
+        DBusError error;
+
+        /* Connect to a well-known bus instance, the system bus */
+        dbus_error_init(&error);
+        sysbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+        if (sysbus_connection == NULL) {
+                dbg("cannot connect to system message bus, error %s: %s", 
+                    error.name, error.message);
+                dbus_error_free(&error);
+                return;
+        }
+
+        /*  Acquire the org.kernel.udev service such that listeners
+         *  know that the message is really from us and not from a
+         *  random attacker. See the file udev_sysbus_policy.conf for
+         *  details.
+         *
+         *  Note that a service can have multiple owners (though there
+         *  is a concept of a primary owner for reception of messages)
+         *  so no race is introduced if two copies of udev is running
+         *  at the same time.
+         */
+        dbus_bus_acquire_service(sysbus_connection, "org.kernel.udev", 0, 
+                                 &error);
+        if (dbus_error_is_set(&error)) {
+                printf("cannot acquire org.kernel.udev service, error %s: %s'",
+                       error.name, error.message);
+                sysbus_disconnect();
+                return;
+        }
+}
+
+#endif /* USE_DBUS */
+
 int main(int argc, char **argv, char **envp)
 {
 	char *action;
@@ -111,6 +165,11 @@
 	/* initialize our configuration */
 	udev_init_config();
 
+#ifdef USE_DBUS
+        /* connect to the system message bus */
+        sysbus_connect();
+#endif /* USE_DBUS */
+
 	/* initialize udev database */
 	retval = udevdb_init(UDEVDB_DEFAULT);
 	if (retval != 0) {
@@ -133,6 +192,11 @@
 	}
 	udevdb_exit();
 
+#ifdef USE_DBUS
+        /* disconnect from the system message bus */
+        sysbus_disconnect();
+#endif /* USE_DBUS */
+
 exit:	
 	return retval;
 }
diff -Nru ../orig/udev-008/udev.h ./udev.h
--- ../orig/udev-008/udev.h	2003-12-03 19:30:25.000000000 +0100
+++ ./udev.h	2003-12-07 20:06:27.000000000 +0100
@@ -92,4 +92,13 @@
 extern char udev_rules_filename[PATH_MAX+NAME_MAX];
 extern char default_mode_str[NAME_MAX];
 
+#ifdef USE_DBUS
+
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus.h>
+
+extern DBusConnection* sysbus_connection;
+
+#endif /* USE_DBUS */
+
 #endif
diff -Nru ../orig/udev-008/udev-remove.c ./udev-remove.c
--- ../orig/udev-008/udev-remove.c	2003-11-24 14:52:18.000000000 +0100
+++ ./udev-remove.c	2003-12-07 23:18:40.842489560 +0100
@@ -110,6 +110,42 @@
 	return retval;
 }
 
+#ifdef USE_DBUS
+/** Send out a signal that a device node is deleted
+ *
+ *  @param  name                Name of the device node, e.g. /udev/sda1
+ *  @param  path                Sysfs path of device
+ */
+static void sysbus_send_remove(const char* name, const char *path)
+{
+        char filename[255];
+        DBusMessage* message;
+        DBusMessageIter iter;
+
+        if (sysbus_connection == NULL)
+                return;
+
+        strncpy(filename, udev_root, sizeof(filename));
+        strncat(filename, name, sizeof(filename));
+
+        /* object, interface, member */
+        message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", 
+                                          "org.kernel.udev.NodeMonitor",
+                                          "NodeDeleted");
+        
+        dbus_message_iter_init(message, &iter);
+        dbus_message_iter_append_string(&iter, filename);
+        dbus_message_iter_append_string(&iter, path);
+        
+        if ( !dbus_connection_send(sysbus_connection, message, NULL) )
+                dbg("error sending d-bus signal");
+        
+        dbus_message_unref(message);
+
+        dbus_connection_flush(sysbus_connection);
+}
+#endif /* USE_DBUS */
+
 int udev_remove_device(char *device, char *subsystem)
 {
 	char *name;
@@ -122,9 +158,15 @@
 		goto exit;
 	}
 
-	udevdb_delete_dev(device);
+	retval = udevdb_delete_dev(device);
+
+#ifdef USE_DBUS
+        if (retval == 0) {
+                sysbus_send_remove(name, device);
+        }
+#endif /* USE_DBUS */
 
-	return delete_node(name);
+ 
 
 exit:
 	return retval;
diff -Nru ../orig/udev-008/udev_sysbus_policy.conf ./udev_sysbus_policy.conf
--- ../orig/udev-008/udev_sysbus_policy.conf	1970-01-01 01:00:00.000000000 +0100
+++ ./udev_sysbus_policy.conf	2003-12-07 22:28:55.000000000 +0100
@@ -0,0 +1,23 @@
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+
+  <!-- This configuration file specifies the required security policies
+       for udev to work. -->
+
+  <!-- Only root can own the udev service and only root can use the
+       org.kernel.udev.NodeMonitor interface to send signals -->
+  <policy user="root">
+    <allow own="org.kernel.udev"/>
+
+    <allow send_interface="org.kernel.udev.NodeMonitor"/>
+  </policy>
+
+  <!-- Allow anyone to listen to the org.kernel.udev.NodeMonitor interface 
+       for messages send from the owner of the org.kernel.udev service -->
+  <policy context="default">
+    <allow receive_interface="org.kernel.udev.NodeMonitor"/>
+  </policy>
+</busconfig>
+

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2003-12-10  1:02 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-12-07 23:01 D-BUS patch for udev-008 David Zeuthen
2003-12-08  0:34 ` Rob Love
2003-12-08 19:40 ` Greg KH
2003-12-08 20:11 ` David Zeuthen
2003-12-10  1:02 ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).