hal/hald/linux block_class_device.c, 1.53, 1.54 bus_device.c, 1.16,
1.17 class_device.c, 1.24, 1.25 ide_bus_device.c, 1.7,
1.8 ide_host_bus_device.c, 1.8, 1.9
David Zeuthen
david at freedesktop.org
Mon Aug 16 11:52:59 PDT 2004
Update of /cvs/hal/hal/hald/linux
In directory pdx:/tmp/cvs-serv7577/hald/linux
Modified Files:
block_class_device.c bus_device.c class_device.c
ide_bus_device.c ide_host_bus_device.c
Log Message:
2004-08-16 David Zeuthen <david at fubar.dk>
* configure.in: Add the --enable-fstab-op to specify whether we
want to use a keyword (currently kudzu) when adding entries
to the fstab. Default is off
* hald/linux/block_class_device.c:
(block_class_visit): Only return the HalDevice if the parent exists
(detect_media): Print out debug statement when we forcibly probe
for media
(block_class_pre_process): Detect the ide-cs driver by looking at
the sysfs path (!) and set the media_check_enable to FALSE. Only
do volume_id and drive_id probing if storage.media_check_enabled
is TRUE. Sets the volume.fstype to 'vfat,msdos,auto' in this case.
Fixes issues with the ide-cs driver
(block_class_in_gdl): Add a comment about how we could defer
the check for non-partitioned media via a timeout
(deferred_check_for_non_partition_media): The function to check
for media; not currently used
(mtab_handle_storage): Use detect_media() to add the new child
when a non-partition volume we didn't know about was mounted
(mtab_handle_volume): Remove non partitioned media on drives
that can't be polled when it's unmounted.
* hald/linux/bus_device.c:
(bus_device_visit): Only return the HalDevice if the parent exists
* hald/linux/class_device.c:
(class_device_visit): Only return the HalDevice if the parent exists
(class_device_got_parent_device): Print out the sysfs path instead
of the HAL UDI
* hald/linux/ide_bus_device.c:
(ide_device_accept): New function; currently the same as the super
class but useful for testing
* hald/linux/ide_host_bus_device.c:
(ide_host_device_accept): Don't pickup toplevel ide_host objects
cause they're not hotplugged anyway (thus no way to remove them)
* tools/fstab-sync.c:
(volume_new): Also check if the volume.fstype is empty
Index: block_class_device.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/block_class_device.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -d -r1.53 -r1.54
--- block_class_device.c 15 Aug 2004 18:54:56 -0000 1.53
+++ block_class_device.c 16 Aug 2004 18:52:39 -0000 1.54
@@ -74,6 +74,8 @@
static char *block_class_compute_udi (HalDevice * d, int append_num);
+static gboolean deferred_check_for_non_partition_media (gpointer data);
+
static void
set_volume_id_values(HalDevice *d, struct volume_id *vid)
@@ -211,7 +213,19 @@
/*hal_device_print (d);*/
- return d;
+ /* Now that a) hotplug happens in the right order; and b) the device
+ * from a hotplug event is completely added to the GDL before the
+ * next event is processed; the aysnc call above is actually
+ * synchronous so we can test immediately whether we want to
+ * proceed
+ */
+ if (hal_device_store_match_key_value_string (
+ hald_get_gdl (),
+ "linux.sysfs_path_device",
+ parent_sysfs_path) == NULL)
+ return NULL;
+ else
+ return d;
}
@@ -659,9 +673,14 @@
got_media = FALSE;
device_file = hal_device_property_get_string (d, "block.device");
+
if (device_file == NULL)
return FALSE;
+ if (force_poll) {
+ HAL_INFO (("Forcing check for media check on device %s", device_file));
+ }
+
if (is_cdrom)
fd = open (device_file, O_RDONLY | O_NONBLOCK | O_EXCL);
else
@@ -1099,12 +1118,26 @@
hal_device_property_set_bool (d, "volume.is_disc", FALSE);
hal_device_property_set_bool (d, "volume.is_mounted", FALSE);
- vid = volume_id_open_node(device_file);
- if (vid != NULL) {
- if (volume_id_probe(vid, VOLUME_ID_ALL, 0) == 0) {
- set_volume_id_values(d, vid);
+ /* only check for volume_id if we are allowed to poll, otherwise we may
+ * cause inifite loops of hotplug events, cf. broken ide-cs driver and
+ * broken zip drives. Merely accessing the top-level block device if it
+ * or any of it partitions are not mounted causes the loop.
+ */
+ if (hal_device_property_get_bool (stordev, "storage.media_check_enabled")) {
+ vid = volume_id_open_node(device_file);
+ if (vid != NULL) {
+ if (volume_id_probe(vid, VOLUME_ID_ALL, 0) == 0) {
+ set_volume_id_values(d, vid);
+ }
+ volume_id_close(vid);
}
- volume_id_close(vid);
+ } else {
+ /* gee, so at least set volume.fstype vfat,msdos,auto so
+ * mount(1) doesn't screw up and causes hotplug events
+ *
+ * GRRRR!!!
+ */
+ hal_device_property_set_string (d, "volume.fstype", "vfat,msdos,auto");
}
return;
@@ -1129,10 +1162,28 @@
"ide") == 0) {
const char *ide_name;
char *model;
- const char *device_file;
- struct drive_id *did;
char *media;
+
+ /* blacklist the broken ide-cs driver */
+ if (physdev != NULL) {
+ size_t len;
+ char buf[256];
+ const char *physdev_sysfs_path;
+
+ snprintf (buf, 256, "%s/devices/ide", sysfs_mount_path);
+ len = strlen (buf);
+
+ physdev_sysfs_path = hal_device_property_get_string (physdev, "linux.sysfs_path");
+
+ if (strncmp (physdev_sysfs_path, buf, len) == 0) {
+ hal_device_property_set_bool (stordev, "storage.media_check_enabled", FALSE);
+ }
+
+ HAL_INFO (("Working around broken ide-cs driver for %s", physdev->udi));
+ }
+
+
ide_name = get_last_element (hal_device_property_get_string
(d, "linux.sysfs_path"));
@@ -1146,20 +1197,6 @@
model);
}
- device_file = hal_device_property_get_string (d, "block.device");
- did = drive_id_open_node(device_file);
- if (drive_id_probe(did, DRIVE_ID_ATA) == 0) {
- if (did->serial[0] != '\0')
- hal_device_property_set_string (stordev,
- "storage.serial",
- did->serial);
- if (did->firmware[0] != '\0')
- hal_device_property_set_string (stordev,
- "storage.firmware_version",
- did->firmware);
- }
- drive_id_close(did);
-
/* According to the function proc_ide_read_media() in
* drivers/ide/ide-proc.c in the Linux sources, media
* can only assume "disk", "cdrom", "tape", "floppy",
@@ -1198,9 +1235,33 @@
has_removable_media = TRUE;
/* TODO: Someone test with tape drives! */
+ }
+ }
+
+ /* only check for drive_id if we are allowed to poll, otherwise we may
+ * cause inifite loops of hotplug events, cf. broken ide-cs driver and
+ * broken zip drives. Merely accessing the top-level block device if it
+ * or any of it partitions are not mounted causes the loop.
+ */
+ if (hal_device_property_get_bool (stordev, "storage.media_check_enabled")) {
+ const char *device_file;
+ struct drive_id *did;
+
+ device_file = hal_device_property_get_string (d, "block.device");
+ did = drive_id_open_node(device_file);
+ if (drive_id_probe(did, DRIVE_ID_ATA) == 0) {
+ if (did->serial[0] != '\0')
+ hal_device_property_set_string (stordev,
+ "storage.serial",
+ did->serial);
+ if (did->firmware[0] != '\0')
+ hal_device_property_set_string (stordev,
+ "storage.firmware_version",
+ did->firmware);
}
-
+ drive_id_close(did);
}
+
} else if (strcmp (hal_device_property_get_string (parent,
"info.bus"),
@@ -1367,6 +1428,7 @@
hal_device_property_get_bool (
stordev, "storage.no_partitions_hint"));
+
/* FINALLY, merge information derived from a .fdi file, from the
* physical device that is backing this block device.
*
@@ -1384,21 +1446,21 @@
/* Merge storage.* from physdev to stordev */
hal_device_merge_with_rewrite (stordev, physdev,
"storage.", "storage.");
-
+
/* If there's a scsi device inbetween merge all
- * storage.lun%d.* properties */
+ * storage_lun%d.* properties */
if (scsidev != NULL) {
int lun;
char propname[64];
-
+
lun = hal_device_property_get_int (
scsidev, "scsi.lun");
/* See 6in1-card-reader.fdi for an example */
-
+
snprintf (propname, sizeof (propname),
"storage_lun%d.", lun);
-
+
hal_device_merge_with_rewrite (stordev, physdev,
"storage.", propname);
}
@@ -1415,8 +1477,63 @@
/* Check the mtab to see if the device is mounted */
etc_mtab_process_all_block_devices (TRUE);
+
+ if (!hal_device_property_get_bool (d, "block.is_volume") &&
+ !hal_device_property_get_bool (d, "storage.media_check_enabled")) {
+ /* Right, if we don't have media_check_enabled we don't really know
+ * if the storage device contains media without partition
+ * tables. This is because of the hotplug infinite loops if trying
+ * to access the top-level block device.
+ *
+ * (man, if only the kernel could tell us that it didn't find
+ * any partition tables!)
+ *
+ * We could try to setup a timer that fires in a few seconds to
+ * see whether we got any childs added and, if not, then resort
+ * to actually doing a detect_media on the top-level block device.
+ *
+ * This works on the ide-cs driver, but there are many other drivers
+ * it might not work on, so I've commented it out. Oh well.
+ */
+ /*g_timeout_add (3000, deferred_check_for_non_partition_media, g_strdup(udi));*/
+ }
+}
+
+static gboolean
+deferred_check_for_non_partition_media (gpointer data)
+{
+ gchar *stordev_udi = (gchar *) data;
+ HalDevice *d;
+ HalDevice *child;
+
+ HAL_INFO (("Entering, udi %s", stordev_udi));
+
+ /* See if device is still there */
+ d = hal_device_store_find (hald_get_gdl (), stordev_udi);
+ if (d == NULL)
+ goto out;
+
+ /* See if we already got children (check both TDL and GDL) */
+ child = hal_device_store_match_key_value_string (hald_get_gdl (), "info.parent",
+ stordev_udi);
+ if (child == NULL)
+ child = hal_device_store_match_key_value_string (hald_get_tdl (), "info.parent",
+ stordev_udi);
+
+ if (child != NULL)
+ goto out;
+
+ HAL_INFO (("Forcing check for media check on udi %s", stordev_udi));
+
+ /* no children so force this check */
+ detect_media (d, TRUE);
+
+out:
+ g_free (stordev_udi);
+ return FALSE;
}
+
static char *
block_class_compute_udi (HalDevice * d, int append_num)
{
@@ -1708,10 +1825,6 @@
/* Search all mount points */
found_mount_point = FALSE;
for (i = 0; i < num_mount_points; i++) {
- char udi[256];
- const char *device_file;
- struct volume_id *vid;
- ClassAsyncData *cad;
mp = &mount_points[i];
@@ -1724,102 +1837,15 @@
}
/* is now mounted, and we didn't have a child.. */
- HAL_INFO (("%s now mounted at %s, "
- "major:minor=%d:%d, " "fstype=%s, udi=%s",
- mp->device, mp->mount_point,
- mp->major, mp->minor, mp->fs_type, d->udi));
-
- child = hal_device_new ();
- hal_device_store_add (hald_get_tdl (), child);
- g_object_unref (child);
-
- /* copy from parent */
- hal_device_merge (child, d);
-
- /* modify some properties */
- hal_device_property_set_string (child, "info.parent", d->udi);
- hal_device_property_set_bool (child, "block.is_volume", TRUE);
- hal_device_property_set_string (child,
- "info.capabilities",
- "block volume");
- hal_device_property_set_string (child,
- "info.category",
- "volume");
- hal_device_property_set_string (child,
- "info.product",
- "Volume");
- /* clear these otherwise we'll
- * imposter the parent on hotplug
- * remove
- */
- hal_device_property_set_string (child, "linux.sysfs_path", "");
- hal_device_property_set_string (child,
- "linux.sysfs_path_device", "");
-
- /* set defaults */
- hal_device_property_set_string (
- child, "volume.label", "");
- hal_device_property_set_string (
- child, "volume.uuid", "");
- hal_device_property_set_string (
- child, "volume.fstype", mp->fs_type);
- hal_device_property_set_string (
- child, "volume.mount_point", mp->mount_point);
- hal_device_property_set_bool (
- child, "volume.is_mounted", TRUE);
- hal_device_property_set_bool (
- child, "volume.is_disc", FALSE);
-
- /* set UDI as appropriate */
- strncpy (udi, hal_device_property_get_string (
- d, "info.udi"), 256);
- strncat (udi, "-volume", 256);
- hal_device_property_set_string (child, "info.udi", udi);
- hal_device_set_udi (child, udi);
-
- device_file = hal_device_property_get_string (d,
- "block.device");
- vid = volume_id_open_node(device_file);
- if (vid != NULL) {
- if (volume_id_probe(vid, VOLUME_ID_ALL, 0) == 0)
- set_volume_id_values(d, vid);
- volume_id_close(vid);
- }
-
- cad = g_new0 (ClassAsyncData, 1);
- cad->device = child;
- cad->handler = &block_class_handler;
- cad->merge_or_add = block_class_handler.merge_or_add;
+ HAL_INFO (("%s now mounted at %s, fstype=%s, udi=%s",
+ mp->device, mp->mount_point, mp->fs_type, d->udi));
- /* add new device */
- g_signal_connect (
- child, "callouts_finished",
- G_CALLBACK (class_device_move_from_tdl_to_gdl), cad);
- hal_callout_device (child, TRUE);
+ /* detect the media and do indeed force this check */
+ detect_media (d, TRUE);
return TRUE;
}
- /* No mount point found */
- if (!found_mount_point) {
- if (child != NULL ) {
- /* We had a child, but is no longer mounted, go
- * remove the child */
- HAL_INFO (("%s not mounted anymore at %s, "
- "major:minor=%d:%d, "
- "fstype=%s, udi=%s",
- mp->device, mp->mount_point,
- mp->major, mp->minor,
- mp->fs_type, d->udi));
-
- g_signal_connect (child, "callouts_finished",
- G_CALLBACK (volume_remove_from_gdl), NULL);
- hal_callout_device (child, FALSE);
-
- return TRUE;
- }
- }
-
return TRUE;
}
@@ -1935,6 +1961,32 @@
DBUS_TYPE_STRING,
device_mount_point,
DBUS_TYPE_INVALID);
+
+ /* Alrighty, we were unmounted and we are some media without
+ * partition tables and we don't like to be polled. So now
+ * the user could actually remove the media and insert some
+ * other media and we wouldn't notice. Ever.
+ *
+ * So, remove the hal device object to be on the safe side.
+ */
+ if ( strcmp (hal_device_property_get_string (d, "block.device"),
+ hal_device_property_get_string (stor, "block.device")) == 0 &&
+ !hal_device_property_get_bool (stor, "storage.media_check_enabled")) {
+
+ HAL_INFO (("Removing hal device object %s since it was unmounted", d->udi));
+
+ /* remove device */
+ g_signal_connect (d, "callouts_finished",
+ G_CALLBACK (volume_remove_from_gdl), NULL);
+ hal_callout_device (d, FALSE);
+
+ /* allow to scan again */
+ hal_device_property_set_bool (stor, "block.have_scanned", FALSE);
+
+ g_free (device_mount_point);
+ return FALSE;
+ }
+
}
g_free (device_mount_point);
Index: bus_device.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/bus_device.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- bus_device.c 15 Aug 2004 18:54:56 -0000 1.16
+++ bus_device.c 16 Aug 2004 18:52:39 -0000 1.17
@@ -79,7 +79,9 @@
* @param self Pointer to class members
* @param path Sysfs-path for device
* @param device libsysfs object for device
- * @return A pointer to the HalDevice* object created
+ * @return A pointer to the HalDevice* object
+ * or NULL if the devices isn't going
+ * to be added anyway
*/
HalDevice *
bus_device_visit (BusDeviceHandler *self, const char *path,
@@ -130,9 +132,23 @@
HAL_LINUX_HOTPLUG_TIMEOUT);
}
- free (parent_sysfs_path);
-
- return d;
+ /* Now that a) hotplug happens in the right order; and b) the device
+ * from a hotplug event is completely added to the GDL before the
+ * next event is processed; the aysnc call above is actually
+ * synchronous so we can test immediately whether we want to
+ * proceed
+ */
+ if (hal_device_store_match_key_value_string (
+ hald_get_gdl (),
+ "linux.sysfs_path_device",
+ parent_sysfs_path) == NULL) {
+
+ free (parent_sysfs_path);
+ return NULL;
+ } else {
+ free (parent_sysfs_path);
+ return d;
+ }
}
@@ -142,7 +158,6 @@
*
* @param device The device being moved
* @param user_data User data provided when connecting the signal
- *
*/
static void
bus_device_move_from_tdl_to_gdl (HalDevice *device, gpointer user_data)
Index: class_device.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/class_device.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- class_device.c 15 Aug 2004 18:54:57 -0000 1.24
+++ class_device.c 16 Aug 2004 18:52:39 -0000 1.25
@@ -103,11 +103,13 @@
const char *path,
struct sysfs_class_device *class_device)
{
+ ClassAsyncData *cad;
HalDevice *d;
char dev_file[SYSFS_PATH_MAX];
char dev_file_prop_name[SYSFS_PATH_MAX];
gboolean merge_or_add;
struct sysfs_device *sysdevice;
+ char *what_to_find;
sysdevice = sysfs_get_classdev_device (class_device);
@@ -181,48 +183,57 @@
}
}
+ cad = g_new0 (ClassAsyncData, 1);
+ cad->device = d;
+ cad->handler = self;
+ cad->merge_or_add = merge_or_add;
+
/* Now find the physical device; this happens asynchronously as it
* might be added later. */
if (merge_or_add) {
- ClassAsyncData *cad = g_new0 (ClassAsyncData, 1);
- cad->device = d;
- cad->handler = self;
- cad->merge_or_add = merge_or_add;
+ what_to_find = sysdevice->path;
/* find the sysdevice */
hal_device_store_match_key_value_string_async (
hald_get_gdl (),
"linux.sysfs_path_device",
- sysdevice->path,
+ what_to_find,
class_device_got_sysdevice, cad,
- HAL_LINUX_HOTPLUG_TIMEOUT);
- } else {
- char *parent_sysfs_path;
- ClassAsyncData *cad = g_new0 (ClassAsyncData, 1);
+ HAL_LINUX_HOTPLUG_TIMEOUT);
+ } else {
if (sysdevice != NULL) {
- parent_sysfs_path =
- get_parent_sysfs_path (sysdevice->path);
+ what_to_find = get_parent_sysfs_path (sysdevice->path);
} else {
- parent_sysfs_path = "(none)";
+ what_to_find = "(none)";
}
- cad->device = d;
- cad->handler = self;
- cad->merge_or_add = merge_or_add;
-
- /* find the parent */
+ /* find the sysdevice */
hal_device_store_match_key_value_string_async (
hald_get_gdl (),
"linux.sysfs_path_device",
- parent_sysfs_path,
+ what_to_find,
class_device_got_parent_device, cad,
HAL_LINUX_HOTPLUG_TIMEOUT);
}
- if (!merge_or_add)
- return d;
- else
+
+ if (!merge_or_add) {
+ /* Now that a) hotplug happens in the right order; and b) the device
+ * from a hotplug event is completely added to the GDL before the
+ * next event is processed; the aysnc call above is actually
+ * synchronous so we can test immediately whether we want to
+ * proceed
+ */
+ if (hal_device_store_match_key_value_string (
+ hald_get_gdl (),
+ "linux.sysfs_path_device",
+ what_to_find) == NULL)
+ return NULL;
+ else
+ return d;
+
+ } else
return NULL;
}
@@ -290,7 +301,7 @@
if (parent == NULL) {
HAL_WARNING (("No parent for class device at sysfs path %s",
- d->udi));
+ hal_device_property_get_string (d, "linux.sysfs_path")));
/* get rid of temporary device */
hal_device_store_remove (hald_get_tdl (), d);
return;
Index: ide_bus_device.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/ide_bus_device.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- ide_bus_device.c 9 Aug 2004 18:33:29 -0000 1.7
+++ ide_bus_device.c 16 Aug 2004 18:52:39 -0000 1.8
@@ -48,6 +48,24 @@
* @{
*/
+static dbus_bool_t
+ide_device_accept (BusDeviceHandler *self, const char *path,
+ struct sysfs_device *device)
+{
+
+/* Uncomment this to test that we can ignore a device
+ * (specifically, in this case, a PCMCIA card reader on a
+ * normal system
+ */
+/*
+ if (strcmp (device->path, "/sys/devices/ide2/2.0") == 0)
+ return FALSE;
+*/
+
+ /* only care about given bus name */
+ return strcmp (device->bus, self->sysfs_bus_name) == 0;
+}
+
static char *
ide_device_compute_udi (HalDevice *d, int append_num)
@@ -94,13 +112,13 @@
bus_device_init, /**< init function */
bus_device_shutdown, /**< shutdown function */
bus_device_tick, /**< timer function */
- bus_device_accept, /**< accept function */
+ ide_device_accept, /**< accept function */
bus_device_visit, /**< visitor function */
bus_device_removed, /**< device is removed */
ide_device_compute_udi, /**< UDI computing function */
ide_device_pre_process, /**< add more properties */
bus_device_got_udi, /**< got UDI */
- bus_device_in_gdl, /**< in GDL */
+ bus_device_in_gdl, /**< in GDL */
"ide", /**< sysfs bus name */
"ide" /**< namespace */
};
Index: ide_host_bus_device.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/ide_host_bus_device.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- ide_host_bus_device.c 9 Aug 2004 18:33:29 -0000 1.8
+++ ide_host_bus_device.c 16 Aug 2004 18:52:39 -0000 1.9
@@ -54,11 +54,21 @@
struct sysfs_device *device)
{
int ide_host_number;
+ char buf[256];
+ size_t len;
if (sscanf (device->bus_id, "ide%d", &ide_host_number) != 1) {
return FALSE;
}
+ /* Don't pickup toplevel ide_host objects */
+ snprintf (buf, 256, "%s/devices/ide", sysfs_mount_path);
+ len = strlen (buf);
+ if (strncmp (buf, device->path, len) == 0)
+ return FALSE;
+
+
+
return TRUE;
}
More information about the hal-commit
mailing list