hal: Branch 'master' - 4 commits

David Zeuthen david at kemper.freedesktop.org
Tue Mar 27 09:40:05 PDT 2007


 configure.in                          |    1 
 doc/man/Makefile.am                   |    4 
 doc/man/hal-is-caller-locked-out.1.in |   11 -
 doc/man/hal-lock.1.in                 |   89 +++++++++++++
 hald/device.c                         |    4 
 libhal/libhal.c                       |    8 -
 libhal/libhal.h                       |    2 
 tools/Makefile.am                     |    6 
 tools/hal-lock.c                      |  232 ++++++++++++++++++++++++++++++++++
 9 files changed, 346 insertions(+), 11 deletions(-)

New commits:
diff-tree 1932745b7a467adeb4d4c23700998160c8161c20 (from parents)
Merge: 020bccd8fa1e96d2b20b4b8b2e47820511044ac1 af0658e1afae94aebcaf00fcffa8fccdec1d5cba
Author: David Zeuthen <davidz at redhat.com>
Date:   Tue Mar 27 12:39:00 2007 -0400

    Merge branch 'master' of ssh://david@git.freedesktop.org/git/hal

diff-tree 020bccd8fa1e96d2b20b4b8b2e47820511044ac1 (from 298285e2a279e81368dddee604b1884628e66b29)
Author: David Zeuthen <davidz at redhat.com>
Date:   Tue Mar 27 12:38:49 2007 -0400

    add new hal-lock(1) utility
    
    Before anyone starts complaining about 0.5.9 freeze, it's OK to add
    this for 0.5.9 as such a utility is key to making legacy apps work
    well. It also helped me uncover bugs in the libhal API and locking
    logic.

diff --git a/configure.in b/configure.in
index 6570b99..483f196 100644
--- a/configure.in
+++ b/configure.in
@@ -863,6 +863,7 @@ doc/man/hal-set-property.1
 doc/man/hal-find-by-property.1
 doc/man/hal-find-by-capability.1
 doc/man/hal-is-caller-locked-out.1
+doc/man/hal-lock.1
 po/Makefile.in
 ])
 
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
index ece5db6..295c694 100644
--- a/doc/man/Makefile.am
+++ b/doc/man/Makefile.am
@@ -1,9 +1,9 @@
 
 if MAN_PAGES_ENABLED
 
-MAN_IN_FILES = hald.1.in lshal.1.in hal-get-property.1.in hal-set-property.1.in hal-find-by-property.1.in hal-find-by-capability.1.in hal-is-caller-locked-out.1.in
+MAN_IN_FILES = hald.1.in lshal.1.in hal-get-property.1.in hal-set-property.1.in hal-find-by-property.1.in hal-find-by-capability.1.in hal-is-caller-locked-out.1.in hal-lock.1.in
 
-man_MANS = hald.1 lshal.1 hal-get-property.1 hal-set-property.1 hal-find-by-property.1 hal-find-by-capability.1 hal-is-caller-locked-out.1
+man_MANS = hald.1 lshal.1 hal-get-property.1 hal-set-property.1 hal-find-by-property.1 hal-find-by-capability.1 hal-is-caller-locked-out.1 hal-lock.1
 
 endif # MAN_PAGES_ENABLED
 
diff --git a/doc/man/hal-is-caller-locked-out.1.in b/doc/man/hal-is-caller-locked-out.1.in
index 41dc842..3df1c1d 100644
--- a/doc/man/hal-is-caller-locked-out.1.in
+++ b/doc/man/hal-is-caller-locked-out.1.in
@@ -27,7 +27,7 @@ The following options are supported:
 The UDI (\fIUnique Device Identifier\fP) of the device object.
 .TP
 .I "--interface"
-The name of the interface to check fo.
+The name of the interface to check for.
 .TP
 .I "--caller"
 The unique D-Bus name on the system bus of the caller.
