From mboxrd@z Thu Jan 1 00:00:00 1970 From: David Zeuthen Date: Sun, 07 Dec 2003 23:01:01 +0000 Subject: D-BUS patch for udev-008 MIME-Version: 1 Content-Type: multipart/mixed; boundary="=-2qKEd0F9QdrPRnwsV1Pi" Message-Id: List-Id: To: linux-hotplug@vger.kernel.org --=-2qKEd0F9QdrPRnwsV1Pi Content-Type: text/plain Content-Transfer-Encoding: 7bit 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 --=-2qKEd0F9QdrPRnwsV1Pi Content-Disposition: attachment; filename=udev-008_add_dbus_signals_dze.patch Content-Type: text/x-patch; name=udev-008_add_dbus_signals_dze.patch; charset=iso-8859-1 Content-Transfer-Encoding: 7bit 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 + +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 @@ + + + + + + + + + + + + + + + + + + --=-2qKEd0F9QdrPRnwsV1Pi-- ------------------------------------------------------- This SF.net email is sponsored by: IBM Linux Tutorials. Become an expert in LINUX or just sharpen your skills. Sign up for IBM's Free Linux Tutorials. Learn everything from the bash shell to sys admin. Click now! http://ads.osdn.com/?ad_id=1278&alloc_id=3371&op=click _______________________________________________ Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net Linux-hotplug-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel