diff options
author | Rob Taylor <rob.taylor@codethink.co.uk> | 2007-11-09 01:37:32 +0000 |
---|---|---|
committer | Rob Taylor <rob.taylor@codethink.co.uk> | 2008-03-12 20:11:09 +0100 |
commit | 227f4a70d1f0d4a9e03935b78dad2947f0e3175c (patch) | |
tree | c5cc96f60ccbf4dc80376f4f8072a04991935d25 | |
parent | process coldplug events as soon as they're generated (diff) | |
download | gentoo-hal-227f4a70d1f0d4a9e03935b78dad2947f0e3175c.tar.gz gentoo-hal-227f4a70d1f0d4a9e03935b78dad2947f0e3175c.tar.bz2 gentoo-hal-227f4a70d1f0d4a9e03935b78dad2947f0e3175c.zip |
rework handling of data from udevinfo for more efficient memory usage
This patch reworks the handling of the output of udevinfo so that the output is
parsed into an intermediatary form (with a hash table of sysfpath to structures
pointing directly into the output as captured). This is converted into
HotplugEvents one at a time when needed by coldplug_get_hotplug_event.
-rw-r--r-- | hald/linux/coldplug.c | 175 |
1 files changed, 115 insertions, 60 deletions
diff --git a/hald/linux/coldplug.c b/hald/linux/coldplug.c index 3ad7199b..dbc18309 100644 --- a/hald/linux/coldplug.c +++ b/hald/linux/coldplug.c @@ -55,23 +55,107 @@ struct sysfs_device { static GHashTable *sysfs_to_udev_map; static GSList *device_list; static char dev_root[HAL_PATH_MAX]; +static gchar *udevinfo_stdout = NULL; -static void hotplug_event_free (HotplugEvent *ev) +typedef struct _UdevInfo UdevInfo; + +struct _UdevInfo +{ + const char *sysfs_path; + const char *device_file; + const char *vendor; + const char *model; + const char *revision; + const char *serial; + const char *fsusage; + const char *fstype; + const char *fsversion; + const char *fsuuid; + const char *fslabel; +}; + +static void udev_info_free (gpointer data) +{ + g_slice_free(UdevInfo, data); +} + + +static HotplugEvent* +udev_info_to_hotplug_event (const UdevInfo *info) { - g_slice_free(HotplugEvent, ev); + HotplugEvent *hotplug_event; + gchar *str; + + hotplug_event = g_slice_new0 (HotplugEvent); + g_strlcpy (hotplug_event->sysfs.sysfs_path, "/sys", sizeof(hotplug_event->sysfs.sysfs_path)); + g_strlcat (hotplug_event->sysfs.sysfs_path, info->sysfs_path, sizeof(hotplug_event->sysfs.sysfs_path)); + + HAL_INFO(("creating HotplugEvent for %s", hotplug_event->sysfs.sysfs_path)); + + if (info->device_file) { + g_snprintf (hotplug_event->sysfs.device_file, sizeof(hotplug_event->sysfs.device_file), + "%s/%s", dev_root, info->device_file); + HAL_INFO(("with device file %s", hotplug_event->sysfs.device_file)); + } + if ((str = hal_util_strdup_valid_utf8(info->vendor)) != NULL) { + g_strlcpy (hotplug_event->sysfs.vendor, str, sizeof(hotplug_event->sysfs.vendor)); + g_free (str); + } + + if ((str = hal_util_strdup_valid_utf8(info->model)) != NULL) { + g_strlcpy (hotplug_event->sysfs.model, str, sizeof(hotplug_event->sysfs.model)); + g_free (str); + } + + if ((str = hal_util_strdup_valid_utf8(info->revision)) != NULL) { + g_strlcpy (hotplug_event->sysfs.revision, str, sizeof(hotplug_event->sysfs.revision)); + g_free (str); + } + + if ((str = hal_util_strdup_valid_utf8(info->serial)) != NULL) { + g_strlcpy (hotplug_event->sysfs.serial, str, sizeof(hotplug_event->sysfs.serial)); + g_free (str); + } + + if ((str = hal_util_strdup_valid_utf8(info->fsusage)) != NULL) { + g_strlcpy (hotplug_event->sysfs.fsusage, str, sizeof(hotplug_event->sysfs.fsusage)); + g_free (str); + } + + if ((str = hal_util_strdup_valid_utf8(info->fstype)) != NULL) { + g_strlcpy (hotplug_event->sysfs.fstype, str, sizeof(hotplug_event->sysfs.fstype)); + g_free (str); + } + + if ((str = hal_util_strdup_valid_utf8(info->fsversion)) != NULL) { + g_strlcpy (hotplug_event->sysfs.fsversion, str, sizeof(hotplug_event->sysfs.fsversion)); + g_free (str); + } + + if ((str = hal_util_strdup_valid_utf8(info->fsuuid)) != NULL) { + g_strlcpy (hotplug_event->sysfs.fsuuid, str, sizeof(hotplug_event->sysfs.fsuuid)); + g_free (str); + } + + if ((str = hal_util_strdup_valid_utf8(info->fslabel)) != NULL) { + g_strlcpy (hotplug_event->sysfs.fslabel, str, sizeof(hotplug_event->sysfs.fslabel)); + g_free (str); + } + + return hotplug_event; } + static gboolean hal_util_init_sysfs_to_udev_map (void) { char *udevdb_export_argv[] = { "/usr/bin/udevinfo", "-e", NULL }; char *udevroot_argv[] = { "/usr/bin/udevinfo", "-r", NULL }; - char *udevinfo_stdout; int udevinfo_exitcode; - HotplugEvent *hotplug_event = NULL; + UdevInfo *info = NULL; char *p; - sysfs_to_udev_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, hotplug_event_free); + sysfs_to_udev_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, udev_info_free); /* get udevroot */ if (g_spawn_sync ("/", udevroot_argv, NULL, 0, NULL, NULL, @@ -114,7 +198,6 @@ hal_util_init_sysfs_to_udev_map (void) p = udevinfo_stdout; while (p[0] != '\0') { char *line, *end; - gchar *str; /* get line, terminate and move to next line */ line = p; @@ -126,79 +209,49 @@ hal_util_init_sysfs_to_udev_map (void) /* insert device */ if (line[0] == '\0') { - if (hotplug_event != NULL) { - g_hash_table_insert (sysfs_to_udev_map, g_strdup (hotplug_event->sysfs.sysfs_path), hotplug_event); - HAL_INFO (("found (udevdb export) '%s' -> '%s'", - hotplug_event->sysfs.sysfs_path, hotplug_event->sysfs.device_file)); - hotplug_event = NULL; + if (info != NULL) { + g_hash_table_insert (sysfs_to_udev_map, g_strdup_printf ("/sys%s", info->sysfs_path), info); + HAL_INFO (("found (udevdb export) '/sys%s' -> '%s/%s'", + info->sysfs_path, dev_root, info->device_file)); + info = NULL; } continue; } /* new device */ if (strncmp(line, "P: ", 3) == 0) { - hotplug_event = g_slice_new0 (HotplugEvent); - g_strlcpy (hotplug_event->sysfs.sysfs_path, "/sys", sizeof(hotplug_event->sysfs.sysfs_path)); - g_strlcat (hotplug_event->sysfs.sysfs_path, &line[3], sizeof(hotplug_event->sysfs.sysfs_path)); + info = g_slice_new0 (UdevInfo); + info->sysfs_path = &line[3]; continue; } /* only valid if we have an actual device */ - if (hotplug_event == NULL) + if (info == NULL) continue; if (strncmp(line, "N: ", 3) == 0) { - g_snprintf (hotplug_event->sysfs.device_file, sizeof(hotplug_event->sysfs.device_file), - "%s/%s", dev_root, &line[3]); + info->device_file = &line[3]; } else if (strncmp(line, "E: ID_VENDOR=", 13) == 0) { - if ((str = hal_util_strdup_valid_utf8(&line[13])) != NULL) { - g_strlcpy (hotplug_event->sysfs.vendor, str, sizeof(hotplug_event->sysfs.vendor)); - g_free (str); - } + info->vendor = &line[13]; } else if (strncmp(line, "E: ID_MODEL=", 12) == 0) { - if ((str = hal_util_strdup_valid_utf8(&line[12])) != NULL) { - g_strlcpy (hotplug_event->sysfs.model, str, sizeof(hotplug_event->sysfs.model)); - g_free (str); - } + info->model = &line[12]; } else if (strncmp(line, "E: ID_REVISION=", 15) == 0) { - if ((str = hal_util_strdup_valid_utf8(&line[15])) != NULL) { - g_strlcpy (hotplug_event->sysfs.revision, str, sizeof(hotplug_event->sysfs.revision)); - g_free (str); - } + info->revision = &line[15]; } else if (strncmp(line, "E: ID_SERIAL=", 13) == 0) { - if ((str = hal_util_strdup_valid_utf8(&line[13])) != NULL) { - g_strlcpy (hotplug_event->sysfs.serial, str, sizeof(hotplug_event->sysfs.serial)); - g_free (str); - } + info->serial = &line[13]; } else if (strncmp(line, "E: ID_FS_USAGE=", 15) == 0) { - if ((str = hal_util_strdup_valid_utf8(&line[15])) != NULL) { - g_strlcpy (hotplug_event->sysfs.fsusage, str, sizeof(hotplug_event->sysfs.fsusage)); - g_free (str); - } + info->fsusage = &line[15]; } else if (strncmp(line, "E: ID_FS_TYPE=", 14) == 0) { - if ((str = hal_util_strdup_valid_utf8(&line[14])) != NULL) { - g_strlcpy (hotplug_event->sysfs.fstype, str, sizeof(hotplug_event->sysfs.fstype)); - g_free (str); - } + info->fstype = &line[14]; } else if (strncmp(line, "E: ID_FS_VERSION=", 17) == 0) { - if ((str = hal_util_strdup_valid_utf8(&line[17])) != NULL) { - g_strlcpy (hotplug_event->sysfs.fsversion, str, sizeof(hotplug_event->sysfs.fsversion)); - g_free (str); - } + info->fsversion = &line[17]; } else if (strncmp(line, "E: ID_FS_UUID=", 14) == 0) { - if ((str = hal_util_strdup_valid_utf8(&line[14])) != NULL) { - g_strlcpy (hotplug_event->sysfs.fsuuid, str, sizeof(hotplug_event->sysfs.fsuuid)); - g_free (str); - } + info->fsuuid = &line[14]; } else if (strncmp(line, "E: ID_FS_LABEL=", 15) == 0) { - if ((str = hal_util_strdup_valid_utf8(&line[15])) != NULL) { - g_strlcpy (hotplug_event->sysfs.fslabel, str, sizeof(hotplug_event->sysfs.fslabel)); - g_free (str); - } + info->fslabel = &line[15]; } } - g_free(udevinfo_stdout); return TRUE; error: @@ -211,19 +264,20 @@ error: static HotplugEvent *coldplug_get_hotplug_event(const gchar *sysfs_path, const gchar *subsystem, HotplugEventType type) { - HotplugEvent *hotplug_event, *hotplug_event_udev; + HotplugEvent *hotplug_event; const char *pos; gchar path[HAL_PATH_MAX]; struct stat statbuf; - - hotplug_event = g_slice_new0 (HotplugEvent); + UdevInfo *info; /* lookup if udev has something stored in its database */ - hotplug_event_udev = (HotplugEvent *) g_hash_table_lookup (sysfs_to_udev_map, sysfs_path); - if (hotplug_event_udev != NULL) { - memcpy(hotplug_event, hotplug_event_udev, sizeof(HotplugEvent)); + info = (UdevInfo*) g_hash_table_lookup (sysfs_to_udev_map, sysfs_path); + if (info) { + hotplug_event = udev_info_to_hotplug_event (info); HAL_INFO (("new event (dev node from udev) '%s' '%s'", hotplug_event->sysfs.sysfs_path, hotplug_event->sysfs.device_file)); } else { + hotplug_event = g_slice_new0 (HotplugEvent); + /* device is not in udev database */ g_strlcpy(hotplug_event->sysfs.sysfs_path, sysfs_path, sizeof(hotplug_event->sysfs.sysfs_path)); @@ -543,6 +597,7 @@ coldplug_synthesize_events (void) } g_hash_table_destroy (sysfs_to_udev_map); + g_free (udevinfo_stdout); return TRUE; error: |