hal/tools/linux Makefile.am, 1.7, 1.8 hal_dev.c, 1.2, 1.3 hal_hotplug.c, 1.15, 1.16

David Zeuthen david at freedesktop.org
Sun Aug 15 11:54:59 PDT 2004


Update of /cvs/hal/hal/tools/linux
In directory pdx:/tmp/cvs-serv28976/tools/linux

Modified Files:
	Makefile.am hal_dev.c hal_hotplug.c 
Log Message:
2004-08-15  David Zeuthen  <david at fubar.dk>

	Sends messages from hotplug and device naming helpers via a local
	socket. Reorder the hotplug events we receive in hald according to
	SEQNUM and use a semaphor pattern to ensure that we don't process
	a hotplug event before the device created in effect to the
	previous event is completely processed (e.g.  add/remove callouts
	have run).

	* hald/Makefile.am: Remove scsi_host_class_device.c and add
	scsi_bus_device.c, hald_helper.h.

	* hald/device_info.c: 
	(handle_match): Comment out debug
	(scan_fdi_files): Comment out debug

	* hald/linux/block_class_device.c: 
	(block_class_visit): Return the HalDevice* object
	(block_class_pre_process): Use 'scsi' instead of 'scsi_device'
	(block_class_compute_udi): -do-
	(mtab_handle_volume): Comment out debug
	(etc_mtab_process_all_block_devices): Comment out debug

	* hald/linux/bus_device.c:
	(bus_device_visit): Return the HalDevice* object

	* hald/linux/bus_device.h: Make the visit method return the HalDevice
	object for tracking purposes

	* hald/linux/class_device.c: 
	(class_device_visit): Return the HalDevice* object
	(class_device_got_sysdevice): Comment out debug

	* hald/linux/class_device.h: Make the visit method return the HalDevice
	object for tracking purposes

	* hald/linux/common.c:
	(rename_and_merge): Comment out debug
	(class_device_get_device_file): Make debug statement more specific

	* hald/linux/net_class_device.c:
	(net_class_compute_udi): Comment out debug
	(net_class_udev_event): New function to ignore the udev event (duh)

	* hald/linux/osspec.c: Remove the ClassDeviceHandler scsi_device_
	class_device in favour of the BusDeviceHandler scsi_bus_device
	(visit_class_device): Return the HalDevice* object
	(visit_device): Return the HalDevice* object
	(osspec_init): Listen for datagrams on a local socket from hal.dev
	and hal.hotplug
	(remove_device): Return the HalDevice* object
	(remove_class_device): Return the HalDevice* object
	(handle_hotplug): Removed
	(handle_device_event): Removed
	(osspec_filter_function): Is empty now. We got our information via
	a local socket now
	(reenable_hotplug_proc): New function
	(hald_helper_hotplug): New function
	(hald_helper_device_node): New function
	(hald_helper_hotplug_process_queue): New function
	(hotplug_sem_up): New function 
	(hotplug_sem_down): New function
	(hald_helper_first_hotplug_event): New function
	(hald_helper_data): New function

	* hald/linux/hald_helper.h: New file
	
	* hald/linux/scsi_bus_device.c: New file

	* hald/linux/scsi_device_class_device.c: Removed

	* hald/linux/scsi_generic_class_device.c:
	(scsi_generic_get_device_file_target): New function. Merge the
	device file information to scsi.generic_device instead

	* tools/device-manager/Const.py.in: s/scsi_device/scsi/

	* tools/linux/Makefile.am: Don't link with D-BUS

	* tools/linux/hal_dev.c:
	(get_sysfs_mnt_path): Removed
	(main): Send the message via a local socket instead

	* tools/linux/hal_hotplug.c:
	(main): Send the message via a local socket instead



Index: Makefile.am
===================================================================
RCS file: /cvs/hal/hal/tools/linux/Makefile.am,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- Makefile.am	7 Apr 2004 23:51:14 -0000	1.7
+++ Makefile.am	15 Aug 2004 18:54:57 -0000	1.8
@@ -1,21 +1,18 @@
 ## Process this file with automake to produce Makefile.in
 
 INCLUDES = \
