The term HAL is overloaded as it used to refer both to a specification and the actual software which implements the specification. From an application developers viewpoint, HAL is way to enumerate the capabilities and features of hardware attached to a system and receive notification when something about the hardware changes.
First, a very quick overview of HAL. Each item of physical hardware in a computer is regarded as being an device object which identified by a Unique Device Identifier (UDI). Associated with each device object is a variable set of well-defined typed key-value pairs (or metadata) called device properties which describe what each device object represents together with its properties. Some device properties are derived from the actual physical hardware, some are merged from XML-formatted files, known as Device Information Files, and some are derived from the actual device configuration. Mandatory device properties are defined in the HAL specification.
A HAL daemon is used to maintain and update the list of device objects forming a hardware configuration and is notified when devices are added or removed. HAL also provides callbacks so that the operating system and applications can react to hardware configuration changes in order to maintain system policy. An example of such a callback and policy is when you plug in a USB memory stick HAL automatically creates a mount point and mounts the device.
For a good backgrounder on HAL, see this article Making Hardware Just Work by Havoc Pennington. For more detailed information, you should read the HAL Specification and the HAL project page at freedesktop.org.
A number of command line utilities are provided for accessing and manipulating device objects.
hal-disable-polling | disable polling on drives with removable media |
hal-find-by-capability | find device objects by capability matching |
hal-find-by-property | find device objects by property matching |
hal-get-property | get a property from a device object |
hal-is-caller-locked-out | determine if caller is locked out |
hal-is-caller-privileged | determine if caller is privileged |
hal-lock | lock an interface |
hal-set-property | set a property on a device object |
lshal | list devices objects and properties |
For the purposes of this post, we are only interested in a small number of the above utilities, i.e. those utilities which locate and return information about device objects.
Here is a simple use of the hal-find-by-property utility to retrieve a list of network interfaces.
$ hal-find-by-property --key linux.subsystem --string net
/org/freedesktop/Hal/devices/net_3a_67_56_92_fb_73
/org/freedesktop/Hal/devices/net_computer_loopback
/org/freedesktop/Hal/devices/net_00_1c_c0_6d_8a_f7
udi=$(hal-find-by-property --key info.product --string Computer)
printf "Board Manufacturer: $(hal-get-property --udi $udi --key system.board.vendor)\n"
printf " Model: $(hal-get-property --udi $udi --key system.board.product)\n"
printf " Version: $(hal-get-property --udi $udi --key system.board.version)\n"
printf " Serial No.: $(hal-get-property --udi $udi --key system.board.serial)\n"
printf " Release Date: $(hal-get-property --udi $udi --key system.firmware.release_date)\n"
printf " Bios Version: $(hal-get-property --udi $udi --key system.firmware.version)\n"
printf " Motherboard UUID: $(hal-get-property --udi $udi --key system.hardware.uuid)\n"
Board Manufacturer: Intel Corporation
Model: DX48BT2
Version: AAE26191-205
Serial No.: BQBQ8280004G
Release Date: 08/07/2008
Bios Version: BTX3810J.86A.1814.2008.0807.2334
Motherboard UUID: 2237F666-4F75-11DD-894F-0007E9747DB3
for udi in $(/usr/bin/hal-find-by-capability --capability volume)
do
mount=$(hal-get-property --udi $udi --key volume.mount_point)
device=$(hal-get-property --udi $udi --key block.device)
label=$(hal-get-property --udi $udi --key volume.label)
fstype=$(hal-get-property --udi $udi --key volume.fstype)
echo "$device $mount $fstype $label"
done
/dev/sda1 /boot ext3 /boot
/dev/sdb2 /abac ext3 /abac
/dev/sdb1 /home/fpm ext3 fpm
/dev/sda2 LVM2_member
/dev/sdc1 LVM2_member
/dev/sdc2 LVM2_member
for i in $(hal-find-by-property --key storage.drive_type --string cdrom)
do
printf "Manufacturer: $(hal-get-property --udi $i --key storage.vendor)\n"
printf " Model: $(hal-get-property --udi $i --key block.device)\n"
printf " Bus: $(hal-get-property --udi $i --key storage.model)\n"
printf " Path: $(hal-get-property --udi $i --key storage.bus)\n"
done
Manufacturer: HP
Model: /dev/sr0
Bus: DVD Writer 1070d
Path: pci
for udi in $(/usr/bin/hal-find-by-capability --capability storage.cdrom)
do
device=$(hal-get-property --udi $udi --key block.device)
vendor=$(hal-get-property --udi $udi --key storage.vendor)
model=$(hal-get-property --udi $udi --key storage.model)
if [[ $(hal-get-property --udi $udi --key storage.removable.media_available) = true ]]
then
parent_udi=$(hal-find-by-property --key block.storage_device --string $udi)
mount=$(hal-get-property --udi $parent_udi --key volume.mount_point)
label=$(hal-get-property --udi $parent_udi --key volume.label)
fi
printf "$vendor $model $device $mount $label\n"
done
$ ./findodrive
HP DVD Writer 1070d /dev/sr0 /media/Kota_Kinabalu1 Kota_Kinabalu1
$ ./findodrive
HP DVD Writer 1070d /dev/sr0
#!/bin/ksh93
#
# list attached USB storage devices
#
for udi in $(/usr/bin/hal-find-by-capability --capability storage)
do
device=$(hal-get-property --udi $udi --key block.device)
vendor=$(hal-get-property --udi $udi --key storage.vendor)
model=$(hal-get-property --udi $udi --key storage.model)
if [[ $(hal-get-property --udi $udi --key storage.bus) = "usb" ]]
then
parent_udi=$(hal-find-by-property --key block.storage_device --string $udi)
mount=$(hal-get-property --udi $parent_udi --key volume.mount_point)
label=$(hal-get-property --udi $parent_udi --key volume.label)
media_size=$(hal-get-property --udi $udi --key storage.removable.media_size)
size=$(( ceil(media_size/(1000*1000*1000)) ))
printf "$vendor $model $device $mount $label "${size}GB" \n"
fi
done
./listusb
Kingston DataTraveler 2.0 /dev/sdd /media/KINGSTON KINGSTON 1GB
Kingston DataTraveler 2.0 /dev/sdc /media/USB-4GB USB-4GB 4GB
$
Remember, however, that the HAL specification and it's implementation in GNU/Linux distributions is still somewhat in a state of flux. The above examples worked on Fedora 10 as of the date of this post. If an example does not work on your system, I recommend that you first check the output from the lshal utility to see if the device object and associated device properties are instantiated on your system. You can use udevadm --monitor to see what kernel events are being pushed out to user space. HAL monitors these events. You can also use lshal --monitor to see what events HAL emits to user space.