hal/hald Makefile.am, 1.52, 1.53 debug-hald.sh, 1.4, 1.5 hald.c,
1.45, 1.46 hald_dbus.c, 1.48, 1.49 hald_dbus.h, 1.10,
1.11 hald_runner.c, NONE, 1.1 hald_runner.h, NONE,
1.1 haldaemon.in, 1.6, 1.7 run-hald.sh, 1.7, 1.8 util.c, 1.34,
1.35 util.h, 1.15, 1.16 valgrind-hald.sh, 1.1, 1.2
David Zeuthen
david at freedesktop.org
Fri Jan 20 18:45:29 PST 2006
- Previous message: hal/hald/linux2 blockdev.c, 1.30, 1.31 classdev.c, 1.40,
1.41 osspec.c, 1.39, 1.40
- Next message: hal/hald-runner Makefile.am, NONE, 1.1 main.c, NONE, 1.1 runner.c,
NONE, 1.1 runner.h, NONE, 1.1 utils.c, NONE, 1.1 utils.h, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvs/hal/hal/hald
In directory gabe:/tmp/cvs-serv12741/hald
Modified Files:
Makefile.am debug-hald.sh hald.c hald_dbus.c hald_dbus.h
haldaemon.in run-hald.sh util.c util.h valgrind-hald.sh
Added Files:
hald_runner.c hald_runner.h
Log Message:
2006-01-20 David Zeuthen <davidz at redhat.com>
Great patch from Sjoerd Simons <sjoerd at luon.net>: As most people
probably know by now, various people don't really like that hal
running as root. We'd much rather see only a small process running
as root and the main hal process running unpriviledged. Which is
exactly what this patch does :)
How does it work? Just before drops it's root privs. a small
program is startup which will remain running as root and does the
real execution of the addons/probes/callouts on hals
behalf. Communication between hald and hald-runner is done via a
p2p dbus connection. Resulting in a process tree like this:
hal /usr/sbin/hald
root \_ /usr/lib/hal/hald-runner
root \_ /usr/lib/hal/hald-addon-acpi
root \_ /usr/lib/hal/hald-addon-storage
root \_ /usr/lib/hal/hald-addon-storage
The patch consists out of two parts. First the implementation of
hald-runner, which is about 700 lines of code. And then a part
transforming the hald code from the current spawning code in utils
to an interface that can talk to the runner.
* AUTHORS: Add Sjoerd Simons <sjoerd at luon.net>. Revise my own
email address.
* configure.in (AC_OUTPUT): Add hald-runner
* Makefile.am (SUBDIRS): Add hald-runner
* hald/Makefile.am (hald_SOURCES): add hald_runner.[ch]
* hald-runner/utils.c, hald-runner/utils.h, hald-runner/runner.c,
hald-runner/runner.h, hald-runner/main.c, hald-runner/Makefile.am,
hald/linux2/osspec.c, hald/linux2/classdev.c,
hald/linux2/blockdev.c, hald/util.[ch], hald/hald_dbus.c,
hald/hald.c, hald/hald_runner.[ch]: New and changed files with
slight changes. See the descriptive text above and discussion at
http://lists.freedesktop.org/archives/hal/2006-January/004327.html
for details.
Changed function hald_runner_start_runner() in hald/hald_runner.c
to print out runner path and improve error handling when runner
is not found. Also removed dbus_server_unref (server) in
handle_connection() in same file.
* hald/haldaemon.in: Remove --retain-privileges as this is no longer
needed
* hald/run-hald.sh, hald/debug-hald.sh, hald/valgrind-hald.sh:
Remove --retain-privileges and use --with-runner pointing to
../hald-runner/hald-runner
Index: Makefile.am
===================================================================
RCS file: /cvs/hal/hal/hald/Makefile.am,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -d -r1.52 -r1.53
--- Makefile.am 29 Nov 2005 17:57:19 -0000 1.52
+++ Makefile.am 21 Jan 2006 02:45:26 -0000 1.53
@@ -40,6 +40,7 @@
hald_SOURCES = \
hald_marshal.h hald_marshal.c \
util.h util.c \
+ hald_runner.h hald_runner.c \
device.h device.c \
device_info.h device_info.c \
device_store.h device_store.c \
Index: debug-hald.sh
===================================================================
RCS file: /cvs/hal/hal/hald/debug-hald.sh,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- debug-hald.sh 25 Feb 2005 04:52:23 -0000 1.4
+++ debug-hald.sh 21 Jan 2006 02:45:27 -0000 1.5
@@ -7,5 +7,5 @@
echo ========================================
echo Just type \'run\' to start debugging hald
echo ========================================
-gdb run --args ./hald --daemon=no --verbose=yes --retain-privileges
+gdb run --args ./hald --daemon=no --verbose=yes --with-runner=../hald-runner/hald-runner
Index: hald.c
===================================================================
RCS file: /cvs/hal/hal/hald/hald.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- hald.c 12 Jan 2006 17:48:44 -0000 1.45
+++ hald.c 21 Jan 2006 02:45:27 -0000 1.46
@@ -55,6 +55,7 @@
#include "osspec.h"
#include "hald_dbus.h"
#include "util.h"
+#include "hald_runner.h"
static void delete_pid(void)
{
@@ -71,15 +72,6 @@
static HalDeviceStore *temporary_device_list = NULL;
-static GSList *running_addons = NULL;
-
-static void
-addon_terminated (HalDevice *d, gboolean timed_out, gint return_code,
- gpointer data1, gpointer data2, HalHelperData *helper_data)
-{
- running_addons = g_slist_remove (running_addons, helper_data);
-}
-
static void
gdl_store_changed (HalDeviceStore *store, HalDevice *device,
gboolean is_added, gpointer user_data)
@@ -94,45 +86,18 @@
for (i = addons; i != NULL; i = g_slist_next (i)) {
const gchar *command_line;
- HalHelperData *helper_data;
gchar *extra_env[2] = {"HALD_ACTION=addon", NULL};
command_line = (const gchar *) i->data;
- helper_data = hal_util_helper_invoke (command_line, extra_env, device,
- NULL, NULL,
- addon_terminated, 0 /* no timeout */);
+ hald_runner_start (device, command_line, extra_env);
- if (helper_data != NULL) {
- HAL_INFO (("Invoked addon %s with pid %d for udi %s",
- command_line, helper_data->pid, helper_data->d->udi));
- running_addons = g_slist_prepend (running_addons, helper_data);
- }
+ HAL_INFO (("Started addon %s for udi %s",
+ command_line, hal_device_get_udi(device)));
}
}
} else {
- GSList *i;
-
HAL_INFO (("Removed device from GDL; udi=%s", hal_device_get_udi(device)));
-
- start_from_beginning:
-
- /* may have several addons running */
- for (i = running_addons; i != NULL; i = g_slist_next (i)) {
- HalHelperData *helper_data;
-
- helper_data = (HalHelperData *) (i->data);
- if (helper_data->d == device) {
- HAL_INFO (("Terminating addon with pid %d for udi %s",
- helper_data->pid, helper_data->d->udi));
- /* will force a callback - the callback removes us from the list */
- hal_util_terminate_helper (helper_data);
- /* TODO: is it safe to remove an elem from a GSList and keep iterating?
- * Better play it safe for now.
- */
- goto start_from_beginning;
- }
- }
-
+ hald_runner_kill_device(device);
}
/*hal_device_print (device);*/
@@ -207,7 +172,7 @@
static void
usage ()
{
- fprintf (stderr, "\n" "usage : hald [--daemon=yes|no] [--verbose=yes|no] [--help]\n");
+ fprintf (stderr, "\n" "usage : hald [--daemon=yes|no] [--verbose=yes|no] [--help] [--with-runner=location]\n");
fprintf (stderr,
"\n"
" --daemon=yes|no Become a daemon\n"
@@ -215,8 +180,8 @@
" --use-syslog Print out debug messages to syslog instead of stderr.\n"
" Use this option to get debug messages if HAL runs as\n"
" daemon.\n"
- " --retain-privileges Run as root instead of normal user (calling of\n"
- " external scripts to modify fstab etc. will work)\n"
+ " --with-runner Use the program at the specified location as the\n"
+ "helper.\n"
" --help Show this information and exit\n"
" --version Output version information and exit"
"\n"
@@ -261,7 +226,6 @@
GError *err = NULL;
gchar data[1];
gsize bytes_read;
- unsigned int num_helpers;
/* Empty the pipe */
if (G_IO_STATUS_NORMAL !=
@@ -273,8 +237,7 @@
}
HAL_INFO (("Caught SIGTERM, initiating shutdown"));
- num_helpers = hal_util_kill_all_helpers ();
- HAL_INFO (("Killed %d helpers; exiting"));
+ hald_runner_kill_all();
exit (0);
out:
@@ -404,12 +367,9 @@
{
GMainLoop *loop;
guint sigterm_iochn_listener_source_id;
- gboolean retain_privs;
char *path;
char newpath[512];
-
- retain_privs = FALSE;
-
+ char *runner_location = NULL;
openlog ("hald", LOG_PID, LOG_DAEMON);
@@ -443,7 +403,7 @@
{"verbose", 1, NULL, 0},
{"use-syslog", 0, NULL, 0},
{"help", 0, NULL, 0},
- {"retain-privileges", 0, NULL, 0},
+ {"with-runner", 1, NULL, 0},
{"version", 0, NULL, 0},
{NULL, 0, NULL, 0}
};
@@ -481,8 +441,8 @@
usage ();
return 1;
}
- } else if (strcmp (opt, "retain-privileges") == 0) {
- retain_privs = TRUE;
+ } else if (strcmp (opt, "with-runner") == 0) {
+ runner_location = strdup(optarg);
} else if (strcmp (opt, "use-syslog") == 0) {
hald_use_syslog = TRUE;
}
@@ -606,13 +566,16 @@
/* set up the local dbus server */
if (!hald_dbus_local_server_init ())
return 1;
+ /* Start the runner helper daemon */
+ if (!hald_runner_start_runner(runner_location)) {
+ return 1;
+ }
+
+ drop_privileges();
/* initialize operating system specific parts */
osspec_init ();
- if (!retain_privs)
- drop_privileges();
-
hald_is_initialising = TRUE;
/* detect devices */
@@ -659,7 +622,7 @@
HAL_INFO (("Device probing completed"));
if (!hald_dbus_init ()) {
- hal_util_kill_all_helpers ();
+ hald_runner_kill_all();
exit (1);
}
Index: hald_dbus.c
===================================================================
RCS file: /cvs/hal/hal/hald/hald_dbus.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -d -r1.48 -r1.49
--- hald_dbus.c 12 Jan 2006 17:48:44 -0000 1.48
+++ hald_dbus.c 21 Jan 2006 02:45:27 -0000 1.49
@@ -46,6 +46,7 @@
#include "logger.h"
#include "osspec.h"
#include "util.h"
+#include "hald_runner.h"
static DBusConnection *dbus_connection = NULL;
@@ -2482,55 +2483,35 @@
}
static void
-hald_exec_method_cb (HalDevice *d, gboolean timed_out, gint return_code,
- gpointer data1, gpointer data2, HalHelperData *helper_data)
+hald_exec_method_cb (HalDevice *d, guint32 exit_type,
+ gint return_code, gchar **error,
+ gpointer data1, gpointer data2)
{
dbus_uint32_t result;
- DBusMessage *reply;
+ DBusMessage *reply = NULL;
DBusMessage *message;
DBusMessageIter iter;
- int *stderr_fd;
- char buf[512]; /* TODO: don't hardcode error message size */
- char *exp_name;
- char *exp_detail;
-
message = (DBusMessage *) data1;
- stderr_fd = (int *) data2;
-
- exp_name = NULL;
- exp_detail = NULL;
+ gchar *exp_name = NULL;
+ gchar *exp_detail = NULL;
- /* read back possible error conditions from stderr */
- if (stderr_fd != NULL) {
- ssize_t num_read;
+ if (exit_type == HALD_RUN_SUCCESS && error != NULL) {
+ exp_name = error[0];
+ if (error[0] != NULL) {
+ exp_detail = error[1];
+ }
+ HAL_INFO (("failed with '%s' '%s'", exp_name, exp_detail));
+ }
- num_read = read (*stderr_fd, buf, sizeof (buf) - 2);
- buf[sizeof (buf) - 2] = '\0';
- buf[sizeof (buf) - 1] = '\0';
- if (num_read > 0) {
- char *p;
- char *s;
- p = buf;
- for (s = p; *s != '\n' && *s != '\0'; s++)
- ;
- if (*s != '\0') {
- exp_name = g_strndup (p, s - p);
- p = s + 1;
- for (s = p; *s != '\n' && *s != '\0'; s++)
- ;
- if (*s != '\0') {
- exp_detail = g_strndup (p, s - p);
- }
- }
+ if (exit_type != HALD_RUN_SUCCESS) {
+ reply = dbus_message_new_error (message, "org.freedesktop.Hal.Device.UnknownError", "An unknown error occured");
+ if (dbus_connection != NULL) {
+ if (!dbus_connection_send (dbus_connection, reply, NULL))
+ DIE (("No memory"));
}
- }
-
- if (exp_name != NULL && exp_detail != NULL) {
- HAL_INFO (("failed with '%s' '%s'", exp_name, exp_detail));
-
- /* throw exception */
-
- reply = dbus_message_new_error (message, exp_name, exp_detail);
+ dbus_message_unref (reply);
+ } else if (exp_name != NULL && exp_detail != NULL) {
+ reply = dbus_message_new_error (message, exp_name, exp_detail);
if (reply == NULL) {
/* error name may be invalid - assume caller fucked up and use a generic HAL error name */
reply = dbus_message_new_error (message, "org.freedesktop.Hal.Device.UnknownError", "An unknown error occured");
@@ -2562,22 +2543,17 @@
dbus_message_unref (reply);
}
- dbus_message_unref (message);
- g_free (stderr_fd);
g_free (exp_name);
g_free (exp_detail);
+ dbus_message_unref (message);
}
static DBusHandlerResult
hald_exec_method (HalDevice *d, DBusConnection *connection, DBusMessage *message, const char *execpath)
{
int type;
- char *stdin;
GString *stdin_str;
DBusMessageIter iter;
- int stdin_fd;
- int *stderr_fd;
- ssize_t written;
const char *sender;
char *extra_env[2];
char uid_export[128];
@@ -2700,21 +2676,15 @@
dbus_message_iter_next (&iter);
}
- stdin = g_string_free (stdin_str, FALSE);
-
- stderr_fd = (int *) g_new0 (int, 1);
-
/* no timeout */
- if (hal_util_helper_invoke_with_pipes (execpath, extra_env, d,
- (gpointer) message, (gpointer) stderr_fd,
- hald_exec_method_cb, 0, &stdin_fd, NULL, stderr_fd) != NULL) {
- written = write (stdin_fd, stdin, strlen (stdin));
- close (stdin_fd);
- }
-
+ hald_runner_run_method(d,
+ execpath, extra_env,
+ stdin_str->str, TRUE,
+ 0,
+ hald_exec_method_cb,
+ (gpointer) message, NULL);
dbus_message_ref (message);
-
- g_free (stdin);
+ g_string_free (stdin_str, TRUE);
return DBUS_HANDLER_RESULT_HANDLED;
Index: hald_dbus.h
===================================================================
RCS file: /cvs/hal/hal/hald/hald_dbus.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- hald_dbus.h 2 Nov 2005 15:38:13 -0000 1.10
+++ hald_dbus.h 21 Jan 2006 02:45:27 -0000 1.11
@@ -94,6 +94,4 @@
DBusHandlerResult hald_dbus_filter_function (DBusConnection * connection, DBusMessage * message, void *user_data);
char *hald_dbus_local_server_addr (void);
-
-
#endif /* HAL_DBUS_H */
--- NEW FILE: hald_runner.c ---
/***************************************************************************
* CVSID: $Id: hald_runner.c,v 1.1 2006/01/21 02:45:27 david Exp $
*
* hald_runner.c - Interface to the hal runner helper daemon
*
* Copyright (C) 2006 Sjoerd Simons, <sjoerd at luon.net>
*
* 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 <glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#include "hald.h"
#include "util.h"
#include "logger.h"
#include "hald_dbus.h"
#include "hald_runner.h"
typedef struct {
HalDevice *d;
HalRunTerminatedCB cb;
gpointer data1;
gpointer data2;
} HelperData;
#define DBUS_SERVER_ADDRESS "unix:tmpdir=/tmp/hald-runner"
static DBusConnection *runner_connection = NULL;
static void
handle_connection(DBusServer *server,
DBusConnection *new_connection,
void *data) {
if (runner_connection == NULL) {
runner_connection = new_connection;
dbus_connection_ref (new_connection);
dbus_connection_setup_with_g_main (new_connection, NULL);
/* dbus_server_unref(server); */
}
}
static void
runner_died(GPid pid, gint status, gpointer data) {
g_spawn_close_pid (pid);
DIE (("Runner died"));
}
gboolean
hald_runner_start_runner(gchar *runner_location) {
DBusServer *server = NULL;
DBusError err;
GError *error = NULL;
GPid pid;
char *argv[] = { NULL, NULL};
char *env[] = { NULL, NULL};
dbus_error_init(&err);
server = dbus_server_listen(DBUS_SERVER_ADDRESS, &err);
if (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,
NULL, NULL);
if (runner_location == NULL) {
runner_location = g_strdup_printf("%s/hald-runner", PACKAGE_LIBEXEC_DIR);
} else {
runner_location = g_strdup(runner_location);
}
HAL_INFO (("Using runner '%s'\n", runner_location));
argv[0] = runner_location;
env[0] = g_strdup_printf("HALD_RUNNER_DBUS_ADDRESS=%s",
dbus_server_get_address(server));
if (!g_spawn_async(NULL, argv, env, G_SPAWN_DO_NOT_REAP_CHILD,
NULL, NULL, &pid, &error)) {
HAL_ERROR (("Could not spawn runner : '%s'", error->message));
g_error_free (error);
goto error;
}
g_free(argv[0]);
g_free(env[0]);
g_child_watch_add(pid, runner_died, NULL);
while (runner_connection == NULL) {
/* Wait for the runner */
g_main_context_iteration(NULL, TRUE);
}
return TRUE;
error:
if (server != NULL)
dbus_server_unref(server);
return FALSE;
}
static gboolean
add_property_to_msg (HalDevice *device, HalProperty *property,
gpointer user_data)
{
char *prop_upper, *value;
char *c;
gchar *env;
DBusMessageIter *iter = (DBusMessageIter *)user_data;
prop_upper = g_ascii_strup (hal_property_get_key (property), -1);
/* periods aren't valid in the environment, so replace them with
* underscores. */
for (c = prop_upper; *c; c++) {
if (*c == '.')
*c = '_';
}
value = hal_property_to_string (property);
env = g_strdup_printf ("HAL_PROP_%s=%s", prop_upper, value);
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &env);
g_free(env);
g_free (value);
g_free (prop_upper);
return TRUE;
}
static void
add_env(DBusMessageIter *iter, const gchar *key, const gchar *value) {
gchar *env;
env = g_strdup_printf ("%s=%s", key, value);
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &env);
g_free(env);
}
static void
add_basic_env(DBusMessageIter *iter, const gchar *udi) {
if (hald_is_verbose) {
add_env(iter, "HALD_VERBOSE", "1");
}
if (hald_is_initialising) {
add_env(iter, "HALD_STARTUP", "1");
}
add_env(iter, "UDI", udi);
add_env(iter, "HALD_DIRECT_ADDR", hald_dbus_local_server_addr());
}
static void
add_extra_env(DBusMessageIter *iter, gchar **env) {
int i;
if (env != NULL) for (i = 0; env[i] != NULL; i++) {
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &env[i]);
}
}
static gboolean
add_command(DBusMessageIter *iter, const gchar *command_line) {
gint argc;
gint x;
char **argv;
GError *err = NULL;
DBusMessageIter array_iter;
if (!g_shell_parse_argv(command_line, &argc, &argv, &err)) {
HAL_ERROR (("Error parsing commandline '%s': %s",
command_line, err->message));
g_error_free (err);
return FALSE;
}
if (!dbus_message_iter_open_container(iter,
DBUS_TYPE_ARRAY,
DBUS_TYPE_STRING_AS_STRING,
&array_iter))
DIE (("No memory"));
for (x = 0 ; argv[x] != NULL; x++) {
dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &argv[x]);
}
dbus_message_iter_close_container(iter, &array_iter);
g_strfreev(argv);
return TRUE;
}
static gboolean
add_first_part(DBusMessageIter *iter, HalDevice *device,
const gchar *command_line, char **extra_env) {
DBusMessageIter array_iter;
const char *udi;
udi = hal_device_get_udi(device);
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &udi);
dbus_message_iter_open_container(iter,
DBUS_TYPE_ARRAY,
DBUS_TYPE_STRING_AS_STRING,
&array_iter);
hal_device_property_foreach (device, add_property_to_msg, &array_iter);
add_basic_env(&array_iter, udi);
add_extra_env(&array_iter, extra_env);
dbus_message_iter_close_container(iter, &array_iter);
if (!add_command(iter, command_line)) {
return FALSE;
}
return TRUE;
}
/* Start a helper, returns true on a successfull start */
gboolean
hald_runner_start(HalDevice *device,
const gchar *command_line, char **extra_env) {
DBusMessage *msg, *reply;
DBusError err;
DBusMessageIter iter;
dbus_error_init(&err);
msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
"/org/freedesktop/HalRunner",
"org.freedesktop.HalRunner",
"Start");
if (msg == NULL)
DIE(("No memory"));
dbus_message_iter_init_append(msg, &iter);
if (!add_first_part(&iter, device, command_line, extra_env))
goto error;
/* Wait for the reply, should be almost instantanious */
reply =
dbus_connection_send_with_reply_and_block(runner_connection,
msg, -1, &err);
if (reply) {
gboolean ret =
(dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN);
dbus_message_unref(reply);
dbus_message_unref(msg);
return ret;
}
error:
dbus_message_unref(msg);
return FALSE;
}
static void
call_notify(DBusPendingCall *pending, void *user_data) {
HelperData *hb = (HelperData *)user_data;
dbus_uint32_t exitt = HALD_RUN_SUCCESS;
dbus_int32_t return_code = 0;
DBusMessage *m;
GArray *error = NULL;
DBusMessageIter iter;
error = g_array_new(TRUE, FALSE, sizeof(char *));
m = dbus_pending_call_steal_reply(pending);
if (dbus_message_get_type(m) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
goto malformed;
if (!dbus_message_iter_init(m, &iter) ||
dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
goto malformed;
dbus_message_iter_get_basic(&iter, &exitt);
if (!dbus_message_iter_next(&iter) ||
dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32)
goto malformed;
dbus_message_iter_get_basic(&iter, &return_code);
while (dbus_message_iter_next(&iter) &&
dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) {
const char *value;
dbus_message_iter_get_basic(&iter, &value);
g_array_append_vals(error, &value, 1);
}
hb->cb(hb->d, exitt, return_code,
(gchar **)error->data, hb->data1, hb->data2);
dbus_message_unref(m);
g_array_free(error, FALSE);
return;
malformed:
/* Send a Fail callback on malformed messages */
HAL_ERROR (("Malformed or unexpected reply message"));
hb->cb(hb->d, HALD_RUN_FAILED, return_code, NULL, hb->data1, hb->data2);
dbus_message_unref(m);
g_array_free(error, FALSE);
}
/* Run a helper program using the commandline, with input as infomation on
* stdin */
void
hald_runner_run_method(HalDevice *device,
const gchar *command_line, char **extra_env,
gchar *input, gboolean error_on_stderr,
guint32 timeout,
HalRunTerminatedCB cb,
gpointer data1, gpointer data2) {
DBusMessage *msg;
DBusMessageIter iter;
DBusPendingCall *call;
HelperData *hd = NULL;
msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
"/org/freedesktop/HalRunner",
"org.freedesktop.HalRunner",
"Run");
if (msg == NULL)
DIE(("No memory"));
dbus_message_iter_init_append(msg, &iter);
if (!add_first_part(&iter, device, command_line, extra_env))
goto error;
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &input);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &error_on_stderr);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &timeout);
if (!dbus_connection_send_with_reply(runner_connection,
msg, &call, INT_MAX))
DIE (("No memory"));
hd = malloc(sizeof(HelperData));
hd->d = device;
hd->cb = cb;
hd->data1 = data1;
hd->data2 = data2;
dbus_pending_call_set_notify(call, call_notify, hd, free);
dbus_message_unref(msg);
return;
error:
dbus_message_unref(msg);
free(hd);
cb(device, HALD_RUN_FAILED, 0, NULL, data1, data2);
}
void
hald_runner_run(HalDevice *device,
const gchar *command_line, char **extra_env,
guint timeout,
HalRunTerminatedCB cb,
gpointer data1, gpointer data2) {
hald_runner_run_method(device, command_line, extra_env,
"", FALSE, timeout, cb, data1, data2);
}
void
hald_runner_kill_device(HalDevice *device) {
DBusMessage *msg, *reply;
DBusError err;
DBusMessageIter iter;
const char *udi;
msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
"/org/freedesktop/HalRunner",
"org.freedesktop.HalRunner",
"Kill");
if (msg == NULL)
DIE(("No memory"));
dbus_message_iter_init_append(msg, &iter);
udi = hal_device_get_udi(device);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &udi);
/* Wait for the reply, should be almost instantanious */
dbus_error_init(&err);
reply =
dbus_connection_send_with_reply_and_block(runner_connection, msg, -1, &err);
if (reply) {
dbus_message_unref(reply);
}
dbus_message_unref(msg);
}
void
hald_runner_kill_all(HalDevice *device) {
DBusMessage *msg, *reply;
DBusError err;
msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
"/org/freedesktop/HalRunner",
"org.freedesktop.HalRunner",
"KillAll");
if (msg == NULL)
DIE(("No memory"));
/* Wait for the reply, should be almost instantanious */
dbus_error_init(&err);
reply =
dbus_connection_send_with_reply_and_block(runner_connection,
msg, -1, &err);
if (reply) {
dbus_message_unref(reply);
}
dbus_message_unref(msg);
}
--- NEW FILE: hald_runner.h ---
/***************************************************************************
*
* CVSID: $Id: hald_runner.h,v 1.1 2006/01/21 02:45:27 david Exp $
*
* hald_runner.h - Interface to the hal runner helper daemon
*
* Copyright (C) 2006 Sjoerd Simons <sjoerd at luon.net>
*
* 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
*
**************************************************************************/
#ifndef HALD_RUNNER_H
#define HALD_RUNNER_H
#include "device.h"
/* Successful run of the program */
#define HALD_RUN_SUCCESS 0x0
/* Process was killed because of running too long */
#define HALD_RUN_TIMEOUT 0x1
/* Failed to start for some reason */
#define HALD_RUN_FAILED 0x2
/* Killed on purpose, e.g. hal_runner_kill_device */
#define HALD_RUN_KILLED 0x4
/* Default sane timeout */
#define HAL_HELPER_TIMEOUT 10000
typedef void (*HalRunTerminatedCB) (HalDevice *d, guint32 exit_type,
gint return_code, gchar **error,
gpointer data1, gpointer data2);
/* Start the runner daemon */
gboolean
hald_runner_start_runner(gchar *runner_location);
/* Start a helper, returns true on a successfull start */
gboolean
hald_runner_start(HalDevice *device, const gchar *command_line,
char **extra_env);
/* Run a helper program using the commandline, with input as infomation on
* stdin */
void
hald_runner_run(HalDevice *device,
const gchar *command_line, char **extra_env,
guint32 timeout,
HalRunTerminatedCB cb,
gpointer data1, gpointer data2);
void
hald_runner_run_method(HalDevice *device,
const gchar *command_line, char **extra_env,
gchar *input, gboolean error_on_stderr,
guint32 timeout,
HalRunTerminatedCB cb,
gpointer data1, gpointer data2);
void hald_runner_kill_device(HalDevice *device);
void hald_runner_kill_all();
#endif
Index: haldaemon.in
===================================================================
RCS file: /cvs/hal/hal/hald/haldaemon.in,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- haldaemon.in 25 Feb 2005 01:55:08 -0000 1.6
+++ haldaemon.in 21 Jan 2006 02:45:27 -0000 1.7
@@ -25,7 +25,7 @@
start() {
echo -n $"Starting HAL daemon: "
- daemon --check $servicename $processname --retain-privileges
+ daemon --check $servicename $processname
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch @LOCALSTATEDIR@/lock/subsys/$servicename
Index: run-hald.sh
===================================================================
RCS file: /cvs/hal/hal/hald/run-hald.sh,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- run-hald.sh 25 Feb 2005 04:52:23 -0000 1.7
+++ run-hald.sh 21 Jan 2006 02:45:27 -0000 1.8
@@ -4,6 +4,6 @@
export HAL_FDI_SOURCE_PREPROBE=../fdi/preprobe
export HAL_FDI_SOURCE_INFORMATION=../fdi/information
export HAL_FDI_SOURCE_POLICY=../fdi/policy
-./hald --daemon=no --verbose=yes --retain-privileges
-#./hald --daemon=no --retain-privileges
+./hald --daemon=no --verbose=yes --with-runner=../hald-runner/hald-runner
+#./hald --daemon=no --with-runner=../hald-runner/hald-runner
Index: util.c
===================================================================
RCS file: /cvs/hal/hal/hald/util.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -d -r1.34 -r1.35
--- util.c 29 Nov 2005 17:38:00 -0000 1.34
+++ util.c 21 Jan 2006 02:45:27 -0000 1.35
@@ -50,6 +50,7 @@
#include "hald_dbus.h"
#include "util.h"
+#include "hald_runner.h"
typedef struct {
int last_level;
@@ -534,235 +535,6 @@
;
}
-void
-hal_util_terminate_helper (HalHelperData *ed)
-{
- if (ed->already_issued_kill) {
- HAL_INFO (("Already issued SIGTERM for pid %d, udi %s",
- ed->pid, ed->d != NULL ? ed->d->udi : "(finalized object)"));
- goto out;
- }
-
- HAL_INFO (("killing %d for udi %s", ed->pid, ed->d != NULL ? ed->d->udi : "(finalized object)"));
-
- /* kill kenny! kill it!! */
- ed->already_issued_kill = TRUE;
- kill (ed->pid, SIGTERM);
-
- if (ed->timeout_watch_id != (guint) -1) {
- g_source_remove (ed->timeout_watch_id);
- ed->timeout_watch_id = -1;
- }
-
- if (!ed->already_issued_callback) {
- ed->already_issued_callback = TRUE;
- ed->cb (ed->d, TRUE, -1, ed->data1, ed->data2, ed);
- }
-
- /* ed will be cleaned up when helper_child_exited reaps the child */
-out:
- ;
-}
-
-static gboolean
-helper_child_timeout (gpointer data)
-{
- HalHelperData *ed = (HalHelperData *) data;
-
- HAL_INFO (("child timeout for pid %d", ed->pid));
-
- /* kill kenny! kill it!! */
- ed->already_issued_kill = TRUE;
- kill (ed->pid, SIGTERM);
-
- ed->timeout_watch_id = -1;
-
- if (!ed->already_issued_callback) {
- ed->already_issued_callback = TRUE;
- ed->cb (ed->d, TRUE, -1, ed->data1, ed->data2, ed);
- }
-
- /* ed will be cleaned up when helper_child_exited reaps the child */
- return FALSE;
-}
-
-static GSList *running_helpers = NULL;
-
-static void
-helper_device_object_finalized (gpointer data, GObject *where_the_object_was)
-{
- HalHelperData *ed = (HalHelperData *) data;
-
- HAL_INFO (("device object finalized for helper with pid %d", ed->pid));
-
- ed->d = NULL;
- hal_util_terminate_helper (ed);
-}
-
-static void
-helper_child_exited (GPid pid, gint status, gpointer data)
-{
- HalHelperData *ed = (HalHelperData *) data;
-
- HAL_INFO (("child exited for pid %d", pid));
-
- if (ed->timeout_watch_id != (guint) -1)
- g_source_remove (ed->timeout_watch_id);
- g_spawn_close_pid (ed->pid);
-
- if (ed->d != NULL)
- g_object_weak_unref (G_OBJECT (ed->d), helper_device_object_finalized, ed);
-
- if (!ed->already_issued_callback)
- ed->cb (ed->d, FALSE, WEXITSTATUS (status), ed->data1, ed->data2, ed);
-
- running_helpers = g_slist_remove (running_helpers, ed);
-
- g_free (ed);
-}
-
-static gboolean
-helper_add_property_to_env (HalDevice *device, HalProperty *property, gpointer user_data)
-{
- char *prop_upper, *value;
- char *c;
- gchar ***ienvp = (gchar ***) user_data;
- gchar **envp;
-
- envp = *ienvp;
- *ienvp = *ienvp + 1;
-
- prop_upper = g_ascii_strup (hal_property_get_key (property), -1);
-
- /* periods aren't valid in the environment, so replace them with
- * underscores. */
- for (c = prop_upper; *c; c++) {
- if (*c == '.')
- *c = '_';
- }
-
- value = hal_property_to_string (property);
-
- *envp = g_strdup_printf ("HAL_PROP_%s=%s", prop_upper, value);
-
- g_free (value);
- g_free (prop_upper);
-
- return TRUE;
-}
-
-static void
-callout_failed (HalHelperData *ed);
-
-HalHelperData *
-hal_util_helper_invoke (const gchar *command_line, gchar **extra_env, HalDevice *d,
- gpointer data1, gpointer data2, HalHelperTerminatedCB cb, guint timeout)
-{
- return hal_util_helper_invoke_with_pipes (command_line, extra_env, d, data1, data2, cb, timeout, NULL, NULL, NULL);
-}
-
-HalHelperData *
-hal_util_helper_invoke_with_pipes (const gchar *command_line, gchar **extra_env, HalDevice *d,
- gpointer data1, gpointer data2, HalHelperTerminatedCB cb, guint timeout,
- int *standard_input, int *standard_output, int *standard_error)
-{
- HalHelperData *ed;
- gint argc;
- gchar **argv;
- gchar **envp;
- gchar **ienvp;
- GError *err = NULL;
- guint num_env_vars;
- guint i, j;
- guint num_properties;
- guint num_extras;
- char *local_addr;
-
- ed = g_new0 (HalHelperData, 1);
- ed->data1 = data1;
- ed->data2 = data2;
- ed->d = d;
- ed->cb = cb;
- ed->already_issued_callback = FALSE;
- ed->already_issued_kill = FALSE;
-
- num_properties = hal_device_num_properties (d);
- if (extra_env == NULL)
- num_extras = 0;
- else
- num_extras = g_strv_length ((gchar **) extra_env);
- num_env_vars = num_properties + 2 + num_extras;
- if (hald_is_verbose)
- num_env_vars++;
- if (hald_is_initialising)
- num_env_vars++;
- if ((local_addr = hald_dbus_local_server_addr ()) != NULL)
- num_env_vars++;
-
- envp = g_new (char *, num_env_vars);
- ienvp = envp;
- hal_device_property_foreach (d, helper_add_property_to_env, &ienvp);
- i = num_properties;
- envp[i++] = g_strdup_printf ("UDI=%s", hal_device_get_udi (d));
- if (hald_is_verbose)
- envp[i++] = g_strdup ("HALD_VERBOSE=1");
- if (hald_is_initialising)
- envp[i++] = g_strdup ("HALD_STARTUP=1");
- if (local_addr != NULL)
- envp[i++] = g_strdup_printf ("HALD_DIRECT_ADDR=%s", local_addr);
- for (j = 0; j < num_extras; j++) {
- envp[i++] = g_strdup (extra_env[j]);
- }
- envp[i++] = NULL;
-
- err = NULL;
- if (!g_shell_parse_argv (command_line, &argc, &argv, &err)) {
- HAL_ERROR (("Error parsing commandline '%s': %s", command_line, err->message));
- g_error_free (err);
- g_free (ed);
- ed = NULL;
- } else {
- err = NULL;
- if (!g_spawn_async_with_pipes (NULL,
- argv,
- envp,
- G_SPAWN_DO_NOT_REAP_CHILD|G_SPAWN_SEARCH_PATH,
- NULL,
- NULL,
- &ed->pid,
- standard_input,
- standard_output,
- standard_error,
- &err)) {
- HAL_ERROR (("Couldn't spawn '%s' err=%s!", command_line, err->message));
- g_error_free (err);
-
- /* move ahead in list */
- callout_failed(ed);
-
- g_free (ed);
- ed = NULL;
- } else {
- ed->child_watch_id = g_child_watch_add (ed->pid, helper_child_exited, (gpointer) ed);
- if (timeout > 0)
- ed->timeout_watch_id = g_timeout_add (timeout, helper_child_timeout, (gpointer) ed);
- else
- ed->timeout_watch_id = (guint) -1;
-
- running_helpers = g_slist_prepend (running_helpers, ed);
- /* device object may disappear from underneath us - this is
- * used to terminate the helper and pass d=NULL in the
- * HalHelperTerminatedCB callback
- */
- g_object_weak_ref (G_OBJECT (d), helper_device_object_finalized, ed);
- }
- }
-
- g_strfreev (envp);
- g_free (argv);
-
- return ed;
-}
gboolean
hal_util_path_ascend (gchar *path)
@@ -1127,21 +899,10 @@
static void callout_do_next (Callout *c);
-static void
-callout_failed (HalHelperData *ed)
-{
- if (ed->data1 != NULL) {
- Callout *c;
- c = (Callout *) ed->data1;
-
- c->next_program++;
- callout_do_next(c);
- }
-}
-
static void
-callout_terminated (HalDevice *d, gboolean timed_out, gint return_code,
- gpointer data1, gpointer data2, HalHelperData *helper_data)
+callout_terminated (HalDevice *d, guint32 exit_type,
+ gint return_code, gchar **error,
+ gpointer data1, gpointer data2)
{
Callout *c;
@@ -1172,8 +933,9 @@
callback (d, userdata1, userdata2);
} else {
- hal_util_helper_invoke (c->programs[c->next_program], c->extra_env, c->d,
- (gpointer) c, NULL, callout_terminated, HAL_HELPER_TIMEOUT);
+ hald_runner_run(c->d, c->programs[c->next_program], c->extra_env,
+ HAL_HELPER_TIMEOUT, callout_terminated,
+ (gpointer)c, NULL);
c->next_program++;
}
}
@@ -1250,29 +1012,6 @@
;
}
-/** Kill all helpers we have running; useful when exiting hald.
- *
- * @return Number of childs killed
- */
-unsigned int
-hal_util_kill_all_helpers (void)
-{
- unsigned int n;
- GSList *i;
-
- n = 0;
- for (i = running_helpers; i != NULL; i = i->next) {
- HalHelperData *ed;
-
- ed = i->data;
- HAL_INFO (("Killing helper with pid %d", ed->pid));
- kill (ed->pid, SIGTERM);
- n++;
- }
-
- return n;
-}
-
void
hal_util_hexdump (const void *mem, unsigned int size)
{
Index: util.h
===================================================================
RCS file: /cvs/hal/hal/hald/util.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- util.h 9 Nov 2005 20:45:44 -0000 1.15
+++ util.h 21 Jan 2006 02:45:27 -0000 1.16
@@ -81,38 +81,6 @@
const gchar *linestart, guint elem, const gchar *expected,
gboolean reuse_file);
-struct HalHelperData_s;
-typedef struct HalHelperData_s HalHelperData;
-
-typedef void (*HalHelperTerminatedCB) (HalDevice *d, gboolean timed_out, gint return_code,
- gpointer data1, gpointer data2, HalHelperData *helper_data);
-
-struct HalHelperData_s
-{
- GPid pid;
- guint timeout_watch_id;
- guint child_watch_id;
- HalHelperTerminatedCB cb;
- gpointer data1;
- gpointer data2;
- HalDevice *d;
-
- gboolean already_issued_callback;
- gboolean already_issued_kill;
-};
-
-unsigned int hal_util_kill_all_helpers (void);
-
-HalHelperData *hal_util_helper_invoke (const gchar *command_line, gchar **extra_env, HalDevice *d,
- gpointer data1, gpointer data2, HalHelperTerminatedCB cb, guint timeout);
-
-HalHelperData *hal_util_helper_invoke_with_pipes (const gchar *command_line, gchar **extra_env, HalDevice *d,
- gpointer data1, gpointer data2, HalHelperTerminatedCB cb,
- guint timeout,
- int *standard_input, int *standard_output, int *standard_error);
-
-void hal_util_terminate_helper (HalHelperData *helper_data);
-
gchar **hal_util_dup_strv_from_g_slist (GSList *strlist);
typedef void (*HalCalloutsDone) (HalDevice *d, gpointer userdata1, gpointer userdata2);
Index: valgrind-hald.sh
===================================================================
RCS file: /cvs/hal/hal/hald/valgrind-hald.sh,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- valgrind-hald.sh 28 Feb 2005 04:53:15 -0000 1.1
+++ valgrind-hald.sh 21 Jan 2006 02:45:27 -0000 1.2
@@ -4,4 +4,4 @@
export HAL_FDI_SOURCE_PREPROBE=../fdi/preprobe
export HAL_FDI_SOURCE_INFORMATION=../fdi/information
export HAL_FDI_SOURCE_POLICY=../fdi/policy
-valgrind --num-callers=20 --show-reachable=yes --leak-check=yes --tool=memcheck ./hald --daemon=no --verbose=yes --retain-privileges
+valgrind --num-callers=20 --show-reachable=yes --leak-check=yes --tool=memcheck ./hald --daemon=no --verbose=yes --with-runner=../hald-runner/hald-runner
- Previous message: hal/hald/linux2 blockdev.c, 1.30, 1.31 classdev.c, 1.40,
1.41 osspec.c, 1.39, 1.40
- Next message: hal/hald-runner Makefile.am, NONE, 1.1 main.c, NONE, 1.1 runner.c,
NONE, 1.1 runner.h, NONE, 1.1 utils.c, NONE, 1.1 utils.h, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the hal-commit
mailing list