+	-DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
 	-DPACKAGE_DATA_DIR=\""$(datadir)"\" \
 	-DPACKAGE_BIN_DIR=\""$(bindir)"\" \
 	-DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
-	@DBUS_CFLAGS@
+	-DPACKAGE_LOCALSTATEDIR=\""$(localstatedir)"\"
 
 libexec_PROGRAMS = hal.hotplug hal.dev
 
 hal_hotplug_SOURCES = hal_hotplug.c
 
-hal_hotplug_LDADD = @DBUS_LIBS@
-
 hal_dev_SOURCES = hal_dev.c
 
-hal_dev_LDADD = @DBUS_LIBS@
-
 clean-local :
 	rm -f *~
 

Index: hal_dev.c
===================================================================
RCS file: /cvs/hal/hal/tools/linux/hal_dev.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- hal_dev.c	5 Jul 2004 17:00:32 -0000	1.2
+++ hal_dev.c	15 Aug 2004 18:54:57 -0000	1.3
@@ -1,8 +1,8 @@
 /***************************************************************************
  * CVSID: $Id$
  *
- * hal_dev.c : Tiny program to transform an udev device event into
- *             a D-BUS message
+ * hal_dev.c : Tiny program to send the udev device event to
+ *             the hal daemon
  *
  * Copyright (C) 2003 David Zeuthen, <david at fubar.dk>
  *
@@ -28,70 +28,25 @@
 #  include <config.h>
 #endif
 
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <stddef.h>
 #include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <getopt.h>
+#include <assert.h>
 #include <unistd.h>
+#include <stdarg.h>
+#include <errno.h>
 #include <mntent.h>
-/*#include <syslog.h>*/
-#include <linux/limits.h>
-
-#include <dbus/dbus.h>
-
-/**
- * @defgroup HalMisc  Misc tools for HAL
- * @brief  Misc. tools for HAL
- */
-
-
-/**
- * @defgroup HalLinuxDeviceEvent  HAL device event for Linux
- * @ingroup HalMisc
- * @brief A short program for translating linux-hotplug events into
- *        D-BUS messages. The messages are sent to the HAL daemon.
- * @{
- */
-
-
-static char sysfs_mnt_path[PATH_MAX];
-
-/** Get the mount path for sysfs. A side-effect is that sysfs_mnt_path
- *  is set on success.
- *
- *  @return                     0 on success, negative on error
- */
-static int
-get_sysfs_mnt_path ()
-{
-	FILE *mnt;
-	struct mntent *mntent;
-	int ret = 0;
-	size_t dirlen = 0;
-
-	if ((mnt = setmntent ("/proc/mounts", "r")) == NULL) {
-		return -1;
-	}
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
 
-	while (ret == 0 && dirlen == 0
-	       && (mntent = getmntent (mnt)) != NULL) {
-		if (strcmp (mntent->mnt_type, "sysfs") == 0) {
-			dirlen = strlen (mntent->mnt_dir);
-			if (dirlen <= (PATH_MAX - 1)) {
-				strcpy (sysfs_mnt_path, mntent->mnt_dir);
-			} else {
-				ret = -1;
-			}
-		}
-	}
-	endmntent (mnt);
+#include "../../hald/linux/hald_helper.h"
 
-	if (dirlen == 0 && ret == 0) {
-		ret = -1;
-	}
-	return ret;
-}
 /** Entry point
  *
  *  @param  argc                Number of arguments
@@ -102,103 +57,73 @@
 int
 main (int argc, char *argv[], char *envp[])
 {
-	int i, j, len;
-	char *str;
+	int fd;
+	struct hald_helper_msg msg;
+	struct sockaddr_un saddr;
+	socklen_t addrlen;
+	char *subsystem;
 	char *devpath;
-	char *devname;
+	char *devnode;
+	char *action;
 	int is_add;
-	DBusError error;
-	DBusConnection *sysbus_connection;
-	DBusMessage *message;
-	DBusMessageIter iter;
-	DBusMessageIter iter_dict;
-	pid_t rc;
 
 	if (argc != 2)
 		return 1;
 
-	/* fork a new process so we exit instantly and child is handling
-	 * the processing; fixes bug where udevstart takes a long time
-	 * to start since udev executes stuff in dev.d sequentially.
-	 *
-	 * TODO, FIXME, HACK, XXX : This is not the right way; we merely
-	 * work around the problem that D-BUS requires us to take a nap
-	 * before exiting because otherwise messages are lost
-	 */
-	rc = fork ();
-	if (rc == -1)
-		return 1;
-	if (rc != 0)
-		return 0;
-
-	if (get_sysfs_mnt_path () != 0)
-		return 1;
-
-	/*openlog ("hal.dev", LOG_PID, LOG_USER);*/
-
-	/* Connect to a well-known bus instance, the system bus */
-	dbus_error_init (&error);
-	sysbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
-	if (sysbus_connection == NULL)
-		return 1;
-
-	/* service, object, interface, member */
-	message = dbus_message_new_method_call (
-		"org.freedesktop.Hal",
-		"/org/freedesktop/Hal/Linux/Hotplug",
-		"org.freedesktop.Hal.Linux.Hotplug",
-		"DeviceEvent");
-
-	/* not interested in a reply */
-	dbus_message_set_no_reply (message, TRUE);
-
-	devpath = NULL;
-	devname = NULL;
-	is_add = FALSE;
+	openlog ("hal.dev", LOG_PID, LOG_USER);
 