@@ -40,11 +40,10 @@ Print the version.
 
 .SH RETURN VALUE
 .PP
-This program determines if a given process on the system bus is locked
-out of a D-Bus interface. If the process is locked out or an error
-occurs this program exits with exit code 1. Otherwise it exits with
-exit code 0. Note that only the super user (root) or other privileged
-users can use this tool.
+If the given process is locked out or an error occurs, this program
+exits with exit code 1. Otherwise it exits with exit code 0. Note that
+only the super user (root) or other privileged users can use this
+tool.
 
 .SH BUGS
 .PP
diff --git a/doc/man/hal-lock.1.in b/doc/man/hal-lock.1.in
new file mode 100644
index 0000000..c086fd2
--- /dev/null
+++ b/doc/man/hal-lock.1.in
@@ -0,0 +1,89 @@
+.\" 
+.\" hal-lock manual page.
+.\" Copyright (C) 2007 David Zeuthen <david at fubar.dk>
+.\"
+.TH HAL-LOCK 1
+.SH NAME
+hal-lock \- lock an interface
+.SH SYNOPSIS
+.PP
+.B hal-lock
+[options]
+
+.SH DESCRIPTION
+
+\fIhal-lock\fP can be used to acquire a lock on a given interface
+either on a given device or globally. For more information about both
+the big picture and the semantics of 
+.B HAL
+locks, refer to the \fIHAL spec\fP which can be found in
+.I "/usr/share/doc/hal-0.5.9/spec/hal-spec.html"
+depending on the distribution.
+
+.SH OPTIONS
+The following options are supported:
+.TP
+.I "--interface"
+The name of the interface to lock.
+.TP
+.I "--run"
+Program to run if the lock was acquired.
+.TP
+.I "--udi"
+The UDI (\fIUnique Device Identifier\fP) of the device object. If this
+is ommitted, the global lock will be tried.
+.TP
+.I "--exclusive"
+Whether the lock can be held by others.
+.TP
+.I "--help"
+Print out usage.
+.TP
+.I "--version"
+Print the version.
+
+.SH RETURN VALUE
+.PP
+This program will attempt to grab a lock on a given interface.
+Unless, a specific 
+.I UDI 
+is given, the global lock will be tried.  If the lock was succesfully
+acquired the program specified by the option --run will be run and
+upon termination this program will exit with exit code 0. If the lock
+wasn't acquired or an error occured while taking the lock, this
+program will exit with a non-zero exit code and the given program will
+not be run.
+
+
+.SH NOTES
+.PP
+This program is only useful for launching software that doesn't use
+HAL to lock devices; for example a partition table editor
+.I part-foo
+may used this wrapper script
+
+For scripts, this tool can be used as follows
+
+.I /bin/bash
+.I hal-lock --interface org.freedesktop.Hal.Storage --exclusive --run /usr/lib/part-foo/real-part-foo-binary
+
+.SH BUGS
+.PP
+Please send bug reports to either the distribution or the HAL
+mailing list, see 
+.I "http://lists.freedesktop.org/mailman/listinfo/hal"
+on how to subscribe.
+
+.SH SEE ALSO
+.PP
+\&\fIhald\fR\|(1), 
+\&\fIlshal\fR\|(1), 
+\&\fIhal-get-property\fR\|(1),
+\&\fIhal-set-property\fR\|(1),
+\&\fIhal-find-by-property\fR\|(1),
+\&\fIhal-find-by-capability\fR\|(1)
+
+.SH AUTHOR
+Written by David Zeuthen <david at fubar.dk> with a lot of help from many
+others.
+
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 3c5a302..0f73f61 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -30,7 +30,8 @@ bin_PROGRAMS =                    \
 	hal-find-by-capability    \
 	hal-find-by-property      \
 	hal-device		  \
