prepare HAL for upcoming udev changes

Kay Sievers kay.sievers at vrfy.org
Tue Jul 5 10:47:18 PDT 2005


The next udev version will not store anything in its database if not
neccessary. So udev does not need to write 600 pretty useless database
files and HAL does not need to process the information that is already
contained in the sysfs-path.

The udevinfo-dump of the next udev version will only print devices which
have a custom configuration. This changes HAL to look for the default
device-node derived from the kernels devpath if udev has not specified
anything else.

Thanks,
Kay
-------------- next part --------------
Index: hald/linux2/coldplug.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/coldplug.c,v
retrieving revision 1.15
diff -u -p -r1.15 coldplug.c
--- hald/linux2/coldplug.c	27 Apr 2005 18:53:39 -0000	1.15
+++ hald/linux2/coldplug.c	5 Jul 2005 17:31:18 -0000
@@ -53,6 +53,8 @@
 #define DMPREFIX "dm-"
 
 
+static GHashTable *sysfs_to_dev_map;
+static char dev_root[HAL_PATH_MAX];
 
 /* Returns the path of the udevinfo program 
  *
@@ -65,14 +67,14 @@ hal_util_get_udevinfo_path (void)
 	struct stat s;
 	static gchar *path = NULL;
 	gchar *possible_paths[] = { 
-		"/sbin/udevinfo",
 		"/usr/bin/udevinfo",
+		"/bin/udevinfo",
 		"/usr/sbin/udevinfo",
-		"/usr/local/sbin/udevinfo"
+		"/sbin/udevinfo",
 	};
 
 	if (path != NULL)
-		return path;
+		 return path;
 
 	for (i = 0; i < sizeof (possible_paths) / sizeof (char *); i++) {
 		if (stat (possible_paths[i], &s) == 0 && S_ISREG (s.st_mode)) {
@@ -83,15 +85,15 @@ hal_util_get_udevinfo_path (void)
 	return path;
 }
 
-static GHashTable *
-hal_util_get_sysfs_to_dev_map (void)
+
+static gboolean
+hal_util_init_sysfs_to_dev_map (void)
 {
-	GHashTable *sysfs_to_dev_map;
-	char *udevinfo_argv[7] = {NULL, "-d", NULL};
+	char *udevdump_argv[] = { "/usr/bin/udevinfo", "-d", NULL };
+	char *udevroot_argv[] = { "/usr/bin/udevinfo", "-r", NULL };
 	char *udevinfo_stdout;
-	char *udevinfo_stderr;
 	int udevinfo_exitcode;
-        char *p;
+	char *p;
 	char *q;
 	char *r;
 	int len;
@@ -101,37 +103,48 @@ hal_util_get_sysfs_to_dev_map (void)
 	gboolean has_more_lines;
 
 	sysfs_mount_path = get_hal_sysfs_path ();
-
 	sysfs_to_dev_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+	udevdump_argv[0] = (char *) hal_util_get_udevinfo_path ();
+	udevroot_argv[0] = (char *) hal_util_get_udevinfo_path ();
 
-	/* get path to udevinfo */
-	udevinfo_argv[0] = (char *) hal_util_get_udevinfo_path ();
-	if (udevinfo_argv[0] == NULL)
+	/* get udevroot */
+	if (g_spawn_sync ("/", udevroot_argv, NULL, 0, NULL, NULL,
+			  &udevinfo_stdout,
+			  NULL,
+			  &udevinfo_exitcode,
+			  NULL) != TRUE) {
+		HAL_ERROR (("Couldn't invoke %s", udevroot_argv[0]));
 		goto error;
+	}
+	if (udevinfo_exitcode != 0) {
+		HAL_ERROR (("%s returned %d", udevroot_argv[0], udevinfo_exitcode));
+		goto error;
+	}
 