-	dbus_message_iter_init (message, &iter);
-	for (i = 0; envp[i] != NULL; i++) {
-		str = envp[i];
-		len = strlen (str);
-		for (j = 0; j < len && str[j] != '='; j++);
-		str[j] = '\0';
+	subsystem = argv[1];
+	if (subsystem == NULL) {
+		syslog (LOG_ERR, "subsystem is not set");
+		goto out;
+	}
 
-		if (strcmp (str, "DEVPATH") == 0) {
-			devpath = str + j + 1;
-		} else if (strcmp (str, "DEVNODE") == 0) {
-			devname = str + j + 1;
-		} else if (strcmp (str, "DEVNAME") == 0) {
-			devname = str + j + 1;
-		} else if (strcmp (str, "ACTION") == 0) {
-			if (strcmp (str + j + 1, "add") == 0) {
-				is_add = TRUE;
-			}
-		}
+	devpath = getenv ("DEVPATH");
+	if (devpath == NULL) {
+		syslog (LOG_ERR, "DEVPATH is not set");
+		goto out;
 	}
 
-	if (devname == NULL || devpath == NULL) {
-		/*syslog (LOG_ERR, "Missing devname or devpath");*/
+	devnode = getenv ("DEVNAME");
+	if (devnode == NULL) {
+		syslog (LOG_ERR, "DEVNAME is not set");
 		goto out;
 	}
 
-	dbus_message_iter_append_boolean (&iter, is_add);
-	dbus_message_iter_append_string (&iter, devname);
-	dbus_message_iter_append_string (&iter, devpath);
+	action = getenv ("ACTION");
+	if (action == NULL) {
+		syslog (LOG_ERR, "ACTION is not set");
+		goto out;
+	}
+	if (strcmp (action, "add") == 0)
+		is_add = 1;
+	else
+		is_add = 0;
 
-	if (!dbus_connection_send (sysbus_connection, message, NULL))
-		return 1;
+	fd = socket(AF_LOCAL, SOCK_DGRAM, 0);
+	if (fd == -1) {
+		syslog (LOG_ERR, "error opening socket");
+		goto out;
+	}
 
-	dbus_message_unref (message);
+	memset (&saddr, 0x00, sizeof(struct sockaddr_un));
+	saddr.sun_family = AF_LOCAL;
+	/* use abstract namespace for socket path */
+	strcpy (&saddr.sun_path[1], HALD_HELPER_SOCKET_PATH);
+	addrlen = offsetof (struct sockaddr_un, sun_path) + strlen (saddr.sun_path+1) + 1;
 
-	dbus_connection_flush (sysbus_connection);
+	memset (&msg, 0x00, sizeof (msg));
+	msg.magic = HALD_HELPER_MAGIC; 
+	msg.is_hotplug_or_dev = 0;
+	msg.is_add = is_add;
+	strncpy (msg.subsystem, subsystem, HALD_HELPER_STRLEN);
+	strncpy (msg.sysfs_path, devpath, HALD_HELPER_STRLEN);
+	strncpy (msg.device_node, devnode, HALD_HELPER_STRLEN);
 
-	/* Do some sleep here so messages are not lost.. */
-	usleep (500 * 1000);
-	
+	if (sendto (fd, &msg, sizeof(struct hald_helper_msg), 0,
+		    (struct sockaddr *)&saddr, addrlen) == -1) {
+		syslog (LOG_ERR, "error sending message to hald");
+	}
 out:
-	dbus_connection_disconnect (sysbus_connection);
-
 	return 0;
 }
-
-/** @} */

Index: hal_hotplug.c
===================================================================
RCS file: /cvs/hal/hal/tools/linux/hal_hotplug.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- hal_hotplug.c	22 Jul 2004 19:06:02 -0000	1.15
+++ hal_hotplug.c	15 Aug 2004 18:54:57 -0000	1.16
@@ -1,8 +1,7 @@
 /***************************************************************************
  * CVSID: $Id$
  *
- * hal_hotplug.c : Tiny program to transform a linux-hotplug event into
- *                 a D-BUS message
+ * hal_hotplug.c : Tiny program to send the hotplug event to the HAL daemon
  *
  * Copyright (C) 2003 David Zeuthen, <david at fubar.dk>
  *
@@ -28,32 +27,24 @@
 #  include <config.h>
 #endif
 
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <stddef.h>
 #include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <getopt.h>
+#include <assert.h>
 #include <unistd.h>
+#include <stdarg.h>
+#include <errno.h>
 #include <mntent.h>
 #include <syslog.h>
-#include <linux/limits.h>
-
-#include <dbus/dbus.h>
-
-/**
- * @defgroup HalMisc  Misc tools for HAL
- * @brief  Misc. tools for HAL
- */
-
-
-/**
- * @defgroup HalLinuxHotplug  HAL hotplug helper for Linux
- * @ingroup HalMisc
- * @brief A short program for translating linux-hotplug events into
- *        D-BUS messages. The messages are sent to the HAL daemon.
- * @{
- */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
 
+#include "../../hald/linux/hald_helper.h"
 
 static char sysfs_mnt_path[PATH_MAX];
 
@@ -63,7 +54,7 @@
  *  @return                     0 on success, negative on error
  */
 static int
-get_sysfs_mnt_path ()
+get_sysfs_mnt_path (void)
 {
 	FILE *mnt;
 	struct mntent *mntent;
@@ -93,21 +84,22 @@
 	return ret;
 }
 
+
 static const char *file_list_usb[] = {
-	 "idProduct",
-	 "idVendor",
-	 "bcdDevice",
-	 "bMaxPower",
-	 /*"serial", */
-	 "bmAttributes",
-	 /*"manufacturer",*/
-	 /*"product",*/
-	 "bDeviceClass",
-	 "bDeviceSubClass",
-	 "bDeviceProtocol",
-	 "bNumConfigurations",
-	 "bConfigurationValue",
-	 "bNumInterfaces",
+	"idProduct",
+	"idVendor",
+	"bcdDevice",
+	"bMaxPower",
+	/*"serial", */
+	"bmAttributes",
+	/*"manufacturer",*/
+	/*"product",*/
+	"bDeviceClass",
+	"bDeviceSubClass",
+	"bDeviceProtocol",
+	"bNumConfigurations",
+	"bConfigurationValue",
+	"bNumInterfaces",
 	NULL
 
 };
@@ -158,9 +150,6 @@
 	int i;
 	char path[PATH_MAX];
 
-	syslog (LOG_NOTICE, "waiting for %s info at %s",
-		hotplug_type, devpath);
-
 	devpath_len = strlen (devpath);
 
 	file_list = NULL;
@@ -172,14 +161,12 @@
 
 		for (i = devpath_len - 1; devpath[i] != '/' && i > 0; --i) {
 			if (devpath[i] == ':') {
-				is_interface = TRUE;
+				is_interface = 1;
 				break;
 			}
 		}
 
 		if (is_interface) {
-			syslog (LOG_NOTICE, "%s is an USB interface",
-				devpath);
 			file_list = file_list_usbif;
 		} else
 			file_list = file_list_usb;
@@ -194,15 +181,12 @@
 	}
 
 	if (file_list == NULL) {
-		syslog (LOG_WARNING, "Dont know how to wait for %s at %s; "
-			"sleeping 1000 ms", hotplug_type, devpath);
-		usleep (1000 * 1000);
 		return -1;
 	}
 
 	num_tries = 0;
 
