I hope these notes might be of some use to the rest of you,
since this stuff basically is a pain in the arse. When I
floated the idea before, people said things like ‘i'd
love a post on ‘what the fuck hald thinks it's for’” so here you
go... There may be many of mistakes in this email, since this
software is all complex and rapidly changing, so apologies in
advance for that.

Basically, the problem I wanted to solve was for removable
storage devices to be automatically mounted when I plug them
into my computer and for them to be mounted at a predictable
point (of my choosing) in the filesytem. This was mostly not
for my own benefit, FWIW, but it turns out to be pleasant when
it's working nonetheless.

Assuming you're using a late 2.6 Linux kernel¹ then your
options for this seem to be:

¹ Even in very late versions of 2.6, like 2.6.13, lots of
these things don't work - when I say late I mean at least 2.6.15...

The traditional approach: plug in the device, tail
/var/log/syslog to find the device name and manually mount the
device. The disadvantages of this are that it doesn't work for
people who don't want to use the terminal or remember how to
mount devices.

A similar, but slightly simpler approach: make entries in fstab
that refer to the /dev/disk symlinks that you get with udev and
late 2.6 kernels, e.g. :

(I can't remember which versions this started working
properly with, but kernel 2.6.15.2 and udev 0.084 are
certainly OK.)

This isn't too bad a solution, in fact - it even gets around
the requirement that you need to use the terminal if you're
using Gnome, since Nautilus's computer folder adds icons for all
the /etc/fstab mount points and you can mount and unmount with
the context menu.

Update: If you are having problems finding the UUID of
a device (e.g. your system doesn't create the by-uuid symlinks)
then you can display them with blkid (from e2fsprogs) or
/lib/udev/vol_id. Thanks to Alexander Amelkin for
pointing this out.

Alternatively, you can use an ungodly combination of udev, hald,
dbus, gnome-volume-manager and friends to get this
functionality. If you're lucky² and you use Gnome, then you
will have noticed some of this working already when folder
windows pop up when you plug in USB mass storage devices, DVDs
are autoplayed, etc.

² Depending on your point of view, I suppose...

So, let's assume that, like me, you want to go down route (c)
since it's interesting to see whether this all works nowadays.
Some cursory exploration will lead you to lovely diagrams like
this:

... which should provoke a certain amount of hollow laughter if
you're a fan of approach (a). Also, AFAICT that diagram is
totally incorrect these days. For example,
/sbin/hotplug is now deprecated and its functionality
absorbed into udevd - you should make sure you have the hotplug
package purged as well as removed from your Debian system. Also
hal.hotplug is replaced by unix domain socket communication from
udevd to hald. And Debian systems don't use the fstab-sync bit
at all - it's replaced by pmount. So there isn't much in that
diagram that applies, except perhaps the “Linux 2.6
kernel” box in the bottom left. ;)

sysfs, which should be mounted on /sys, has the
canonical representation of devices in your computer (devfs was
thrown out before 2.6 for
good reasons.)
sysfs has a very clean layout compared to /proc
or a traditional /dev as you'll see if you poke around in there.
Particularly of note are the files with leafname “dev”, which
contain the major and minor device numbers of the device and
“uevent”. If you write the correct string to a uevent file the
kernel generates an event as if the device had just been plugged
in, so that udev (or whatever) can create devices in
/dev in a consistent fashion across all devices, both
fixed and removable. (This isn't quite the case yet, though;
some devices are still created manually by the init scripts.)

AFAICT, sysfs is the only bit which is more-or-less guaranteed
to be the same across different distributions. Everything else
is now done in userspace. If you're interested in device
creation and removal events then you listen to a kernel netlink
socket. (This has changed somewhat since 2.6.14 - userspace
used to be notified by invoking the binary named in
/proc/sys/kernel/hotplug, which has in the past been
/sbin/hotplug and /sbin/udevsend...)

So, from this point on, assume that everything else in this
email is Debian specific. When you boot up, then one of the
first init scripts (/etc/rcS.d/S03udev) does the following
(missing out some hackery):

starts the udevd daemon, which listens on the netlink socket
for kernel device events

mounts a tmpfs on /dev

walks the /sys structure and synthesizes device
creation events by echoing something like ‘add ’ to
the uevent files. (This is done in the
/sbin/udevsynthesize script.)

udevd basically checks all the events it receives against rules
in /etc/udev and does various things for matching
rules, such as creating a /dev entry for newly created
devices. This does have to advantage of keeping your
/dev directory down to a reasonable size compared to
the MAKEDEV approach. (It also does helpful things like create
the /dev/disk/by-label/ symlinks and so on.)

HAL gets all its information from udevd via one of these rules.
When the hal package is installed it adds various rules files to
/etc/udev which basically tell udevd to copy everything to HAL:

RUN+="socket:/org/freedesktop/hal/udev_event"

