- Sections
- Misc.
Customising HAL for an MPeye mp3player
I got my daughter an MP3 player for her birthday. It is an MPeye HTS550 which is also marketed as the HTS150. The player is very nice. It has a 5GB hard drive, it plays ogg as well as mp3 files. It has a built in FM tuner, and can record from a microphone or line in. In short it works exactly as described by the manufacturer and I would have no hesitation in recommending it to Linux users wanting to buy an MP3 player.I got it from mp3players.co.uk , but readers in the US and Asia might be shocked to see how much we have to pay for these things in Europe.
One feature that makes this player particularly suitable for Linux is the fact that it does not need any host based software. Just plug in the USB cable. Press the button on the player to make it go into USB mode, and Linux will detect the device as usb-storage and make it available as a hard drive partition. Files may then be transferred to and from the player with any file manager. There is Windows software provided with the MPeye HTS550, but it is only a simple playlist editor. The HTS550 supports m3u playlists which I found can be exported from the Linux application amarok quite successfully making the MPeye software unneccessary.
Mandriva 2005LE with MPeye HTS550
Mandriva 2005LE supports the new Hardware Abstraction Layer system. The objective of HAL is to quote the project home page "Making Hardware Just Work". The idea is that it should be possible to just plug in a device like the HTS550 and it should be recognised and automatically configured.
I was pleasantly surprised to find that it worked almost perfectly. On plugging the MPeye HTS550 into the USB port it was immediately recognised as a usb-storage device, and was mounted as /dev/sda on /mnt/removable, and an icon appeared on my KDE desktop. Clicking on the icon opened up konqueror file manager, and I could drag and drop files on or off the mp3player. Nothing could be easier!!
However I did find one little niggle. I found that if I were to delete a file on the mp3player, and then disconnect the player, the deleted file was still present. I immediately recognised what was happening because this is the sort of thing that would get newbies totally confused when they tried to copy files to floppy discs in Linux and then found the files were not copied after all. The issue is that in Linux spare memory is used as a disc cache and is only written out when memory is full or is forced to be written by a 'sync' command.
The solution to this problem is to unmount the device before disconnecting it, or to issue a 'sync command.
So a suitable entry for the MPeye HTS550 in /etc/fstab might look like this :-
/dev/sda /mnt/removable vfat noatime,noauto,utf8 0 0
In a Linux distribution without HAL creating this line is all that is required to make the HTS550 work. However in Mandriva 2005LE and any other distro with HAL there is no point editing /etc/fstab because HAL creates the fstab entry itself automatically, and will delete it again when the device is removed. Instead it is necessary to customise HAL to write the fstab file the way we want it.
Customising HAL
Now I am no expert on HAL, but in the course of researching this issue I learned a few things about HAL's operation.
Note: A useful description of hotplugging and HAL has been produced by Mandriva
The HAL daemon will recognise when a device has been added and will load the appropriate module. The HAL daemon will then attempt to configure the device using a series of configuration files found in the location /usr/share/hal/fdi
When the HAL daemon is invoked it will parse these folders in numerical order, and will parse the files inside them in alphabetical order. The files themselves are in XML format. Once all the files have been parsed HAL will construct the required configuration for the device detected and will perform the configuration. HAL will create the fstab entry for the device by invoking the utility fstab-sync. See 'man fstab-sync' for details of its operation.
The user should not edit any of the files in /usr/share/hal/fdi/ other than in /usr/share/hal/fdi/95userpolicy because an upgrade in the distro could overwrite the other files. The user is able to add files to 95userpolicy to configure any device, and because this folder is processed last the user is able to override any configuration in the other files. The name of the user defined files is not important so long as it ends in the suffix '.fdi'. Just remember the files are parsed in alphabetical order. I chose to create a file called mpeye_hts550.fdi for my customised configuration.
Well now we know what file to edit what should we put in it? A look at the default file /usr/share/hal/fdi/90defaultpolicy.fdi/storage-policy.fdi reveals the format to us. Here are the parts of the file that would apply to a device such as the MPeye HTS550.
<?xml version="1.0" encoding="ISO-8859-1"?> <!-- -*- SGML -*- -->
<deviceinfo version="0.2">
<!-- Default policies merged onto computer root object -->
<device>
<match key="info.udi" string="/org/freedesktop/Hal/devices/computer">
<merge key="storage.policy.default.mount_root" type="string">/mnt</merge>
<merge key="storage.policy.default.use_managed_keyword" type="bool">true</merge>
<merge key="storage.policy.default.managed_keyword.primary" type="string">managed</merge>
<merge key="storage.policy.default.managed_keyword.secondary" type="string">kudzu</merge>
<merge key="storage.policy.default.mount_option.noauto" type="bool">true</merge>
<merge key="storage.policy.default.mount_option.pamconsole" type="bool">true</merge>
<merge key="storage.policy.default.mount_option.exec" type="bool">true</merge>
</match>
</device>
<device>
<!-- Whitelist bus types of storage devices we care about -->
<match key="info.category" string="storage">
<match key="storage.bus" string="usb">
<merge key="storage.policy.should_mount" type="bool">true</merge>
</match>
<match key="storage.bus" string="ide">
<merge key="storage.policy.should_mount" type="bool">true</merge>
</match>
<match key="storage.bus" string="ieee1394">
<merge key="storage.policy.should_mount" type="bool">true</merge>
</match>
<match key="storage.bus" string="sata">
<merge key="storage.policy.should_mount" type="bool">true</merge>
</match>
<match key="storage.bus" string="platform">
<merge key="storage.policy.should_mount" type="bool">true</merge>
</match>
</match>
<!-- Normal volumes; use volume label, uuid or drive_type -->
<match key="block.is_volume" bool="true">
<match key="volume.fsusage" string="filesystem">
<!-- skip for drives with the no partitions hint (they are handled above) -->
<match key="@block.storage_device:storage.no_partitions_hint" bool="false">
<merge key="volume.policy.should_mount" type="bool">true</merge>
<merge key="volume.policy.mount_filesystem" type="copy_property">volume.fstype</merge>
<!-- Fallback is '<storage.bus>', appended with 'disk', e.g. usbdisk,
idedisk, scsidisk etc. -->
<!--
<merge key="volume.policy.desired_mount_point" type="copy_property">@block.storage_device:storage.bus</merge>
<append key="volume.policy.desired_mount_point" type="string">disk</append>
-->
<merge key="volume.policy.desired_mount_point" type="string">removable</merge>
<!-- Best: If available use filesystem label -->
<match key="volume.label" empty="false">
<!-- unless it's a path (e.g. /boot, /, /home etc) -->
<match key="volume.label" is_absolute_path="false">
<!-- and only if the label is ascii -->
<match key="volume.label" is_ascii="true">
<merge key="volume.policy.desired_mount_point" type="copy_property">volume.label</merge>
</match>
</match>
</match>
<!-- Use noatime and sync options for all hotpluggable or removable
volumes smaller than 2GB -->
<match key="volume.size" compare_lt="2147483648">
<match key="@block.storage_device:storage.hotpluggable" bool="true">
<merge key="volume.policy.mount_option.sync" type="bool">true</merge>
<merge key="volume.policy.mount_option.noatime" type="bool">true</merge>
</match>
<match key="@block.storage_device:storage.removable" bool="true">
<merge key="volume.policy.mount_option.sync" type="bool">true</merge>
<merge key="volume.policy.mount_option.noatime" type="bool">true</merge>
</match>
</match>
<!-- Use UTF-8 charset for vfat -->
<!--
<match key="volume.fstype" string="vfat">
<merge key="volume.policy.mount_option.iocharset=utf8" type="bool">true</merge>
</match>-->
</match>
</match>
</match>
</match>
</device>
</deviceinfo>
Looking at this code we can quickly see how our device will be configured as default.
- All devices will have their 'noauto', 'pamconsole', and 'exec' options set in their fstab entries. - see 'man mount for a description of the options
- The device is usb-storage, so it will be automatically mounted
- It is a storage device so the mount point is set to /mnt/removable
- The HTS550 has a capacity greater than 2GB so the 'noatime' option is not set
So all we need to do is create a file to add the noatime options. I used the example files at /use/share/doc/hal-x.x.x as an example to come up with the file /usr/share/hal/fdi/95userpolicy/mpeye_hts550.fdi containing the text :-
<?xml version="1.0" encoding="ISO-8859-1"?> <!-- -*- SGML -*- -->
<deviceinfo version="0.2">
<!-- Match a volume from an MPeye HTS550 USB Storage Based mp3 player
by the file system UUID and assign a mount point.
NB: When reformatting the volume a new UUID will be
used and this rule will have to be altered -->
<device>
<match key="block.is_volume" bool="true">
<match key="volume.fsusage" string="filesystem">
<match key="volume.uuid" string="0C15-8CCD">
<merge key="volume.policy.desired_mount_point" type="string">mp3player</merge>
<merge key="volume.policy.mount_option.noatime" type="bool">true</merge>
</match>
</match>
</match>
</device>
</deviceinfo>
Here I have used the File system UUID number from the MPeye player so this rule will only apply to that specific device. I got the UUID number by installing the hal-gnome package and then running hal-device-manager in a terminal to pull up a GUI showing all the hardware devices managed by HAL. Select the MPeye player and select the 'Advanced' tab and the UUID number can be discovered. In my case it was 0C15-8CCD I do not know if is the same for all MPeye HTS550 players or not. If anyone tries this out perhaps they could let me know.
In my file I have added noatime option, and I have also changed the mount point to '/mnt/mp3player'. There is no need to create the mount point folder manually. HAL will do that for you when it creates the device, and will remove it again when the device is removed.
Wednesday 29th June 2005

