Shallow Thoughts : tags : udev

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Wed, 18 Apr 2012

Mounting a Samsung Galaxy Player on Linux

My new toy: a Samsung Galaxy Player 5.0!

So far I love it. It's everything my old Archos 5 wanted to be when it grew up, except the Archos never grew up. It's the same size, a little lighter weight, reliable hardware (no random reboots), great battery life, fast GPS, modern Android 2.3, and the camera is even not too bad (though it certainly wouldn't tempt me away from my Canon).

For the record, Dave got a Galaxy Player 4.0, and it's very nifty too, and choosing between them was a tough choice -- the 4-inch is light and so easy to hold, and it uses replaceable batteries, while the 5-inch's screen is better for reading and maps.

USB-storage devices don't register

I love the Galaxy ... but there's one thing that bugs me about it. When I plug it in to Linux, dmesg reports two new storage devices, one for main storage and one for the SD card. Just like most Android devices, so far.

The difference is that these Samsung devices aren't fully there. They don't show up in /proc/partitions or in /dev/disk/by-uuid, dmesg doesn't show sizes for them, and, most important, they can't be mounted by UUID from an fstab entry, like

UUID=62B0-C667   /droidsd    vfat   user,noauto,exec,fmask=111,shortname=lower 0 0
That meant I couldn't mount it as myself -- I had to become root, figure out where it happened to show up this time (/dev/sdf or wherever, depending on what else might be plugged in), mount it, then do all my file transfers as root.

I found that if I mounted it explicitly using the device pathname -- mount /dev/sdf /mnt -- then subsequently the device shows up normally, even after I unmount it. So I could check dmesg to find the device name, mount it as root, unmount as root, then mount it again as myself using my fstab entry. What a pain!

A kernel expert I asked thought it looked like the Samsung is pretending to be a removable device, but only "plugging in" when the system actually tries to access it. Annoying. So how do you get Linux to "access" it?

Udev: still an exercise in frustration

The obvious solution is a udev rule. Some scrutiny of /lib/udev/rules.d/60-persistent-storage.rules found some rules that did this intriguing thing: IMPORT{program}="ata_id --export $tempnode".

Naturally, this mysterious ata_id is undocumented. It's hidden in /lib/udev/ata_id, and I found this tiny ata_id man page online since there's none available in Ubuntu. Running ata_id /dev/sdf seemed to do what I needed: it made the device show up in /proc/partitions and /dev/disk/by-uuid, and after that, I could mount it without being root.

I created a file named /etc/udev/rules.d/59-galaxy.rules, with the rule:

KERNEL=="sd[b-g]", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04e8", SYMLINK+="galaxy-%k-%n", IMPORT{program}="ata_id --export $tempnode"

When I tested it with udevadm test /block/sdf, not only did the rule trigger correctly, but it actually ran ata_id and the device became visible -- even though udevadm test states clearly no programs will be run. How do I love udev -- let me count the ways.

But a reboot revealed that udev was not actually running the rule when I actually plugged the Galaxy in -- the devices did not become visible. Did I mention how much I love udev?

Much simpler: a shell alias

But one thing I'd noticed in all this: side by side with /dev/disk/by-uuid is a directory called /dev/disk/by-id. And the Samsung devices did show up there, with names like usb-Android_UMS_Composite_c197022a2b41c1ae-0:0.

Faced with the prospect of spending the rest of the day trying random udev rules, rebooting each time since that's the only way to test udev, I decided to cheat and find another way. I made a shell alias:

alias galaxy='sudo sh -c "for d in /dev/disk/by-id/usb-Android*; do /lib/udev/ata_id --export \$d; done"'

Typing galaxy will now cause the Samsung to register both devices; and from then on I can mount and unmount them without needing root, using my normal fstab entries.

Update: This works for the Nook's main storage, too -- just add x/dev/disk/by-id/usb-B_N_Ebook_Disk* to the list -- but it doesn't work reliably for the Nook's SD card. The SD card does show up in /dev/disk/by-id along with main storage; but running ata_id on it doesn't make its UUID appear. I may just change my fstab entry to refer to the /dev/disk/by-id device directly.

Tags: , ,
[ 13:43 Apr 18, 2012    More linux/kernel | permalink to this entry | ]

Wed, 20 Apr 2011

Making static devices in UDEV

(or: Fixing a multi flash card reader on Ubuntu Natty)

For the first time after installing Ubuntu Natty, I needed to upload some photos from my camera -- and realized with a sinking feeling that I now had the new UDEV, which no longer lets you use the udev all_partitions directive, so that cards inserted into a multi flash card reader will show up as /dev/sdb1 or whatever the appropriate device name is.

Without all_partitions, you get the initial sdb, sdc, sdd and sde for the various slots in the card reader, but since there's no card there when the machine boots, and the reader doesn't send an event when you insert a card later, you never get a mountable /dev/sdb1 device.

But the udev developers in their infinite wisdom removed all_partitions some time last year, apparently without providing any replacement for it. So you can no longer solve this problem through udev rules.

Static udev devices

Fortunately, there's another way, which is actually easier (though less flexible) than udev rules: udev static devices. You can create the devices you need once, and tell udev to create exactly those devices every time.

To begin, first find out what your base devices are. Look through dmesg | more for your card reader. Mine looks something like this:

[    3.304938] scsi 4:0:0:0: Direct-Access     Generic  USB SD Reader    1.00 PQ
: 0 ANSI: 0
[    3.305440] scsi 4:0:0:1: Direct-Access     Generic  USB CF Reader    1.01 PQ
: 0 ANSI: 0
[    3.305939] scsi 4:0:0:2: Direct-Access     Generic  USB xD/SM Reader 1.02 PQ
: 0 ANSI: 0
[    3.306438] scsi 4:0:0:3: Direct-Access     Generic  USB MS Reader    1.03 PQ
: 0 ANSI: 0
[    3.306876] sd 4:0:0:0: Attached scsi generic sg1 type 0
[    3.307020] sd 4:0:0:1: Attached scsi generic sg2 type 0
[    3.307165] sd 4:0:0:2: Attached scsi generic sg3 type 0
[    3.307293] sd 4:0:0:3: Attached scsi generic sg4 type 0
[    3.313181] sd 4:0:0:1: [sdc] Attached SCSI removable disk
[    3.313806] sd 4:0:0:0: [sdb] Attached SCSI removable disk
[    3.314430] sd 4:0:0:2: [sdd] Attached SCSI removable disk
[    3.315055] sd 4:0:0:3: [sde] Attached SCSI removable disk

Notice that the SD reader is scsi 4:0:0:0, and a few lines later, 4:0:0:0 is mapped to sdb. They're out of order, so make sure you match those scsi numbers. If I want to read SD cards, /dev/sdb is where to look.

(Note: sd in "sdb" stands for "SCSI disk", while SD in "SD card" stands for "Secure Digital". Two completely different meanings for the same abbreviation -- just an unfortunate coincidence to make this all extra confusing.)

To create static devices, I'll need the major and minor device numbers for the devices I want to create. Since I know the SD card slot is sdb, I can get those with ls:

$ ls -l /dev/sdb
brw-rw---- 1 root disk 8, 16 2011-04-20 09:43 /dev/sdb
The b at the beginning of the line tells me it's a block device; the major and minor device numbers for the base SD card device are 8 and 16. To get the first partition on that card, use the same major device and add one to the minor device: 8 and 17.

Now you can create new static block devices, as root, using mknod in the /lib/udev/devices directory:

$ sudo mknod /lib/udev/devices/sdb1 b 8 17
$ sudo mknod /lib/udev/devices/sdb2 b 8 18
$ sudo mknod /lib/udev/devices/sdb3 b 8 19

Update: Previously I had here
$ sudo mknod b 8 17 /lib/udev/devices/sdb1
but the syntax seems to have changed as of mid-2012.

Although my camera only uses one partition, sdb1, I created devices for a couple of extra partitions because I sometimes partition cards that way. If you only use flash cards for cameras and MP3 players, you may not need anything beyond sdb1.

You can make devices for the other slots in the card reader the same way. The memory stick reader showed up as scsi 4:0:0:3 or sde, and /dev/sde has device numbers 8, 64 ... so to read the memory stick from Dave's Sony camera, I'd need:

$ sudo mknod /lib/udev/devices/sde1 b 8 65

You don't have to call the devices sdb1, either. You can call them sdcard1 or whatever you like. However, the base device will still be named sdb (unless you write a udev rule to change that).

fstab entry

I like to use fstab entries and keep control over what's mounted, rather than letting the system automatically mount everything it sees. I can do that with this entry in /etc/fstab:

/dev/sdb1 /sdcard vfat user,noauto,exec,fmask=111,shortname=lower 0 0
plus sudo mkdir /sdcard.

Now, whenever I insert an SD card and want to mount it, I type mount /sdcard as myself. There's no need for sudo because of the user directive.

Tags: , ,
[ 20:22 Apr 20, 2011    More linux | permalink to this entry | ]

Sun, 09 May 2010

The new udev in Lucid

Ubuntu's latest release, 10.04 "Lucid Lynx", really seems remarkably solid. It boots much faster than any Ubuntu of the past three years, and has some other nice improvements too.

But like every release, they made some pointless random undocumented changes that broke stuff. The most frustrating has been getting my front-panel flash card reader to work under Lucid's new udev, so I could read SD cards from my camera and PDA.

The SD card slot shows up as /dev/sdb, but unless there's a card plugged in at boot time, there's no /dev/sdb1 that you can actually mount.

hal vs udisks

Prior to Lucid, the "approved" way of creating sdb1 was to let hald-addons-storage poll every USB device every so often, to see if anyone has plugged in a card and if so, check its partition table and create appropriate devices.

That's a lot of polling -- and in any case, hald isn't standard on Lucid, and even when it's installed, it sometimes runs and sometimes doesn't. (I haven't figured out what controls whether it decides to run). Hal isn't even supposed to be needed on Lucid -- it's supposed to use devicekit (renamed to) udisks for that.

Except I guess they couldn't quite figure out how to get udisks working in time, so they patched things together so that on Gnome systems, hald does the same old polling stuff -- and on non Gnome systems, well, maybe it does and maybe it doesn't. And maybe you can't read your camera cards. Oh well!

udev rules

But on systems prior to Lucid there was another way: make a udev rule to create sdb1 through sdb15 every time. I have an older article on setting up udev rules for multicard readers, but none of my old udev rules worked on Lucid.

After many rounds of udevadm info -a -p /block/sdb and udevadm test /block/sdb, service udev restart, and many reboots, I finally found a rule that worked.

Create a /etc/udev/rules.d/71-multicard-reader.rules file containing the following:

# Create all devices for multicard reader:
KERNEL=="sd[b-g]", SUBSYSTEMS=="usb", ATTRS{idVendor}=="1d6b", ATTRS{idProduct}=="0002", OPTIONS+="all_partitions,last_rule"

Replace the 1d6b and 0002 with the vendor and product of your own device, as determined with udevadm info -a -p /block/sdb ... and don't be tempted to use the vendor and device ID you get from lsusb, because those are different.

What didn't work that used to? String matches. Some of them. For example, this worked:

KERNEL=="sd[b-g]", SUBSYSTEMS=="scsi", ATTRS{model}=="*SD*", NAME{all_partitions}="sdcard"
but these didn't:
KERNEL=="sd[b-g]", SUBSYSTEMS=="scsi", ATTRS{model}=="*SD*Reader*", NAME{all_partitions}="sdcard"
KERNEL=="sd[a-g]", SUBSYSTEMS=="scsi", ATTRS{model}=="USB SD Reader   ", NAME{all_partitions}="cardsd"

Update: The first of those two lines does indeed work now, whereas it didn't when I was testing. It's possible that this has something to do with saving hardware states and needing an extra udevadm trigger, as suggested in Alex's Changes in Ubuntu Lucid to udev.

According to udevadm info, the model is "USB SD Reader " (three spaces at the end). But somehow "*SD*" matches this while "*SD*Reader*" and the exact string do not. Go figure.

Numeric order

I'd like to have this rule run earlier, so it runs before /lib/udev/rules.d/60-persistent-storage.rules and could use OPTIONS+="last_rule" to keep the persistent storage rules from firing (they run a lot of unnecessary external programs for each device). But if I rename the rule from 71-multicard-reader.rules to 59-, it doesn't run at all. Why? Shrug. It's not like udevadm test will tell me.

Other things I love (not) about the new udev

Tags: , , , ,
[ 21:51 May 09, 2010    More linux/kernel | permalink to this entry | ]

Sat, 18 Apr 2009

Update on writing udev rules for flash card readers

Long ago I wrote about getting my multi-flash card reader to work using udev rules.

This always evokes horrified exclaimations from people in the Ubuntu project -- "You shouldn't need to do that!" But there are several reasons for wanting special udev rules for multi-card readers. You might want your SD card to show up in the same place every time (is it /dev/sdb1 or /dev/sdc1 today?); or you might be trying to reduce polling to cut down your CPU and battery use.

But my older article referred to a script that no longer exists, and as I recently had to update my udev rules on a fairly fresh Intrepid install, I needed something more up-to-date and less dependent on Ubuntu's specific udev scripts (which change frequently).

I found a wonderful forum article, Create your own udev rules to control removable devices, that explains exactly how to find out the names of your devices and make rules for them. Another excellent article with essentially the same information is Linux Format's Connect your devices with udev.

Start by guessing at the current device name: for example, in this particular session, my SD card reader showed up on /dev/sdd. Find out the corresponding /block device name for it, like this:

udevinfo -q path -n /dev/sdd
Update: In Ubuntu jaunty, udevinfo is gone. But you can substitute udevadm info for udevinfo, with the same flags.

In my case, the SD reader was /block/sdd. Now pass that into udevinfo -a, like so:

udevinfo -a -p /block/sdd
and look for a few items that you can use to identify that slot uniquely. If you can find a make or model, that's ideal.

For my card reader, I chose

 ATTRS{model}=="CardReader SD   "

Note that SUBSYSTEM was scsi: usb-storage devices (handled by the scsi system) sometimes show up as usb and sometimes as scsi.

Now you're ready to create some udev rules. In your favorite text editor, create a new file named /etc/udev/rules.d/59-multicard-reader.rules. You can name it whatever you want, but make sure the number at the beginning is lower than the number of the udev rule that would otherwise create the device's name -- in this case, 60-persistent-storage.rules.

Now write your udev rule. Include the identifying lines you picked out from udevinfo -a:

KERNEL=="sd[a-g]", SUBSYSTEMS=="scsi", ATTRS{vendor}=="USB2.0  ", ATTRS{model}=="CardReader SD   ", NAME{all_partitions}="card-sd", group=plugdev

A few things to notice. First, I used KERNEL=="sd[a-g]" instead of just sdd, in case the devices might some day show up in a different order.

The NAME field can be whatever you choose. NAME{all_partitions}="card-sd" will make the device show up as /dev/card-sd, so to mount the first partition I'll use /dev/card-sd1. The {all_partitions} part tells the kernel to create partitions like /dev/card-sd1 even if there's no SD card inserted in the slot when you boot. Otherwise, you have to run touch /dev/card-sd after inserting a card to get the device created -- or run a daemon like hald-addons-storage that polls the device a few times every second checking to see if anything has been inserted (as Ubuntu normally prefers to do).

GROUP="plugdev" ensures the devices will be owned by the group named "plugdev". This isn't particularly important since you'll probably be mounting the cards using /etc/fstab lines or some sort of automount daemon.

Pause and reflect sadly on the confusing coincidence of "scsi disk" and "secure digital" both having the same abbreviation, so that you need context to tell what each of these "sd"s means.

Test your new udev line by restarting udev:

/etc/init.d/udev restart
and see if your new device is there in /dev. If it is, you're all set! Now you can add the rest of the devices from your multicard reader: go back to the udevinfo steps and find out what each device is called, then add a line for each of them.

Tags: , ,
[ 16:45 Apr 18, 2009    More linux | permalink to this entry | ]

Sun, 04 Jan 2009

Garmin Vista Cx on Ubuntu "Hardy"

I got myself a GPS unit for Christmas.

I've been resisting the GPS siren song for years -- mostly because I knew it would be a huge time sink involving months of futzing with drivers and software trying to get it to do something useful.

But my experience at an OpenStreetMap mapping party got me fired up about it, and I ordered a Garmin Vista Cx.

Shopping for a handheld GPS is confusing. I was fairly convinced I wanted a Garmin, just because it's the brand used by most people in the open source mapping community so I knew they were likely to work. I wanted one with a barometric altimeter, because I wanted that data from my hikes and bike rides (and besides, it's fun to know how much you've climbed on an outing; I used to have a bike computer with an altimeter and it was a surprisingly good motivator for working harder and getting in better shape).

But Garmin has a bazillion models and I never found any comparison page explaining the differences among the various hiking eTrex models. Eventually I worked it out:

Garmin eTrex models, decoded

Color display. This generally also implies USB connectivity instead of serial, just because the color models are newer.
High precision (a more sensitive satellite receiver).
Takes micro-SD cards. This may not be important for storing tracks and waypoints (you can store quite a long track with the built-in memory) but they mean that you can load extra base maps, like topographic data or other useful features.
Vista, Summit
These models have barometric altimeters and magnetic compasses. (I never did figure out the difference between a Vista and a Summit, except that in the color models (C), Vistas take micro-SD cards (x) while Summits don't, so there's a Summit C and HC while Vistas come in Cx and HCx. I don't know what the difference is between a monochrome Summit and Vista.)
Legend, Venture
These have no altimeter or compass. A Venture is a Legend that comes without the bundled extras like SD card, USB cable and base maps, so it's cheaper.

For me, the price/performance curve pointed to the Vista Cx.

Loading maps

Loading base maps was simplicity itself, and I found lots of howtos on how to use downloadable maps. Just mount the micro-SD card on any computer, make a directory called Garmin, and name the file gmapsupp.img. I used the CloudMade map for California, and it worked great. There are lots of howtos on generating your own maps, too, and I'm looking forward to making some with topographic data (which the CloudMade maps don't have). The most promising howtos I've found so far are the OSM Map On Garmin page on the OSM wiki and the much more difficult, but gorgeous, Hiking Biking Mapswiki page.

Uploading tracks and waypoints

But the real goal was to be able to take this toy out on a hike, then come back and upload the track and waypoint files.

I already knew, from the mapping party, that Garmins have an odd misfeature: you can connect them in usb-storage mode, where they look like an external disk and don't need any special software ... but then you can't upload any waypoints. (In fact, when I tried it with my Vista Cx I didn't even see the track file.) To upload tracks and waypoints, you need to use something that speaks Garmin protocol: namely, the excellent GPSBabel.

So far so good. How do you call GPSbabel? Luckily for me, just before my GPS arrived, Iván Sánchez Ortega posted a useful little gpsbabel script to the OSM newbies list and I thought I was all set.

But once I actually had the Vista in hand, complete with track and waypoints from a walk around the block, it turned out it wasn't quite that simple -- because Ubuntu didn't create the /dev/ttyUSB0 that Iván's script used. A web search found tons of people having that problem on Ubuntu and talking about various workarounds, involving making sure the garmin_usb driver is blacklisted in /etc/modprobe.d/blacklist (it was already), adding a /etc/udev/rules.d/45-garmin.rules file that changes permissions and ownership of ... um, I guess of the file that isn't being created? That didn't make much sense. Anyway, none of it helped.

But finally I found the fix: keep the garmin_usb driver blacklisted use "usb:" as the device to pass to GPSBabel rather than "/dev/ttyUSB0". So the commands are:

gpsbabel -t -i garmin -f usb: -o gpx -F tracks.gpx
gpsbabel -i garmin -f usb: -o gpx -F waypoints.gpx

Like so many other things, it's easy once you know the secret! Viewing tracklogs works great in Merkaartor, though I haven't yet found an app that does anything useful with the elevation data. I may have to write one.

Update: After I wrote this but before I was able to post it, a discussion on the OSM Newbies list with someone who was having similar troubles resulted in this useful wiki page: Garmin on GNU/Linux. It may also be worth checking the Discussion tab on that wiki page for further information.

Update, October 2011:
As of Debian Squeeze or Ubuntu Natty, you need two steps:

  1. Add a line to /etc/modprobe.d/blacklist.conf:
    blacklist garmin_gps
  2. Create a udev file, /etc/udev/rules.d/51-garmin.rules, to set the permissions so that you can access the device without being root. It contains the line:
    ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", MODE="0660", GROUP="plugdev"

Then use gpsbabel with usb: and you should be fine.

Tags: , , , , ,
[ 16:31 Jan 04, 2009    More mapping | permalink to this entry | ]

Thu, 22 May 2008

Fixing scanner permissions on Hardy

Dave needed something scanned. Oh, good! The first use of a scanner under a new distro is always an interesting test. Though the last few Ubuntu releases have been so good about making scanners "just work" that I was beginning to take scanners for granted. "Sure, no problem," I told Dave, taking the sketch he gave me.

Ha! Famous last words. For Hardy, I guess the Ubuntu folks decided that users had had it too easy for a while and it was time to throw us a challenge. Under Hardy, scanning works fine as root, but normal users can't access the scanner. sane-find-scanner sees the scanner, but xsane and the xsane-gimp plug-in can't talk to it (except as root).

It turns out the code for noticing you plugged in a scanner and setting appropriate permissions (like making it group "scanner") has been removed from udev, the obvious place for it ... and moved into hal. Except, you guessed it, whatever hal is supposed to be doing isn't working, so the device's group is never set to "scanner" to make it accessible to non-root users. Lots of people are hitting this and filing bugs (search for scanner permissions), in particular bug 121082 and bug 217571.

Fortunately, the fix is quite easy if you have a copy of your old gutsy install: just copy /etc/udev/rules.d/45-libsane.rules from gutsy to the same place on hardy. (If you don't have your gutsy udev rules handy, I attached the file to the latter of the two bugs I linked above.)

Then udev will handle your scanner just like it used to, and you don't have to wait for the hal developers to figure out what's wrong with the new hal rules.

Tags: , , , ,
[ 16:56 May 22, 2008    More linux | permalink to this entry | ]

Fri, 04 Apr 2008

Handling a network card automatically: Calling ifup from udev

I'm experimenting with Ubuntu's "Hardy Heron" beta on the laptop, and one problem I've hit is that it never configures my network card properly.

The card is a cardbus 3Com card that uses the 3c59x driver. When I plug it in, or when I boot or resume after a suspend, the card ends up in a state where it shows up in ifconfig eth0, but it isn't marked UP. ifup eth0 says it's already up; ifdown eth0 complains error: SIOCDELRT: No such process but afterward, I can run ifup eth0 and this time it works. I've made an alias, net, that does sudo ifdown eth0; sudo ifup eth0. That's silly -- I wanted to fix it so it happened automatically.

Unfortunately, there's nothing written anywhere on debugging udev. I fiddled a little with udevmonitor and udevtest /class/net/eth0 and it looked like udev was in fact running the ifup rule in /etc/udev/rules.d/85-ifupdown.rules, which calls: /sbin/start-stop-daemon --start --background --pid file /var/run/network/bogus --startas /sbin/ifup -- --allow auto $env{INTERFACE} So I tried running that by hand (with $env{INTERFACE} being eth0) and, indeed, it didn't bring the interface up.

But that suggested a fix: how about adding --force to that ifup line? I don't know why the card is already in a state where ifup doesn't want to handle it, but it is, and maybe --force would fix it. Sure enough: that worked fine, and it even works when resuming after a suspend.

I filed bug 211955 including a description of the fix. Maybe there's some reason for not wanting to use --force in 85-ifupdown (why wouldn't you always want to configure a network card when it's added and is specified as auto and allow-hotplug in /etc/network/interfaces?) but if so, maybe someone will suggest a better fix.

Tags: , , ,
[ 14:41 Apr 04, 2008    More linux | permalink to this entry | ]

Sun, 23 Dec 2007

Gutsy's persistent net rules don't persist

I use wireless so seldom that it seems like each time I need it, it's a brand new adventure finding out what has changed since the last time to make it break in a new and exciting way.

This week's wi-fi adventure involved Ubuntu's current "Gutsy Gibbon" release and my prism54 wireless card. I booted the machine, switched to the right (a href="">network scheme, inserted the card, and ... no lights. ifconfig -a showed the card on eth1 rather than eth0.

After some fiddling, I ejected the card and re-inserted it; now ifconfig -a showed it on eth2. Each time I inserted it, the number incremented by one.

Ah, that's something I remembered from Debian Etch -- a problem with the udev "persistent net rules" file in /etc/udev.

Sure enough, /etc/udev/70-persistent-net.rules had two entries for the card, one on eth1 and the other on eth2. Ejecting and re-inserting added another one for eth3. Since my network scheme is set up to apply to eth0, this obviously wouldn't work.

A comment in that file says it's generated from 75-persistent-net-generator.rules. But unfortunately, the rules uesd by that file are undocumented and opaque -- I've never been able to figure out how to make a change in its behavior. I fiddled around for a bit, then gave up and chose the brute force solution:

And that worked fine. Without 75-persistent-net-generator.rules getting in the way, the name seen in 70-persistent-net.rules works fine and I'm able to use the network.

The weird thing about this is that I've been using Gutsy with my wired network card (a 3com) for at least a month now without this problem showing up. For some reason, the persistent net generator doesn't work for the Prism54 card though it works fine for the 3com. A scan of the Ubuntu bug repository reveals lots of other people hitting similar problems on an assortment of wireless cards; bug 153727 is a fairly typical report, but the older bug 31502 (marked as fixed) points to a likely reason this is apparently so common on wireless cards -- apparently some of them report the wrong MAC address before the firmware is loaded.

Tags: , , ,
[ 19:02 Dec 23, 2007    More linux | permalink to this entry | ]

Sun, 13 May 2007

Feisty Fawn: The Adventure Continues, with the Visor Driver

When we left off, I had just found a workaround for my Feisty Fawn installer problems and had gotten the system up and running.

By now, it was late in the day, time for my daily Sitescooper run to grab some news to read on my Treo PDA. The process starts with making a backup (pilot-xfer -s). But pilot-xfer failed because it couldn't find the device, /dev/ttyUSB1. The system was seeing the device connection -- dmesg said

[ 1424.598770] usb 5-2.3: new full speed USB device using ehci_hcd and address 4
[ 1424.690951] usb 5-2.3: configuration #1 chosen from 1 choice
"configuration #1"? What does that mean? I poked around /etc/udev a bit and found this rule in rules.d/60-symlinks.rules:
# Create /dev/pilot symlink for Palm Pilots
KERNEL=="ttyUSB*", ATTRS{product}=="Palm Handheld*|Handspring *|palmOne Handheld", \
Oh, maybe they were calling it /dev/pilot1? But no, there was nothing matching /dev/*pilot*, just as there was nothing matching /dev/ttyUSB*.

But this time googling led me right to the bug, bug 108512. Turns out that for some reason (which no one has investigated yet), feisty doesn't autoload the visor module when you plug in a USB palm device the way other distros always have. The temporary workaround is sudo modprobe visor; the long-term workaround is to add visor to /etc/modules.

On the subject of Feisty's USB support, though, I do have some good news to report.

My biggest motivation for upgrading from edgy was because USB2 had stopped working a few months ago -- bug 54419. I hoped that the newer kernel in Feisty might fix the problem.

So once I had the system up and running, I plugged my trusty hated-by-edgy MP3 player into the USB2 hub, and checked dmesg. It wasn't working -- but the error message was actually useful. Rather than obscure complaints like end_request: I/O error, dev sde, sector 2033440 or device descriptor read/64, error -110 or 3:0:0:0: rejecting I/O to dead device it had a message (which I've since lost) about "insufficient power". Now that's something I might be able to do something about!

So I dug into my bag o' cables and found a PS/2 power adaptor that fit my USB2 hub, plugged it in, plugged the MP3 player into the hub, and voila! it was talking on USB2 again.

Tags: , , , , ,
[ 21:10 May 13, 2007    More linux | permalink to this entry | ]

Wed, 07 Feb 2007

Udev Tidbits Picked Up at LCA

A couple of udev tips I picked up at LinuxConf, mostly from talking to folks in the hallways:

I'd been having trouble getting my laptop to read its built-in memory stick since upgrading to Ubuntu Edgy. It's basically the same problem I described in an earlier article: the machine boots, sees the built-in reader with no card there, and udev creates /dev/sda but not /dev/sda1. Later, I insert a memory stick, but the reader (like so many other USB-based flash card readers) does not generate an event, so no new device is created.

In that earlier article, the solution was to change the udev rule that creates the device and add something like NAME{all_partitions}="stick". The all_partitions tells it to create /dev/stick1, /dev/stick2 etc. up through the possible maximum number of partitions. (It would be nice to limit it just to /dev/stick1, but there doesn't seem to be any way to do that.)

Unfortunately, in edgy, the udev rules have been rewritten to be a lot more general, and adding {all_partitions} wasn't working. But LinuxConf gave me two solutions to this problem:

First, I was able to pester one of the hal developers about hal's annoying mandatory polling. (This is the official Ubuntu solution to the problem, by the way: if you let hald wake up twice a second to poll every device on the USB bus to see whether anything new has been added, then you'll get that /dev/sda1 device appearing. I wasn't the only one at the conference, I was happy to find, who was unhappy about this hald misbehavior. It got mentioned in at least two other talks as an example of inefficient behavior that can eat batteries and CPU, and a questioner during the hal talk echoed my opinion that the polling should be made optional for those of us who don't want it.)

Anyway, I asked him what hald does to create the /dev/sda1 device once it sees a card. It turns out that touch /dev/sda causes udev to wake up and re-check the device, and create any new device nodes which might have appeared. Hurrah! That's a much cleaner workaround than sudo mknod.

But at breakfast a few days later, I found myself sitting next to a udev expert. He took a look at the file I'd created, /etc/udev/rules.d/memstick.rules, and after a few minutes of fiddling discovered what it was missing: a crucial ACTION=="add" directive which hadn't been required under the old system. The working line now looks like this:

KERNEL=="sda", ACTION=="add", OPTIONS=="all_partitions", NAME{all_partitions}="stick"

Tags: , ,
[ 22:14 Feb 07, 2007    More linux | permalink to this entry | ]

Mon, 07 Nov 2005

UDEV and Multiple Flash Card Readers

Update: Some of this has changed; see my newer entry, Update on writing udev rules for flash card readers.

Dave had one of those nifty front-panel multiple flash card readers sitting on a shelf, so I borrowed it. It's USB based, fits in a CD drive bay, and has slots for all the common types of flash memory, as well as a generic USB socket.

With the device installed, I booted into my usual Ubuntu (hoary) partition, inserted an SD card and checked dmesg. Nothing! The four logical units of the device had been seen at boot time, but nothing new happened when I inserted a card.

I tried mounting /dev/sda1, /dev/sdb1, /dev/sdc1, /dev/sdd1, and /dev/sde1 anyway, but got "No such device" each time.

Dave muttered darkly about udev and hal and said I should try it under an older Debian with a normal /dev. I rebooted my old sid partition, with a kernel I built myself. I needed a kernel with "Probe all LUNs on each SCSI device", of course. I still got no messages or hotplug events when inserting the card, but /dev/sdd1 mounted the SD card.

(For anyone reading this who's not familiar with Linux' handling of USB storage devices, sd in /dev/sdd1 stands for "SCSI disk" and has nothing to do with the fact that I was using a "secure digital" media card. Any USB disk or flash card is supposed to show up under /dev/sdsomething and the main trick is figuring out the something. Which is part of what udev and hal are supposed to help with.)

Then I discovered that doing an fdisk -l /dev/hdd gave the right answer (one partition) for the SD card. And as soon as I did that, the /dev/sdd1 device appeared and I was able to mount it normally.

Apparently, when udev sees the logical units at boot time, with no cards inserted, it decides that there's a /dev/sdd, but it has no partitions on it so there's no such device as /dev/sdd1. Since inserting a card later doesn't generate a hotplug event, udev never re-evaluates this, unless somehow forced to (apparently running fdisk forces it, though I'm not sure why). Dave was right: udev/hal are the culprit here, and the kernel was fine.

A helpful person on #ubuntu pointed me to this tutorial on writing rules for udev. It mentions the problem with multi USB card readers not getting additional events when cards are plugged in, and suggests modifying the NAME key in the rules (which seem to be in /etc/udev/rules.d/udev.rules to:

BUS="usb", SYSFS{product}="USB 2.0 Storage Device", NAME{all_partitions}="usbhd"
Elsewhere in the document, it suggests getting that SYSFS{product} string by running a command like udevinfo -a -p /sys/block/sdd

Unfortunately, that seems to be completely ignored. udevinfo told me the string was "CardReader SD ", but plugging that in to udev.rules did not create any /dev/usbhd* devices. It also seemed clear that udev is using BUS="scsi" rather than BUS="usb" for these devices, based on the device names that are being created (sd* rather than ub*). But making that change didn't help.

Eventually I found a combination that worked. Ubuntu's current rules for usb-storage devices are:

BUS="scsi", KERNEL="sd[a-z]*", PROGRAM="/etc/udev/scripts/ %k", RESULT="1", NAME="%k", MODE="0640", GROUP="plugdev"
BUS="usb", KERNEL="ub[a-z]*", NAME="%k", MODE="0640", GROUP="plugdev"
(I don't know what devices create the ub* devices. It's nothing I've used so far).

I changed the "sd[a-z]*" to "sd[e-z]*", so that it wouldn't apply to the four devices grabbed by the multicard reader. Then I added these four lines:

BUS="scsi", KERNEL="sda*", PROGRAM="/etc/udev/scripts/ %k", RESULT="1", NAME{all_partitions}="cfcard", MODE="0640", GROUP="plugdev"
BUS="scsi", KERNEL="sdb*", PROGRAM="/etc/udev/scripts/ %k", RESULT="1", NAME{all_partitions}="smcard", MODE="0640", GROUP="plugdev"
BUS="scsi", KERNEL="sdc*", PROGRAM="/etc/udev/scripts/ %k", RESULT="1", NAME{all_partitions}="mscard", MODE="0640", GROUP="plugdev"
BUS="scsi", KERNEL="sdd*", PROGRAM="/etc/udev/scripts/ %k", RESULT="1", NAME{all_partitions}="sdcard", MODE="0640", GROUP="plugdev"

That worked. Now udev creates /dev/sdcard[1-15] as well as /dev/sdcard (and likewise for the other three flash types), and I can make a normal /etc/fstab entry:

/dev/sdcard1    /sd             auto    rw,user,noauto   0       0

Now as a user I can say mount /sd without needing to su to root or do any extra fiddling. Hurrah!

Tags: , ,
[ 16:49 Nov 07, 2005    More linux | permalink to this entry | ]