(Contrary to what you might read elsewhere, hald doesn't talk to
the kernel directly using netlink. I think it used to do this
in order to find when devices were mounted and unmounted, but
nowadays it does that by polling /proc/mounts.)

You might have noticed that the original question
(i.e. “what the fuck hald thinks it's for”) is still
unanswered. HAL basically maintains its own database of devices
connected to your computer, but gets into the business of
guessing what devices are likely to be cameras, which are iPoda,
etc. You can see all the devices it knows about with lshal in a
terminal or using a GUI like this:

(That's hal-device-manager, which is in its own Debian package
of the same name, and found in the standard Gnome setup in
Desktop -> Administration -> Device Manager.)

If you're interested in changes to this device hierarchy (as the
gnome-volume-manager and presumably the KDE equivalent are) then
you talk to hald via D-BUS. There's more detail about that, and
an example Python program here:

HAL has its own namespace for devices in a filesystem-like
hierarchy under /org/freedesktop/Hal/devices/. I suspect that
the objects in this hierarchy have a one-to-one mapping to D-BUS
objects, rather than this just being a case of
over-generalized-namespace-itis, but it's not really clear from
the documentation I've read. Possibly someone who knows about
D-BUS can tell me? Each of the objects in this hierarchy has a
series of properties whose key names are in their own
dot-separated namespace, and whose values have a very simple
type system. (You can see examples in the hal-device-manager
image linked above.)

The HAL package also has large pile of carefully crafted XML
files full of rules and device information; udev doesn't care
about any of this stuff (and quite right too, since it's
obviously a nightmare.)

A common misconception about HAL is that it actually handles the
mounting and unmounting of devices itself. In fact this is done
by gnome-volume-manager, which listens for HAL events via D-BUS
and then invokes pmount-hal to mount devices. (Or it might not
mount them at all - it depends if you've configured that to
happen via Desktop -> Preferences -> Removable Drives and Media:

... which is gnome-volume-properties, the configuration GUI
in the gnome-volume-manager package. The difference between a
device being “inserted” and “hotplugged”
is left as an exercise for the reader, since I don't know and
I'm sure the answer will cause pain and gnashing of teeth.)

This means that HAL maintains an object representing the
device throughout the time that it's plugged in, but when you
log in and out of Gnome the removable devices currently inserted
are mounted and unmounted, and become owned by whatever user is
logged in. (pmounted drives, incidentally, don't appear in
/etc/mtab, only in /proc/mounts, so if you
want to manually unmount them then you have to use pumount
rather than umount. Another point that may be helpful is that
on Debian you have to be a member of the plugdev group for
pmount to work.)

So, to return to my original aim, how do I get my iPod to appear
at a consistent point of my choosing in the filesystem? The
default for such devces is to be mounted at
/media/<VOLUME-LABEL> or /media/MARK'S IPOD in my case. That
name causes problems for many pieces of distinctly average
software, so I wanted to change it to /media/ipod. In order to
do this you add rules to one of the .fdi files that HAL looks
at. In this case, I edited /etc/hal/fdi/policy/preferences.fdi
(although you could add a new fdi file and that would work fine)
and added the following after the <deviceinfo version="0.2">
line:

In that case I'm matching on the udi (“unique device
identifier”) which according to the HAL spec is “computed using
bus-specific information and is meant to be unique across device
insertions and independent of the physical port or slot the
device may be plugged into”. However, you can match on any of
the properties in the hierarchy and nest matches, etc. I should
probably make my matching smarter so that it would also match
the iPod when I plug it into a firewire port. The
desired_mount_point option is appropriately named since, of
course, it's only a recommendation from HAL to whatever system
might want to deal with mounting and unmounting the volume.
I've had varying success with the mount_option properties. The
sync option above does seem to be dealt with correctly, but the
iocharset one isn't. It looks highly suspicious, since surely
the key should be “volume.policy.mount_option.iocharset” and the
value of type string, but apparently this is correct (or has
been at some point in the past):

... in at least the current “testing” versions. One useful tip
is that hald's --use-syslog option isn't documented in the
Debian man page, and without it you can't see anything that hald
is up to. (I've submitted a bug about this.) Update: As
the message from hald --help suggests, --use-syslog
only works if you also have --verbose=yes.

So, this all vaguely works for me now. There lots of niggling
problems still that I won't go into, but it's all worth it to
have a little iPod icon pop up on your desktop when you plug it
in ;)

... the other drive with the USB logo is a bog-standard
removable hard disk.

I hope this nightmarish email is of some interest to you. These
documents are also useful on these topics:

Since the only parts of this system that are really fixed by the
kernel are the sysfs interface and the netlink socket, I wonder
how many alternatives people have built replacing each component
in this rather byzantine architecture? For example, it's
certainly possible to conceive of much simpler systems than HAL
that will do the basic things that users like myself want to do
in response to the events from udevd. Equally, if you were
so-inclined you could replace the udevd part with something else
- if anyone knows of any such attempts, I'd be interested to
hear about them.