-
-	/* Invoke udevinfo */
-	if (udevinfo_argv[0] == NULL || g_spawn_sync ("/",
-						  udevinfo_argv,
-						  NULL,
-						  0,
-						  NULL,
-						  NULL,
-						  &udevinfo_stdout,
-						  &udevinfo_stderr,
-						  &udevinfo_exitcode,
-						  NULL) != TRUE) {
-		HAL_ERROR (("Couldn't invoke %s", udevinfo_argv[0]));
+	g_strlcpy(dev_root, udevinfo_stdout, sizeof(dev_root));
+	p = strchr(dev_root, '\n');
+	if (p)
+		p[0] = '\0';
+	g_free(udevinfo_stdout);
+	HAL_INFO (("dev_root is %s", dev_root));
+
+	/* get udevdump */
+	if (g_spawn_sync ("/", udevdump_argv, NULL, 0, NULL, NULL,
+			  &udevinfo_stdout,
+			  NULL,
+			  &udevinfo_exitcode,
+			  NULL) != TRUE) {
+		HAL_ERROR (("Couldn't invoke %s", udevdump_argv[0]));
+		g_free(udevinfo_stdout);
 		goto error;
 	}
 
 	if (udevinfo_exitcode != 0) {
-		HAL_ERROR (("%s returned %d", udevinfo_argv[0], udevinfo_exitcode));
+		HAL_ERROR (("%s returned %d", udevdump_argv[0], udevinfo_exitcode));
 		goto error;
 	}
 
 	has_more_lines = TRUE;
-
 	p = udevinfo_stdout;
 
 	do {
@@ -142,7 +155,7 @@ hal_util_get_sysfs_to_dev_map (void)
 
 		for (q = p; *q != '\n' && *q != '\0' && *q != '='; q++)
 			;
-		
+
 		len = q - p;
 		switch (*q) {
 		case '=':
@@ -162,12 +175,12 @@ hal_util_get_sysfs_to_dev_map (void)
 			HAL_ERROR (("Expected '=', not '%c' in line '%s'", *q, p));
 			goto error;
 		}
-		
+
 		q++;
 		r = q;
 		for ( ; *q != '\n' && *q != '\0'; q++)
 			;
-		
+
 		len = q - r;
 		switch (*q) {
 		case '\0':
@@ -178,7 +191,6 @@ hal_util_get_sysfs_to_dev_map (void)
 			strncpy (device_file, r, len > PATH_MAX ? PATH_MAX : len);
 			device_file [len > PATH_MAX ? PATH_MAX : len] = '\0';
 			break;
-			
 		default:
 			HAL_ERROR (("Expected '\\n' or '\\0', not '%c' in line '%s'", *q, p));
 			goto error;
@@ -186,7 +198,7 @@ hal_util_get_sysfs_to_dev_map (void)
 
 		g_hash_table_insert (sysfs_to_dev_map, g_strdup_printf ("%s%s", sysfs_mount_path, sysfs_path), 
 				     g_strdup(device_file));
-		
+
 #ifdef HAL_COLDPLUG_VERBOSE
 		printf ("Got '%s' -> '%s'\n", sysfs_path, device_file);
 #endif
@@ -194,22 +206,54 @@ hal_util_get_sysfs_to_dev_map (void)
 
 	} while (has_more_lines);
 
-	return sysfs_to_dev_map;
+	g_free(udevinfo_stdout);
+	return TRUE;
 
 error:
+	g_free(udevinfo_stdout);
 	g_hash_table_destroy (sysfs_to_dev_map);
-	return NULL;
+	return FALSE;
 }
 
+static gchar
+*coldplug_get_device_file(const gchar *sysfs_path)
+{
+	const gchar *device_file;
+	const char *pos;
+	gchar path[HAL_PATH_MAX];
+	struct stat statbuf;
+
+	device_file = (gchar *) g_hash_table_lookup (sysfs_to_dev_map, sysfs_path);
+	if (device_file != NULL)
+		return g_strdup(device_file);
+
+	HAL_INFO (("sysfs_path %s not in udevdb", sysfs_path));
+
+	/* device is not in udevdb, use the default kernel name  */
+	pos = strrchr(sysfs_path, '/');
+	if (pos == NULL)
+		return NULL;
+
+	g_strlcpy(path, dev_root, sizeof(path));
+	g_strlcat(path, pos, sizeof(path));
+	if (stat (path, &statbuf))
+		return NULL;
+
+	if (!S_ISBLK (statbuf.st_mode) && !S_ISCHR (statbuf.st_mode))
+		return NULL;
+
+	HAL_INFO (("return sysfs_path %s", path));
+
+	return g_strdup(path);
+}
 
 static gboolean
-coldplug_synthesize_block_event(const gchar *f, GHashTable *sysfs_to_dev_map);
+coldplug_synthesize_block_event(const gchar *f);
 
 static void
 coldplug_compute_visit_device (const gchar *path, 
 			       GHashTable *sysfs_to_bus_map, 
-			       GHashTable *sysfs_to_class_in_devices_map,
-			       GHashTable *sysfs_to_dev_map);
+			       GHashTable *sysfs_to_class_in_devices_map);
 
 /* For debugging */
 /*#define HAL_COLDPLUG_VERBOSE*/
