Digital cameras, libusb, permissions, hal, and other annoyances

At some point in the near past, I stopped being able to access my Canon PowerShot S30 (yeah, it’s an old non-PTP camera) as any user other than root. I poked around at the hotplug rules, and everything seemed ok. The device file in /proc/bus/usb was getting correct permissions, but still no good. I even tried setting permissions to rwxrwxrwx, and changing ownership to brian:brian, but still no luck.

So I googled, and googled, and googled. After reading through about 25 Gentoo forum posts, I came upon one thread with a post (at the bottom of page 1) that suggested something different: export USB_DEVFS_PATH=/proc/bus/usb. I thought that seemed somewhat redundant, but tried it anyway, and it worked. So, I thought, if /proc/bus/usb is no longer the default, what is? So I unset the env var, and ran gphoto2 through strace. I saw a bunch of attempts to open files in /dev/bus/usb. Wait… /dev? Sure enough, the device files in /proc/bus/usb are now duplicated as character devices in /dev/bus/usb, and of course the permissions weren’t set properly there.

So I grepped through /etc/udev/rules.d for anything related to usb, and found the rule that was creating the entries in /dev/bus/usb. I modified it to set some of the stuff to 0664, with group plugdev owning (this group is specific to Gentoo). The final line, which goes in /etc/udev/rules.d/10-local.rules, looks like this:

SUBSYSTEM=="usb_device", DRIVER!="usbhid", DRIVER!="hub", DRIVER!="hci_usb", PROGRAM="/bin/sh -c 'K=%k; K=$${K#usbdev}; printf bus/usb/%%03i/%%03i $${K%%%%.*} $${K#*.}'", NAME="%c", GROUP="plugdev", MODE="0664"

The “DRIVER!=” bits are so it doesn’t set the group and permissions on things like my mouse, keyboard, the USB hub itself, and Bluetooth. Since those “DRIVER!=” bits make that particular rule not match, udev will continue on until it hits the default rule in 50-udev.rules which will set it up for those devices.

Whew. Unplug the camera, plug it back in, and now gphoto2 works as my normal user.

Next I thought it would be cool if Benny’s new Thunar volume manager would launch gtkam when I plug in the camera. So I enabled the option in the volume manager to launch something on camera connection, typed “gtkam” in the box, and plugged my camera in. Nothing. sigh

So, I know all of this uses HAL, so I opened up hal-device-manager to have a look. I found my camera in the tree, and, of course, there aren’t any property strings in the device nodes that actually identify it as a camera. Great. Clearly, thunar-volman isn’t going to know it’s a camera if HAL doesn’t identify it as such. But, I remembered a page out of the gphoto2 documentation that mentioned something about HAL. As it turns out, HAL ships with a .fdi file that identifies all PTP-type cameras properly (apparently they share common system, subsystem, class, etc. ids), but doesn’t identify any older cameras such as mine. Fortunately, it told me what to do. First, run /usr/lib/libgphoto2/print-camera-list hal-fdi >90-camera-libgphoto2.fdi to generate a .fdi file. Then, move it to /usr/share/hal/fdi/information/90local/. Sweet. I unplug and replug my camera, and thunar-volman starts up gtkam. Finally.

Meh. So why was this so difficult? How come no one noticed that libusb changed its default device path to stuff under /dev/ instead of /proc/? I know this hasn’t been working for months and months.

Anyway, it’s done, and instead of going to bed more or less right when I got home, it’s now 2am. Brilliant.

(On a side note, yeah, I know I haven’t posted much in the past month. For those brave few of you who care, I’ll get back to that soon.)