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