diff options
-rw-r--r-- | ChangeLog | 14 | ||||
-rwxr-xr-x | examples/volumed/volumed.py | 24 | ||||
-rw-r--r-- | hald/linux/linux_class_block.c | 7 | ||||
-rw-r--r-- | hald/linux/linux_class_scsi.c | 2 | ||||
-rw-r--r-- | hald/linux/linux_osspec.c | 101 | ||||
-rw-r--r-- | hald/linux/linux_usb.c | 1 | ||||
-rw-r--r-- | tools/linux/hal_hotplug.c | 9 |
7 files changed, 142 insertions, 16 deletions
@@ -1,5 +1,19 @@ 2003-12-21 David Zeuthen <david@fubar.dk> + * examples/volumed/volumed.py: be less verbose + + * hald/linux/linux_osspec (osspec_init): Add match for udev signals + (osspec_hotplug): renamed to handle_hotplug since old name didn't make + any sense + (handle_udev_node_created): new function + (handle_udev_node_created_found_device): new function + (osspec_filter_function): add check for udev signals + + * tools/linux/hal_hotplug.c (main): sleep a while so the kernel has + time to populate sysfs (hmmm) + +2003-12-21 David Zeuthen <david@fubar.dk> + * Doxyfile.in: add tools directory * hald/device_store.c: fixup doxygen grouping diff --git a/examples/volumed/volumed.py b/examples/volumed/volumed.py index 5ace4793..5d7cf5e4 100755 --- a/examples/volumed/volumed.py +++ b/examples/volumed/volumed.py @@ -10,10 +10,12 @@ import time # # A volume daemon should also support optical and floppy disks, it should # handle multi-session cdroms and much more. Maybe someone will write -# this one day... +# this one day... Maybe the disc change stuff should even be in HAL? +# +# This requires udev with D-BUS enabled and HAL to work correctly # -def get_mount_point(udi, device_name): +def get_mount_location(udi, device_name): """Given a the UDI for a device and the name of the device file, determine a name for the mount point""" return '/mnt/somewhere/unique%f'%(time.time()) @@ -23,19 +25,19 @@ def attempt_mount(udi): dobj = hal_service.get_object(udi, 'org.freedesktop.Hal.Device') if (not mount_dict.has_key(udi)) and dobj.PropertyExists('block.device'): device = dobj.GetProperty('block.device') - mount_point = get_mount_point(udi, device) - print "mounting device=%s at %s udi=%s"%(device, mount_point, udi) - mount_dict[udi] = mount_point + mount_location = get_mount_location(udi, device) + print "mounting device=%s at %s udi=%s"%(device, mount_location, udi) + mount_dict[udi] = mount_location def unmount(udi): """Unmount a device""" - mount_point = mount_dict[udi] - print "unmounting %s"%mount_point + mount_location = mount_dict[udi] + print "unmounting %s"%mount_location del mount_dict[udi] def device_changed(dbus_if, member, svc, obj_path, message): """Called when properties on a HAL device changes""" - print member + #print member udi = obj_path if udi in vol_list: attempt_mount(udi) @@ -43,7 +45,7 @@ def device_changed(dbus_if, member, svc, obj_path, message): def gdl_changed(dbus_if, member, svc, obj_path, message): """Called when a HAL device is added, removed or it got a new capability""" - print member + #print member if member=='NewCapability': [udi, cap] = message.get_args_list() if cap=='volume': @@ -55,7 +57,7 @@ def gdl_changed(dbus_if, member, svc, obj_path, message): udi) attempt_mount(udi) - print " %s %s"%(cap,udi) + #print " %s %s"%(cap,udi) elif member=='DeviceRemoved': [udi] = message.get_args_list() @@ -70,6 +72,8 @@ def gdl_changed(dbus_if, member, svc, obj_path, message): elif member=='DeviceAdded': [udi] = message.get_args_list() dobj = hal_service.get_object(udi, 'org.freedesktop.Hal.Device') + #if dobj.PropertyExists('Capabilities'): + # print ' caps=%s'%(dobj.GetProperty('Capabilities')) if dobj.QueryCapability('volume'): vol_list.append(udi) bus.add_signal_receiver(device_changed, diff --git a/hald/linux/linux_class_block.c b/hald/linux/linux_class_block.c index 0f2624f9..93bdd79d 100644 --- a/hald/linux/linux_class_block.c +++ b/hald/linux/linux_class_block.c @@ -183,9 +183,13 @@ void visit_class_device_block(const char* path, ds_device_async_find_by_key_value_string("Linux.sysfs_path_device", parent_sysfs_path, visit_class_device_block_got_parent, - (void*) d, NULL, + (void*) d, + (void*) parent_sysfs_path/*NULL*/, is_probing ? 0 : HAL_LINUX_HOTPLUG_TIMEOUT); + + HAL_INFO(("*** finding parent_sysfs_path=%s, 0x%08x", + parent_sysfs_path, parent_sysfs_path)); } /** Callback when the parent is found or if there is no parent.. This is @@ -202,6 +206,7 @@ static void visit_class_device_block_got_parent(HalDevice* parent, if( parent==NULL ) { + HAL_INFO(("data2=0x%08x", data2)); HAL_WARNING(("No parent for block device!")); ds_device_destroy(d); return; diff --git a/hald/linux/linux_class_scsi.c b/hald/linux/linux_class_scsi.c index 5254c9d2..6b3d3c17 100644 --- a/hald/linux/linux_class_scsi.c +++ b/hald/linux/linux_class_scsi.c @@ -186,7 +186,7 @@ static void visit_class_device_scsi_host_got_parent(HalDevice* parent, { HalDevice* d = (HalDevice*) data1; - printf("parent=0x%08x\n", parent); + /*printf("parent=0x%08x\n", parent);*/ if( parent!=NULL ) { diff --git a/hald/linux/linux_osspec.c b/hald/linux/linux_osspec.c index fea372b6..17795a38 100644 --- a/hald/linux/linux_osspec.c +++ b/hald/linux/linux_osspec.c @@ -218,6 +218,7 @@ static void visit_device(const char* path, dbus_bool_t visit_children) void osspec_init(DBusConnection* dbus_connection) { int rc; + DBusError error; /* get mount path for sysfs */ rc = sysfs_get_mnt_path(sysfs_mount_path, SYSFS_PATH_MAX); @@ -233,6 +234,19 @@ void osspec_init(DBusConnection* dbus_connection) linux_class_scsi_init(); linux_class_block_init(); linux_class_net_init(); + + /* Add match for signals from udev */ + dbus_error_init(&error); + dbus_bus_add_match(dbus_connection, + "type='signal'," + "interface='org.kernel.udev.NodeMonitor'," + /*"sender='org.kernel.udev'," until D-BUS is fixed*/ + "path='/org/kernel/udev/NodeMonitor'", &error); + if( dbus_error_is_set(&error) ) + { + HAL_WARNING(("Cannot subscribe to udev signals, error=%s", + error.message)); + } } /** This is set to #TRUE if we are probing and #FALSE otherwise */ @@ -309,7 +323,7 @@ void osspec_probe() * @param message Message * @return What to do with the message */ -static DBusHandlerResult osspec_hotplug(DBusConnection* connection, +static DBusHandlerResult handle_hotplug(DBusConnection* connection, DBusMessage* message) { DBusMessageIter iter; @@ -467,6 +481,75 @@ static DBusHandlerResult osspec_hotplug(DBusConnection* connection, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } +/* fwd decl */ +static void handle_udev_node_created_found_device(HalDevice* d, + void* data1, void* data2); + +/** Handle a org.freedesktop.Hal.HotplugEvent message. This message + * origins from the hal.hotplug program, tools/linux/hal_hotplug.c, + * and is basically just a D-BUS-ification of the hotplug event. + * + * @param connection D-BUS connection + * @param message Message + * @return What to do with the message + */ +static DBusHandlerResult handle_udev_node_created(DBusConnection* connection, + DBusMessage* message) +{ + char* filename; + char* sysfs_path; + char sysfs_dev_path[SYSFS_PATH_MAX]; + + if( dbus_message_get_args(message, NULL, + DBUS_TYPE_STRING, &filename, + DBUS_TYPE_STRING, &sysfs_path, + DBUS_TYPE_INVALID) ) + { + strncpy(sysfs_dev_path, sysfs_mount_path, SYSFS_PATH_MAX); + strncat(sysfs_dev_path, sysfs_path, SYSFS_PATH_MAX); + HAL_INFO(("udev NodeCreated: %s %s\n", filename, sysfs_dev_path)); + + /* Find block device; this happens asynchronously as our it might + * be added later.. + */ + ds_device_async_find_by_key_value_string( + "Linux.sysfs_path_device", + sysfs_dev_path, + handle_udev_node_created_found_device, + (void*) filename, NULL, + HAL_LINUX_HOTPLUG_TIMEOUT); + + /* NOTE NOTE NOTE: we will free filename in async result function */ + + dbus_free(sysfs_path); + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +/** Callback when the block device is found or if there is none.. + * + * @param d Async Return value from the find call + * @param data1 User data, in this case the filename + * @param data2 User data + */ +static void handle_udev_node_created_found_device(HalDevice* d, + void* data1, void* data2) +{ + char* filename = (char*) data1; + + if( d!=NULL ) + { + ds_property_set_string(d, "block.device", filename); + } + else + { + HAL_WARNING(("No HAL device corresponding to device %s", filename)); + } + + dbus_free(filename); +} + /** Message handler for method invocations. All invocations on any object * or interface is routed through this function. * @@ -479,6 +562,7 @@ DBusHandlerResult osspec_filter_function(DBusConnection* connection, DBusMessage* message, void* user_data) { + /* HAL_INFO(("obj_path=%s interface=%s method=%s", dbus_message_get_path(message), @@ -493,7 +577,20 @@ DBusHandlerResult osspec_filter_function(DBusConnection* connection, strcmp(dbus_message_get_path(message), "/org/freedesktop/Hal/Linux/Hotplug")==0 ) { - return osspec_hotplug(connection, message); + return handle_hotplug(connection, message); + } + else if( dbus_message_is_signal(message, + "org.kernel.udev.NodeMonitor", + "NodeCreated") ) + { + return handle_udev_node_created(connection, message); + } + else if( dbus_message_is_signal(message, "org.kernel.udev.NodeMonitor", + "NodeDeleted") ) + { + /* This is left intentionally blank since this it means that a + * block device is removed and we'll catch that other places + */ } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; diff --git a/hald/linux/linux_usb.c b/hald/linux/linux_usb.c index 175f8484..afb4bd51 100644 --- a/hald/linux/linux_usb.c +++ b/hald/linux/linux_usb.c @@ -846,6 +846,7 @@ void visit_device_usb(const char* path, struct sysfs_device *device) /* USB interfaces are handled by a separate function */ if( is_interface ) { + HAL_INFO(("usb device @ %s is an interface", path)); visit_device_usb_interface(path, device); return; } diff --git a/tools/linux/hal_hotplug.c b/tools/linux/hal_hotplug.c index 29b23c7f..d982d305 100644 --- a/tools/linux/hal_hotplug.c +++ b/tools/linux/hal_hotplug.c @@ -101,14 +101,19 @@ int main(int argc, char* argv[], char* envp[]) dbus_message_iter_append_string(&iter_dict, str+j+1); } + /* Do some sleep here so the kernel have time to publish it's + * stuff in sysfs + */ + usleep(500*1000); + if ( !dbus_connection_send(sysbus_connection, message, NULL) ) return 1; dbus_message_unref(message); dbus_connection_flush(sysbus_connection); - /* If I don't do this messages are lost.. */ - sleep(1); + /* Do some sleep here so messages are not lost.. */ + usleep(500*1000); dbus_connection_disconnect(sysbus_connection); |