hal: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Mon Oct 9 00:16:04 PDT 2006


 hald-runner/main.c    |    4 +
 hald/debug-hald.sh    |   10 ++-
 hald/device.c         |   78 ++++++++++++++++-------------
 hald/device.h         |   14 ++---
 hald/device_info.c    |   17 +++---
 hald/device_store.c   |    2 
 hald/dummy/osspec.c   |    2 
 hald/hald.c           |   39 +++++++++++---
 hald/hald.h           |    2 
 hald/hald_dbus.c      |   61 +++++++++++++++-------
 hald/hald_dbus.h      |    1 
 hald/hald_runner.c    |  134 +++++++++++++++++++++++++++++++++++++-------------
 hald/hald_runner.h    |    4 +
 hald/ids.c            |    3 -
 hald/linux/acpi.c     |   20 ++++---
 hald/linux/apm.c      |    6 +-
 hald/linux/blockdev.c |   31 +++++------
 hald/linux/classdev.c |   52 +++++++++----------
 hald/linux/coldplug.c |   38 +++++++++++++-
 hald/linux/hotplug.c  |   21 ++++---
 hald/linux/hotplug.h  |    2 
 hald/linux/osspec.c   |    2 
 hald/linux/physdev.c  |   34 ++++++------
 hald/linux/pmu.c      |    8 +-
 hald/property.c       |   23 +++++---
 hald/util.c           |    6 +-
 hald/valgrind-hald.sh |   10 ++-
 27 files changed, 406 insertions(+), 218 deletions(-)

New commits:
diff-tree 54192c66659d5c531f74b9859052db06a58b8eaf (from bd9e32febb881700d76fb3524c86ee469463a946)
Author: David Zeuthen <davidz at redhat.com>
Date:   Mon Oct 9 03:15:27 2006 -0400

    some memory optimization work
    
    There's an interesting behavior on startup. On my machine we allocate
    around 300 HotplugEvent objects (each of 3604 bytes) on startup and
    put them on the queue. When we're done processing an event it's freed.
    This leads to interesting memory fragmentation problems. Some
    experimental code I've just put in allocates the first 1000 in a fixed
    array. Seems to save 200-300kb writable memory.
    
    Also move some bits of HalDevice into HalDevicePrivate. Fix up the
    rest of the code not to rely on the ->udi member as it's now only
    available through the existing hal_device_get_uid() method.