-      try_again:
+try_again:
 	if (num_tries > 0) {
 		usleep (100 * 1000);
 	}
@@ -247,11 +231,10 @@
 
 	syslog (LOG_NOTICE, "got info for %s (waited %d ms)",
 		devpath, (num_tries - 1) * 100);
-
+	
 	return 0;
 }
 
-
 /** Entry point
  *
  *  @param  argc                Number of arguments
@@ -262,111 +245,96 @@
 int
 main (int argc, char *argv[], char *envp[])
 {
-	int i, j, len;
-	char *str;
-	char *hotplug_type;
+	int fd;
+	struct hald_helper_msg msg;
+	struct sockaddr_un saddr;
+	socklen_t addrlen;
+	char *subsystem;
 	char *devpath;
+	char *action;
+	char *seqnum_str;
 	int is_add;
-	DBusError error;
-	DBusConnection *sysbus_connection;
-	DBusMessage *message;
-	DBusMessageIter iter;
-	DBusMessageIter iter_dict;
-	int rc;
+	int seqnum;
 
 	if (argc != 2)
 		return 1;
 
-	if (get_sysfs_mnt_path () != 0)
-		return 1;
-
-	/* fork a new process so we exit instantly and child is handling
-	 * the processing; 
-	 *
-	 * TODO, FIXME, HACK, XXX : This is not the right way; we merely
-	 * work around the problem that D-BUS requires us to take a nap
-	 * before exiting because otherwise messages are lost
-	 */
-	rc = fork ();
-	if (rc == -1)
-		return 1;
-	if (rc != 0)
-		return 0;
-
-
 	openlog ("hal.hotplug", LOG_PID, LOG_USER);
 
