Ejecting the mobile phone

Okay, yesterday was my birthday, nothing to say about that as XMMS was removed already. Thanks to a friend of mine (Alberto), I gone shopping in the afternoon… strange but true, I also found the nullmodem cable!

What I was going to buy was a TransFlash/MicroSD memory card for my cell phone, so that I could use it as an mp3 player for those rare cases where I’d like to listen to music without a PC around.

The card works fine on the phone, and it all seems well, till I tried copying some music to it.. some of the music ended up fine, but most was lost, and the vfat corrupted (so much to require me to install dosfstools to run a dosfsck).

After some tries, I found the problem in a non-flushed buffer: when KDE was unmounting the device, it was calling “eject /dev/sdc1”, unfortunately unieject wasn’t smart enough to actually work on /dev/sdc, to the result that the device wasn’t being ejected at all.

I so decided to improve unieject so that it could take care of finding if the device it was asked to eject was a partition or an actual block device, and if it was a partition, to find its parent’s block device.

Easy you’d say, just use the final name of the device.. but no, udev allows you to change the names of the devices, so I ended up looking for the major/minor device numbers of the open device. But that just tells me if it’s a device or a partition, how do I find the device for a given partition?

I originally implemented it as an hack, by removing the digits at the end of the device name, and probing that for being the root device of a given partition, but of course it wouldn’t help if the devices were all renamed.

The best implementation I could think of used sysfs, and thus works only on Linux 2.6 (after all on 2.4 you expect the devices to have a sane naming scheme at least), but I admit myself it’s slow. It iterates over the content of /sys/block/*/dev and looks for a device with the correct major/minor devices.

The other problem was finding all the partitions for a given device; I couldn’t base myself over using the name here either, so I took all the directories in /sys/block/$namefoundbefore/ and removed the ones that are sysfs-related, and then hoped they were directly in /dev to find and unmount them. The solution might not be perfect, it might not cover all the possible cases for strange names of the devices, but it should cover most of it and thus allow a decent use of unieject.

Now I have this feeling that if I asked to someone in the known how I’m supposed to find the devices and the partitions, the answer would be “use HAL”.. and no I’m not interested in using HAL in a eject command! Why should I, in the first place, need HAL to look up simple data that would have been trivial to find with a stable naming scheme?

I also hoped that libsysfs would have helped me, but a part being one of the libraries where the documentation can be summarised with the following code:

int strange_var; // A strange variable

it also does not seem to allow for much more than looking up entries knowing their path already without using fopen to inspect the content.

Unfortunately even after fixing unieject to correctly unmount the partitions and eject the correct version, ejecting the mobile takes a lot of time to flush the buffers, and I’ve seen it losing data when loading too much data in a short time, and then ejecting. I wonder if there’s a way to tweak the size of the buffers on a per-device basis.

Off topic, last night I downloaded my nephew’s photos using DigiKam directly from my sister’s digital camera.. I think the current experience with gphoto2-based programs on Gentoo leave to desire, as it didn’t set the permissions on the USB device automatically (of course, I didn’t configure anything, but the point is that stuff shouldn’t require to be configured at all, many things already work this way).