hal/hald/linux2 hotplug.c, 1.20, 1.20.2.1 hotplug_helper.h, 1.3, 1.3.2.1

David Zeuthen david at kemper.freedesktop.org
Wed Jul 26 11:03:19 PDT 2006


Update of /cvs/hal/hal/hald/linux2
In directory kemper:/tmp/cvs-serv28896/hald/linux2

Modified Files:
      Tag: hal-0_5_7-branch
	hotplug.c hotplug_helper.h 
Log Message:
2006-07-26  David Zeuthen  <davidz at redhat.com>

        * hald/linux2/hotplug.c: Backport this fix done by Kay Sievers
        <kay.sievers at vrfy.org> to fix sysfs changes post Linux 2.6.17:
        (hotplug_event_begin_sysfs): Prepare for
        new class devices showing up in /sys/devices instead of /sys/class.

        * hald/linux2/hotplug_helper.h (HALD_HELPER_STRLEN): Bump from 256
        to 512 as the kernel emits longer sysfs paths post Linux
        2.6.17. And udev now also uses 512.



Index: hotplug.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/hotplug.c,v
retrieving revision 1.20
retrieving revision 1.20.2.1
diff -u -d -r1.20 -r1.20.2.1
--- hotplug.c	23 Jan 2006 12:15:50 -0000	1.20
+++ hotplug.c	26 Jul 2006 18:03:17 -0000	1.20.2.1
@@ -130,26 +130,87 @@
 static void
 hotplug_event_begin_sysfs (HotplugEvent *hotplug_event)
 {
-	static char sys_devices_path[HAL_PATH_MAX];
-	static char sys_class_path[HAL_PATH_MAX];
-	static char sys_block_path[HAL_PATH_MAX];
-	static gsize sys_devices_path_len;
-	static gsize sys_class_path_len;
-	static gsize sys_block_path_len;
-
-	sys_devices_path_len = g_snprintf (sys_devices_path, HAL_PATH_MAX, "%s/devices", get_hal_sysfs_path ());
-	sys_class_path_len   = g_snprintf (sys_class_path, HAL_PATH_MAX, "%s/class", get_hal_sysfs_path ());
-	sys_block_path_len   = g_snprintf (sys_block_path, HAL_PATH_MAX, "%s/block", get_hal_sysfs_path ());
+	HalDevice *d;
+	char subsystem[HAL_PATH_MAX];
+	gchar *subsystem_target;
 
-	if (hotplug_event->action == HOTPLUG_ACTION_ADD && hal_device_store_match_key_value_string (hald_get_gdl (),
+	d = hal_device_store_match_key_value_string (hald_get_gdl (),
 						     "linux.sysfs_path",
-						     hotplug_event->sysfs.sysfs_path)) {
+						     hotplug_event->sysfs.sysfs_path);
+
+	/* FIXME: we should reprobe the device instead of skipping the event */
+	if (d != NULL && hotplug_event->action == HOTPLUG_ACTION_ADD) {
 		HAL_ERROR (("devpath %s already present in the store, ignore event", hotplug_event->sysfs.sysfs_path));
 		hotplug_event_end ((void *) hotplug_event);
 		return;
 	}
 
-	if (strncmp (hotplug_event->sysfs.sysfs_path, sys_devices_path, sys_devices_path_len) == 0) {
+	/* get device type from already known device object */
+	if (d != NULL) {
+		HotplugEventType type;
+
+		type = hal_device_property_get_int (d, "linux.hotplug_type");
+		if (type == HOTPLUG_EVENT_SYSFS_BUS) {
+			HAL_INFO (("%s is a bus device (store)", hotplug_event->sysfs.sysfs_path));
+			hotplug_event->type = HOTPLUG_EVENT_SYSFS_BUS;
+		} else if (type == HOTPLUG_EVENT_SYSFS_CLASS) {
+			HAL_INFO (("%s is a class device (store)", hotplug_event->sysfs.sysfs_path));
+			hotplug_event->type = HOTPLUG_EVENT_SYSFS_CLASS;
+		} else if (type == HOTPLUG_EVENT_SYSFS_BLOCK) {
+			HAL_INFO (("%s is a block device (store)", hotplug_event->sysfs.sysfs_path));
+			hotplug_event->type = HOTPLUG_EVENT_SYSFS_BLOCK;
+		}
+	}
+
+	/*
+	 * determine device type by "subsystem" link (from kernel 2.6.18, class devices
+	 * start to move from /class to /devices and have a "subsystem" link pointing
+	 * back to the "class" or "bus" directory
+	 */
+	if (hotplug_event->type == HOTPLUG_EVENT_SYSFS) {
+		g_snprintf (subsystem, HAL_PATH_MAX, "%s/subsystem", hotplug_event->sysfs.sysfs_path);
+		subsystem_target = g_file_read_link (subsystem, NULL);
+		if (subsystem_target != NULL) {
+			if (strstr(subsystem_target, "/bus/") != NULL) {
+				HAL_INFO (("%s is a bus device (subsystem)", hotplug_event->sysfs.sysfs_path));
+				hotplug_event->type = HOTPLUG_EVENT_SYSFS_BUS;
+			} else if (strstr(subsystem_target, "/class/") != NULL) {
+				HAL_INFO (("%s is a class device (subsystem)", hotplug_event->sysfs.sysfs_path));
+				hotplug_event->type = HOTPLUG_EVENT_SYSFS_CLASS;
+			} else if (strstr(subsystem_target, "/block") != NULL) {
+				HAL_INFO (("%s is a block device (subsystem)", hotplug_event->sysfs.sysfs_path));
+				hotplug_event->type = HOTPLUG_EVENT_SYSFS_BLOCK;
+			}
+			g_free (subsystem_target);
+		}
+	}
+
+	/* older kernels get the device type from the devpath */
+	if (hotplug_event->type == HOTPLUG_EVENT_SYSFS) {
+		char sys_devices_path[HAL_PATH_MAX];
+		char sys_class_path[HAL_PATH_MAX];
+		char sys_block_path[HAL_PATH_MAX];
+		gsize sys_devices_path_len;
+		gsize sys_class_path_len;
+		gsize sys_block_path_len;
+
+		sys_devices_path_len = g_snprintf (sys_devices_path, HAL_PATH_MAX, "%s/devices", get_hal_sysfs_path ());
+		sys_class_path_len   = g_snprintf (sys_class_path, HAL_PATH_MAX, "%s/class", get_hal_sysfs_path ());
+		sys_block_path_len   = g_snprintf (sys_block_path, HAL_PATH_MAX, "%s/block", get_hal_sysfs_path ());
+
+		if (strncmp (hotplug_event->sysfs.sysfs_path, sys_devices_path, sys_devices_path_len) == 0) {
+			HAL_INFO (("%s is a bus device (devpath)", hotplug_event->sysfs.sysfs_path));
+			hotplug_event->type = HOTPLUG_EVENT_SYSFS_BUS;
+		} else if (strncmp (hotplug_event->sysfs.sysfs_path, sys_class_path, sys_class_path_len) == 0) {
+			HAL_INFO (("%s is a class device (devpath)", hotplug_event->sysfs.sysfs_path));
+			hotplug_event->type = HOTPLUG_EVENT_SYSFS_CLASS;
+		} else if (strncmp (hotplug_event->sysfs.sysfs_path, sys_block_path, sys_block_path_len) == 0) {
+			HAL_INFO (("%s is a block device (devpath)", hotplug_event->sysfs.sysfs_path));
+			hotplug_event->type = HOTPLUG_EVENT_SYSFS_BLOCK;
+		}
+	}
+
+	if (hotplug_event->type == HOTPLUG_EVENT_SYSFS_BUS) {
 		if (hotplug_event->action == HOTPLUG_ACTION_ADD) {
 			HalDevice *parent;
 			parent = hal_util_find_closest_ancestor (hotplug_event->sysfs.sysfs_path);
@@ -162,11 +223,11 @@
 							    hotplug_event->sysfs.sysfs_path, 
 							    (void *) hotplug_event);
 		}
-	} else if (strncmp (hotplug_event->sysfs.sysfs_path, sys_class_path, sys_class_path_len) == 0) {
+	} else if (hotplug_event->type == HOTPLUG_EVENT_SYSFS_CLASS) {
 		if (hotplug_event->action == HOTPLUG_ACTION_ADD) {
 			gchar *target;
 			HalDevice *physdev;
-			char physdevpath[256];
+			char physdevpath[HAL_PATH_MAX];
 			gchar *sysfs_path_in_devices;
 
 			sysfs_path_in_devices = NULL;
@@ -175,7 +236,7 @@
 			 * so if index doesn't match, go ahead and find a new sysfs path
 			 */
 			fixup_net_device_for_renaming (hotplug_event);
-			
+
 			g_snprintf (physdevpath, HAL_PATH_MAX, "%s/device", hotplug_event->sysfs.sysfs_path);
 			if (((target = g_file_read_link (physdevpath, NULL)) != NULL)) {
 				gchar *normalized_target;
@@ -196,9 +257,7 @@
 					/* go up one directory */
 					if (!hal_util_path_ascend (normalized_target))
 						break;
-
 				} while (physdev == NULL);
-
 				g_free (normalized_target);
 			} else {
 				physdev = NULL;
@@ -218,23 +277,29 @@
 							     hotplug_event->sysfs.sysfs_path,
 							     (void *) hotplug_event);
 		}
-	} else if (strncmp (hotplug_event->sysfs.sysfs_path, sys_block_path, sys_block_path_len) == 0) {
-		gchar *parent_path;
+	} else if (hotplug_event->type == HOTPLUG_EVENT_SYSFS_BLOCK) {
 		gboolean is_partition;
+		size_t len;
 
-		parent_path = hal_util_get_parent_path (hotplug_event->sysfs.sysfs_path);
-		is_partition = (strcmp (parent_path, sys_block_path) != 0);
+		len = strlen(hotplug_event->sysfs.sysfs_path);
+		is_partition = isdigit(hotplug_event->sysfs.sysfs_path[len - 1]) ||
+			       strstr (hotplug_event->sysfs.sysfs_path, "/fakevolume") ;
 
 		if (hotplug_event->action == HOTPLUG_ACTION_ADD) {
-			HalDevice *parent;
+			HalDevice *parent = NULL;
 
 			if (is_partition) {
+				gchar *parent_path;
+
+				parent_path = hal_util_get_parent_path (hotplug_event->sysfs.sysfs_path);
+
 				parent = hal_device_store_match_key_value_string (hald_get_gdl (),
 										  "linux.sysfs_path_device",
 										  parent_path);
+				g_free (parent_path);
 			} else {
 				gchar *target;
-				char physdevpath[256];
+				char physdevpath[HAL_PATH_MAX];
 
 				g_snprintf (physdevpath, HAL_PATH_MAX, "%s/device", hotplug_event->sysfs.sysfs_path);
 				if (((target = g_file_read_link (physdevpath, NULL)) != NULL)) {
@@ -246,8 +311,6 @@
 											  "linux.sysfs_path_device",
 											  normalized_target);
 					g_free (normalized_target);
-				} else {
-					parent = NULL;
 				}
 			}
 
@@ -261,8 +324,6 @@
 							     is_partition,
 							     (void *) hotplug_event);
 		}
-
-		g_free (parent_path);
 	} else {
 		/* just ignore this hotplug event */
 		hotplug_event_end ((void *) hotplug_event);

Index: hotplug_helper.h
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/hotplug_helper.h,v
retrieving revision 1.3
retrieving revision 1.3.2.1
diff -u -d -r1.3 -r1.3.2.1
--- hotplug_helper.h	2 Nov 2005 15:38:14 -0000	1.3
+++ hotplug_helper.h	26 Jul 2006 18:03:17 -0000	1.3.2.1
@@ -28,7 +28,7 @@
 
 #define HALD_HELPER_MAGIC 0x68616c64
 #define HALD_HELPER_SOCKET_PATH "/var/run/hal/hotplug_socket2"
-#define HALD_HELPER_STRLEN 256
+#define HALD_HELPER_STRLEN 512
 
 struct hald_helper_msg
 {




More information about the hal-commit mailing list