-	/* Connect to a well-known bus instance, the system bus */
-	dbus_error_init (&error);
-	sysbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
-	if (sysbus_connection == NULL)
-		return 1;
-
-	/* service, object, interface, member */
-	message = dbus_message_new_method_call (
-		"org.freedesktop.Hal",
-		"/org/freedesktop/Hal/Linux/Hotplug",
-		"org.freedesktop.Hal.Linux.Hotplug",
-		"HotplugEvent");
-
-	/* not interested in a reply */
-	dbus_message_set_no_reply (message, TRUE);
+	if (get_sysfs_mnt_path() != 0) {
+		syslog (LOG_ERR, "could not get mountpoint for sysfs");
+		goto out;
+	}
 
-	hotplug_type = argv[1];
-	devpath = NULL;
+	fd = socket(AF_LOCAL, SOCK_DGRAM, 0);
+	if (fd == -1) {
+		syslog (LOG_ERR, "error opening socket");
+		goto out;
+	}
 
-	is_add = FALSE;
+	subsystem = argv[1];
+	if (subsystem == NULL) {
+		syslog (LOG_ERR, "subsystem is not set");
+		goto out;
+	}
 
-	dbus_message_iter_init (message, &iter);
-	dbus_message_iter_append_string (&iter, hotplug_type);
-	dbus_message_iter_append_dict (&iter, &iter_dict);
-	for (i = 0; envp[i] != NULL; i++) {
-		str = envp[i];
-		len = strlen (str);
-		for (j = 0; j < len && str[j] != '='; j++);
-		str[j] = '\0';
+	devpath = getenv ("DEVPATH");
+	if (devpath == NULL) {
+		syslog (LOG_ERR, "DEVPATH is not set");
+		goto out;
+	}
 
-		dbus_message_iter_append_dict_key (&iter_dict, str);
-		dbus_message_iter_append_string (&iter_dict, str + j + 1);
+	action = getenv ("ACTION");
+	if (action == NULL) {
+		syslog (LOG_ERR, "ACTION is not set");
+		goto out;
+	}
+	if (strcmp (action, "add") == 0)
+		is_add = 1;
+	else
+		is_add = 0;
 
-		if (strcmp (str, "DEVPATH") == 0) {
-			devpath = str + j + 1;
-		} else if (strcmp (str, "ACTION") == 0) {
-			if (strcmp (str + j + 1, "add") == 0) {
-				is_add = TRUE;
-			}
-		}
+	seqnum_str = getenv ("SEQNUM");
+	if (seqnum_str == NULL) {
+		syslog (LOG_ERR, "SEQNUM is not set");
+		goto out;
 	}
+	seqnum = atoi (seqnum_str);
 
-	if (devpath != NULL && is_add) {
+	if (is_add) {
 		int rc;
 
 		/* wait for information to be published in sysfs */
-		rc = wait_for_sysfs_info (devpath, hotplug_type);
+		rc = wait_for_sysfs_info (devpath, subsystem);
 		if (rc != 0) {
-	    /** @todo handle error */
+			/* Don't know how to wait, just sleep one econd */
+			syslog (LOG_WARNING, "Dont know how to wait for %s at %s; "
+				"sleeping 1000 ms", subsystem, devpath);
+			usleep (1000 * 1000);
 		}
-	} else {
-		/* Do some sleep here so the kernel have time to publish it's
-		 * stuff in sysfs
-		 */
-		/*usleep(1000*1000); */
 	}
 
-	usleep (1000 * 1000);
-
-	if (!dbus_connection_send (sysbus_connection, message, NULL))
-		return 1;
-
-	dbus_message_unref (message);
-	dbus_connection_flush (sysbus_connection);
+	memset (&saddr, 0x00, sizeof(struct sockaddr_un));
+	saddr.sun_family = AF_LOCAL;
+	/* use abstract namespace for socket path */
+	strcpy (&saddr.sun_path[1], HALD_HELPER_SOCKET_PATH);
+	addrlen = offsetof (struct sockaddr_un, sun_path) + strlen (saddr.sun_path+1) + 1;
 
-	/* Do some sleep here so messages are not lost.. */
-	usleep (500 * 1000);
+	memset (&msg, 0x00, sizeof (msg));
+	msg.magic = HALD_HELPER_MAGIC; 
+	msg.is_hotplug_or_dev = 1;
+	msg.is_add = is_add;
+	msg.seqnum = seqnum;
+	strncpy (msg.subsystem, subsystem, HALD_HELPER_STRLEN);
+	strncpy (msg.sysfs_path, devpath, HALD_HELPER_STRLEN);
 
-	dbus_connection_disconnect (sysbus_connection);
+	if (sendto (fd, &msg, sizeof(struct hald_helper_msg), 0,
+		    (struct sockaddr *)&saddr, addrlen) == -1) {
+		syslog (LOG_INFO, "error sending message to hald");
+		goto out;
+	}
 
+out:
 	return 0;
 }
 
-/** @} */




More information about the hal-commit mailing list