This question was actually fun for learning more about
mount - and about the kernel code involved. =:c)
Fred Crowson wrote on Mon, Oct 02, 2006 at 10:31:24AM +0200:
Karel Kulhavy wrote:
I tried to mount a CD-ROM twice:
[EMAIL PROTECTED]:~$ mount /dev/cd0c /mnt/cdrom
mount_ffs: /dev/cd0c on /mnt/cdrom: \
specified device does not match mounted device
[EMAIL PROTECTED]:~$ mount /dev/cd0c /mnt/cdrom
If i understand correctly, the second mount command succeeded.
In first time I got an error message which doesn't make sense -
there was only specified device, no mounted device (when you
invoke the mount with intention to mount a device, the device
is not mounted yet).
Yes, *hopefully*.
On the other hand, *if* you invoke mount(8) on a device which is
already mounted, specifying the -u (change status) flag, you *do*
get the same errno(2) in case you give the wrong mount point:
[EMAIL PROTECTED] # mount | grep ftp
/dev/wd0l on /ftp type ffs (local, nodev, noexec)
[EMAIL PROTECTED] # mount /dev/wd0l /mnt
mount_ffs: /dev/wd0l on /mnt: Device busy
[EMAIL PROTECTED] # mount -u /dev/wd0l /mnt
mount_ffs: /dev/wd0l on /mnt: \
specified device does not match mounted device
Man mount doesn't mention the error message.
When citing man pages, please do not omit the section number.
The error message is not explained in mount(8), but in mount(2):
[EINVAL] An argument given was invalid.
OK, i admit this is not at all obvious.
I suggest the error message to be added and explained in the
mount manual page.
Maybe the mount_ffs(8) man page could be improved; i will perhaps
think about it...
Could you please also tell me what the error
message means and why I got it once and not second time?
The error message is explicit mount_ffs (mount a Berkeley Fast
File System) does not match the file format on the CD-ROM -
if you had used the -t switch to mount(8) or used mount_cd9660(8)
you would have not received that error message.
In one respect, this is almost certainly correct - clearly, if
mount_ffs(8) is invoked on a cd9660 file system, it will fail
just like Karel reported.
But the point is - why did mount(8) invoke mount_ffs(8) at all?
Usually, mount(8) is able to autodetect cd9660 file systems.
It uses readlabelfs(3) from /usr/src/lib/libutil/readlabel.c
to accomplish that. Thus, why did readlabelfs(3) fail the
first time, and why did it succeed the second time?
To find out, i just tried the following: I opened my CD drive,
put a CD into the tray, typed the command below, hit return and
only *then* pressed the close tray button on the CD drive.
The first time i tried, the message specified device does not
match mounted device did NOT show up. So i unmounted and
removed the CD and started over.
Now look at the result i got from the second try:
[EMAIL PROTECTED] # \
( while true; do
mount /dev/cd0c /mnt echo DONE break
done;
mount /dev/cd0c /mnt
) mount.out 21; \
tail -n 6 mount.out
mount_ffs: /dev/cd0c on /mnt: Operation not supported by device
mount_ffs: /dev/cd0c on /mnt: Operation not supported by device
mount_ffs: /dev/cd0c on /mnt: Operation not supported by device
mount_ffs: /dev/cd0c on /mnt: \
specified device does not match mounted device
DONE
mount_cd9660: /dev/cd0c on /mnt: Device busy
I read this as follows: Before the CD is accessible,
readlabelfs(3) will fail, so mount(8) will use its default
which happens to be -t ffs. As soon as the CD becomes
accessible, readlabelfs(3) will of course return the correct
value cd9660.
Before the CD is accessible, mount(2) called by mount_ffs(8)
will fail with ENODEV, translated to Operation not supported by
device by strerror(3). As soon as the CD becomes accessible,
mount(2) will notice the file system type mismatch, returning
EINVAL, translated to specified device does not match mounted
device by mount_ffs(8).
Apparently, there is a race condition. Consider the following
timeline:
1. the user starts mount(8)
2. mount(8) calls readlabelfs(3)
*** ASSUME THE CD IS STILL UNAVAILABLE AT THIS TIME ***
3. readlabelfs(3) returns NULL to mount(8)
(note: if the CD would already be readable now, the return
value would be cd9660 and the mount would succeed)
4. mount(8) does fork(2) and exec(3) to start mount_ffs(8)
5. mount_ffs(8) calls mount(2) with option MOUNT_FFS
6. switch to kernel space, sys_mount from kern/vfs_syscalls.c
7. sys_mount uses copyinstr(9) to get fstypename from user space
8. sys_mount calls ffs_mount from ufs/ffs/ffs_vfsops.c
9. ffs_mount uses copyinstr(9) to get mount point and device name
10. ffs_mount calls ffs_mountfs from ufs/ffs/ffs_vfsops.c
*** ASSUME THE CD HAS NOW BECOME AVAILABLE ***
11. ffs_mountfs successfully opens the cd(4) device for reading
by calling VOP_OPEN from kern/vnode_if.c = cdopen from scsi/cd.c
12. ffs_mountfs searches for an ffs superblock on the CD -
of