-	hal-is-caller-locked-out
+	hal-is-caller-locked-out  \
+	hal-lock
 
 lshal_SOURCES = lshal.c
 lshal_LDADD = @GLIB_LIBS@ $(top_builddir)/libhal/libhal.la
@@ -53,6 +54,9 @@ hal_device_LDADD = @DBUS_LIBS@ $(top_bui
 hal_is_caller_locked_out_SOURCES = hal-is-caller-locked-out.c
 hal_is_caller_locked_out_LDADD = @DBUS_LIBS@ $(top_builddir)/libhal/libhal.la
 
+hal_lock_SOURCES = hal-lock.c
+hal_lock_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/libhal/libhal.la
+
 libexec_PROGRAMS =                          \
 	hal-storage-mount	            \
 	hal-storage-unmount 	            \
diff --git a/tools/hal-lock.c b/tools/hal-lock.c
new file mode 100644
index 0000000..cd54f26
--- /dev/null
+++ b/tools/hal-lock.c
@@ -0,0 +1,232 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * hal-lock.c : Lock an interface
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <glib.h>
+
+#include "libhal.h"
+
+/** 
+ *  usage:
+ *  @argc:                Number of arguments given to program
+ *  @argv:                Arguments given to program
+ *
+ *  Print out program usage. 
+ */
+static void
+usage (int argc, char *argv[])
+{
+	fprintf (stderr,
+                 "\n"
+                 "usage : hal-lock --interface <interface>\n"
+                 "                 --run <program-and-args>\n"
+                 "                 [--udi <udi>]\n"
+                 "                 [--exclusive]\n"
+                 "                 [--help] [--version]\n");
+	fprintf (stderr,
+                 "\n"
+                 "        --interface      Interface to lock\n"
+                 "        --run            Program to run if the lock was acquired\n"
+                 "        --udi            Unique Device Id of device to lock. If\n"
+                 "                         ommitted the global lock will be tried\n"
+                 "        --exclusive      Whether the lock can be held by others\n"
+                 "        --version        Show version and exit\n"
+                 "        --help           Show this information and exit\n"
+                 "\n"
+                 "This program will attempt to grab a lock on a given interface.\n"
+                 "Unless, a specific UDI is given, the global lock will be tried.\n"
+                 "If the lock was succesfully acquired the program specified by\n"
+                 "the option --run will be run and upon termination this program\n"
+                 "will exit with exit code 0. If the lock wasn't acquired or an\n"
+                 "error occured while taking the lock, this program will exit with a\n"
+                 "non-zero exit code and the given program will not be run.\n"
+                 "\n");
+}
+
+/** 
+ *  main:
+ *  @argc:                Number of arguments given to program
+ *  @argv:                Arguments given to program
+ *
+ *  Returns:              Return code
+ *
+ *  Main entry point 
+ */
+int
+main (int argc, char *argv[])
+{
+	char *udi = NULL;
+	char *interface = NULL;
+        char *run = NULL;
+        dbus_bool_t is_version = FALSE;
+        dbus_bool_t exclusive = FALSE;
+        dbus_bool_t got_lock = FALSE;
+	DBusError error;
+        LibHalContext *hal_ctx;
+        int ret;
+        GError *g_error = NULL;
+
+        ret = 1;
+
+	if (argc <= 1) {
+		usage (argc, argv);
+                goto out;
+	}
+
+	while (1) {
+		int c;
+		int option_index = 0;
+		const char *opt;
+		static struct option long_options[] = {
+			{"udi", 1, NULL, 0},
+			{"interface", 1, NULL, 0},
+			{"run", 1, NULL, 0},
+			{"exclusive", 0, NULL, 0},
+			{"version", 0, NULL, 0},
+			{"help", 0, NULL, 0},
+			{NULL, 0, NULL, 0}
+		};
+
+		c = getopt_long (argc, argv, "",
+				 long_options, &option_index);
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 0:
+			opt = long_options[option_index].name;
+
+			if (strcmp (opt, "help") == 0) {
+				usage (argc, argv);
+				return 0;
+			} else if (strcmp (opt, "version") == 0) {
+				is_version = TRUE;
+			} else if (strcmp (opt, "udi") == 0) {
+				udi = strdup (optarg);
+			} else if (strcmp (opt, "run") == 0) {
+				run = strdup (optarg);
+			} else if (strcmp (opt, "exclusive") == 0) {
+                                exclusive = TRUE;
+			} else if (strcmp (opt, "interface") == 0) {
+				interface = strdup (optarg);
+			}
+			break;
+
+		default:
+			usage (argc, argv);
+			return 1;
+			break;
+		}
+	}
+
+	if (is_version) {
+		printf ("hal-lock " PACKAGE_VERSION "\n");
+                ret = 0;
+                goto out;
+	}
+
+	if (interface == NULL || run == NULL) {
+		usage (argc, argv);
+                goto out;
+	}
+
+
+        dbus_error_init (&error);	
+        if ((hal_ctx = libhal_ctx_new ()) == NULL) {
+                fprintf (stderr, "error: libhal_ctx_new\n");
+                goto out;
+        }
+        if (!libhal_ctx_set_dbus_connection (hal_ctx, dbus_bus_get (DBUS_BUS_SYSTEM, &error))) {
+                fprintf (stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n", error.name, error.message);
+                LIBHAL_FREE_DBUS_ERROR (&error);
+                goto out;
+        }
+        if (!libhal_ctx_init (hal_ctx, &error)) {
+                if (dbus_error_is_set(&error)) {
+                        fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message);
+                        dbus_error_free (&error);
+                }
+                fprintf (stderr, "Could not initialise connection to hald.\n"
+                         "Normally this means the HAL daemon (hald) is not running or not ready.\n");
+                goto out;
+        }
+        
+        if (udi != NULL) {
+                got_lock = libhal_device_acquire_interface_lock (hal_ctx,
+                                                                 udi,
+                                                                 interface,
+                                                                 exclusive,
+                                                                 &error);
+        } else {
+                got_lock = libhal_acquire_global_interface_lock (hal_ctx,
+                                                                 interface,
+                                                                 exclusive,
+                                                                 &error);
+        }
+                
+        if (dbus_error_is_set(&error)) {
+                fprintf (stderr, 
+                         "error: %s: %s: %s\n", 
+                         udi != NULL ? "libhal_device_acquire_interface_lock" : 
+                         "libhal_acquire_global_interface_lock",
+                         error.name, 
+                         error.message);
+                dbus_error_free (&error);
+                goto out;
+        }
+        
+        if (!got_lock) {
+                goto out;
+        }
+
+        /* now run the program while holding the lock */
+        if (!g_spawn_command_line_sync (run,
+                                        NULL,
+                                        NULL,
+                                        NULL,
+                                        &g_error)) {
+                
+                fprintf (stderr, "error: g_spawn_command_line_sync: %s\n", g_error->message);
+                g_error_free (g_error);
+                goto out;
+        }
+
+        ret = 0;
+
+out:
+        return ret;
+}
diff-tree 298285e2a279e81368dddee604b1884628e66b29 (from fb5db0c9fb1c85c2ee513053354e302bb16d0375)
Author: David Zeuthen <davidz at redhat.com>
Date:   Tue Mar 27 12:36:52 2007 -0400

    only acquire a lock exclusively if no-one else is holding the lock

