I just found an interesting bug, so I thought it might be worthwhile to share it with these intertubes to prevent other people from making the same mistake.
I was just transferring some more music onto my iPhone with Amarok while at the same time listening to music. I wanted to listen to a particular track (from a Moby album I bought recently), so stopped and switched to that, but Amarok would not play it and complained about the sound device being busy. This seemed rather odd as it had just been playing fine until I tried to change tracks. Wanting to get to the bottom of this, I checked who had what open:
andrew@rata:~$ sudo lsof /dev/snd/*
lsof: WARNING: can't stat() fuse.sshfs file system /media/iphone
Output information may be incomplete.
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
timidity 4162 root 6u CHR 116,1 4973 /dev/snd/seq
kmix 4511 andrew 10u CHR 116,0 5260 /dev/snd/controlC0
ssh 5605 andrew 16u CHR 116,0 5260 /dev/snd/controlC0
ssh 5605 andrew 33r CHR 116,33 4954 /dev/snd/timer
ssh 5605 andrew 39u CHR 116,16 5236 /dev/snd/pcmC0D0p
ssh 5605 andrew 41u CHR 116,0 5260 /dev/snd/controlC0
sshfs 5609 andrew 16u CHR 116,0 5260 /dev/snd/controlC0
sshfs 5609 andrew 33r CHR 116,33 4954 /dev/snd/timer
sshfs 5609 andrew 39u CHR 116,16 5236 /dev/snd/pcmC0D0p
sshfs 5609 andrew 41u CHR 116,0 5260 /dev/snd/controlC0
I should point out at this point that the way I get Amarok to sync music to my (jailbroken) iPhone is to FUSE-mount the iPhone via SFTP over the network, so that is why SSH was running. But on with the story.
SSH had my sound device open‽ What? That seemed very odd. I wondered whether perhaps there was some new SSH feature I had not heard about to forward sound over the network connection (as it can do for GUI applications using X11), but there I could find no mention of such a feature in the manpage or via Google, nor any possible reason why it might want to open a sound device. I asked lorne, and he was equally confused, but suggested a few things to check.
After a bit of poking around I discovered that I could not replicate this behaviour by mounting the filesystem myself, only when Amarok did it. This prompted a realisation of what must be happening: when Amarok launches sshfs to mount the iPhone filesystem, it presumably does a fork and exec to start the new process. But when you do this, the new process inherits all the open file handles of the parent process. Amarok of course had the sound device open to play the music I was listening to originally, so sshfs and subsequently ssh ended up with the same device file open. Amarok must then have closed it and tried to reopen it when I switched tracks, and this failed because the other processes it had launched still had it open. Of course.
So, lesson of the day: when you fork, remember to close any excess files before you exec. Especially if they are device files or other special files.
I should probably file a bug report for Amarok, but I am not sure that I can be bothered.