hal: Branch 'origin' - 4 commits

David Zeuthen david at kemper.freedesktop.org
Wed Feb 21 09:33:46 PST 2007


 NEWS                              |    3 
 hald/hald_dbus.c                  |    2 
 hald/linux/addons/Makefile.am     |    2 
 hald/linux/addons/addon-storage.c |  478 ++++++++++++++++++++++++--------------
 4 files changed, 314 insertions(+), 171 deletions(-)

New commits:
diff-tree ba6584a1af85fc09f5262ac2bf728b05358ed236 (from e280630a2c3e5594eadff640b0fd78892588fa4f)
Author: David Zeuthen <davidz at redhat.com>
Date:   Tue Feb 20 19:23:53 2007 -0500

    only invoke hal-acl-tool if HAVE_ACLMGMT is set

diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c
index c40a1df..8c05adb 100644
--- a/hald/hald_dbus.c
+++ b/hald/hald_dbus.c
@@ -4609,6 +4609,7 @@ out:
 static void
 hald_dbus_ck_availability_changed (gboolean ck_available)
 {
+#ifdef HAVE_ACLMGMT
 	HalDevice *d;
 	char *extra_env[1] = {NULL};
 
@@ -4630,6 +4631,7 @@ hald_dbus_ck_availability_changed (gbool
 			 NULL  /* userdata2 */ );
 out:
 	;
+#endif /* HAVE_ACLMGMT */
 }
 
 static void
diff-tree e280630a2c3e5594eadff640b0fd78892588fa4f (from f71089e20649ddaa6cdc4628feffc3e853a795e6)
Author: David Zeuthen <davidz at redhat.com>
Date:   Tue Feb 20 17:46:13 2007 -0500

    update dependencies and versions for HAL

diff --git a/NEWS b/NEWS
index 6c22799..0a78d69 100644
--- a/NEWS
+++ b/NEWS
@@ -5,7 +5,7 @@ HAL 0.5.9 ""
 Requirements for HAL 0.5.9 ""
 
  - Linux kernel     >= 2.6.17
- - util-linux       >= 2.12r1
+ - util-linux       >= 2.12r1    (--enable-umount-helper requires patch from RH #188193)
  - bash             >= 2.0
  - udev             >= 089
  - dbus             >= 0.60      (with glib bindings)
@@ -17,6 +17,7 @@ Requirements for HAL 0.5.9 ""
  - dmidecode        >= 2.7       (optional)
  - parted           == 1.7.1     (optional)
  - cryptsetup-luks  >= 1.0.1     (optional, needs LUKS patches)
+ - ConsoleKit       >= git version as of 20070220 (optional)
 
 ==========
 HAL 0.5.8 "The Skynet Funding Bill is passed."
diff-tree f71089e20649ddaa6cdc4628feffc3e853a795e6 (from d11a896c7cf1edd2d1d1e46647abdbdc53651224)
Author: David Zeuthen <davidz at redhat.com>
Date:   Tue Feb 20 17:35:10 2007 -0500

    make hald-addon-storage usage of ConsoleKit depend on HAVE_CONKIT

diff --git a/hald/linux/addons/addon-storage.c b/hald/linux/addons/addon-storage.c
index 45d245e..469fc2a 100644
--- a/hald/linux/addons/addon-storage.c
+++ b/hald/linux/addons/addon-storage.c
@@ -58,7 +58,7 @@ static LibHalContext *ctx = NULL;
 static DBusConnection *con = NULL;
 static guint poll_timer = -1;
 static GMainLoop *loop;
-static gboolean system_is_idle;
+static gboolean system_is_idle = FALSE;
 
 static void 
 force_unmount (LibHalContext *ctx, const char *udi)
@@ -477,6 +477,7 @@ skip_check:
 	return TRUE;
 }
 
+#ifdef HAVE_CONKIT
 static gboolean
 get_system_idle_from_ck (void)
 {
@@ -514,10 +515,12 @@ get_system_idle_from_ck (void)
 error:
 	return ret;
 }
