UFS Read-only root filesystem changing on boot

A little background information; I'm trying to make a small embedded system (Beaglebone Black) with a read-only main boot drive (eMMC or SD card). And by read-only, I mean that there are no writes to the device, and a checksum of the entire drive (using /dev device directly) doesn't change.
Set up FreeBSD, with a boot msdos (fat32lba) partition, and root partition, and a usr partition. All mounted read-only in fstab.
The msdos and usr partitions stay completely persistent across reboots. A md5 checksum of the whole /dev device stays the same. However, the root partition changes, even though it is mounted read-only.
So I did a little digging using a plain old x86 Virtualbox image. Set the root partition to be read-only and rebooted a couple times taking checksums. I think the issue is with the filesystem metadata. Here is what I found:
1) Booting into single-user mode doesn't change the filesystem at all or the underlying block device (checksum stays persistent). Checking the filesystem metadata (dumpfs / | head) shows that the last mounted time doesn't change.
2) Continuing into multi-user mode does change the filesystem. It updates the last-mounted time, even though it is mounting it read-only.

Is this the intended behavior? To me, a read-only filesystem should include the metadata, and not do any writes to the underlying device, but perhaps I am wrong about that.
Is the kernel sneaking in a read-write remount of the root filesystem before finally mounting it read-only?
What do I need to do to truly prevent any changes to the underlying block device?
Thanks,
 
Is this the intended behavior? To me, a read-only filesystem should include the metadata, and not do any writes to the underlying device
In single-user mode the root partition is mounted read-only by default. Perhaps there's something else going on too that would explain the difference between single and multi-user modes. I'm not sure so I don't know if it's intentional.
That being said, I must disagree: the last-mounted information of a partition should not have anything to do with its read-write status. One is the partition's metadata, the other is the filesystem's metadata. When you're mounting read-only, you're still mounting the partition, so last-mounted should always be recorded correctly. Just my humble opinion.

What do I need to do to truly prevent any changes to the underlying block device?
Very easy: flip the read-write notch on the card. Software can't tamper with that ;)
 
It's a tricky question, a gray zone. Clearly, file and directory metadata should not changed when mounted read-only. For example, since files can't be modified, the mtime should not change. So far, I think any sane person would agree.

Should the file atime change when a file is read, in read-only mode? Good question. I happen to know that most file systems will not change it. But logically, this is troubling: The file was really read! And not changing the atime means that we are now lying about the time the file was last accessed. On the other hand, changing the atime would contradict the fact that the underlying block device might be read-only.

The arguments pro or con changing the "last mounted" time are similar. Yes, it would be good to update it, to show that this file system was actually used. No, it would be bad to update it, because it was not modified. Yes, it may be necessary to update it, to indicate that it might be currently mounted, which affects the meaning of blocks held in the buffer cache. No, it may be bad to update it, because it might wrongly indicate that it has been potentially modified, and might trigger a needless fsck. No, it can not be updated because the underlying block device might be read-only. And your original argument (in read-only mode absolutely nothing should change) is also pretty good, but not strong enough to override everything.

So implementors of file systems have to find a compromise between conflicting arguments. You or me may have different value judgements about what argument is most powerful. But what really matters is: the implementors of the file system you are complaining about (probably UFS) had a different judgement; given that I know how extremely smart and experienced they are (Hallo Kirk!), I respect their opinions. Or maybe there is a bug, and this is not the intended behavior.

My suggestion: If this really bothers you, do some background research (including reading the source code), and if you still think that it is doing the wrong thing, open a bug report (it's called a PR). You might end up being right, but your opinion might also get rejected.
 
Thanks for the thoughtful replies. What gets me though is that I think the implementors of UFS were more in line with my reasoning, which is that nothing, including metadata, should change if a file system is mounted read-only. The reason I say that is because if you mount a non-root file system read-only, nothing at all changes. Here's a quick experiment to see that:
Create a temporary file to use as backing for our experimental filesystem:
dd if=/dev/zero of=/tmp/backing-file bs=10M count=1
Create an md device with the file as backing store:
mdconfig -t vnode -f /tmp/backing-file
The resulting device is probably md0. Create a new UFS2 filesystem on it:
newfs /dev/md0
Now do a checksum of the whole device (I'm using md5, but it shouldn't matter):
md5 /dev/md0
or
md5 /tmp/backing-file
(they should be the same)
Also do a dumpfs and take note of the last mounted time:
dumpfs /dev/md0 | head
Now have the system mount it read-only:
mount -r /dev/md0 /mnt
Do an ls on it just to show that it's working:
ls /mnt
Do the checksum again (it should be the same):
md5 /tmp/backing-file
Unmount it:
umount /mnt
Do the checksum again (it should be the same):
md5 /tmp/backing-file
Do an fsck on it and check it again:
fsck /dev/md0
md5 /tmp/backing-file

When I do all this, the checksum stays constant, indicating that none of the metadata or data is changing.

However, this is not true for the root filesystem when going into multi-user mode, even if it's not being fsck'd. Why would that be?
 
Just an update for anyone interested. I finally figured out the root cause of this issue. There is an rc script called "root" that mounts the root filesystem read-write unless the variable root_rw_mount is set to "NO" in rc.conf. It does this even if you have the root filesystem marked as read-only is /etc/fstab. Setting the variable in rc.conf fixes the issue.
 
Back
Top