hal/hald/linux block_class_device.c, 1.52, 1.53 bus_device.c, 1.15,
1.16 bus_device.h, 1.7, 1.8 class_device.c, 1.23,
1.24 class_device.h, 1.10, 1.11 common.c, 1.12, 1.13 common.h,
1.6, 1.7 hald_helper.h, NONE, 1.1 net_class_device.c, 1.15,
1.16 osspec.c, 1.30, 1.31 scsi_bus_device.c, NONE,
1.1 scsi_device_class_device.c, 1.10,
NONE scsi_generic_class_device.c, 1.3, 1.4
David Zeuthen
david at freedesktop.org
Sun Aug 15 11:54:59 PDT 2004
Update of /cvs/hal/hal/hald/linux
In directory pdx:/tmp/cvs-serv28976/hald/linux
Modified Files:
block_class_device.c bus_device.c bus_device.h class_device.c
class_device.h common.c common.h net_class_device.c osspec.c
scsi_generic_class_device.c
Added Files:
hald_helper.h scsi_bus_device.c
Removed Files:
scsi_device_class_device.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: block_class_device.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/block_class_device.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -d -r1.52 -r1.53
--- block_class_device.c 12 Aug 2004 14:34:36 -0000 1.52
+++ block_class_device.c 15 Aug 2004 18:54:56 -0000 1.53
@@ -140,7 +140,7 @@
}
-static void
+static HalDevice *
block_class_visit (ClassDeviceHandler *self,
const char *path,
struct sysfs_class_device *class_device)
@@ -152,7 +152,7 @@
/* only care about given sysfs class name */
if (strcmp (class_device->classname, "block") != 0)
- return;
+ return NULL;
d = hal_device_new ();
hal_device_store_add (hald_get_tdl (), d);
@@ -186,9 +186,9 @@
if (!class_device_get_device_file (path, dev_file,
SYSFS_PATH_MAX)) {
- HAL_WARNING (("Couldn't get device file for class "
- "device with sysfs path", path));
- return;
+ /*HAL_WARNING (("Couldn't get device file for class "
+ "device with sysfs path", path));*/
+ return NULL;
}
/* If we are not probing this function will be called upon
@@ -209,7 +209,9 @@
class_device_got_parent_device, cad,
HAL_LINUX_HOTPLUG_TIMEOUT);
- hal_device_print (d);
+ /*hal_device_print (d);*/
+
+ return d;
}
@@ -1023,7 +1025,7 @@
/* walk up the device chain to find the physical device,
* start with our parent. On the way, optionally pick up
- * the scsi_device if it exists */
+ * the scsi if it exists */
udi_it = parent->udi;
while (udi_it != NULL) {
@@ -1037,7 +1039,7 @@
/* Check info.bus */
bus = hal_device_property_get_string (d_it,"info.bus");
- if (strcmp (bus, "scsi_device") == 0) {
+ if (strcmp (bus, "scsi") == 0) {
scsidev = d_it;
physdev = d_it;
physdev_udi = udi_it;
@@ -1202,7 +1204,7 @@
} else if (strcmp (hal_device_property_get_string (parent,
"info.bus"),
- "scsi_device") == 0) {
+ "scsi") == 0) {
const char *device_file;
struct drive_id *did;
const char *sysfs_path;
@@ -1298,7 +1300,7 @@
* giving us the type of the SCSI device
*/
scsi_host = hal_device_property_get_int (
- parent, "scsi_device.host");
+ parent, "scsi.host");
scsi_protocol = read_single_line_grep (
" Protocol: ",
"/proc/scsi/usb-storage/%d",
@@ -1390,7 +1392,7 @@
char propname[64];
lun = hal_device_property_get_int (
- scsidev, "scsi_device.lun");
+ scsidev, "scsi.lun");
/* See 6in1-card-reader.fdi for an example */
@@ -1466,8 +1468,8 @@
if (idev == NULL)
break;
- if (hal_device_has_capability (idev, "scsi_device")) {
- lun = hal_device_property_get_int (idev, "scsi_device.lun");
+ if (hal_device_has_capability (idev, "scsi")) {
+ lun = hal_device_property_get_int (idev, "scsi.lun");
break;
}
@@ -1851,8 +1853,6 @@
const char *existing_block_device;
dbus_bool_t was_mounted;
- HAL_INFO (("%s mounted at %s, major:minor=%d:%d, fstype=%s, udi=%s", mp->device, mp->mount_point, mp->major, mp->minor, mp->fs_type, d->udi));
-
device_property_atomic_update_begin ();
existing_block_device =
@@ -1887,6 +1887,9 @@
device_property_atomic_update_end ();
if (!was_mounted) {
+
+ HAL_INFO (("%s is mounted at %s, major:minor=%d:%d, fstype=%s, udi=%s", mp->device, mp->mount_point, mp->major, mp->minor, mp->fs_type, d->udi));
+
device_send_signal_condition (
d,
"VolumeMount",
@@ -1981,8 +1984,9 @@
if (!force)
HAL_INFO (("/etc/mtab changed, processing all block devices"));
- else
- HAL_INFO (("processing /etc/mtab"));
+ else {
+ /*HAL_INFO (("processing /etc/mtab"));*/
+ }
hal_device_store_foreach (hald_get_gdl (), mtab_foreach_device, NULL);
}
Index: bus_device.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/bus_device.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- bus_device.c 21 Jul 2004 22:32:17 -0000 1.15
+++ bus_device.c 15 Aug 2004 18:54:56 -0000 1.16
@@ -79,8 +79,9 @@
* @param self Pointer to class members
* @param path Sysfs-path for device
* @param device libsysfs object for device
+ * @return A pointer to the HalDevice* object created
*/
-void
+HalDevice *
bus_device_visit (BusDeviceHandler *self, const char *path,
struct sysfs_device *device)
{
@@ -130,6 +131,8 @@
}
free (parent_sysfs_path);
+
+ return d;
}
Index: bus_device.h
===================================================================
RCS file: /cvs/hal/hal/hald/linux/bus_device.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- bus_device.h 5 Jul 2004 18:21:07 -0000 1.7
+++ bus_device.h 15 Aug 2004 18:54:57 -0000 1.8
@@ -80,10 +80,11 @@
* the device in sysfs
* @param device Libsysfs object representing new device
* instance
+ * @return A pointer to the HalDevice* object created
*/
- void (*visit) (BusDeviceHandler *self,
- const char *sysfs_path,
- struct sysfs_device *device);
+ HalDevice* (*visit) (BusDeviceHandler *self,
+ const char *sysfs_path,
+ struct sysfs_device *device);
/** Called when the class device instance have been removed
*
@@ -163,8 +164,8 @@
dbus_bool_t bus_device_accept (BusDeviceHandler *self, const char *path,
struct sysfs_device *device);
-void bus_device_visit (BusDeviceHandler *self, const char *path,
- struct sysfs_device *device);
+HalDevice *bus_device_visit (BusDeviceHandler *self, const char *path,
+ struct sysfs_device *device);
void bus_device_init (BusDeviceHandler *self);
Index: class_device.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/class_device.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- class_device.c 22 Jul 2004 19:06:01 -0000 1.23
+++ class_device.c 15 Aug 2004 18:54:57 -0000 1.24
@@ -98,7 +98,7 @@
* @param path Sysfs-path for class device
* @param class_device Libsysfs object for device
*/
-void
+HalDevice *
class_device_visit (ClassDeviceHandler *self,
const char *path,
struct sysfs_class_device *class_device)
@@ -172,7 +172,7 @@
SYSFS_PATH_MAX)) {
HAL_WARNING (("Couldn't get device file for "
"sysfs path %s", path));
- return;
+ return NULL;
}
/* If we are not probing this function will be called
@@ -219,6 +219,11 @@
class_device_got_parent_device, cad,
HAL_LINUX_HOTPLUG_TIMEOUT);
}
+
+ if (!merge_or_add)
+ return d;
+ else
+ return NULL;
}
/** Called when the class device instance have been removed
@@ -331,7 +336,7 @@
ClassDeviceHandler *self = cad->handler;
gboolean merge_or_add = cad->merge_or_add;
- HAL_INFO (("Entering d=0x%0x, sysdevice=0x%0x!", d, sysdevice));
+ /*HAL_INFO (("Entering d=0x%0x, sysdevice=0x%0x!", d, sysdevice));*/
if (sysdevice == NULL) {
HAL_WARNING (("Sysdevice for a class device never appeared!"));
Index: class_device.h
===================================================================
RCS file: /cvs/hal/hal/hald/linux/class_device.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- class_device.h 6 Jul 2004 23:18:08 -0000 1.10
+++ class_device.h 15 Aug 2004 18:54:57 -0000 1.11
@@ -90,10 +90,14 @@
* the class device in sysfs
* @param class_device Libsysfs object representing new class device
* instance
+ * @return A pointer to the HalDevice* object created
+ * if this class device is going to be a separate
+ * object in the GDL rather than merged onto
+ * another device object
*/
- void (*visit) (ClassDeviceHandler* self,
- const char *sysfs_path,
- struct sysfs_class_device *class_device);
+ HalDevice* (*visit) (ClassDeviceHandler* self,
+ const char *sysfs_path,
+ struct sysfs_class_device *class_device);
/** Called when the class device instance have been removed
*
@@ -242,9 +246,9 @@
const char *path,
struct sysfs_class_device *class_device);
-void class_device_visit (ClassDeviceHandler *self,
- const char *path,
- struct sysfs_class_device *class_device);
+HalDevice *class_device_visit (ClassDeviceHandler *self,
+ const char *path,
+ struct sysfs_class_device *class_device);
void class_device_removed (ClassDeviceHandler* self,
const char *sysfs_path,
Index: common.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/common.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- common.c 11 Aug 2004 18:53:50 -0000 1.12
+++ common.c 15 Aug 2004 18:54:57 -0000 1.13
@@ -560,7 +560,7 @@
/* Device is not in list... */
/* assign the computed device name */
- HAL_INFO ((" ##### computed_udi=%s", computed_udi));
+ /*HAL_INFO ((" ##### computed_udi=%s", computed_udi));*/
hal_device_set_udi (d, computed_udi);
hal_device_property_set_string (d, "info.udi", computed_udi);
@@ -683,8 +683,8 @@
}
if (udev_exitcode != 0) {
- HAL_ERROR (("%s returned %d", udevinfo_path (),
- udev_exitcode));
+ HAL_ERROR (("%s returned %d for %s", udevinfo_path (),
+ udev_exitcode, sysfs_path_trunc));
return FALSE;
}
Index: common.h
===================================================================
RCS file: /cvs/hal/hal/hald/linux/common.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- common.h 11 Aug 2004 18:53:50 -0000 1.6
+++ common.h 15 Aug 2004 18:54:57 -0000 1.7
@@ -98,6 +98,7 @@
extern char sysfs_mount_path[SYSFS_PATH_MAX];
+
/* @} */
#endif /* COMMON_H */
--- NEW FILE: hald_helper.h ---
/***************************************************************************
* CVSID: $Id: hald_helper.h,v 1.1 2004/08/15 18:54:57 david Exp $
*
* HAL daemon hotplug.d and dev.d helper details
*
* Copyright (C) 2004 David Zeuthen, <david at fubar.dk>
*
* Licensed under the Academic Free License version 2.0
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
**************************************************************************/
#ifndef HALD_HELPER_H
#define HALD_HELPER_H
#define HALD_HELPER_MAGIC 0x68616c64
#define HALD_HELPER_SOCKET_PATH PACKAGE_LOCALSTATEDIR "/run/hal/hotplug_socket"
#define HALD_HELPER_STRLEN 256
struct hald_helper_msg
{
unsigned int magic; /**< magic */
int is_hotplug_or_dev; /**< 1 if hotplug msg, 0 if device msg */
int is_add; /**< 1 if add, 0 if remove */
int seqnum; /**< Sequence number (only for hotplug) */
char subsystem[HALD_HELPER_STRLEN]; /**< subsystem e.g. usb, pci (only for hotplug msg) */
char sysfs_path[HALD_HELPER_STRLEN]; /**< path into sysfs without sysfs mountpoint, e.g. /block/sda */
char device_node[HALD_HELPER_STRLEN]; /**< fully qualified path of device node (only for device msg) */
};
#endif /* HALD_HELPER_H */
Index: net_class_device.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/net_class_device.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- net_class_device.c 30 Jul 2004 20:59:45 -0000 1.15
+++ net_class_device.c 15 Aug 2004 18:54:57 -0000 1.16
@@ -583,7 +583,7 @@
const char *format;
static char buf[256];
- hal_device_print (d);
+ /*hal_device_print (d);*/
if (append_num == -1)
format = "/org/freedesktop/Hal/devices/net-%s";
@@ -597,6 +597,15 @@
return buf;
}
+static void
+net_class_udev_event (ClassDeviceHandler *self, HalDevice *d,
+ char *dev_file)
+{
+ /* how rude; udev sends us a device event for the networking device;
+ * ignore it */
+ HAL_INFO (("Ignoring udev event for %s", dev_file));
+}
+
/** Method specialisations for input device class */
ClassDeviceHandler net_class_handler = {
class_device_init, /**< init function */
@@ -605,7 +614,7 @@
net_class_accept, /**< accept function */
class_device_visit, /**< visitor function */
class_device_removed, /**< class device is removed */
- class_device_udev_event, /**< handle udev event */
+ net_class_udev_event, /**< handle udev event */
class_device_get_device_file_target,/**< where to store devfile name */
net_class_pre_process, /**< add more properties */
net_class_post_merge, /**< post merge function */
Index: osspec.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/osspec.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- osspec.c 30 Jul 2004 17:00:42 -0000 1.30
+++ osspec.c 15 Aug 2004 18:54:57 -0000 1.31
@@ -30,12 +30,18 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stddef.h>
#include <string.h>
#include <getopt.h>
#include <assert.h>
#include <unistd.h>
#include <stdarg.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
@@ -45,6 +51,7 @@
#include "../callout.h"
#include "common.h"
+#include "hald_helper.h"
#include "bus_device.h"
#include "class_device.h"
@@ -67,6 +74,7 @@
extern BusDeviceHandler usbif_bus_handler;
extern BusDeviceHandler ide_host_bus_handler;
extern BusDeviceHandler ide_bus_handler;
+extern BusDeviceHandler scsi_bus_handler;
extern BusDeviceHandler macio_bus_handler;
extern BusDeviceHandler platform_bus_handler;
@@ -81,7 +89,7 @@
&net_class_handler,
&printer_class_handler,
&scsi_host_class_handler,
- &scsi_device_class_handler,
+ /*&scsi_device_class_handler,*/
&scsi_generic_class_handler,
&block_class_handler,
&pcmcia_socket_class_handler,
@@ -99,9 +107,17 @@
&ide_bus_handler,
&macio_bus_handler,
&platform_bus_handler,
+ &scsi_bus_handler,
NULL
};
+
+static void hotplug_sem_up (void);
+static void hotplug_sem_down (void);
+static void hald_helper_hotplug (gboolean is_add, int seqnum, char *subsystem, char *sysfs_path);
+static void hald_helper_device_node (gboolean is_add, char *subsystem, char *sysfs_path, char *device_node);
+static gboolean hald_helper_data (GIOChannel *source, GIOCondition condition, gpointer user_data);
+
/**
* @defgroup HalDaemonLinux Linux 2.6 support
* @ingroup HalDaemon
@@ -127,35 +143,47 @@
* all devices. For hotplug events, it should
* be set to #FALSE as each sysfs object will
* generate a separate event.
+ * @return A HalDevice pointer if the device is going
+ * to be added to the GDL. The caller can
+ * track the device by listening to signals
+ * from this object. Returns NULL if the
+ * device wasn't matched by any handler or
+ * if it isn't going to be a separate hal
+ * device object.
*/
-static void
+static HalDevice *
visit_class_device (const char *path, ClassDeviceHandler *handler,
dbus_bool_t visit_children)
{
int i;
+ HalDevice *hal_device = NULL;
struct sysfs_class_device *class_device;
class_device = sysfs_open_class_device_path (path);
if (class_device == NULL) {
HAL_WARNING (("Coulnd't get sysfs class device object at "
"path %s", path));
- return;
+ return NULL;
}
sysfs_get_classdev_device(class_device);
sysfs_get_classdev_driver(class_device);
- HAL_INFO (("*** classname=%s path=%s",
+ /*HAL_INFO (("*** classname=%s path=%s",
class_device->classname,
- class_device->path));
+ class_device->path));*/
if (handler != NULL) {
- if (handler->accept (handler, path, class_device))
- handler->visit (handler, path, class_device);
+ if (handler->accept (handler, path, class_device)) {
+ hal_device = handler->visit (handler, path, class_device);
+ }
} else {
for (i=0; class_device_handlers[i] != NULL; i++) {
ClassDeviceHandler *ch = class_device_handlers[i];
- if (ch->accept (ch, path, class_device))
- ch->visit (ch, path, class_device);
+ if (ch->accept (ch, path, class_device)) {
+ hal_device = ch->visit (ch, path, class_device);
+ if (hal_device != NULL)
+ break;
+ }
}
}
@@ -168,12 +196,12 @@
dir = sysfs_open_directory(path);
if (dir == NULL)
- return;
+ return NULL;
subdirs = sysfs_get_dir_subdirs(dir);
if (subdirs == NULL) {
sysfs_close_directory(dir);
- return;
+ return NULL;
}
dlist_for_each_data (subdirs, subdir,
@@ -182,6 +210,8 @@
sysfs_close_directory(dir);
}
+
+ return hal_device;
}
/** Visit all devices of a given class
@@ -236,28 +266,37 @@
* all devices. For hotplug events, it should
* be set to #FALSE as each sysfs object will
* generate a separate event.
+ * @return A HalDevice pointer if the device is going
+ * to be added to the GDL. The caller can
+ * track the device by listening to signals
+ * from this object. Returns NULL if the
+ * device wasn't matched by any handler.
*/
-static void
+static HalDevice *
visit_device (const char *path, BusDeviceHandler *handler,
dbus_bool_t visit_children)
{
struct sysfs_device *device;
+ HalDevice *hal_device = NULL;
device = sysfs_open_device_path (path);
if (device == NULL) {
HAL_WARNING (("Coulnd't get sysfs device at path %s", path));
- return;
+ return NULL;
}
if (handler != NULL ) {
if (handler->accept (handler, device->path, device))
- handler->visit (handler, device->path, device);
+ hal_device = handler->visit (handler, device->path, device);
} else {
int i;
for (i=0; bus_device_handlers[i] != NULL; i++) {
BusDeviceHandler *bh = bus_device_handlers[i];
- if (bh->accept (bh, device->path, device))
- bh->visit (bh, device->path, device);
+ if (bh->accept (bh, device->path, device)) {
+ hal_device = bh->visit (bh, device->path, device);
+ if (hal_device != NULL)
+ break;
+ }
}
}
sysfs_close_device(device);
@@ -269,12 +308,12 @@
dir = sysfs_open_directory(path);
if (dir == NULL)
- return;
+ return NULL;
subdirs = sysfs_get_dir_subdirs(dir);
if (subdirs == NULL) {
sysfs_close_directory(dir);
- return;
+ return NULL;
}
dlist_for_each_data (subdirs, subdir,
@@ -283,6 +322,8 @@
sysfs_close_directory(dir);
}
+
+ return hal_device;
}
/** Timeout handler for polling
@@ -308,12 +349,44 @@
return TRUE;
}
+
/* This function is documented in ../osspec.h */
void
osspec_init (void)
{
int i;
int rc;
+ int socketfd;
+ struct sockaddr_un saddr;
+ socklen_t addrlen;
+ GIOChannel *channel;
+ const int on = 1;
+
+ /* setup socket for listening from datagrams from the
+ * hal.hotplug and hal.dev helpers.
+ */
+ memset(&saddr, 0x00, sizeof(saddr));
+ 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;
+
+ socketfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
+ if (socketfd == -1) {
+ DIE (("Couldn't open socket"));
+ }
+
+ if (bind(socketfd, (struct sockaddr *) &saddr, addrlen) < 0) {
+ DIE (("bind failed, exit"));
+ }
+
+ /* enable receiving of the sender credentials */
+ setsockopt(socketfd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
+
+ channel = g_io_channel_unix_new (socketfd);
+ g_io_add_watch (channel, G_IO_IN, hald_helper_data, NULL);
+ g_io_channel_unref (channel);
+
/* get mount path for sysfs */
rc = sysfs_get_mnt_path (sysfs_mount_path, SYSFS_PATH_MAX);
@@ -413,10 +486,11 @@
hal_device_store_remove (hald_get_gdl (), d);
}
-static void
+static HalDevice *
remove_device (const char *path, const char *subsystem)
-{ HalDevice *d;
+{
+ HalDevice *d;
d = hal_device_store_match_key_value_string (hald_get_gdl (),
"linux.sysfs_path",
@@ -435,9 +509,11 @@
HAL_INFO (("in remove_device for udi=%s", d->udi));
hal_callout_device (d, FALSE);
}
+
+ return d;
}
-static void
+static HalDevice *
remove_class_device (const char *path, const char *subsystem)
{
int i;
@@ -486,98 +562,12 @@
}
/* For now, just call the normal remove_device */
- remove_device (path, subsystem);
-}
-
-/** Handle a org.freedesktop.Hal.HotplugEvent message. This message
- * origins from the hal.hotplug program, tools/linux/hal_hotplug.c,
- * and is basically just a D-BUS-ification of the hotplug event.
- *
- * @param connection D-BUS connection
- * @param message Message
- * @return What to do with the message
- */
-static DBusHandlerResult
-handle_hotplug (DBusConnection * connection, DBusMessage * message)
-{
- DBusMessageIter iter;
- DBusMessageIter dict_iter;
- dbus_bool_t is_add;
- char *subsystem;
- char sysfs_devpath[SYSFS_PATH_MAX];
- char sysfs_devpath_wo_mp[SYSFS_PATH_MAX];
-
- sysfs_devpath[0] = '\0';
-
- dbus_message_iter_init (message, &iter);
-
- if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) {
- /** @todo Report error */
- dbus_message_unref (message);
- return DBUS_HANDLER_RESULT_HANDLED;
- }
- subsystem = dbus_message_iter_get_string (&iter);
-
- dbus_message_iter_next (&iter);
- dbus_message_iter_init_dict_iterator (&iter, &dict_iter);
-
- is_add = FALSE;
-
- do {
- char *key;
- char *value;
-
- key = dbus_message_iter_get_dict_key (&dict_iter);
- value = dbus_message_iter_get_string (&dict_iter);
-
- /*HAL_INFO (("key/value : %s=%s", key, value));*/
-
- if (strcmp (key, "ACTION") == 0) {
- if (strcmp (value, "add") == 0) {
- is_add = TRUE;
- }
- } else if (strcmp (key, "DEVPATH") == 0) {
- strncpy (sysfs_devpath, sysfs_mount_path,
- SYSFS_PATH_MAX);
- strncat (sysfs_devpath, value, SYSFS_PATH_MAX);
- strncpy (sysfs_devpath_wo_mp, value, SYSFS_PATH_MAX);
- }
- } while (dbus_message_iter_has_next (&dict_iter) &&
- dbus_message_iter_next (&dict_iter));
-
- /* ignore events without DEVPATH */
- if (sysfs_devpath[0] == '\0')
- goto out;
-
- HAL_INFO (("HotplugEvent %s, subsystem=%s devpath=%s foo=%s",
- (is_add ? "add" : "remove"), subsystem,
- sysfs_devpath[0] != '\0' ? sysfs_devpath : "(none)",
- sysfs_devpath_wo_mp));
-
- /* See if this is a class device or a bus device */
- if (strncmp (sysfs_devpath_wo_mp, "/block", 6)==0 ||
- strncmp (sysfs_devpath_wo_mp, "/class", 6)==0 ) {
- /* handle class devices */
- if (is_add)
- /* dunno what handler to use; try all */
- visit_class_device (sysfs_devpath, NULL, FALSE);
- else
- remove_class_device (sysfs_devpath, subsystem);
- } else {
- /* handle bus devices */
- if (is_add) {
- /* dunno what handler to use; try all */
- visit_device (sysfs_devpath, NULL, FALSE);
- } else {
- remove_device (sysfs_devpath, subsystem);
- }
- }
-
+ /*remove_device (path, subsystem);*/
-out:
- return DBUS_HANDLER_RESULT_HANDLED;
+ return d;
}
+
/* fwd decl */
static void handle_udev_node_created_found_device (HalDevice * d,
void *data1,
@@ -593,56 +583,6 @@
}
-/** Handle a org.freedesktop.Hal.DeviceEvent message. This message
- * origins from the hal.dev program, tools/linux/hal_dev.c,
- * and is basically just a D-BUS-ification of the device event from udev.
- *
- * @param connection D-BUS connection
- * @param message Message
- * @return What to do with the message
- */
-static DBusHandlerResult
-handle_device_event (DBusConnection * connection,
- DBusMessage * message)
-{
- dbus_bool_t is_add;
- char *filename;
- char *sysfs_path;
- char sysfs_dev_path[SYSFS_PATH_MAX];
-
- if (dbus_message_get_args (message, NULL,
- DBUS_TYPE_BOOLEAN, &is_add,
- DBUS_TYPE_STRING, &filename,
- DBUS_TYPE_STRING, &sysfs_path,
- DBUS_TYPE_INVALID)) {
- strncpy (sysfs_dev_path, sysfs_mount_path, SYSFS_PATH_MAX);
- strncat (sysfs_dev_path, sysfs_path, SYSFS_PATH_MAX);
-
- if (is_add ) {
-
- HAL_INFO (("DeviceEvent add devpath=%s devfile=%s",
- sysfs_dev_path, filename));
-
- hal_device_store_match_key_value_string_async (
- hald_get_tdl (),
- ".udev.sysfs_path",
- sysfs_dev_path,
- udev_node_created_cb, filename,
- HAL_LINUX_HOTPLUG_TIMEOUT);
-
- /* NOTE NOTE NOTE: we will free filename in async
- * result function
- */
- } else {
- dbus_free (filename);
- }
-
- dbus_free (sysfs_path);
- }
-
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
/** Callback when the block device is found or if there is none..
*
* @param d Async Return value from the find call
@@ -660,7 +600,7 @@
if (d != NULL) {
HAL_INFO (("dev_file=%s is for udi=%s", dev_file, d->udi));
- hal_device_print (d);
+ /*hal_device_print (d);*/
sysfs_class_name =
hal_device_property_get_string (d, ".udev.class_name");
@@ -693,22 +633,7 @@
osspec_filter_function (DBusConnection * connection,
DBusMessage * message, void *user_data)
{
-
- if (dbus_message_is_method_call (message,
- "org.freedesktop.Hal.Linux.Hotplug",
- "HotplugEvent") &&
- strcmp (dbus_message_get_path (message),
- "/org/freedesktop/Hal/Linux/Hotplug") == 0) {
- return handle_hotplug (connection, message);
- } else if (dbus_message_is_method_call (message,
- "org.freedesktop.Hal.Linux.Hotplug",
- "DeviceEvent") &&
- strcmp (dbus_message_get_path (message),
- "/org/freedesktop/Hal/Linux/Hotplug") == 0) {
- return handle_device_event (connection, message);
- }
-
- return DBUS_HANDLER_RESULT_HANDLED;
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
@@ -757,4 +682,285 @@
NULL);
}
+
+static void
+reenable_hotplug_proc (HalDevice *d, gpointer user_data)
+{
+ g_signal_handlers_disconnect_by_func (d, reenable_hotplug_proc, user_data);
+ hotplug_sem_down ();
+}
+
+static void
+hald_helper_hotplug (gboolean is_add, int seqnum, gchar *subsystem, gchar *sysfs_path)
+{
+ HalDevice *d = NULL;
+ char sysfs_path_full[SYSFS_PATH_MAX];
+
+ snprintf (sysfs_path_full, SYSFS_PATH_MAX, "%s%s", sysfs_mount_path, sysfs_path);
+
+ HAL_INFO (("entering %s, SEQNUM=%d subsystem=%s devpath=%s devpath_full=%s",
+ (is_add ? "add" : "rem"), seqnum, subsystem, sysfs_path, sysfs_path_full));
+
+ /* See if this is a class device or a bus device */
+ if (strncmp (sysfs_path, "/block", 6)==0 ||
+ strncmp (sysfs_path, "/class", 6)==0 ) {
+ /* handle class devices */
+ if (is_add) {
+ /* dunno what handler to use; try all */
+ d = visit_class_device (sysfs_path_full, NULL, FALSE);
+ } else {
+ d = remove_class_device (sysfs_path_full, subsystem);
+ }
+ } else {
+ /* handle bus devices */
+ if (is_add) {
+ /* Try to add the device */
+ d = visit_device (sysfs_path_full, NULL, FALSE);
+ } else {
+ d = remove_device (sysfs_path_full, subsystem);
+ }
+ }
+
+ if (d != NULL) {
+ /* Ok, this leads to something; this hotplug event is going
+ * to result in adding/removing a device object to the GDL.
+ *
+ * Disable hotplug processing for now
+ */
+ hotplug_sem_up ();
+
+ /* and enable it when our device has processed all the
+ * callouts
+ */
+ g_signal_connect (d, "callouts_finished",
+ G_CALLBACK (reenable_hotplug_proc), NULL);
+ }
+
+
+ g_free (subsystem);
+ g_free (sysfs_path);
+}
+
+static void
+hald_helper_device_node (gboolean is_add, gchar *subsystem, gchar *sysfs_path, gchar *device_node)
+{
+ char sysfs_path_full[SYSFS_PATH_MAX];
+
+ snprintf (sysfs_path_full, SYSFS_PATH_MAX, "%s%s", sysfs_mount_path, sysfs_path);
+
+ HAL_INFO (("entering %s, subsystem=%s devpath=%s devnode=%s",
+ (is_add ? "add" : "rem"), subsystem, sysfs_path, device_node));
+
+ if (is_add ) {
+
+ hal_device_store_match_key_value_string_async (
+ hald_get_tdl (),
+ ".udev.sysfs_path",
+ sysfs_path_full,
+ udev_node_created_cb,
+ g_strdup (device_node),
+ HAL_LINUX_HOTPLUG_TIMEOUT);
+
+ /* NOTE: we will free the dupped device_node in the
+ * async result function */
+
+ } else {
+ /* TODO FIXME: do something here :-) */
+ }
+
+ g_free (subsystem);
+ g_free (sysfs_path);
+ g_free (device_node);
+}
+
+
+
+/** queue of hotplug events (struct hald_helper_msg pointers) */
+static GList *hotplug_queue = NULL;
+
+/** Last hotplug sequence number */
+static gint last_hotplug_seqnum = -1;
+
+/** Hotplug semaphore */
+static gint hotplug_counter = 0;
+
+static void
+hald_helper_hotplug_process_queue (void)
+{
+ GList *i;
+ struct hald_helper_msg *msg;
+
+trynext:
+ if (hotplug_counter > 0)
+ return;
+
+ for (i = hotplug_queue; i != NULL; i = g_list_next (i)) {
+ msg = (struct hald_helper_msg *) i->data;
+
+ if (msg->seqnum == last_hotplug_seqnum + 1) {
+ /* yup, found it */
+ last_hotplug_seqnum = msg->seqnum;
+ hald_helper_hotplug (msg->is_add, msg->seqnum, g_strdup (msg->subsystem),
+ g_strdup (msg->sysfs_path));
+ g_free (msg);
+ hotplug_queue = g_list_delete_link (hotplug_queue, i);
+ goto trynext;
+ }
+ }
+}
+
+/** Increment the hotplug semaphore; useful when not wanting to process
+ * hotplug events for a while, like when e.g. adding a hal device
+ * object (which is an asynchronous operation).
+ *
+ * Remember to release with hotplug_sem_down.
+ */
+static void
+hotplug_sem_up (void)
+{
+ ++hotplug_counter;
+}
+
+/** Decrement the hotplug semaphore.
+ *
+ */
+static void
+hotplug_sem_down (void)
+{
+ --hotplug_counter;
+
+ if (hotplug_counter < 0) {
+ HAL_ERROR (("****************************************"));
+ HAL_ERROR (("****************************************"));
+ HAL_ERROR (("DANGER WILL ROBISON! hotplug semaphore<0!"));
+ HAL_ERROR (("****************************************"));
+ HAL_ERROR (("****************************************"));
+ hotplug_counter = 0;
+ }
+
+ /* Process remaining hotplug events */
+ if (hotplug_counter == 0)
+ hald_helper_hotplug_process_queue ();
+}
+
+static gboolean
+hald_helper_first_hotplug_event (gpointer data)
+{
+ GList *i;
+ struct hald_helper_msg *msg;
+
+ last_hotplug_seqnum = G_MAXINT;
+ /* find the seqnum we should start with */
+ for (i = hotplug_queue; i != NULL; i = g_list_next (i)) {
+ msg = (struct hald_helper_msg *) i->data;
+ if (msg->seqnum < last_hotplug_seqnum)
+ last_hotplug_seqnum = msg->seqnum;
+ }
+ --last_hotplug_seqnum;
+
+ HAL_INFO (("Starting with SEQNUM=%d", last_hotplug_seqnum+1));
+
+ hotplug_sem_down ();
+
+ /* no further timer event */
+ return FALSE;
+}
+
+static gboolean
+hald_helper_data (GIOChannel *source,
+ GIOCondition condition,
+ gpointer user_data)
+{
+ struct hald_helper_msg msg;
+ int fd;
+ int retval;
+ struct msghdr smsg;
+ struct cmsghdr *cmsg;
+ struct iovec iov;
+ struct ucred *cred;
+ char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
+
+ fd = g_io_channel_unix_get_fd (source);
+
+ iov.iov_base = &msg;
+ iov.iov_len = sizeof (struct hald_helper_msg);
+
+ memset(&smsg, 0x00, sizeof (struct msghdr));
+ smsg.msg_iov = &iov;
+ smsg.msg_iovlen = 1;
+ smsg.msg_control = cred_msg;
+ smsg.msg_controllen = sizeof (cred_msg);
+
+ retval = recvmsg (fd, &smsg, 0);
+ if (retval < 0) {
+ if (errno != EINTR)
+ HAL_INFO (("Unable to receive message, errno=%d", errno));
+ goto out;
+ }
+ cmsg = CMSG_FIRSTHDR (&smsg);
+ cred = (struct ucred *) CMSG_DATA (cmsg);
+
+ if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
+ HAL_INFO (("No sender credentials received, message ignored"));
+ goto out;
+ }
+
+ if (cred->uid != 0) {
+ HAL_INFO (("Sender uid=%i, message ignored", cred->uid));
+ goto out;
+ }
+
+ if (msg.magic != HALD_HELPER_MAGIC) {
+ HAL_INFO (("Magic is wrong, message ignored", cred->uid));
+ goto out;
+ }
+
+ if (!msg.is_hotplug_or_dev) {
+ /* device events doesn't have seqnum on them, however udev also respect sequence numbers */
+ hald_helper_device_node (msg.is_add, g_strdup (msg.subsystem), g_strdup (msg.sysfs_path),
+ g_strdup (msg.device_node));
+ goto out;
+ }
+
+ /* need to process hotplug events in proper sequence */
+
+ /*HAL_INFO (("Before reordering, SEQNUM=%d, last_hotplug_seqnum=%d, subsystem=%s, sysfs=%s",
+ msg.seqnum, last_hotplug_seqnum, msg.subsystem, msg.sysfs_path));*/
+
+ if (last_hotplug_seqnum == -1 ) {
+ /* gotta start somewhere; however sleep one second to allow
+ * some more hotplug events to propagate so we know where
+ * we're at.
+ */
+
+ HAL_WARNING (("First SEQNUM=%d; sleeping 2500ms to get a few more events", msg.seqnum));
+
+ hotplug_sem_up ();
+ g_timeout_add (2500, hald_helper_first_hotplug_event, NULL);
+
+ /* so we only setup one timer */
+ last_hotplug_seqnum = -2;
+ }
+
+ if (msg.seqnum < last_hotplug_seqnum) {
+ /* yikes, this means were started during a hotplug */
+ HAL_WARNING (("Got SEQNUM=%d, but last_hotplug_seqnum=%d", msg.seqnum, last_hotplug_seqnum));
+
+ /* have to process immediately other we may deadlock due to
+ * the hotplug semaphore */
+ hald_helper_hotplug (msg.is_add, msg.seqnum, g_strdup (msg.subsystem),
+ g_strdup (msg.sysfs_path));
+ /* still need to process the queue though */
+ hald_helper_hotplug_process_queue ();
+ goto out;
+ }
+
+ /* Queue up this hotplug event and process the queue */
+ hotplug_queue = g_list_append (hotplug_queue, g_memdup (&msg, sizeof (struct hald_helper_msg)));
+ hald_helper_hotplug_process_queue ();
+
+out:
+ return TRUE;
+}
+
/** @} */
--- NEW FILE: scsi_bus_device.c ---
/***************************************************************************
* CVSID: $Id: scsi_bus_device.c,v 1.1 2004/08/15 18:54:57 david Exp $
*
* SCSI bus devices
*
* Copyright (C) 2003 David Zeuthen, <david at fubar.dk>
*
* Licensed under the Academic Free License version 2.0
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
**************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <assert.h>
#include <unistd.h>
#include <stdarg.h>
#include "../logger.h"
#include "../device_store.h"
#include "bus_device.h"
#include "common.h"
static char *
scsi_device_compute_udi (HalDevice *d, int append_num)
{
const char *format;
static char buf[256];
if (append_num == -1)
format =
"/org/freedesktop/Hal/devices/scsi_%d_%d_%d_%d";
else
format =
"/org/freedesktop/Hal/devices/scsi_%d_%d_%d_%d-%d";
snprintf (buf, 256, format,
hal_device_property_get_int (d, "scsi.host"),
hal_device_property_get_int (d, "scsi.bus"),
hal_device_property_get_int (d, "scsi.target"),
hal_device_property_get_int (d, "scsi.lun"),
append_num);
return buf;
}
static void
scsi_device_pre_process (BusDeviceHandler *self,
HalDevice *d,
const char *sysfs_path,
struct sysfs_device *device)
{
const char *last_elem;
int host_num, bus_num, target_num, lun_num;
/* Sets last_elem to 1:2:3:4 in
* path=/sys/class/scsi_host/host23/1:2:3:4
*/
last_elem = get_last_element (sysfs_path);
sscanf (last_elem, "%d:%d:%d:%d",
&host_num, &bus_num, &target_num, &lun_num);
hal_device_property_set_int (d, "scsi.host", host_num);
hal_device_property_set_int (d, "scsi.bus", bus_num);
hal_device_property_set_int (d, "scsi.target", target_num);
hal_device_property_set_int (d, "scsi.lun", lun_num);
/* guestimate product name */
hal_device_property_set_string (d, "info.product", "SCSI Device");
}
/** Method specialisations for bustype pci */
BusDeviceHandler scsi_bus_handler = {
bus_device_init, /**< init function */
bus_device_shutdown, /**< shutdown function */
bus_device_tick, /**< timer function */
bus_device_accept, /**< accept function */
bus_device_visit, /**< visitor function */
bus_device_removed, /**< device is removed */
scsi_device_compute_udi, /**< UDI computing function */
scsi_device_pre_process, /**< add more properties */
bus_device_got_udi, /**< got UDI */
bus_device_in_gdl, /**< in GDL */
"scsi", /**< sysfs bus name */
"scsi" /**< namespace */
};
/** @} */
--- scsi_device_class_device.c DELETED ---
Index: scsi_generic_class_device.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/scsi_generic_class_device.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- scsi_generic_class_device.c 5 Jul 2004 18:21:07 -0000 1.3
+++ scsi_generic_class_device.c 15 Aug 2004 18:54:57 -0000 1.4
@@ -76,6 +76,19 @@
hal_device_add_capability (d, "scsi_generic");
}
+static void
+scsi_generic_get_device_file_target (ClassDeviceHandler *self,
+ HalDevice *d,
+ const char *sysfs_path,
+ struct sysfs_class_device *class_device,
+ char* dev_file_prop,
+ int dev_file_prop_len)
+{
+ strncpy(dev_file_prop, "scsi.generic_device", dev_file_prop_len);
+}
+
+
+
/** Method specialisations for input device class */
ClassDeviceHandler scsi_generic_class_handler = {
class_device_init, /**< init function */
@@ -85,7 +98,7 @@
class_device_visit, /**< visitor function */
class_device_removed, /**< class device is removed */
class_device_udev_event, /**< handle udev event */
- class_device_get_device_file_target,/**< where to store devfile name */
+ scsi_generic_get_device_file_target,/**< where to store devfile name */
scsi_generic_class_pre_process, /**< add more properties */
class_device_post_merge, /**< post merge function */
class_device_got_udi, /**< got UDI */
More information about the hal-commit
mailing list