diff -u -r1.15 -r1.16 --- hald/linux2/coldplug.c 2005/04/27 18:53:39 1.15 +++ hald/linux2/coldplug.c 2005/07/07 16:08:51 1.16 @@ -1,5 +1,5 @@ /*************************************************************************** - * CVSID: $Id: coldplug.c,v 1.15 2005/04/27 18:53:39 david Exp $ + * CVSID: $Id: coldplug.c,v 1.16 2005/07/07 16:08:51 kay Exp $ * * coldplug.c : Synthesize hotplug events when starting up * @@ -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 @@ 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 @@ 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 @@ 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 @@ for (q = p; *q != '\n' && *q != '\0' && *q != '='; q++) ; - + len = q - p; switch (*q) { case '=': @@ -162,12 +175,12 @@ 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 @@ 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 @@ 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 @@ } 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 @@ */ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ /* 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); } } }