« NOTHING TO REPORT HERE, MOVE ALONG | Main | I HEART MTSEND.PY »

November 13, 2005

A CASE STUDY IN FREEBSD USABILITY

Since I got tired of having to use my Windows box to remove photos from a digital camera for my photo album (which, by the way, is now working properly, or at least well enough that I don't fear the hand of God coming down and righteously smiting me for removing the "experimental!" warning), and even more tired of SCPing them across, I decided to try and get FreeBSD to recognise a digital camera. Lest you should think that this is some ignorant, biased rant by a cluebie, I've been using FreeBSD for three years now and Linux GNU/Linux for about five. And it's not like Windows is necessarily any better, as I will demonstrate by these instructions:

  1. Attach the camera to your PC, thusly:

    plug the damned thing in

  2. Wait two seconds for this dialog box:

    camera attach dialog

  3. Click OK.
  4. Copy your images to your disk.
  5. Unplug your camera.

So now, for making it "work" in FreeBSD.

1. FART AROUND A BIT

First, create a directory you want to mount the camera to.

# mkdir /mnt/cam

Now, you might think that you'd have to make this user-owned in order to read/write to it (i.e. delete photos) without being root. That's what I thought, too, since that's how other permission-free filesystems work, and the FreeBSD mount_msdosfs(8) manual would seem to agree with that:

The default owner is the owner of the directory on which the file system is being mounted.

Except, hurrah! It doesn't work like that at all. Since we'll be mounting the camera's pictures as an MS-DOS file system, we'll have to find our numerical userid and pass it as an argument to mount_msdosfs(8) (since, inexplicably, it can't take a named user, only a numeric user ID). So:

# grep you /etc/passwd
you:*:1001:1001:Lewis Collard:/home/you:/bin/zsh

You write down or remember the third field, because you'll need it.

Next, you edit your /boot/loader.conf so that the USB storage driver is loaded automatically on boot, by adding this at the end:

umass_load="YES"

2. FART AROUND SOME MORE

Next, you need to edit your /etc/usbd.conf, realise you have no idea of what you're doing, study the usbd.conf(5) man page, and put something like the following in:

device "Olympus digital camera"
       devname "umass0"
       attach "sleep 4; /sbin/mount_msdosfs -m 644 -u 1001 /dev/da0s1 /mnt/cam"
       detach "umount /mnt/cam"

The "sleep 4" is necessary because, as we will otherwise find out the hard way, usbd will sometimes notice the device before /dev/da0s1 is created and be unable to mount it. (And yeah, it is curious that da0s1 is actually the name of a SCSI device, not, say, "umass0", a USB mass storage device. But I digress.)

Except, of course, if you want any other mass-storage devices mounted at the same time, you'll have to specify a vendor ID, product ID, and release ID so that usbd will be able to recognise that specifically. You'd think you'd be able to do that with usbdevs(8), right? Hah. No hexadecimal release ID there. So, instead, stop usbd, and restart it in debugging mode:

# killall usbd
# usbd -dvv   
[ tons of crap deleted ]

Then plug in your camera and look for something like this:

usbd: device-attach event at 1131867261.356505000, u-miniS,StylusVS, OLYMPUS:
  vndr=0x07b4 prdct=0x0118 rlse=0x0100 clss=0x0000 subclss=0x0000 prtcl=0x0000
  device names: umass0

"vndr", "prdct", "rlse" (what do these people have against vowels??) are your vendor, product, and release IDs. So back to our usbd.conf:

device "Olympus digital camera"
       vendor 0x07b4
       product 0x0118
       release 0x0100
       attach "sleep 4; /sbin/mount_msdosfs -m 644 -u 1001 /dev/da0s1 /mnt/cam"
       detach "umount /mnt/cam"

3. FART AROUND A LITTLE MORE

Now, restart usbd:

killall -HUP usbd

Uh, except you're not sure that will work, since the usbd manual does not say that receiving a SIGHUP will restart it. It might do, if every other Unix daemon every written is any guide. But you're not sure. So to make certain:

# killall usbd
# usbd

Now, plug your camera in, and wait for five seconds or so. Cross your fingers, pray, offer the computer a sacrifice or two, then see if your camera has mounted:

# ls /mnt/cam
dcim

Hurrah! Doesn't that make you smile? Just to be certain, you unplug your camera, plug it back in, wait for five seconds, then:

# ls /mnt/cam
# 

Well, that's not right, is it? Well, maybe that was a technical fault, so we'll try that again. Unplug the camera, wait five seconds, and, behold!

black screen of death

That's right, the operating system which regularly gets four and five year uptimes, well, it crashes trying to deal with a USB camera. That, as Unix people say, is "utterly crap and useless".

4. CRY, THEN DO SOME MORE FARTING AROUND

On the plus side, your computer just rebooted itself, so you don't need to worry about hitting the reset button or anything. Wait for FreeBSD to boot up again, and let it perform its file system checks. Obviously, you want to check /etc/usbd.conf to see if you've done something really stupid, so:

# cat /etc/usbd.conf
#

Oops. It looks like your system crashed at a bad time, because usbd.conf was being kept around in cache and wasn't written to disk. So you re-create /etc/usbd.conf (including reading a hundred man pages to remind you of exactly what you did the first time around). So, we start flushing our disk caches religiously:

# sync

Now, kill usbd and start it in the foreground again:

# killall usbd
# usbd -dvv   

Plug in your camera, and all seems to go swimmingly as before. So, you unplug it, plug it back in, and see

da0s1: Device not configured

What the bollocks does that mean? If you'd never programmed (and hence, have never had any need to look around section 2 and 3 of the Unix man pages), you'll be disheartened, and this error message might as well read:

da0s1: Something went wrong

or some other "no shit, Sherlock" truism. But we're smarter than that, so we check the man page for these things,

man errno

and scroll down to:

6 ENXIO      Device not configured.  Input or output on a special file
             referred to a device that did not exist, or made a request
             beyond the limits of the device. This error may also occur
             when, for example, a tape drive is not online or no disk  
             pack is loaded on a drive.

Uh, yeah, thanks. In desperation, you check the umass(4), da(4), usb(4), helpmeorillcommitsuicide(7), etc man pages, and the case is the same: you still have no idea of what this means in this particular instance.

Resigned to fate, you unplug your camera, and then, knowing what will happen, and yet knowing you have to do it to fulfill your purpose on earth or somesuch....you plug the camera in.

blank screen

And all of a sudden, SCPing files across from a Windows box doesn't seem so bad, does it?

5. GIVE UP

Well, you don't have to give up at this stage. You can, in fact, manually mount and unmount the camera each time you want to use it. But really, you shouldn't have to do that. With all the hassle I have had, the mere mention of "FreeBSD" and "USB storage device" in the same sentence is enough to make me curl up in the fetal position in a corner of my room. And on that note, I'll be right back.

Anyway, this is not some "Aunt Tillie"-type problem, as Eric Raymond puts it. It is a "Lewis Collard, who has been using various flavours of Unix for five years, isn't in the least bit averse to hand-editing config files, doesn't mind reading a hundred man pages in order to work out how to do something that, in Windows, would require one to click OK a couple of times"-type problem. And this is not me trying to put myself in the shoes of the AverageHomeUser™, it is me trying with all my meagre intellectual might to make it work. If it takes me close to an hour to have a simple USB storage device automatically mounted when it is plugged in, there is no way in Hades that someone would be able to come from a Windows environment and do the same. And best of all, even if they did, they could only plug it in once without rebooting. If they did it three times their computer crash.

So yeah, reliability my ass. Yes, I know what probably caused the problem, which was the camera not being properly unmounted before trying to remount it (when the "detach" command in usbd was invoked, the device was physically detached, which made it impossible to unmount). Thing is, that doesn't map on to the way things are in the real world. If your kernel can't unmount a USB device which has been unplugged, well, you can talk as much as you like about how theoretically reliable FreeBSD is. But if that isn't precisely how reliable it is doing normal, every-day tasks then the "theoretical" reliability is worth precisely quarter of a damn.

Sigh. Someone buy me a Mac. :/

Posted by Lewis at November 13, 2005 09:42 AM

Come now, and let us reason together: though your sins be as scarlet, they shall be as white as snow; though they be red like crimson, they shall be as wool. -- God (Isaiah 1:18)