summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rwxr-xr-xexamples/volumed/volumed.py24
-rw-r--r--hald/linux/linux_class_block.c7
-rw-r--r--hald/linux/linux_class_scsi.c2
-rw-r--r--hald/linux/linux_osspec.c101
-rw-r--r--hald/linux/linux_usb.c1
-rw-r--r--tools/linux/hal_hotplug.c9
7 files changed, 142 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 84046cd6..9e1857c2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);