diff --git a/hald-runner/main.c b/hald-runner/main.c
index fbb7a63..18565bf 100644
--- a/hald-runner/main.c
+++ b/hald-runner/main.c
@@ -180,6 +180,10 @@ filter(DBusConnection *con, DBusMessage 
 	} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "Kill")) {
 		handle_kill(con, msg);
 		return DBUS_HANDLER_RESULT_HANDLED;
+	} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "Shutdown")) {
+		run_kill_all ();
+		exit (0);
+		return DBUS_HANDLER_RESULT_HANDLED;
 	} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "KillAll")) {
 		run_kill_all();
 		/* alwasy successfull */
diff --git a/hald/debug-hald.sh b/hald/debug-hald.sh
index c2aab4b..acc91aa 100755
--- a/hald/debug-hald.sh
+++ b/hald/debug-hald.sh
@@ -3,8 +3,12 @@
 export HALD_RUNNER_PATH=`pwd`/linux:`pwd`/linux/probing:`pwd`/linux/addons:`pwd`/.:`pwd`/../tools:`pwd`/../tools/linux
 export PATH=`pwd`/../hald-runner:$PATH
 
-rm -rf .local-fdi
-make -C ../fdi install DESTDIR=`pwd`/.local-fdi prefix=/
+if [ "$1" = "--skip-fdi-install" ] ; then
+    shift
+else
+    rm -rf .local-fdi
+    make -C ../fdi install DESTDIR=`pwd`/.local-fdi prefix=/
+fi
 export HAL_FDI_SOURCE_PREPROBE=.local-fdi/share/hal/fdi/preprobe
 export HAL_FDI_SOURCE_INFORMATION=.local-fdi/share/hal/fdi/information
 export HAL_FDI_SOURCE_POLICY=.local-fdi/share/hal/fdi/policy
@@ -12,5 +16,5 @@ export HAL_FDI_SOURCE_POLICY=.local-fdi/
 echo ========================================
 echo Just type \'run\' to start debugging hald
 echo ========================================
-gdb run --args ./hald --daemon=no --verbose=yes
+gdb run --args ./hald --daemon=no --verbose=yes $@
 
diff --git a/hald/device.c b/hald/device.c
index f54401f..223d431 100644
--- a/hald/device.c
+++ b/hald/device.c
@@ -39,6 +39,14 @@
 
 static GObjectClass *parent_class;
 
+struct _HalDevicePrivate
+{
+	char *udi;	
+	int num_addons;
+	int num_addons_ready;
+	GSList *properties;
+};
+
 enum {
 	PROPERTY_CHANGED,
 	CAPABILITY_ADDED,
@@ -62,17 +70,19 @@ hal_device_finalize (GObject *obj)
 
 #ifdef HALD_MEMLEAK_DBG
 	dbg_hal_device_object_delta--;
-	printf ("************* in finalize for udi=%s\n", device->udi);
+	printf ("************* in finalize for udi=%s\n", device->private->udi);
 #endif
 
 
-	g_slist_foreach (device->properties, (GFunc) hal_property_free, NULL);
+	g_slist_foreach (device->private->properties, (GFunc) hal_property_free, NULL);
+	g_slist_free (device->private->properties);
 
-	g_free (device->udi);
+	g_free (device->private->udi);
+
+	g_free (device->private);
 
 	if (parent_class->finalize)
 		parent_class->finalize (obj);
-
 }
 
 static void
@@ -134,10 +144,12 @@ hal_device_init (HalDevice *device)
 {
 	static int temp_device_counter = 0;
 
-	device->udi = g_strdup_printf ("/org/freedesktop/Hal/devices/temp/%d",
+	device->private = g_new0 (HalDevicePrivate, 1);
+
+	device->private->udi = g_strdup_printf ("/org/freedesktop/Hal/devices/temp/%d",
 				       temp_device_counter++);
-	device->num_addons = 0;
-	device->num_addons_ready = 0;
+	device->private->num_addons = 0;
+	device->private->num_addons_ready = 0;
 }
 
 GType
@@ -204,7 +216,7 @@ hal_device_merge_with_rewrite  (HalDevic
 
 	/* device_property_atomic_update_begin (); */
 
-	for (iter = source->properties; iter != NULL; iter = iter->next) {
+	for (iter = source->private->properties; iter != NULL; iter = iter->next) {
 		HalProperty *p = iter->data;
 		int type;
 		const char *key;
@@ -279,7 +291,7 @@ hal_device_merge (HalDevice *target, Hal
 
 	/* device_property_atomic_update_begin (); */
 
-	for (iter = source->properties; iter != NULL; iter = iter->next) {
+	for (iter = source->private->properties; iter != NULL; iter = iter->next) {
 		HalProperty *p = iter->data;
 		int type;
 		const char *key;
@@ -353,7 +365,7 @@ hal_device_matches (HalDevice *device1, 
 
 	len = strlen (namespace);
 
-	for (iter = device1->properties; iter != NULL; iter = iter->next) {
+	for (iter = device1->private->properties; iter != NULL; iter = iter->next) {
 		HalProperty *p;
 		const char *key;
 		int type;
@@ -413,15 +425,15 @@ hal_device_matches (HalDevice *device1, 
 const char *
 hal_device_get_udi (HalDevice *device)
 {
-	return device->udi;
+	return device->private->udi;
 }
 
 void
 hal_device_set_udi (HalDevice *device, const char *udi)
 {
-	if (device->udi != NULL)
-		g_free (device->udi);
-	device->udi = g_strdup (udi);
+	if (device->private->udi != NULL)
+		g_free (device->private->udi);
+	device->private->udi = g_strdup (udi);
 }
 
 void
@@ -467,7 +479,7 @@ hal_device_num_properties (HalDevice *de
 {
 	g_return_val_if_fail (device != NULL, -1);
 
-	return g_slist_length (device->properties);
+	return g_slist_length (device->private->properties);
 }
 
 HalProperty *
@@ -478,7 +490,7 @@ hal_device_property_find (HalDevice *dev
 	g_return_val_if_fail (device != NULL, NULL);
 	g_return_val_if_fail (key != NULL, NULL);
 
-	for (iter = device->properties; iter != NULL; iter = iter->next) {
+	for (iter = device->private->properties; iter != NULL; iter = iter->next) {
 		HalProperty *p = iter->data;
 
 		if (strcmp (hal_property_get_key (p), key) == 0)
@@ -510,7 +522,7 @@ hal_device_property_foreach (HalDevice *
 	g_return_if_fail (device != NULL);
 	g_return_if_fail (callback != NULL);
 
-	for (iter = device->properties; iter != NULL; iter = iter->next) {
+	for (iter = device->private->properties; iter != NULL; iter = iter->next) {
 		HalProperty *p = iter->data;
 		gboolean cont;
 
@@ -708,7 +720,7 @@ hal_device_property_set_string (HalDevic
 
 		prop = hal_property_new_string (key, value);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -742,7 +754,7 @@ hal_device_property_set_int (HalDevice *
 	} else {
 		prop = hal_property_new_int (key, value);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -776,7 +788,7 @@ hal_device_property_set_uint64 (HalDevic
 	} else {
 		prop = hal_property_new_uint64 (key, value);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -810,7 +822,7 @@ hal_device_property_set_bool (HalDevice 
 	} else {
 		prop = hal_property_new_bool (key, value);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -844,7 +856,7 @@ hal_device_property_set_double (HalDevic
 	} else {
 		prop = hal_property_new_double (key, value);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -898,7 +910,7 @@ hal_device_property_remove (HalDevice *d
 	if (prop == NULL)
 		return FALSE;
 
-	device->properties = g_slist_remove (device->properties, prop);
+	device->private->properties = g_slist_remove (device->private->properties, prop);
 
 	hal_property_free (prop);
 
@@ -931,7 +943,7 @@ hal_device_print (HalDevice *device)
 
         fprintf (stderr, "device udi = %s\n", hal_device_get_udi (device));
 
-	for (iter = device->properties; iter != NULL; iter = iter->next) {
+	for (iter = device->private->properties; iter != NULL; iter = iter->next) {
 		HalProperty *p = iter->data;
                 int type;
                 const char *key;
@@ -1073,7 +1085,7 @@ hal_device_callouts_finished (HalDevice 
 void
 hal_device_cancel (HalDevice *device)
 {
-	HAL_INFO (("udi=%s", device->udi));
+	HAL_INFO (("udi=%s", device->private->udi));
 	g_signal_emit (device, signals[CANCELLED], 0);
 }
 
@@ -1139,7 +1151,7 @@ hal_device_property_strlist_append (HalD
 		prop = hal_property_new_strlist (key);
 		hal_property_strlist_append (prop, value);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -1171,7 +1183,7 @@ hal_device_property_strlist_prepend (Hal
 		prop = hal_property_new_strlist (key);
 		hal_property_strlist_prepend (prop, value);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -1217,7 +1229,7 @@ hal_device_property_strlist_clear (HalDe
 	if (prop == NULL) {
 		prop = hal_property_new_strlist (key);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -1265,7 +1277,7 @@ hal_device_property_strlist_add (HalDevi
 		prop = hal_property_new_strlist (key);
 		hal_property_strlist_prepend (prop, value);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -1323,7 +1335,7 @@ hal_device_property_strlist_is_empty (Ha
 void
 hal_device_inc_num_addons (HalDevice *device)
 {
-	device->num_addons++;
+	device->private->num_addons++;
 }
 
 gboolean
@@ -1331,18 +1343,18 @@ hal_device_inc_num_ready_addons (HalDevi
 {
 	if (hal_device_are_all_addons_ready (device)) {
 		HAL_ERROR (("In hal_device_inc_num_ready_addons for udi=%s but all addons are already ready!", 
-			    device->udi));
+			    device->private->udi));
 		return FALSE;
 	}
 
-	device->num_addons_ready++;
+	device->private->num_addons_ready++;
 	return TRUE;
 }
 
 gboolean
 hal_device_are_all_addons_ready (HalDevice *device)
 {
-	if (device->num_addons_ready == device->num_addons) {
+	if (device->private->num_addons_ready == device->private->num_addons) {
 		return TRUE;
 	} else {
 		return FALSE;
diff --git a/hald/device.h b/hald/device.h
index a9531ba..6ffe494 100644
--- a/hald/device.h
+++ b/hald/device.h
@@ -32,18 +32,16 @@
 
 #include "property.h"
 
+struct _HalDevicePrivate;
+typedef struct _HalDevicePrivate HalDevicePrivate;
+
+
 typedef struct _HalDevice      HalDevice;
 typedef struct _HalDeviceClass HalDeviceClass;
 
 struct _HalDevice {
 	GObject parent;
-
-	char *udi;
-	
-	GSList *properties;
-
-	int num_addons;
-	int num_addons_ready;
+	HalDevicePrivate *private;
 };
 
 struct _HalDeviceClass {
@@ -84,7 +82,7 @@ typedef gboolean (*HalDevicePropertyFore
 
 GType         hal_device_get_type            (void);
 
-HalDevice   *hal_device_new                  (void);
+HalDevice    *hal_device_new                 (void);
 
 void          hal_device_merge               (HalDevice    *target,
 					      HalDevice    *source);
diff --git a/hald/device_info.c b/hald/device_info.c
index cf42935..6f2a153 100644
--- a/hald/device_info.c
+++ b/hald/device_info.c
@@ -345,10 +345,10 @@ handle_match (ParsingContext * pc, const
 
 	/* Resolve key paths like 'someudi/foo/bar/baz:prop.name' '@prop.here.is.an.udi:with.prop.name' */
 	if (!resolve_udiprop_path (key,
-				   pc->device->udi,
+				   hal_device_get_udi (pc->device),
 				   udi_to_check, sizeof (udi_to_check),
 				   prop_to_check, sizeof (prop_to_check))) {
-		HAL_ERROR (("Could not resolve keypath '%s' on udi '%s'", key, pc->device->udi));
+		HAL_ERROR (("Could not resolve keypath '%s' on udi '%s'", key, hal_device_get_udi (pc->device)));
 		return FALSE;
 	}
 
@@ -537,7 +537,7 @@ handle_match (ParsingContext * pc, const
 		if (strcmp (attr[3], "false") == 0)
 			should_be_absolute_path = FALSE;
 
-		/*HAL_INFO (("d->udi='%s', prop_to_check='%s'", d->udi, prop_to_check));*/
+		/*HAL_INFO (("hal_device_get_udi (d)='%s', prop_to_check='%s'", hal_device_get_udi (d), prop_to_check));*/
 
 		if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_STRING)
 			return FALSE;
@@ -1074,7 +1074,7 @@ start (ParsingContext * pc, const char *
 static void 
 spawned_device_callouts_add_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
 {
-	HAL_INFO (("Add callouts completed udi=%s", d->udi));
+	HAL_INFO (("Add callouts completed udi=%s", hal_device_get_udi (d)));
 
 	/* Move from temporary to global device store */
 	hal_device_store_remove (hald_get_tdl (), d);
@@ -1165,10 +1165,11 @@ end (ParsingContext * pc, const char *el
 			 * '@prop.here.is.an.udi:with.prop.name'
 			 */
 			if (!resolve_udiprop_path (pc->cdata_buf,
-						   pc->device->udi,
+						   hal_device_get_udi (pc->device),
 						   udi_to_merge_from, sizeof (udi_to_merge_from),
 						   prop_to_merge, sizeof (prop_to_merge))) {
-				HAL_ERROR (("Could not resolve keypath '%s' on udi '%s'", pc->cdata_buf, pc->device->udi));
+				HAL_ERROR (("Could not resolve keypath '%s' on udi '%s'", pc->cdata_buf, 
+					    hal_device_get_udi (pc->device)));
 			} else {
 				HalDevice *d;
 
@@ -1286,12 +1287,12 @@ end (ParsingContext * pc, const char *el
 
 		if (spawned == NULL) {
 			HAL_INFO (("Spawning new device object '%s' caused by <spawn> on udi '%s'", 
-				   pc->merge_key, pc->device->udi));
+				   pc->merge_key, hal_device_get_udi (pc->device)));
 
 			spawned = hal_device_new ();
 			hal_device_property_set_string (spawned, "info.bus", "unknown");
 			hal_device_property_set_string (spawned, "info.udi", pc->merge_key);
-			hal_device_property_set_string (spawned, "info.parent", pc->device->udi);
+			hal_device_property_set_string (spawned, "info.parent", hal_device_get_udi (pc->device));
 			hal_device_set_udi (spawned, pc->merge_key);
 			
 			hal_device_store_add (hald_get_tdl (), spawned);
diff --git a/hald/device_store.c b/hald/device_store.c
index d11cf6e..1515450 100644
--- a/hald/device_store.c
+++ b/hald/device_store.c
@@ -174,7 +174,7 @@ hal_device_store_add (HalDeviceStore *st
 {
 	const char buf[] = "/org/freedesktop/Hal/devices/";
 
-	if (strncmp(device->udi, buf, sizeof (buf) - 1) != 0) {
+	if (strncmp(hal_device_get_udi (device), buf, sizeof (buf) - 1) != 0) {
 		
 		HAL_ERROR(("Can't add HalDevice with incorrect UDI. Valid "
 			   "UDI must start with '/org/freedesktop/Hal/devices/'"));
diff --git a/hald/dummy/osspec.c b/hald/dummy/osspec.c
index 74165ec..4d010f7 100644
--- a/hald/dummy/osspec.c
+++ b/hald/dummy/osspec.c
@@ -45,7 +45,7 @@ osspec_init (void)
 static void 
 computer_callouts_add_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
 {
-	HAL_INFO (("Add callouts completed udi=%s", d->udi));
+	HAL_INFO (("Add callouts completed udi=%s", hal_device_get_udi (d)));
 
 	/* Move from temporary to global device store */
 	hal_device_store_remove (hald_get_tdl (), d);
diff --git a/hald/hald.c b/hald/hald.c
index cb5c6c7..48b35f4 100644
--- a/hald/hald.c
+++ b/hald/hald.c
@@ -79,7 +79,7 @@ addon_terminated (HalDevice *device, gui
 		  gint return_code, gchar **error,
 		  gpointer data1, gpointer data2)
 {
-	HAL_INFO (("in addon_terminated for udi=%s", device->udi));
+	HAL_INFO (("in addon_terminated for udi=%s", hal_device_get_udi (device)));
 
 	/* TODO: log to syslog - addons shouldn't just terminate, this is a bug with the addon */
 
@@ -371,6 +371,10 @@ main (int argc, char *argv[])
 
 	openlog ("hald", LOG_PID, LOG_DAEMON);
 
+#ifdef HALD_MEMLEAK_DBG
+	g_mem_set_vtable (glib_mem_profiler_table);
+#endif
+
 	g_type_init ();
 
 	if (getenv ("HALD_VERBOSE"))
@@ -473,6 +477,7 @@ main (int argc, char *argv[])
 	/*master_slave_setup ();
 	  sleep (100000000);*/
 
+
 	loop = g_main_loop_new (NULL, FALSE);
 
 	HAL_INFO ((PACKAGE_STRING));
@@ -543,7 +548,6 @@ main (int argc, char *argv[])
 		HAL_INFO (("Will not daemonize"));
 	}
 
-
 	/* we need to do stuff when we are expected to terminate, thus
 	 * this involves looking for SIGTERM; UNIX signal handlers are
 	 * evil though, so set up a pipe to transmit the signal.
@@ -569,6 +573,7 @@ main (int argc, char *argv[])
 	/* set up the local dbus server */
 	if (!hald_dbus_local_server_init ())
 		return 1;
+
 	/* Start the runner helper daemon */
 	if (!hald_runner_start_runner ()) {
 		return 1;
@@ -595,12 +600,21 @@ extern int dbg_hal_device_object_delta;
 
 /* useful for valgrinding; see below */
 static gboolean
+my_shutdown2 (gpointer data)
+{
+	g_mem_profile ();
+	sleep (10000);
+	/*exit (1);*/
+	return FALSE;
+}
+
+static gboolean
 my_shutdown (gpointer data)
 {
 	HalDeviceStore *gdl;
 	
-	printf ("Num devices in TDL: %d\n", g_slist_length ((hald_get_tdl ())->devices));
-	printf ("Num devices in GDL: %d\n", g_slist_length ((hald_get_gdl ())->devices));
+	HAL_INFO (("Num devices in TDL: %d", g_slist_length ((hald_get_tdl ())->devices)));
+	HAL_INFO (("Num devices in GDL: %d", g_slist_length ((hald_get_gdl ())->devices)));
 	
 	gdl = hald_get_gdl ();
 next:
@@ -609,10 +623,19 @@ next:
 		hal_device_store_remove (gdl, d);
 		g_object_unref (d);
 		goto next;
-	}
-	
-	printf ("hal_device_object_delta = %d (should be zero)\n", dbg_hal_device_object_delta);
-	exit (1);
+	}	
+
+	HAL_INFO (("hal_device_object_delta = %d (should be zero)", dbg_hal_device_object_delta));
+
+	hald_dbus_local_server_shutdown ();
+	hald_runner_stop_runner ();
+
+	HAL_INFO (("Shutting down in five seconds"));
+	g_timeout_add (5 * 1000,
+		       my_shutdown2,
+		       NULL);
+
+	return FALSE;
 }
 #endif
 
diff --git a/hald/hald.h b/hald/hald.h
index b810947..cb86cd7 100644
--- a/hald/hald.h
+++ b/hald/hald.h
@@ -56,7 +56,7 @@ extern dbus_bool_t hald_is_shutting_down
  *
  * Use hald/valgrind-hald.sh for this
  */
-/*#define HALD_MEMLEAK_DBG 60*/
+/*#define HALD_MEMLEAK_DBG 10*/
 
 /**
  *  @}
diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c
index 7a51bfb..834ee06 100644
--- a/hald/hald_dbus.c
+++ b/hald/hald_dbus.c
@@ -342,7 +342,7 @@ foreach_device_match_get_udi_tdl (HalDev
 	const char *dev_value;
 
 	/* skip devices in the TDL that hasn't got a real UDI yet */
-	if (strncmp (device->udi, "/org/freedesktop/Hal/devices/temp",
+	if (strncmp (hal_device_get_udi (device), "/org/freedesktop/Hal/devices/temp",
 		     sizeof ("/org/freedesktop/Hal/devices/temp")) == 0)
 		return TRUE;
 
@@ -444,9 +444,11 @@ foreach_device_by_capability (HalDeviceS
 	DeviceCapabilityInfo *info = (DeviceCapabilityInfo *) user_data;
 
 	if (hal_device_has_capability (device, info->capability)) {
+		const char *udi;
+		udi = hal_device_get_udi (device);
 		dbus_message_iter_append_basic (info->iter,
 						DBUS_TYPE_STRING,
-						&(device->udi));
+						&udi);
 	}
 
 	return TRUE;
@@ -2125,7 +2127,7 @@ device_send_signal_property_modified (Ha
 
 /*
     HAL_INFO(("Entering, udi=%s, key=%s, in_gdl=%s, removed=%s added=%s",
-              device->udi, key, 
+              hal_device_get_udi (device), key, 
               in_gdl ? "true" : "false",
               removed ? "true" : "false",
               added ? "true" : "false"));
@@ -2629,7 +2631,7 @@ manager_new_device (DBusConnection * con
 static void 
 manager_remove_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
 {
-	HAL_INFO (("Remove callouts completed udi=%s", d->udi));
+	HAL_INFO (("Remove callouts completed udi=%s", hal_device_get_udi (d)));
 
 	if (!hal_device_store_remove (hald_get_gdl (), d)) {
 		HAL_WARNING (("Error removing device"));
@@ -2708,7 +2710,7 @@ manager_remove (DBusConnection * connect
 static void
 manager_commit_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
 {
-	HAL_INFO (("Add callouts completed udi=%s", d->udi));
+	HAL_INFO (("Add callouts completed udi=%s", hal_device_get_udi (d)));
 }
 
 /*
@@ -2902,7 +2904,7 @@ device_is_executing_method (HalDevice *d
 
 	ret = FALSE;
 
-	if (g_hash_table_lookup_extended (udi_to_method_queue, d->udi, &origkey, (gpointer) &queue)) {
+	if (g_hash_table_lookup_extended (udi_to_method_queue, hal_device_get_udi (d), &origkey, (gpointer) &queue)) {
 
 		if (queue != NULL) {
 			MethodInvocation *mi;
@@ -3013,7 +3015,7 @@ hald_exec_method_cb (HalDevice *d, guint
 	gchar *exp_name = NULL;
 	gchar *exp_detail = NULL;
 
-	hald_exec_method_process_queue (d->udi);
+	hald_exec_method_process_queue (hal_device_get_udi (d));
 
 	message = (DBusMessage *) data1;
 	conn = (DBusConnection *) data2;
@@ -3218,7 +3220,7 @@ hald_exec_method (HalDevice *d, DBusConn
 	}
 
 	mi = g_new0 (MethodInvocation, 1);
-	mi->udi = g_strdup (d->udi);
+	mi->udi = g_strdup (hal_device_get_udi (d));
 	mi->execpath = g_strdup (execpath);
 	mi->extra_env = g_strdupv (extra_env);
 	mi->mstdin = g_strdup (stdin_str->str);
@@ -3943,11 +3945,11 @@ local_server_message_handler (DBusConnec
 			      DBusMessage *message, 
 			      void *user_data)
 {
-	/*HAL_INFO (("local_server_message_handler: destination=%s obj_path=%s interface=%s method=%s", 
+	HAL_INFO (("local_server_message_handler: destination=%s obj_path=%s interface=%s method=%s", 
 		   dbus_message_get_destination (message), 
 		   dbus_message_get_path (message), 
 		   dbus_message_get_interface (message),
-		   dbus_message_get_member (message)));*/
+		   dbus_message_get_member (message)));
 
 	if (dbus_message_is_method_call (message, "org.freedesktop.DBus", "AddMatch")) {
 		DBusMessage *reply;
@@ -3965,7 +3967,9 @@ local_server_message_handler (DBusConnec
 		GSList *i;
 		GSList *j;
 		
-		HAL_INFO (("Client to local_server was disconnected"));
+		HAL_INFO (("************************"));
+		HAL_INFO (("Client to local_server was disconnected for %x", connection));
+		HAL_INFO (("************************"));
 
 		for (i = helper_interface_handlers; i != NULL; i = j) {
 			HelperInterfaceHandler *hih = i->data;
@@ -3993,7 +3997,9 @@ local_server_message_handler (DBusConnec
 		}
 		dbus_message_unref (copy);
 	} else {
-		return hald_dbus_filter_handle_methods (connection, message, user_data, TRUE);
+		DBusHandlerResult ret;
+		ret = hald_dbus_filter_handle_methods (connection, message, user_data, TRUE);
+		return ret;
 	}
 
 	return DBUS_HANDLER_RESULT_HANDLED;
@@ -4002,7 +4008,9 @@ local_server_message_handler (DBusConnec
 static void
 local_server_unregister_handler (DBusConnection *connection, void *user_data)
 {
-	HAL_INFO (("unregistered"));
+	HAL_INFO (("***************************"));
+	HAL_INFO (("********* unregistered %x", connection));
+	HAL_INFO (("***************************"));
 }
 
 static void
@@ -4014,8 +4022,9 @@ local_server_handle_connection (DBusServ
 					&local_server_message_handler, 
 					NULL, NULL, NULL, NULL};
 
-	HAL_INFO (("%d: Got a connection", getpid ()));
-	HAL_INFO (("dbus_connection_get_is_connected = %d", dbus_connection_get_is_connected (new_connection)));
+	HAL_INFO (("***************************"));
+	HAL_INFO (("********* got a connection %x", new_connection));
+	HAL_INFO (("***************************"));
 
 	/*dbus_connection_add_filter (new_connection, server_filter_function, NULL, NULL);*/
 
@@ -4029,14 +4038,12 @@ local_server_handle_connection (DBusServ
 
 
 static DBusServer *local_server = NULL;
+static char *local_server_address = NULL;
 
 char *
 hald_dbus_local_server_addr (void)
 {
-	if (local_server == NULL)
-		return NULL;
-
-	return dbus_server_get_address (local_server);
+	return local_server_address;
 }
 
 gboolean
@@ -4055,7 +4062,8 @@ hald_dbus_local_server_init (void)
 		HAL_ERROR (("Cannot create D-BUS server"));
 		goto out;
 	}
-	HAL_INFO (("local server is listening at %s", dbus_server_get_address (local_server)));
+	local_server_address = dbus_server_get_address (local_server);
+	HAL_INFO (("local server is listening at %s", local_server_address));
 	dbus_server_setup_with_g_main (local_server, NULL);
 	dbus_server_set_new_connection_function (local_server, local_server_handle_connection, NULL, NULL);	
 
@@ -4065,6 +4073,19 @@ out:
 	return ret;
 }
 
+void
+hald_dbus_local_server_shutdown (void)
+{
+	if (local_server != NULL) {
+		HAL_INFO (("Shutting down local server"));
+		dbus_server_disconnect (local_server);
+		dbus_server_unref (local_server);
+		local_server = NULL;
+		dbus_free (local_server_address);
+		local_server_address = NULL;
+	}
+}
+
 gboolean
 hald_dbus_init (void)
 {
diff --git a/hald/hald_dbus.h b/hald/hald_dbus.h
index d81cb47..439f451 100644
--- a/hald/hald_dbus.h
+++ b/hald/hald_dbus.h
@@ -90,6 +90,7 @@ void device_property_atomic_update_end  
 gboolean hald_dbus_init (void);
 
 gboolean hald_dbus_local_server_init (void);
+void hald_dbus_local_server_shutdown (void);
 
 DBusHandlerResult hald_dbus_filter_function (DBusConnection * connection, DBusMessage * message, void *user_data);
 
diff --git a/hald/hald_runner.c b/hald/hald_runner.c
index db76103..b605424 100644
--- a/hald/hald_runner.c
+++ b/hald/hald_runner.c
@@ -33,6 +33,10 @@
 #include <glib.h>
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib-lowlevel.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <signal.h>
 
 #include "hald.h"
 #include "util.h"
@@ -61,7 +65,7 @@ typedef struct
 } RunningProcess;
 
 /* mapping from PID to RunningProcess */
-static GHashTable *running_processes;
+static GHashTable *running_processes = NULL;
 
 static gboolean
 rprd_foreach (gpointer key,
@@ -72,7 +76,7 @@ rprd_foreach (gpointer key,
 	RunningProcess *rp = value;
 	HalDevice *device = user_data;
 
-	if (rp->device == device) {
+	if (device == NULL || rp->device == device) {
 		remove = TRUE;
 		g_free (rp);
 	}
@@ -83,7 +87,9 @@ rprd_foreach (gpointer key,
 static void
 running_processes_remove_device (HalDevice *device)
 {
-	g_hash_table_foreach_remove (running_processes, rprd_foreach, device);
+	if (running_processes != NULL) {
+		g_hash_table_foreach_remove (running_processes, rprd_foreach, device);
+	}
 }
 
 void
@@ -99,11 +105,11 @@ runner_server_message_handler (DBusConne
 			       void *user_data)
 {
 
-	/*HAL_INFO (("runner_server_message_handler: destination=%s obj_path=%s interface=%s method=%s", 
+	HAL_INFO (("runner_server_message_handler: destination=%s obj_path=%s interface=%s method=%s", 
 		   dbus_message_get_destination (message), 
 		   dbus_message_get_path (message), 
 		   dbus_message_get_interface (message),
-		   dbus_message_get_member (message)));*/
+		   dbus_message_get_member (message)));
 	if (dbus_message_is_signal (message, 
 				    "org.freedesktop.HalRunner", 
 				    "StartedProcessExited")) {
@@ -118,22 +124,33 @@ runner_server_message_handler (DBusConne
 
 			pid = (GPid) dpid;
 
-			/*HAL_INFO (("Previously started process with pid %d exited", pid));*/
-			rp = g_hash_table_lookup (running_processes, (gpointer) pid);
-			if (rp != NULL) {
-				rp->cb (rp->device, 0, 0, NULL, rp->data1, rp->data2);
-				g_hash_table_remove (running_processes, (gpointer) pid);
-				g_free (rp);
+			if (running_processes != NULL) {
+				/*HAL_INFO (("Previously started process with pid %d exited", pid));*/
+				rp = g_hash_table_lookup (running_processes, (gpointer) pid);
+				if (rp != NULL) {
+					rp->cb (rp->device, 0, 0, NULL, rp->data1, rp->data2);
+					g_hash_table_remove (running_processes, (gpointer) pid);
+					g_free (rp);
+				}
 			}
 		}
+	} else if (dbus_message_is_signal (message, 
+					   DBUS_INTERFACE_LOCAL, 
+					   "Disconnected") &&
+		   strcmp (dbus_message_get_path (message), DBUS_PATH_LOCAL) == 0) {
+		HAL_INFO (("runner process disconnected"));
+		dbus_connection_unref (connection);
 	}
+
 	return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 static void
 runner_server_unregister_handler (DBusConnection *connection, void *user_data)
 {
-	HAL_INFO (("unregistered"));
+	HAL_INFO (("========================================"));
+	HAL_INFO (("runner_server_unregister_handler"));
+	HAL_INFO (("========================================"));
 }
 
 
@@ -152,6 +169,8 @@ handle_connection(DBusServer *server,
 		dbus_connection_ref (new_connection);
 		dbus_connection_setup_with_g_main (new_connection, NULL);
 
+		HAL_INFO (("runner connection is %p", new_connection));
+
 		dbus_connection_register_fallback (new_connection, 
 						   "/org/freedesktop",
 						   &vtable,
@@ -162,40 +181,79 @@ handle_connection(DBusServer *server,
 	}
 }
 
+static GPid runner_pid;
+static DBusServer *runner_server = NULL;
+static guint runner_watch;
+
+
 static void
-runner_died(GPid pid, gint status, gpointer data) {
-  g_spawn_close_pid (pid);
-  DIE (("Runner died"));
+runner_died(GPid pid, gint status, gpointer data)
+{
+	g_spawn_close_pid (pid);
+	DIE (("Runner died"));
+}
+
+void
+hald_runner_stop_runner (void)
+{
+	if (runner_server != NULL) {
+		DBusMessage *msg;
+
+		/* Don't care about running processes anymore */
+		g_hash_table_foreach_remove (running_processes, rprd_foreach, NULL);
+		g_hash_table_destroy (running_processes);
+		running_processes = NULL;
+
+		HAL_INFO (("Killing runner with pid %d", runner_pid));
+
+		g_source_remove (runner_watch);
+		g_spawn_close_pid (runner_pid);
+
+		msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
+						   "/org/freedesktop/HalRunner",
+						   "org.freedesktop.HalRunner",
+						   "Shutdown");
+		if (msg == NULL) 
+			DIE(("No memory"));
+		dbus_connection_send (runner_connection, msg, NULL);
+		dbus_message_unref(msg);
+
+		dbus_server_disconnect (runner_server);
+		dbus_server_unref (runner_server);
+		runner_server = NULL;
+
+	}
 }
 
 gboolean
 hald_runner_start_runner(void)
 {
-  DBusServer *server = NULL;
   DBusError err;
   GError *error = NULL;
-  GPid pid;
   char *argv[] = { NULL, NULL};
   char *env[] =  { NULL, NULL, NULL, NULL};
   const char *hald_runner_path;
+  char *server_address;
 
   running_processes = g_hash_table_new (g_direct_hash, g_direct_equal);
 
   dbus_error_init(&err);
-  server = dbus_server_listen(DBUS_SERVER_ADDRESS, &err);
-  if (server == NULL) {
+  runner_server = dbus_server_listen(DBUS_SERVER_ADDRESS, &err);
+  if (runner_server == NULL) {
     HAL_ERROR (("Cannot create D-BUS server for the runner"));
     goto error;
   }
 
-  dbus_server_setup_with_g_main(server, NULL);
-  dbus_server_set_new_connection_function(server, handle_connection, 
+  dbus_server_setup_with_g_main(runner_server, NULL);
+  dbus_server_set_new_connection_function(runner_server, handle_connection, 
                                           NULL, NULL);
 
 
   argv[0] = "hald-runner";
+  server_address = dbus_server_get_address(runner_server);
   env[0] = g_strdup_printf("HALD_RUNNER_DBUS_ADDRESS=%s",
-             dbus_server_get_address(server));
+			   server_address);
+  dbus_free (server_address);
   hald_runner_path = g_getenv("HALD_RUNNER_PATH");
   if (hald_runner_path != NULL) {
 	  env[1] = g_strdup_printf ("PATH=%s:" PACKAGE_LIBEXEC_DIR ":" PACKAGE_SCRIPT_DIR ":" PACKAGE_BIN_DIR, hald_runner_path);
@@ -207,7 +265,7 @@ hald_runner_start_runner(void)
   
   
   if (!g_spawn_async(NULL, argv, env, G_SPAWN_DO_NOT_REAP_CHILD|G_SPAWN_SEARCH_PATH, 
-        NULL, NULL, &pid, &error)) {
+        NULL, NULL, &runner_pid, &error)) {
     HAL_ERROR (("Could not spawn runner : '%s'", error->message));
     g_error_free (error);
     goto error;
@@ -215,18 +273,18 @@ hald_runner_start_runner(void)
   g_free(env[0]);
   g_free(env[1]);
 
-  HAL_INFO (("Runner has pid %d", pid));
+  HAL_INFO (("Runner has pid %d", runner_pid));
 
-  g_child_watch_add(pid, runner_died, NULL);
+  runner_watch = g_child_watch_add(runner_pid, runner_died, NULL);
   while (runner_connection == NULL) {
     /* Wait for the runner */
-    g_main_context_iteration(NULL, TRUE);
+    g_main_context_iteration (NULL, TRUE);
   }
   return TRUE;
 
 error:
-  if (server != NULL)
-    dbus_server_unref(server);
+  if (runner_server != NULL)
+    dbus_server_unref(runner_server);
   return FALSE;
 }
 
@@ -389,7 +447,7 @@ hald_runner_start (HalDevice *device, co
 	if (dbus_message_get_args (reply, &err,
 				   DBUS_TYPE_INT64, &pid_from_runner,
 				   DBUS_TYPE_INVALID)) {
-		if (cb != NULL) {
+		if (cb != NULL && running_processes != NULL) {
 			RunningProcess *rp;
 			rp = g_new0 (RunningProcess, 1);
 			rp->pid = (GPid) pid_from_runner;
@@ -454,8 +512,11 @@ call_notify(DBusPendingCall *pending, vo
   g_object_unref (hb->d);
 
   dbus_message_unref(m);
-  g_array_free(error, FALSE);
+  g_array_free(error, TRUE);
 
+  g_free (hb);
+
+  dbus_pending_call_unref (pending);
   return;
 malformed:
   /* Send a Fail callback on malformed messages */
@@ -465,7 +526,11 @@ malformed:
   g_object_unref (hb->d);
 
   dbus_message_unref(m);
-  g_array_free(error, FALSE);
+  g_array_free(error, TRUE);
+
+  g_free (hb);
+
+  dbus_pending_call_unref (pending);
 }
 
 /* Run a helper program using the commandline, with input as infomation on
@@ -481,6 +546,7 @@ hald_runner_run_method(HalDevice *device
   DBusMessageIter iter;
   DBusPendingCall *call;
   HelperData *hd = NULL;
+
   msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
                              "/org/freedesktop/HalRunner",
                              "org.freedesktop.HalRunner",
@@ -500,7 +566,7 @@ hald_runner_run_method(HalDevice *device
                                               msg, &call, INT_MAX))
     DIE (("No memory"));
 
-  hd = malloc(sizeof(HelperData));
+  hd = g_new0 (HelperData, 1);
   hd->d = device;
   hd->cb = cb;
   hd->data1 = data1;
@@ -508,12 +574,12 @@ hald_runner_run_method(HalDevice *device
 
   g_object_ref (device);
 
-  dbus_pending_call_set_notify(call, call_notify, hd, free);
+  dbus_pending_call_set_notify(call, call_notify, hd, NULL);
   dbus_message_unref(msg);
   return;
 error:
   dbus_message_unref(msg);
-  free(hd);
+  g_free(hd);
   cb(device, HALD_RUN_FAILED, 0, NULL, data1, data2);
 }
 
diff --git a/hald/hald_runner.h b/hald/hald_runner.h
index ca05573..0fc2425 100644
--- a/hald/hald_runner.h
+++ b/hald/hald_runner.h
@@ -49,6 +49,10 @@ typedef void (*HalRunTerminatedCB) (HalD
 gboolean
 hald_runner_start_runner(void);
 
+/* Stop the runner daemon */
+void
+hald_runner_stop_runner(void);
+
 /* Start a helper, returns true on a successfull start. 
  * cb will be called on abnormal or premature termination
  * only 
diff --git a/hald/ids.c b/hald/ids.c
index 6c10f52..5d2fe62 100644
--- a/hald/ids.c
+++ b/hald/ids.c
@@ -545,7 +545,6 @@ ids_init (void)
 	usb_ids_load (HWDATA_DIR "/usb.ids");
 }
 
-
 /* This, somewhat incomplete, list is from this sources:
  * http://www.plasma-online.de/english/identify/serial/pnp_id_pnp.html 
  * http://www-pc.uni-regensburg.de/hardware/TECHNIK/PCI_PNP/pnpid.txt
@@ -555,7 +554,7 @@ ids_init (void)
 struct pnp_id {
 	char *id;
    	char *desc;
-} static pnp_ids_list[] = {
+} static  pnp_ids_list[] = {
 	/* Crystal Semiconductor devices */
 	{"CSC0000", "Crystal Semiconductor CS423x sound -- SB/WSS/OPL3 emulation"},
 	{"CSC0001", "Crystal Semiconductor CS423x sound -- joystick"},
diff --git a/hald/linux/acpi.c b/hald/linux/acpi.c
index eae5c51..040cb33 100644
--- a/hald/linux/acpi.c
+++ b/hald/linux/acpi.c
@@ -211,11 +211,13 @@ battery_refresh_poll (HalDevice *d)
 	hal_device_property_set_int (d, "battery.charge_level.last_full", normalised_lastfull);
 	hal_device_property_set_int (d, "battery.charge_level.rate", normalised_rate);
 
-	remaining_time = util_compute_time_remaining (d->udi, normalised_rate, normalised_current, normalised_lastfull,
-				hal_device_property_get_bool (d, "battery.rechargeable.is_discharging"),
-				hal_device_property_get_bool (d, "battery.rechargeable.is_charging"),
-				hal_device_property_get_bool (d, "battery.remaining_time.calculate_per_time"));
-	remaining_percentage = util_compute_percentage_charge (d->udi, normalised_current, normalised_lastfull);
+	remaining_time = util_compute_time_remaining (
+		hal_device_get_udi (d), 
+		normalised_rate, normalised_current, normalised_lastfull,
+		hal_device_property_get_bool (d, "battery.rechargeable.is_discharging"),
+		hal_device_property_get_bool (d, "battery.rechargeable.is_charging"),
+		hal_device_property_get_bool (d, "battery.remaining_time.calculate_per_time"));
+	remaining_percentage = util_compute_percentage_charge (hal_device_get_udi (d), normalised_current, normalised_lastfull);
 	/*
 	 * Only set keys if no error (signified with negative return value)
 	 * Scrict checking is needed to ensure that the values presented by HAL
@@ -1065,7 +1067,7 @@ acpi_generic_add (const gchar *acpi_path
 	hal_device_property_set_string (d, "linux.acpi_path", acpi_path);
 	hal_device_property_set_int (d, "linux.acpi_type", handler->acpi_type);
 	if (parent != NULL)
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	else
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	if (handler->refresh == NULL || !handler->refresh (d, handler)) {
@@ -1211,7 +1213,7 @@ acpi_callouts_add_done (HalDevice *d, gp
 {
 	void *end_token = (void *) userdata1;
 
-	HAL_INFO (("Add callouts completed udi=%s", d->udi));
+	HAL_INFO (("Add callouts completed udi=%s", hal_device_get_udi (d)));
 
 	/* Move from temporary to global device store */
 	hal_device_store_remove (hald_get_tdl (), d);
@@ -1225,7 +1227,7 @@ acpi_callouts_remove_done (HalDevice *d,
 {
 	void *end_token = (void *) userdata1;
 
-	HAL_INFO (("Remove callouts completed udi=%s", d->udi));
+	HAL_INFO (("Remove callouts completed udi=%s", hal_device_get_udi (d)));
 
 	if (!hal_device_store_remove (hald_get_gdl (), d)) {
 		HAL_WARNING (("Error removing device"));
@@ -1331,7 +1333,7 @@ acpi_rescan_device (HalDevice *d)
 		}
 	}
 
-	HAL_WARNING (("Didn't find a rescan handler for udi %s", d->udi));
+	HAL_WARNING (("Didn't find a rescan handler for udi %s", hal_device_get_udi (d)));
 	return TRUE;
 }
 
diff --git a/hald/linux/apm.c b/hald/linux/apm.c
index a11148f..ae5873a 100644
--- a/hald/linux/apm.c
+++ b/hald/linux/apm.c
@@ -229,7 +229,7 @@ battery_refresh (HalDevice *d, APMDevHan
 		hal_device_property_set_bool (d, "battery.rechargeable.is_discharging", is_discharging);
 
 		/* set the percentage charge, easy. */
-		remaining_percentage = util_compute_percentage_charge (d->udi, i.battery_percentage, 100);
+		remaining_percentage = util_compute_percentage_charge (hal_device_get_udi (d), i.battery_percentage, 100);
 	
 		/* Only set keys if no error (signified with negative return value) */
 		if (remaining_percentage > 0)
@@ -328,7 +328,7 @@ apm_generic_add (const gchar *apm_path, 
 	hal_device_property_set_string (d, "linux.apm_path", apm_path);
 	hal_device_property_set_int (d, "linux.apm_type", handler->apm_type);
 	if (parent != NULL)
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	else
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	if (handler->refresh == NULL || !handler->refresh (d, handler)) {
@@ -500,7 +500,7 @@ apm_rescan_device (HalDevice *d)
 		}
 	}
 
-	HAL_WARNING (("Didn't find a rescan handler for udi %s", d->udi));
+	HAL_WARNING (("Didn't find a rescan handler for udi %s", hal_device_get_udi (d)));
 
 out:
 	return ret;
diff --git a/hald/linux/blockdev.c b/hald/linux/blockdev.c
index 0510065..b3f9b11 100644
--- a/hald/linux/blockdev.c
+++ b/hald/linux/blockdev.c
@@ -122,7 +122,7 @@ blockdev_callouts_add_done (HalDevice *d
 {
 	void *end_token = (void *) userdata1;
 
-	HAL_INFO (("Add callouts completed udi=%s", d->udi));
+	HAL_INFO (("Add callouts completed udi=%s", hal_device_get_udi (d)));
 
 	/* Move from temporary to global device store */
 	hal_device_store_remove (hald_get_tdl (), d);
@@ -136,7 +136,7 @@ blockdev_callouts_remove_done (HalDevice
 {
 	void *end_token = (void *) userdata1;
 
-	HAL_INFO (("Remove callouts completed udi=%s", d->udi));
+	HAL_INFO (("Remove callouts completed udi=%s", hal_device_get_udi (d)));
 
 	if (!hal_device_store_remove (hald_get_gdl (), d)) {
 		HAL_WARNING (("Error removing device"));
@@ -247,7 +247,7 @@ blockdev_refresh_mount_state (HalDevice 
 		 * lost... it is merely delayed...
 		 */
 		if (device_is_executing_method (dev, "org.freedesktop.Hal.Device.Volume", "Unmount")) {
-			HAL_INFO (("/proc/mounts tells that %s is unmounted - waiting for Unmount() to complete to change mount state", dev->udi));
+			HAL_INFO (("/proc/mounts tells that %s is unmounted - waiting for Unmount() to complete to change mount state", hal_device_get_udi (dev)));
 		} else {
 			char *mount_point;
 
@@ -697,8 +697,8 @@ hotplug_event_begin_add_blockdev (const 
 							HAL_INFO ((" slave_volume_stordev_udi='%s'!", slave_volume_stordev_udi));
 							parent = hal_device_store_find (hald_get_gdl (), slave_volume_stordev_udi);
 							if (parent != NULL) {
-								HAL_INFO ((" parent='%s'!", parent->udi));
-								hal_device_property_set_string (d, "volume.crypto_luks.clear.backing_volume", slave_volume->udi);
+								HAL_INFO ((" parent='%s'!", hal_device_get_udi (parent)));
+								hal_device_property_set_string (d, "volume.crypto_luks.clear.backing_volume", hal_device_get_udi (slave_volume));
 								is_device_mapper = TRUE;
 							}
 						}
@@ -725,7 +725,7 @@ hotplug_event_begin_add_blockdev (const 
 
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", parent->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	hal_device_property_set_int (d, "linux.hotplug_type", HOTPLUG_EVENT_SYSFS_BLOCK);
 
 	hal_device_property_set_string (d, "block.device", device_file);
@@ -755,7 +755,7 @@ hotplug_event_begin_add_blockdev (const 
 		hal_device_property_set_string (d, "info.vendor", "");
 		hal_device_property_set_string (d, "info.product", "PC Floppy Drive");
 		hal_device_property_set_string (d, "storage.drive_type", "floppy");
-		hal_device_property_set_string (d, "storage.physical_device", parent->udi);
+		hal_device_property_set_string (d, "storage.physical_device", hal_device_get_udi (parent));
 		hal_device_property_set_bool (d, "storage.removable", TRUE);
 		hal_device_property_set_bool (d, "storage.removable.media_available", FALSE);
 		hal_device_property_set_bool (d, "storage.hotpluggable", FALSE);
@@ -820,7 +820,7 @@ hotplug_event_begin_add_blockdev (const 
 		/* walk up the device chain to find the physical device, 
 		 * start with our parent. On the way, optionally pick up
 		 * the scsi if it exists */
-		udi_it = parent->udi;
+		udi_it = hal_device_get_udi (parent);
 		while (udi_it != NULL) {
 			HalDevice *d_it;
 
@@ -1034,7 +1034,7 @@ hotplug_event_begin_add_blockdev (const 
 		 * VOLUMES
 		 *
 		 ************************/
-		hal_device_property_set_string (d, "block.storage_device", parent->udi);
+		hal_device_property_set_string (d, "block.storage_device", hal_device_get_udi (parent));
 
 		/* defaults */
 		hal_device_property_set_string (d, "storage.model", "");
@@ -1140,7 +1140,7 @@ force_unmount_cb (HalDevice *d, guint32 
 {
 	void *end_token = (void *) data1;
 
-	HAL_INFO (("force_unmount_cb for udi='%s', exit_type=%d, return_code=%d", d->udi, exit_type, return_code));
+	HAL_INFO (("force_unmount_cb for udi='%s', exit_type=%d, return_code=%d", hal_device_get_udi (d), exit_type, return_code));
 
 	if (exit_type == HALD_RUN_SUCCESS && error != NULL && 
 	    error[0] != NULL && error[1] != NULL) {
@@ -1175,7 +1175,7 @@ force_unmount (HalDevice *d, void *end_t
 		extra_env[0] = "HAL_METHOD_INVOKED_BY_UID=0";
 		extra_env[1] = NULL;
 		
-		HAL_INFO (("force_unmount for udi='%s'", d->udi));
+		HAL_INFO (("force_unmount for udi='%s'", hal_device_get_udi (d)));
 		syslog (LOG_NOTICE, "forcibly attempting to lazy unmount %s as enclosing drive was disconnected", device_file);
 		
 		unmount_stdin = "lazy\n";
@@ -1235,7 +1235,7 @@ hotplug_event_begin_remove_blockdev (con
 		if (fakevolume != NULL) {
 			HotplugEvent *hotplug_event;
 			HAL_INFO (("Storage device with a fakevolume is going away; "
-				   "synthesizing hotplug rem for fakevolume %s", fakevolume->udi));
+				   "synthesizing hotplug rem for fakevolume %s", hal_device_get_udi (fakevolume)));
 			hotplug_event = blockdev_generate_remove_hotplug_event (fakevolume);
 			if (hotplug_event != NULL) {
 				/* push synthesized event at front of queue and repost this event... this is such that
@@ -1295,7 +1295,8 @@ block_rescan_storage_done (HalDevice *d,
 		if (fakevolume != NULL) {
 			/* generate hotplug event to remove the fakevolume */
 			HotplugEvent *hotplug_event;
-			HAL_INFO (("Media removal detected; synthesizing hotplug rem for fakevolume %s", fakevolume->udi));
+			HAL_INFO (("Media removal detected; synthesizing hotplug rem for fakevolume %s", 
+				   hal_device_get_udi (fakevolume)));
 			hotplug_event = blockdev_generate_remove_hotplug_event (fakevolume);
 			if (hotplug_event != NULL) {
 				hotplug_event_enqueue (hotplug_event);
@@ -1315,11 +1316,11 @@ blockdev_rescan_device (HalDevice *d)
 
 	ret = FALSE;
 
-	HAL_INFO (("Entering, udi=%s", d->udi));
+	HAL_INFO (("Entering, udi=%s", hal_device_get_udi (d)));
 
 	/* This only makes sense on storage devices */
 	if (hal_device_property_get_bool (d, "block.is_volume")) {
-		HAL_INFO (("No action on volumes", d->udi));
+		HAL_INFO (("No action on volumes", hal_device_get_udi (d)));
 		goto out;
 	}
 
diff --git a/hald/linux/classdev.c b/hald/linux/classdev.c
index 5e61ce9..dfbb338 100644
--- a/hald/linux/classdev.c
+++ b/hald/linux/classdev.c
@@ -67,8 +67,8 @@ input_add (const gchar *sysfs_path, cons
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	if (physdev != NULL) {
-		hal_device_property_set_string (d, "input.physical_device", physdev->udi);
-		hal_device_property_set_string (d, "info.parent", physdev->udi);
+		hal_device_property_set_string (d, "input.physical_device", hal_device_get_udi (physdev));
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -122,12 +122,12 @@ bluetooth_add (const gchar *sysfs_path, 
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 
 	hal_device_property_set_string (d, "info.category", "bluetooth_hci");
 	hal_device_add_capability (d, "bluetooth_hci");
 
-	hal_device_property_set_string (d, "bluetooth_hci.physical_device", physdev->udi);
+	hal_device_property_set_string (d, "bluetooth_hci.physical_device", hal_device_get_udi (physdev));
 	hal_util_set_string_from_file (d, "bluetooth_hci.interface_name", sysfs_path, "name");
 
 	hal_device_property_set_string (d, "info.product", "Bluetooth Host Controller Interface");
@@ -166,12 +166,12 @@ net_add (const gchar *sysfs_path, const 
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 
 	hal_device_property_set_string (d, "info.category", "net");
 	hal_device_add_capability (d, "net");
 
-	hal_device_property_set_string (d, "net.physical_device", physdev->udi);
+	hal_device_property_set_string (d, "net.physical_device", hal_device_get_udi (physdev));
 
 	ifname = hal_util_get_last_element (sysfs_path);
 	hal_device_property_set_string (d, "net.interface", ifname);
@@ -290,7 +290,7 @@ scsi_generic_add (const gchar *sysfs_pat
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 	hal_device_property_set_string (d, "info.category", "scsi_generic");
 	hal_device_add_capability (d, "scsi_generic");
 	hal_device_property_set_string (d, "info.product", "SCSI Generic Interface");
@@ -332,7 +332,7 @@ scsi_host_add (const gchar *sysfs_path, 
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path_in_devices);
 	
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 
 	hal_device_property_set_string (d, "info.category", "scsi_host");
 	hal_device_add_capability (d, "scsi_host");
@@ -381,7 +381,7 @@ usbclass_add (const gchar *sysfs_path, c
 		d = hal_device_new ();
 		hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 		hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path_in_devices);
-		hal_device_property_set_string (d, "info.parent", physdev->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 
 		hal_device_property_set_string (d, "info.category", "hiddev");
 		hal_device_add_capability (d, "hiddev");
@@ -394,7 +394,7 @@ usbclass_add (const gchar *sysfs_path, c
 		d = hal_device_new ();
 		hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 		hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path_in_devices);
-		hal_device_property_set_string (d, "info.parent", physdev->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 
 		hal_device_property_set_string (d, "info.category", "printer");
 		hal_device_add_capability (d, "printer");
@@ -402,7 +402,7 @@ usbclass_add (const gchar *sysfs_path, c
 		hal_device_property_set_string (d, "info.product", "Printer");
 		hal_device_property_set_string (d, "printer.device", device_file);
 
-		hal_device_property_set_string (d, "printer.physical_device", physdev->udi);
+		hal_device_property_set_string (d, "printer.physical_device", hal_device_get_udi (physdev));
 	}
 
 out:
@@ -460,7 +460,7 @@ usbraw_add (const gchar *sysfs_path, con
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 	hal_device_property_set_string (d, "info.category", "usbraw");
 	hal_device_add_capability (d, "usbraw");
 	hal_device_property_set_string (d, "info.product", "USB Raw Device Access");
@@ -498,7 +498,7 @@ video4linux_add (const gchar *sysfs_path
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 	hal_device_property_set_string (d, "info.category", "video4linux");
 	hal_device_add_capability (d, "video4linux");
 	hal_device_property_set_string (d, "info.product", "Video Device");
@@ -536,7 +536,7 @@ dvb_add (const gchar *sysfs_path, const 
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 	hal_device_property_set_string (d, "info.category", "dvb");
 	hal_device_add_capability (d, "dvb");
 	hal_device_property_set_string (d, "info.product", "DVB Device");
@@ -618,8 +618,8 @@ sound_add (const gchar *sysfs_path, cons
 			hal_device_property_set_string (d, "info.category", "alsa");
 			hal_device_add_capability (d, "alsa");
 			hal_device_property_set_string (d, "alsa.device_file", device_file);
-			hal_device_property_set_string (d, "info.parent", physdev->udi);
-			hal_device_property_set_string (d, "alsa.physical_device", physdev->udi);
+			hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
+			hal_device_property_set_string (d, "alsa.physical_device", hal_device_get_udi (physdev));
 			hal_device_property_set_int (d, "alsa.card", cardnum);
 			hal_device_property_set_string (d, "alsa.type", "control");
 	
@@ -635,8 +635,8 @@ sound_add (const gchar *sysfs_path, cons
 			hal_device_property_set_string (d, "info.category", "alsa");
 			hal_device_add_capability (d, "alsa");
 			hal_device_property_set_string (d, "alsa.device_file", device_file);
-			hal_device_property_set_string (d, "info.parent", physdev->udi);
-			hal_device_property_set_string (d, "alsa.physical_device", physdev->udi);
+			hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
+			hal_device_property_set_string (d, "alsa.physical_device", hal_device_get_udi (physdev));
 			hal_device_property_set_int (d, "alsa.card", cardnum);
 			hal_device_property_set_int (d, "alsa.device", devicenum);
 	
@@ -708,8 +708,8 @@ sound_add (const gchar *sysfs_path, cons
 			hal_device_property_set_string (d, "info.category", "oss");
 			hal_device_add_capability (d, "oss");
 			hal_device_property_set_string (d, "oss.device_file", device_file);
-			hal_device_property_set_string (d, "info.parent", physdev->udi);
-			hal_device_property_set_string (d, "oss.physical_device", physdev->udi);
+			hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
+			hal_device_property_set_string (d, "oss.physical_device", hal_device_get_udi (physdev));
 			hal_device_property_set_int (d, "oss.card", cardnum);
 	
 			snprintf (aprocdir, sizeof (aprocdir), "%s/asound/card%d", get_hal_proc_path (), cardnum);
@@ -843,10 +843,10 @@ serial_add (const gchar *sysfs_path, con
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 	hal_device_property_set_string (d, "info.category", "serial");
 	hal_device_add_capability (d, "serial");
-	hal_device_property_set_string (d, "serial.physical_device", physdev->udi);
+	hal_device_property_set_string (d, "serial.physical_device", hal_device_get_udi (physdev));
 	hal_device_property_set_string (d, "serial.device", device_file);
 
 	last_elem = hal_util_get_last_element(sysfs_path);
@@ -932,7 +932,7 @@ tape_add (const gchar *sysfs_path, const
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 	hal_device_property_set_string (d, "info.category", "tape");
 	hal_device_add_capability (d, "tape");
 	hal_device_add_capability (physdev, "tape");
@@ -987,7 +987,7 @@ mmc_host_add (const gchar *sysfs_path, c
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path_in_devices);
 
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 
 	hal_device_property_set_string (d, "info.category", "mmc_host");
 	hal_device_add_capability (d, "mmc_host");
@@ -1205,7 +1205,7 @@ classdev_callouts_add_done (HalDevice *d
 {
 	void *end_token = (void *) userdata1;
 
-	HAL_INFO (("Add callouts completed udi=%s", d->udi));
+	HAL_INFO (("Add callouts completed udi=%s", hal_device_get_udi (d)));
 
 	/* Move from temporary to global device store */
 	hal_device_store_remove (hald_get_tdl (), d);
@@ -1219,7 +1219,7 @@ classdev_callouts_remove_done (HalDevice
 {
 	void *end_token = (void *) userdata1;
 
-	HAL_INFO (("Remove callouts completed udi=%s", d->udi));
+	HAL_INFO (("Remove callouts completed udi=%s", hal_device_get_udi (d)));
 
 	if (!hal_device_store_remove (hald_get_gdl (), d)) {
 		HAL_WARNING (("Error removing device"));
diff --git a/hald/linux/coldplug.c b/hald/linux/coldplug.c
index 2ce29f6..3693cda 100644
--- a/hald/linux/coldplug.c
+++ b/hald/linux/coldplug.c
@@ -198,9 +198,26 @@ hal_util_init_sysfs_to_udev_map (void)
 error:
 	g_free(udevinfo_stdout);
 	g_hash_table_destroy (sysfs_to_udev_map);
+	sysfs_to_udev_map = NULL;
 	return FALSE;
 }
 
+static HotplugEvent *pool = NULL;
+static int pool_next_free = 0;
+static int pool_num_freed = 0;
+static int pool_size = 1000;
+
+static void 
+pool_free (gpointer data)
+{
+	HAL_INFO (("pool_num_freed = %d (of %d)", pool_num_freed, pool_next_free));
+	pool_num_freed++;
+	if (pool_num_freed == pool_next_free) {
+		HAL_INFO (("Freeing whole pool"));
+		g_free (pool);
+	}
+}
+
 static HotplugEvent
 *coldplug_get_hotplug_event(const gchar *sysfs_path, const gchar *subsystem, HotplugEventType type)
 {
@@ -208,15 +225,29 @@ static HotplugEvent
 	const char *pos;
 	gchar path[HAL_PATH_MAX];
 	struct stat statbuf;
+	gboolean from_pool = FALSE;
 
-	hotplug_event = g_new0 (HotplugEvent, 1);
-	if (hotplug_event == NULL)
-		return NULL;
+	if (pool == NULL) {
+		pool = g_new0 (HotplugEvent, pool_size);
+		pool_next_free = 0;
+		pool_num_freed = 0;
+	}
+
+	if (pool_next_free >= pool_size) {
+		hotplug_event = g_new0 (HotplugEvent, 1);
+	} else {
+		from_pool = TRUE;
+		hotplug_event = pool + pool_next_free++;
+		hotplug_event->free_function = pool_free;
+	}
 
 	/* 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));
+		if (from_pool) {
+			hotplug_event->free_function = pool_free;
+		}
 		HAL_INFO (("new event (dev node from udev) '%s' '%s'", hotplug_event->sysfs.sysfs_path, hotplug_event->sysfs.device_file));
 	} else {
 		/* device is not in udev database */
@@ -462,6 +493,7 @@ static void queue_events(void)
 
 		g_free (sysfs_dev->path);
 		g_free (sysfs_dev->subsystem);
+		g_free (sysfs_dev);
 	}
 
 	g_slist_free (device_list);
diff --git a/hald/linux/hotplug.c b/hald/linux/hotplug.c
index 5187c97..ab6618f 100644
--- a/hald/linux/hotplug.c
+++ b/hald/linux/hotplug.c
@@ -62,7 +62,12 @@ hotplug_event_end (void *end_token)
 	HotplugEvent *hotplug_event = (HotplugEvent *) end_token;
 
 	hotplug_events_in_progress = g_slist_remove (hotplug_events_in_progress, hotplug_event);
-	g_free (hotplug_event);
+
+	if (hotplug_event->free_function != NULL) {
+		hotplug_event->free_function (hotplug_event);
+	} else {
+		g_free (hotplug_event);
+	}
 	hotplug_event_process_queue ();
 }
 
@@ -438,7 +443,7 @@ hotplug_rescan_device (HalDevice *d)
 		break;
 
 	default:
-		HAL_INFO (("Unknown hotplug type for udi=%s", d->udi));
+		HAL_INFO (("Unknown hotplug type for udi=%s", hal_device_get_udi (d)));
 		ret = FALSE;
 		break;
 	}
@@ -454,7 +459,7 @@ hotplug_reprobe_generate_remove_events (
 	HotplugEvent *e;
 
 	/* first remove childs */
-	childs = hal_device_store_match_multiple_key_value_string (hald_get_gdl (), "info.parent", d->udi);
+	childs = hal_device_store_match_multiple_key_value_string (hald_get_gdl (), "info.parent", hal_device_get_udi (d));
 	for (i = childs; i != NULL; i = g_slist_next (i)) {
 		HalDevice *child;
 
@@ -463,7 +468,7 @@ hotplug_reprobe_generate_remove_events (
 	}
 
 	/* then remove self */
-	HAL_INFO (("Generate remove event for udi %s", d->udi));
+	HAL_INFO (("Generate remove event for udi %s", hal_device_get_udi (d)));
 	switch (hal_device_property_get_int (d, "linux.hotplug_type")) {
 	case HOTPLUG_EVENT_SYSFS_BUS:
 		e = physdev_generate_remove_hotplug_event (d);
@@ -491,7 +496,7 @@ hotplug_reprobe_generate_remove_events (
 
 	default:
 		e = NULL;
-		HAL_INFO (("Unknown hotplug type for udi=%s", d->udi));
+		HAL_INFO (("Unknown hotplug type for udi=%s", hal_device_get_udi (d)));
 		break;
 	}
 
@@ -508,7 +513,7 @@ hotplug_reprobe_generate_add_events (Hal
 	HotplugEvent *e;
 
 	/* first add self */
-	HAL_INFO (("Generate add event for udi %s", d->udi));
+	HAL_INFO (("Generate add event for udi %s", hal_device_get_udi (d)));
 	switch (hal_device_property_get_int (d, "linux.hotplug_type")) {
 	case HOTPLUG_EVENT_SYSFS_BUS:
 		e = physdev_generate_add_hotplug_event (d);
@@ -536,7 +541,7 @@ hotplug_reprobe_generate_add_events (Hal
 
 	default:
 		e = NULL;
-		HAL_INFO (("Unknown hotplug type for udi=%s", d->udi));
+		HAL_INFO (("Unknown hotplug type for udi=%s", hal_device_get_udi (d)));
 		break;
 	}
 
@@ -545,7 +550,7 @@ hotplug_reprobe_generate_add_events (Hal
 	}
 
 	/* then add childs */
-	childs = hal_device_store_match_multiple_key_value_string (hald_get_gdl (), "info.parent", d->udi);
+	childs = hal_device_store_match_multiple_key_value_string (hald_get_gdl (), "info.parent", hal_device_get_udi (d));
 	for (i = childs; i != NULL; i = g_slist_next (i)) {
 		HalDevice *child;
 
diff --git a/hald/linux/hotplug.h b/hald/linux/hotplug.h
index d93d620..3619617 100644
--- a/hald/linux/hotplug.h
+++ b/hald/linux/hotplug.h
@@ -56,6 +56,8 @@ typedef struct
 	HotplugActionType action;				/* Whether the event is add or remove */
 	HotplugEventType type;					/* Type of event */
 
+	void (*free_function) (gpointer data);
+
 	union {
 		struct {
 			char subsystem[HAL_NAME_MAX];		/* Kernel subsystem the device belongs to */
diff --git a/hald/linux/osspec.c b/hald/linux/osspec.c
index bcfe115..def76ff 100644
--- a/hald/linux/osspec.c
+++ b/hald/linux/osspec.c
@@ -325,7 +325,7 @@ osspec_init (void)
 static void 
 computer_callouts_add_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
 {
-	HAL_INFO (("Add callouts completed udi=%s", d->udi));
+	HAL_INFO (("Add callouts completed udi=%s", hal_device_get_udi (d)));
 
 	/* Move from temporary to global device store */
 	hal_device_store_remove (hald_get_tdl (), d);
diff --git a/hald/linux/physdev.c b/hald/linux/physdev.c
index 0c92a3e..c49d0b9 100644
--- a/hald/linux/physdev.c
+++ b/hald/linux/physdev.c
@@ -61,7 +61,7 @@ pci_add (const gchar *sysfs_path, HalDev
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "pci");
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -225,7 +225,7 @@ usb_add (const gchar *sysfs_path, HalDev
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	}
 
 	/* only USB interfaces got a : in the bus_id */
@@ -376,7 +376,7 @@ ide_add (const gchar *sysfs_path, HalDev
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "ide");
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -427,7 +427,7 @@ pnp_add (const gchar *sysfs_path, HalDev
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "pnp");
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -483,7 +483,7 @@ platform_add (const gchar *sysfs_path, H
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "platform");
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -528,7 +528,7 @@ serio_add (const gchar *sysfs_path, HalD
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "serio");
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -576,7 +576,7 @@ pcmcia_add (const gchar *sysfs_path, Hal
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "pcmcia");
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -656,7 +656,7 @@ scsi_add (const gchar *sysfs_path, HalDe
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "scsi");
-	hal_device_property_set_string (d, "info.parent", parent->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 
 	bus_id = hal_util_get_last_element (sysfs_path);
 	sscanf (bus_id, "%d:%d:%d:%d", &host_num, &bus_num, &target_num, &lun_num);
@@ -750,7 +750,7 @@ mmc_add (const gchar *sysfs_path, HalDev
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "mmc");
-	hal_device_property_set_string (d, "info.parent", parent->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 
 	hal_util_set_driver (d, "info.linux.driver", sysfs_path);
 
@@ -826,7 +826,7 @@ xen_add (const gchar *sysfs_path, HalDev
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "xen");
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -899,7 +899,7 @@ ieee1394_add (const gchar *sysfs_path, H
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "ieee1394");
-	hal_device_property_set_string (d, "info.parent", parent->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 
 	hal_util_set_driver (d, "info.linux.driver", sysfs_path);
 
@@ -1038,7 +1038,7 @@ ccw_add (const gchar *sysfs_path, HalDev
 					sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "ccw");
 	if (parent != NULL)
-                hal_device_property_set_string (d, "info.parent", parent->udi);
+                hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
         else
                 hal_device_property_set_string
 		  (d, "info.parent",
@@ -1210,7 +1210,7 @@ ccwgroup_add (const gchar *sysfs_path, H
 					sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "ccwgroup");
 	if (parent != NULL)
-                hal_device_property_set_string (d, "info.parent", parent->udi);
+                hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
         else
                 hal_device_property_set_string
 		  (d, "info.parent",
@@ -1277,7 +1277,7 @@ iucv_add (const gchar *sysfs_path, HalDe
 					sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "iucv");
 	if (parent != NULL)
-                hal_device_property_set_string (d, "info.parent", parent->udi);
+                hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
         else
                 hal_device_property_set_string
 		  (d, "info.parent",
@@ -1323,7 +1323,7 @@ pseudo_add (const gchar *sysfs_path, Hal
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "pseudo");
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -1505,7 +1505,7 @@ physdev_callouts_add_done (HalDevice *d,
 {
 	void *end_token = (void *) userdata1;
 
-	HAL_INFO (("Add callouts completed udi=%s", d->udi));
+	HAL_INFO (("Add callouts completed udi=%s", hal_device_get_udi (d)));
 
 	/* Move from temporary to global device store */
 	hal_device_store_remove (hald_get_tdl (), d);
@@ -1519,7 +1519,7 @@ physdev_callouts_remove_done (HalDevice 
 {
 	void *end_token = (void *) userdata1;
 
-	HAL_INFO (("Remove callouts completed udi=%s", d->udi));
+	HAL_INFO (("Remove callouts completed udi=%s", hal_device_get_udi (d)));
 
 	if (!hal_device_store_remove (hald_get_gdl (), d)) {
 		HAL_WARNING (("Error removing device"));
diff --git a/hald/linux/pmu.c b/hald/linux/pmu.c
index b43d5f0..3a174f0 100644
--- a/hald/linux/pmu.c
+++ b/hald/linux/pmu.c
@@ -131,14 +131,14 @@ battery_refresh (HalDevice *d, PMUDevHan
 
 		/* TODO: could read some pmu file? */
 		remaining_time = util_compute_time_remaining (
-					d->udi,
+					hal_device_get_udi (d),
 					hal_device_property_get_int (d, "battery.charge_level.rate"),
 					current,
 					last_full,
 					hal_device_property_get_bool (d, "battery.rechargeable.is_discharging"),
 					hal_device_property_get_bool (d, "battery.rechargeable.is_charging"),
 					hal_device_property_get_bool (d, "battery.remaining_time.calculate_per_time"));
-		remaining_percentage = util_compute_percentage_charge (d->udi, current, last_full);
+		remaining_percentage = util_compute_percentage_charge (hal_device_get_udi (d), current, last_full);
 		/*
 		 * Only set keys if no error (signified with negative return value)
 		 * Scrict checking is needed to ensure that the values presented by HAL
@@ -400,7 +400,7 @@ pmu_generic_add (const gchar *pmu_path, 
 	hal_device_property_set_string (d, "linux.pmu_path", pmu_path);
 	hal_device_property_set_int (d, "linux.pmu_type", handler->pmu_type);
 	if (parent != NULL)
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	else
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	if (handler->refresh == NULL || !handler->refresh (d, handler)) {
@@ -580,7 +580,7 @@ pmu_rescan_device (HalDevice *d)
 		}
 	}
 
-	HAL_WARNING (("Didn't find a rescan handler for udi %s", d->udi));
+	HAL_WARNING (("Didn't find a rescan handler for udi %s", hal_device_get_udi (d)));
 
 out:
 	return ret;
diff --git a/hald/property.c b/hald/property.c
index 2caeb2b..8a4955d 100644
--- a/hald/property.c
+++ b/hald/property.c
@@ -37,6 +37,8 @@
 struct _HalProperty {
 	char *key;
 
+	void *foo;
+
 	int type;
 	union {
 		char *str_value;
@@ -54,7 +56,6 @@ struct _HalProperty {
 void
 hal_property_free (HalProperty *prop)
 {
-
 	g_free (prop->key);
 
 	if (prop->type == HAL_PROPERTY_TYPE_STRING) {
@@ -70,6 +71,14 @@ hal_property_free (HalProperty *prop)
 	g_free (prop);
 }
 
+static inline HalProperty *
+hal_property_new (void)
+{
+	HalProperty *prop;
+	prop = g_new0 (HalProperty, 1); 
+	return prop;
+}
+
 HalProperty *
 hal_property_new_string (const char *key, const char *value)
 {
@@ -77,7 +86,7 @@ hal_property_new_string (const char *key
 	char *endchar;
 	gboolean validated = TRUE;
 
-	prop = g_new0 (HalProperty, 1);
+	prop = hal_property_new ();
 
 	prop->type = HAL_PROPERTY_TYPE_STRING;
 	prop->key = g_strdup (key);
@@ -102,7 +111,7 @@ hal_property_new_int (const char *key, d
 {
 	HalProperty *prop;
 
-	prop = g_new0 (HalProperty, 1);
+	prop = hal_property_new ();
 
 	prop->type = HAL_PROPERTY_TYPE_INT32;
 	prop->key = g_strdup (key);
@@ -116,7 +125,7 @@ hal_property_new_uint64 (const char *key
 {
 	HalProperty *prop;
 
-	prop = g_new0 (HalProperty, 1);
+	prop = hal_property_new ();
 
 	prop->type = HAL_PROPERTY_TYPE_UINT64;
 	prop->key = g_strdup (key);
@@ -130,7 +139,7 @@ hal_property_new_bool (const char *key, 
 {
 	HalProperty *prop;
 
-	prop = g_new0 (HalProperty, 1);
+	prop = hal_property_new ();
 
 	prop->type = HAL_PROPERTY_TYPE_BOOLEAN;
 	prop->key = g_strdup (key);
@@ -144,7 +153,7 @@ hal_property_new_double (const char *key
 {
 	HalProperty *prop;
 
-	prop = g_new0 (HalProperty, 1);
+	prop = hal_property_new ();
 
 	prop->type = HAL_PROPERTY_TYPE_DOUBLE;
 	prop->key = g_strdup (key);
@@ -377,7 +386,7 @@ hal_property_new_strlist (const char *ke
 {
 	HalProperty *prop;
 
-	prop = g_new0 (HalProperty, 1);
+	prop = hal_property_new ();
 
 	prop->type = HAL_PROPERTY_TYPE_STRLIST;
 	prop->key = g_strdup (key);
diff --git a/hald/util.c b/hald/util.c
index 225142b..8cac0f1 100644
--- a/hald/util.c
+++ b/hald/util.c
@@ -868,7 +868,7 @@ hal_util_callout_device_add (HalDevice *
 		goto out;
 	}	
 
-	HAL_INFO (("Add callouts for udi=%s", d->udi));
+	HAL_INFO (("Add callouts for udi=%s", hal_device_get_udi (d)));
 
 	hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env);
 out:
@@ -886,7 +886,7 @@ hal_util_callout_device_remove (HalDevic
 		goto out;
 	}	
 
-	HAL_INFO (("Remove callouts for udi=%s", d->udi));
+	HAL_INFO (("Remove callouts for udi=%s", hal_device_get_udi (d)));
 
 	hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env);
 out:
@@ -904,7 +904,7 @@ hal_util_callout_device_preprobe (HalDev
 		goto out;
 	}	
 
-	HAL_INFO (("Preprobe callouts for udi=%s", d->udi));
+	HAL_INFO (("Preprobe callouts for udi=%s", hal_device_get_udi (d)));
 
 	hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env);
 out:
diff --git a/hald/valgrind-hald.sh b/hald/valgrind-hald.sh
index 11f95c3..d9f3fec 100755
--- a/hald/valgrind-hald.sh
+++ b/hald/valgrind-hald.sh
@@ -3,10 +3,14 @@
 export HALD_RUNNER_PATH=`pwd`/linux:`pwd`/linux/probing:`pwd`/linux/addons:`pwd`/.:`pwd`/../tools:`pwd`/../tools/linux
 export PATH=`pwd`/../hald-runner:$PATH
 
-rm -rf .local-fdi
-make -C ../fdi install DESTDIR=`pwd`/.local-fdi prefix=/
+if [ "$1" = "--skip-fdi-install" ] ; then
+    shift
+else
+    rm -rf .local-fdi
+    make -C ../fdi install DESTDIR=`pwd`/.local-fdi prefix=/
+fi
 export HAL_FDI_SOURCE_PREPROBE=.local-fdi/share/hal/fdi/preprobe
 export HAL_FDI_SOURCE_INFORMATION=.local-fdi/share/hal/fdi/information
 export HAL_FDI_SOURCE_POLICY=.local-fdi/share/hal/fdi/policy
 
-valgrind --num-callers=20 --show-reachable=yes --leak-check=yes --tool=memcheck ./hald --daemon=no --verbose=yes
+valgrind --num-callers=20 --show-reachable=yes --leak-check=yes --tool=memcheck ./hald --daemon=no --verbose=yes $@


More information about the hal-commit mailing list