@@ -297,15 +341,11 @@ coldplug_synthesize_events (void)
 	 */
 	GSList *sysfs_dm_dev = NULL;
 
-	GHashTable *sysfs_to_dev_map = NULL;
-
-	
-	if ((sysfs_to_dev_map = hal_util_get_sysfs_to_dev_map ()) == NULL) {
+	if (hal_util_init_sysfs_to_dev_map () == FALSE) {
 		HAL_ERROR (("Unable to get sysfs to dev map"));
 		goto error;
 	}
 
-
 	/* build bus map */
 	sysfs_to_bus_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 	g_snprintf (path, HAL_PATH_MAX, "%s/bus", get_hal_sysfs_path ());
@@ -431,7 +471,7 @@ coldplug_synthesize_events (void)
 		while ((f1 = g_dir_read_name (dir1)) != NULL) {
 
 			g_snprintf (path, HAL_PATH_MAX, "%s/devices/%s/%s", get_hal_sysfs_path (), f, f1);
-			coldplug_compute_visit_device (path, sysfs_to_bus_map, sysfs_to_class_in_devices_map, sysfs_to_dev_map);
+			coldplug_compute_visit_device (path, sysfs_to_bus_map, sysfs_to_class_in_devices_map);
 		}
 		g_dir_close (dir1);
 	}
@@ -461,9 +501,10 @@ coldplug_synthesize_events (void)
 		g_strlcpy (hotplug_event->sysfs.subsystem, subsystem, sizeof (hotplug_event->sysfs.subsystem));
 		g_strlcpy (hotplug_event->sysfs.sysfs_path, sysfs_path, sizeof (hotplug_event->sysfs.sysfs_path));
 
-		device_file = (gchar *) g_hash_table_lookup (sysfs_to_dev_map, sysfs_path);
+		device_file = coldplug_get_device_file (sysfs_path);
 		if (device_file != NULL) {
 			strncpy (hotplug_event->sysfs.device_file, device_file, sizeof (hotplug_event->sysfs.device_file));
+			g_free (device_file);
 		}
 		hotplug_event->sysfs.net_ifindex = -1;
 		
@@ -487,12 +528,12 @@ coldplug_synthesize_events (void)
 			sysfs_dm_dev = g_slist_append(sysfs_dm_dev, g_strdup(f));
 			continue;
 		}
-		if (coldplug_synthesize_block_event(f, sysfs_to_dev_map) == FALSE)
+		if (coldplug_synthesize_block_event(f) == FALSE)
 			goto error;
 	}
 	/* process all dm devices last so that their backing devices exist */
 	for (li = sysfs_dm_dev; li != NULL; li = g_slist_next (g_slist_next (li))) {
-		if (coldplug_synthesize_block_event (li->data, sysfs_to_dev_map) == FALSE)
+		if (coldplug_synthesize_block_event (li->data) == FALSE)
 			goto error;
 		g_free (li->data);
 	}
@@ -500,7 +541,7 @@ coldplug_synthesize_events (void)
 	g_dir_close (dir);
 
 	g_hash_table_destroy (sysfs_to_dev_map);
-       
+
 	return TRUE;
 error:
 	HAL_ERROR (("Error building the orderered list of sysfs paths"));
@@ -508,7 +549,7 @@ error:
 }
 
 static gboolean