diff --git a/hald/device.c b/hald/device.c
index a471d2c..f1f5847 100644
--- a/hald/device.c
+++ b/hald/device.c
@@ -1637,6 +1637,10 @@ hal_device_acquire_lock (HalDevice *devi
 	hal_device_property_set_bool (device, buf, exclusive);
 
 	g_snprintf (buf, sizeof (buf), "info.named_locks.%s.dbus_name", lock_name);
+        if (exclusive && hal_device_has_property (device, buf)) {
+                /* cannot obtain exclusive lock */
+                goto out;
+        }
 	if (hal_device_property_strlist_contains (device, buf, sender)) {
                 /* already locked */
                 goto out;
diff-tree fb5db0c9fb1c85c2ee513053354e302bb16d0375 (from 28fc2fa7c6bbde540d4f17e810ab59fda0c186ba)
Author: David Zeuthen <davidz at redhat.com>
Date:   Tue Mar 27 12:36:03 2007 -0400

    make libhal locking API take 'bool exclusive' and fix a bug

diff --git a/libhal/libhal.c b/libhal/libhal.c
index 6f0323e..b5f3c1e 100644
--- a/libhal/libhal.c
+++ b/libhal/libhal.c
@@ -4134,6 +4134,7 @@ dbus_bool_t 
 libhal_device_acquire_interface_lock (LibHalContext *ctx,
                                       const char *udi,
                                       const char *interface,
+                                      dbus_bool_t exclusive,
                                       DBusError *error)
 {
 	DBusMessage *message;
@@ -4158,6 +4159,7 @@ libhal_device_acquire_interface_lock (Li
 
 	dbus_message_iter_init_append (message, &iter);
 	dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &interface);
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &exclusive);
 	
 	reply = dbus_connection_send_with_reply_and_block (ctx->connection,
 							   message, -1,
@@ -4225,6 +4227,7 @@ dbus_bool_t libhal_device_release_interf
 
 dbus_bool_t libhal_acquire_global_interface_lock (LibHalContext *ctx,
                                                   const char *interface,
+                                                  dbus_bool_t exclusive,
                                                   DBusError *error)
 {
 	DBusMessage *message;
@@ -4236,7 +4239,7 @@ dbus_bool_t libhal_acquire_global_interf
 
 	message = dbus_message_new_method_call ("org.freedesktop.Hal",
 						"/org/freedesktop/Hal/Manager",
-						"org.freedesktop.Hal.Device",
+						"org.freedesktop.Hal.Manager",
 						"AcquireGlobalInterfaceLock");
 
 	if (message == NULL) {
@@ -4248,6 +4251,7 @@ dbus_bool_t libhal_acquire_global_interf
 
 	dbus_message_iter_init_append (message, &iter);
 	dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &interface);
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &exclusive);
 	
 	reply = dbus_connection_send_with_reply_and_block (ctx->connection,
 							   message, -1,
@@ -4280,7 +4284,7 @@ dbus_bool_t libhal_release_global_interf
 
 	message = dbus_message_new_method_call ("org.freedesktop.Hal",
 						"/org/freedesktop/Hal/Manager",
-						"org.freedesktop.Hal.Device",
+						"org.freedesktop.Hal.Manager",
 						"ReleaseGlobalInterfaceLock");
 
 	if (message == NULL) {
diff --git a/libhal/libhal.h b/libhal/libhal.h
index 5021f87..897787a 100644
--- a/libhal/libhal.h
+++ b/libhal/libhal.h
@@ -607,6 +607,7 @@ dbus_bool_t libhal_device_addon_is_ready
 dbus_bool_t libhal_device_acquire_interface_lock (LibHalContext *ctx,
                                                   const char *udi,
                                                   const char *interface,
+                                                  dbus_bool_t exclusive,
                                                   DBusError *error);
 
 /* Release a mandatory lock on an interface on a device. */
@@ -618,6 +619,7 @@ dbus_bool_t libhal_device_release_interf
 /* Take a mandatory lock on an interface (the lock affects all devices the caller have access to). */
 dbus_bool_t libhal_acquire_global_interface_lock (LibHalContext *ctx,
                                                   const char *interface,
+                                                  dbus_bool_t exclusive,
                                                   DBusError *error);
 
 /* Release a mandatory lock on an interface (affects all devices the caller have access to). */


More information about the hal-commit mailing list