+#endif /* HAVE_CONKIT */
 
 static DBusHandlerResult
 dbus_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data)
 {
+#ifdef HAVE_CONKIT
 	gboolean system_is_idle_new;
 
 	if (dbus_message_is_signal (message, 
@@ -536,6 +539,8 @@ dbus_filter_function (DBusConnection *co
 		}
 	}
 out:
+#endif /* HAVE_CONKIT */
+
 	return DBUS_HANDLER_RESULT_HANDLED;
 }
 
@@ -600,19 +605,21 @@ main (int argc, char *argv[])
 
 	media_status = MEDIA_STATUS_UNKNOWN;
 
+#ifdef HAVE_CONKIT
 	/* TODO: ideally we should track the sessions on the seats on
 	 * which the device belongs to. But right now we don't really
 	 * do multi-seat so I'm going to punt on this for now.
 	 */
 	get_system_idle_from_ck ();
 
-	dbus_connection_add_filter (con, dbus_filter_function, NULL, NULL);
 	dbus_bus_add_match (con,
 			    "type='signal'"
 			    ",interface='org.freedesktop.ConsoleKit.Manager'"
 			    ",sender='org.freedesktop.ConsoleKit'"
 			    ",member='SystemIdleHintChanged'",
 			    NULL);
+#endif
+	dbus_connection_add_filter (con, dbus_filter_function, NULL, NULL);
 
 	update_polling_interval ();
 	g_main_loop_run (loop);
diff-tree d11a896c7cf1edd2d1d1e46647abdbdc53651224 (from 7b83d3fae632f62cef2edc6729911e4192426824)
Author: David Zeuthen <davidz at redhat.com>
Date:   Tue Feb 20 17:27:45 2007 -0500

    make hald-addon-storage use hints from ConsoleKit about session idleness
    
    In particular, when CK says all sessions are idle (specifically this
    happens if no sessions exist; e.g. server use case) reduce polling
    interval to 16 seconds. Track whether all sessions are idle and toggle
    between 2 and 16 seconds. Also print the polling interval in the
    process name for easy inspection:
    
     hald-addon-storage: polling /dev/sdf (every 16 sec)
    
    respectively
    
     hald-addon-storage: polling /dev/sdf (every 2 sec)

diff --git a/hald/linux/addons/Makefile.am b/hald/linux/addons/Makefile.am
index 597aee8..bea0a17 100644
--- a/hald/linux/addons/Makefile.am
+++ b/hald/linux/addons/Makefile.am
@@ -74,4 +74,4 @@ hald_addon_pmu_SOURCES = addon-pmu.c ../
 hald_addon_pmu_LDADD = $(top_builddir)/libhal/libhal.la
 
 hald_addon_storage_SOURCES = addon-storage.c ../../logger.c ../../util_helper.c
-hald_addon_storage_LDADD = $(top_builddir)/libhal/libhal.la
+hald_addon_storage_LDADD = $(top_builddir)/libhal/libhal.la @GLIB_LIBS@
diff --git a/hald/linux/addons/addon-storage.c b/hald/linux/addons/addon-storage.c
index 2f06685..45d245e 100644
--- a/hald/linux/addons/addon-storage.c
+++ b/hald/linux/addons/addon-storage.c
@@ -39,12 +39,27 @@
 #include <string.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
+#include <glib/gmain.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
 #include "libhal/libhal.h"
 
 #include "../../logger.h"
 #include "../../util_helper.h"
 
+
+static char *udi;
+static char *device_file;
+static int media_status;
+static int is_cdrom;
+static int support_media_changed;
+static LibHalContext *ctx = NULL;
+static DBusConnection *con = NULL;
+static guint poll_timer = -1;
+static GMainLoop *loop;
+static gboolean system_is_idle;
+
 static void 
 force_unmount (LibHalContext *ctx, const char *udi)
 {
@@ -260,19 +275,277 @@ enum {
 	MEDIA_STATUS_NO_MEDIA = 2
 };
 
+static gboolean poll_for_media (gpointer user_data);
+
+static void
+update_polling_interval (void)
+{
+	int interval_in_seconds;
+
+	/* TODO: ideally we want all things that do polling to do it
+	 * at the same time.. such as to minimize battery
+	 * usage. Suppose we want to wake up to do poll_for_media()
+	 * every N seconds.  Suppose M is the number of seconds since
+	 * epoch. The fix is to wake up at exactly when M is divisible
+	 * by N... plus some system wide offset (ideally read from
+	 * /sys so kernel threads can use the same offset) to make Xen
+	 * + friends work.... 
+	 *
+	 * Also, the polling intervals should be powers of two to
+	 * ensure that wakeup's with different intervals happen at the
+	 * same time when possible.
+	 *
+	 * This is sorta-kinda what g_timeout_source_new_seconds()
+	 * tries to achieve, not enough I think, and it's only
+	 * available in glib >= 2.14. Too little, too late? *shrug*
+	 */
+
+	if (system_is_idle)
+		interval_in_seconds = 16;
+	else
+		interval_in_seconds = 2;
+
+	if (poll_timer > 0)
+		g_source_remove (poll_timer);
+	poll_timer = g_timeout_add (interval_in_seconds * 1000, poll_for_media, NULL);
+	hal_set_proc_title ("hald-addon-storage: polling %s (every %d sec)", device_file, interval_in_seconds);
+}
+
+static gboolean
+poll_for_media (gpointer user_data)
+{
+	int fd;
+	int got_media;
+	
+	got_media = FALSE;
+	
+	if (is_cdrom) {
+		int drive;
+		
+		fd = open (device_file, O_RDONLY | O_NONBLOCK | O_EXCL);
+		
+		if (fd < 0 && errno == EBUSY) {
+			/* this means the disc is mounted or some other app,
+			 * like a cd burner, has already opened O_EXCL */
+			
+			/* HOWEVER, when starting hald, a disc may be
+			 * mounted; so check /etc/mtab to see if it
+			 * actually is mounted. If it is we retry to open
+			 * without O_EXCL
+			 */
+			if (!is_mounted (device_file))
+				goto skip_check;
+			
+			fd = open (device_file, O_RDONLY | O_NONBLOCK);
+		}
+		
+		if (fd < 0) {
+			HAL_ERROR (("open failed for %s: %s", device_file, strerror (errno))); 
+			goto skip_check;
+		}
+		
+		
+		/* Check if a disc is in the drive
+		 *
+		 * @todo Use MMC-2 API if applicable
+		 */
+		drive = ioctl (fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
+		switch (drive) {
+		case CDS_NO_INFO:
+		case CDS_NO_DISC:
+		case CDS_TRAY_OPEN:
+		case CDS_DRIVE_NOT_READY:
+			break;
+			
+		case CDS_DISC_OK:
+			/* some CD-ROMs report CDS_DISK_OK even with an open
+			 * tray; if media check has the same value two times in
+			 * a row then this seems to be the case and we must not
+			 * report that there is a media in it. */
+			if (support_media_changed &&
+			    ioctl (fd, CDROM_MEDIA_CHANGED, CDSL_CURRENT) && 
+			    ioctl (fd, CDROM_MEDIA_CHANGED, CDSL_CURRENT)) {
+			} else {
+				got_media = TRUE;
+			}
+			break;
+			
+		case -1:
+			HAL_ERROR (("CDROM_DRIVE_STATUS failed: %s\n", strerror(errno)));
+			break;
+			
+		default:
+			break;
+		}
+		
+		/* check if eject button was pressed */
+		if (got_media) {
+			unsigned char cdb[10] = { 0x4a, 1, 0, 0, 16, 0, 0, 0, 8, 0};
+			unsigned char buffer[8];
+			struct sg_io_hdr sg_h;
+			int retval;
+			
+			memset(buffer, 0, sizeof(buffer));
+			memset(&sg_h, 0, sizeof(struct sg_io_hdr));
+			sg_h.interface_id = 'S';
+			sg_h.cmd_len = sizeof(cdb);
+			sg_h.dxfer_direction = SG_DXFER_FROM_DEV;
+			sg_h.dxfer_len = sizeof(buffer);
+			sg_h.dxferp = buffer;
+			sg_h.cmdp = cdb;
+			sg_h.timeout = 5000;
+			retval = ioctl(fd, SG_IO, &sg_h);
+			if (retval == 0 && sg_h.status == 0 && (buffer[4] & 0x0f) == 0x01) {
+				DBusError error;
+				
+				/* emit signal from drive device object */
+				dbus_error_init (&error);
+				libhal_device_emit_condition (ctx, udi, "EjectPressed", "", &error);
+			}
+		}
+		close (fd);
+	} else {
+		fd = open (device_file, O_RDONLY);
+		if (fd < 0 && errno == ENOMEDIUM) {
+			got_media = FALSE;
+		} else if (fd >= 0) {
+			got_media = TRUE;
+			close (fd);
+		} else {
+			HAL_ERROR (("open failed for %s: %s", device_file, strerror (errno))); 
+			goto skip_check;
+		}
+	}
+	
+	switch (media_status) {
+	case MEDIA_STATUS_GOT_MEDIA:
+		if (!got_media) {
+			DBusError error;
+			
+			HAL_DEBUG (("Media removal detected on %s", device_file));
+			libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, NULL);
+			libhal_device_set_property_string (ctx, udi, "storage.partitioning_scheme", "", NULL);
+			
+			
+			/* attempt to unmount all childs */
+			unmount_childs (ctx, udi);
+			
+			/* could have a fs on the main block device; do a rescan to remove it */
+			dbus_error_init (&error);
+			libhal_device_rescan (ctx, udi, &error);
+			
+			/* have to this to trigger appropriate hotplug events */
+			fd = open (device_file, O_RDONLY | O_NONBLOCK);
+			if (fd >= 0) {
+				ioctl (fd, BLKRRPART);
+				close (fd);
+			}
+		}
+		break;
+		
+	case MEDIA_STATUS_NO_MEDIA:
+		if (got_media) {
+			DBusError error;
+			
+			HAL_DEBUG (("Media insertion detected on %s", device_file));
+			
+			/* our probe will trigger the appropriate hotplug events */
+			libhal_device_set_property_bool (
+				ctx, udi, "storage.removable.media_available", TRUE, NULL);
+			
+			/* could have a fs on the main block device; do a rescan to add it */
+			dbus_error_init (&error);
+			libhal_device_rescan (ctx, udi, &error);
+			
+		}
+		break;
+		
+	case MEDIA_STATUS_UNKNOWN:
+	default:
+		break;
+	}
+	
+	/* update our current status */
+	if (got_media)
+		media_status = MEDIA_STATUS_GOT_MEDIA;
+	else
+		media_status = MEDIA_STATUS_NO_MEDIA;
+	
+	/*HAL_DEBUG (("polling %s; got media=%d", device_file, got_media));*/
+	
+skip_check:
+	return TRUE;
+}
+
+static gboolean
+get_system_idle_from_ck (void)
+{
+	gboolean ret;
+	DBusError error;
+	DBusMessage *message;
+	DBusMessage *reply;
+
+	ret = FALSE;
+
+	message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", 
+						"/org/freedesktop/ConsoleKit/Manager",
+						"org.freedesktop.ConsoleKit.Manager",
+						"GetSystemIdleHint");
+	dbus_error_init (&error);
+	reply = dbus_connection_send_with_reply_and_block (con, message, -1, &error);
+	if (reply == NULL || dbus_error_is_set (&error)) {
+		HAL_ERROR (("Error doing Manager.GetSystemIdleHint on ConsoleKit: %s: %s", error.name, error.message));
+		dbus_message_unref (message);
+		if (reply != NULL)
+			dbus_message_unref (reply);
+		goto error;
+	}
+	if (!dbus_message_get_args (reply, NULL,
+				    DBUS_TYPE_BOOLEAN, &(system_is_idle),
+				    DBUS_TYPE_INVALID)) {
+		HAL_ERROR (("Invalid GetSystemIdleHint reply from CK"));
+		goto error;
+	}
+	dbus_message_unref (message);
+	dbus_message_unref (reply);
+
+	ret = TRUE;
+
+error:
+	return ret;
+}
+
+static DBusHandlerResult
+dbus_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+	gboolean system_is_idle_new;
+
+	if (dbus_message_is_signal (message, 
+				    "org.freedesktop.ConsoleKit.Manager", 
+				    "SystemIdleHintChanged")) {
+		if (!dbus_message_get_args (message, NULL,
+					    DBUS_TYPE_BOOLEAN, &system_is_idle_new,
+					    DBUS_TYPE_INVALID)) {
+			HAL_ERROR (("Invalid SystemIdleHintChanged signal from CK"));
+			goto out;
+		}
+
+		if (system_is_idle_new != system_is_idle) {
+			system_is_idle = system_is_idle_new;
+			update_polling_interval ();
+		}
+	}
+out:
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
 int
 main (int argc, char *argv[])
 {
-	char *udi;
-	char *device_file;
-	LibHalContext *ctx = NULL;
 	DBusError error;
 	char *bus;
 	char *drive_type;
-	int is_cdrom;
-	int media_status;
 	char *support_media_changed_str;
-	int support_media_changed;
 
 	hal_set_proc_title_init (argc, argv);
 
@@ -299,6 +572,15 @@ main (int argc, char *argv[])
 		support_media_changed = FALSE;
 
 	dbus_error_init (&error);
+	con = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+	if (con == NULL) {
+		HAL_ERROR (("Cannot connect to system bus"));
+		goto out;
+	}
+	loop = g_main_loop_new (NULL, FALSE);
+	dbus_connection_setup_with_g_main (con, NULL);
+
+	dbus_error_init (&error);
 	if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
 		goto out;
 
@@ -311,8 +593,6 @@ main (int argc, char *argv[])
 	HAL_DEBUG (("Doing addon-storage for %s (bus %s) (drive_type %s) (udi %s)", device_file, bus, drive_type, udi));
 	HAL_DEBUG (("**************************************************"));
 
-	hal_set_proc_title ("hald-addon-storage: polling %s", device_file);
-
 	if (strcmp (drive_type, "cdrom") == 0)
 		is_cdrom = 1;
 	else
@@ -320,169 +600,22 @@ main (int argc, char *argv[])
 
 	media_status = MEDIA_STATUS_UNKNOWN;
 
-	while (TRUE) {
-		int fd;
-		int got_media;
-
-		got_media = FALSE;
-
-		if (is_cdrom) {
-			int drive;
-
-			fd = open (device_file, O_RDONLY | O_NONBLOCK | O_EXCL);
-
-			if (fd < 0 && errno == EBUSY) {
-				/* this means the disc is mounted or some other app,
-				 * like a cd burner, has already opened O_EXCL */
-
-				/* HOWEVER, when starting hald, a disc may be
-				 * mounted; so check /etc/mtab to see if it
-				 * actually is mounted. If it is we retry to open
-				 * without O_EXCL
-				 */
-				if (!is_mounted (device_file))
-					goto skip_check;
-
-				fd = open (device_file, O_RDONLY | O_NONBLOCK);
-			}
-
-			if (fd < 0) {
-				HAL_ERROR (("open failed for %s: %s", device_file, strerror (errno))); 
-				goto skip_check;
-			}
-
-
-			/* Check if a disc is in the drive
-			 *
-			 * @todo Use MMC-2 API if applicable
-			 */
-			drive = ioctl (fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
-			switch (drive) {
-			case CDS_NO_INFO:
-			case CDS_NO_DISC:
-			case CDS_TRAY_OPEN:
-			case CDS_DRIVE_NOT_READY:
-				break;
-
-			case CDS_DISC_OK:
-				/* some CD-ROMs report CDS_DISK_OK even with an open
-				 * tray; if media check has the same value two times in
-				 * a row then this seems to be the case and we must not
-				 * report that there is a media in it. */
-				if (support_media_changed &&
-				    ioctl (fd, CDROM_MEDIA_CHANGED, CDSL_CURRENT) && 
-				    ioctl (fd, CDROM_MEDIA_CHANGED, CDSL_CURRENT)) {
-				} else {
-					got_media = TRUE;
-				}
-				break;
-
-			case -1:
-				HAL_ERROR (("CDROM_DRIVE_STATUS failed: %s\n", strerror(errno)));
-				break;
-
-			default:
-				break;
-			}
-
-			/* check if eject button was pressed */
-			if (got_media) {
-				unsigned char cdb[10] = { 0x4a, 1, 0, 0, 16, 0, 0, 0, 8, 0};
-				unsigned char buffer[8];
-				struct sg_io_hdr sg_h;
-				int retval;
-
-				memset(buffer, 0, sizeof(buffer));
-				memset(&sg_h, 0, sizeof(struct sg_io_hdr));
-				sg_h.interface_id = 'S';
-				sg_h.cmd_len = sizeof(cdb);
-				sg_h.dxfer_direction = SG_DXFER_FROM_DEV;
-				sg_h.dxfer_len = sizeof(buffer);
-				sg_h.dxferp = buffer;
-				sg_h.cmdp = cdb;
-				sg_h.timeout = 5000;
-				retval = ioctl(fd, SG_IO, &sg_h);
-				if (retval == 0 && sg_h.status == 0 && (buffer[4] & 0x0f) == 0x01) {
-					DBusError error;
-
-					/* emit signal from drive device object */
-					dbus_error_init (&error);
-					libhal_device_emit_condition (ctx, udi, "EjectPressed", "", &error);
-				}
-			}
-			close (fd);
-		} else {
-			fd = open (device_file, O_RDONLY);
-			if (fd < 0 && errno == ENOMEDIUM) {
-				got_media = FALSE;
-			} else if (fd >= 0) {
-				got_media = TRUE;
-				close (fd);
-			} else {
-				HAL_ERROR (("open failed for %s: %s", device_file, strerror (errno))); 
-				goto skip_check;
-			}
-		}
-
-		switch (media_status) {
-		case MEDIA_STATUS_GOT_MEDIA:
-			if (!got_media) {
-				DBusError error;
-				
-				HAL_DEBUG (("Media removal detected on %s", device_file));
-				libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, NULL);
-				libhal_device_set_property_string (ctx, udi, "storage.partitioning_scheme", "", NULL);
-
-				
-				/* attempt to unmount all childs */
-				unmount_childs (ctx, udi);
-				
-				/* could have a fs on the main block device; do a rescan to remove it */
-				dbus_error_init (&error);
-				libhal_device_rescan (ctx, udi, &error);
-				
-				/* have to this to trigger appropriate hotplug events */
-				fd = open (device_file, O_RDONLY | O_NONBLOCK);
-				if (fd >= 0) {
-					ioctl (fd, BLKRRPART);
-					close (fd);
-				}
-			}
-			break;
-
-		case MEDIA_STATUS_NO_MEDIA:
-			if (got_media) {
-				DBusError error;
-
-				HAL_DEBUG (("Media insertion detected on %s", device_file));
-
-				/* our probe will trigger the appropriate hotplug events */
-				libhal_device_set_property_bool (
-					ctx, udi, "storage.removable.media_available", TRUE, NULL);
-
-				/* could have a fs on the main block device; do a rescan to add it */
-				dbus_error_init (&error);
-				libhal_device_rescan (ctx, udi, &error);
-				
-			}
-			break;
-
-		case MEDIA_STATUS_UNKNOWN:
-		default:
-			break;
-		}
-
-		/* update our current status */
-		if (got_media)
-			media_status = MEDIA_STATUS_GOT_MEDIA;
-		else
-			media_status = MEDIA_STATUS_NO_MEDIA;
+	/* TODO: ideally we should track the sessions on the seats on
+	 * which the device belongs to. But right now we don't really
+	 * do multi-seat so I'm going to punt on this for now.
+	 */
+	get_system_idle_from_ck ();
 
-		/*HAL_DEBUG (("polling %s; got media=%d", device_file, got_media));*/
+	dbus_connection_add_filter (con, dbus_filter_function, NULL, NULL);
+	dbus_bus_add_match (con,
+			    "type='signal'"
+			    ",interface='org.freedesktop.ConsoleKit.Manager'"
+			    ",sender='org.freedesktop.ConsoleKit'"
+			    ",member='SystemIdleHintChanged'",
+			    NULL);
 
-	skip_check:
-		sleep (2);
-	}
+	update_polling_interval ();
+	g_main_loop_run (loop);
 
 out:
 	if (ctx != NULL) {


More information about the hal-commit mailing list