-coldplug_synthesize_block_event(const gchar *f, GHashTable *sysfs_to_dev_map)
+coldplug_synthesize_block_event(const gchar *f)
 {
 	GDir *dir1;
 	gsize flen;
@@ -540,9 +581,10 @@ coldplug_synthesize_block_event(const gc
 	g_strlcpy (hotplug_event->sysfs.subsystem, "block", sizeof (hotplug_event->sysfs.subsystem));
 	g_strlcpy (hotplug_event->sysfs.sysfs_path, path, sizeof (hotplug_event->sysfs.sysfs_path));
 
-	device_file = (gchar *) g_hash_table_lookup (sysfs_to_dev_map, path);
+	device_file = coldplug_get_device_file (path);
 	if (device_file != NULL) {
 		strncpy (hotplug_event->sysfs.device_file, device_file, sizeof (hotplug_event->sysfs.device_file));
+		g_free (device_file);
 	}
 
 	if (normalized_target != NULL)
@@ -573,9 +615,10 @@ coldplug_synthesize_block_event(const gc
 			g_strlcpy (hotplug_event->sysfs.subsystem, "block", sizeof (hotplug_event->sysfs.subsystem));
 			g_strlcpy (hotplug_event->sysfs.sysfs_path, path1, sizeof (hotplug_event->sysfs.sysfs_path));
 			g_strlcpy (hotplug_event->sysfs.wait_for_sysfs_path, path, sizeof (hotplug_event->sysfs.wait_for_sysfs_path));
-			device_file = (gchar *) g_hash_table_lookup (sysfs_to_dev_map, path1);
+			device_file = coldplug_get_device_file (path1);
 			if (device_file != NULL) {
 				strncpy (hotplug_event->sysfs.device_file, device_file, sizeof (hotplug_event->sysfs.device_file));
+				g_free (device_file);
 			}
 			hotplug_event->sysfs.net_ifindex = -1;
 			hotplug_event_enqueue (hotplug_event);
@@ -592,8 +635,7 @@ error:
 static void
 coldplug_compute_visit_device (const gchar *path, 
 			       GHashTable *sysfs_to_bus_map, 
-			       GHashTable *sysfs_to_class_in_devices_map,
-			       GHashTable *sysfs_to_dev_map)
+			       GHashTable *sysfs_to_class_in_devices_map)
 {
 	gchar *bus;
 	GError *err = NULL;
@@ -647,9 +689,10 @@ coldplug_compute_visit_device (const gch
 		g_strlcpy (hotplug_event->sysfs.subsystem, subsystem, sizeof (hotplug_event->sysfs.subsystem));
 		g_strlcpy (hotplug_event->sysfs.sysfs_path, sysfs_path, sizeof (hotplug_event->sysfs.sysfs_path));
 
-		device_file = (gchar *) g_hash_table_lookup (sysfs_to_dev_map, sysfs_path);
+		device_file = coldplug_get_device_file (sysfs_path);
 		if (device_file != NULL) {
 			strncpy (hotplug_event->sysfs.device_file, device_file, sizeof (hotplug_event->sysfs.device_file));
+			g_free (device_file);
 		}
 		if (path != NULL)
 			g_strlcpy (hotplug_event->sysfs.wait_for_sysfs_path, path, sizeof (hotplug_event->sysfs.wait_for_sysfs_path));
@@ -669,7 +712,7 @@ coldplug_compute_visit_device (const gch
 	while ((f = g_dir_read_name (dir)) != NULL) {
 		gchar path_child[HAL_PATH_MAX];
 		struct stat statbuf;
-	
+
 		g_snprintf (path_child, HAL_PATH_MAX, "%s/%s", path, f);
 
 		if (lstat (path_child, &statbuf) == 0) {
@@ -678,8 +721,7 @@ coldplug_compute_visit_device (const gch
 				/* recursion fun */
 				coldplug_compute_visit_device (path_child, 
 							       sysfs_to_bus_map, 
-							       sysfs_to_class_in_devices_map,
-							       sysfs_to_dev_map);
+							       sysfs_to_class_in_devices_map);
 			}
 		}
 	}
-------------- next part --------------
_______________________________________________
hal mailing list
hal at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/hal


More information about the Hal mailing list