Disk (Linux): Don't mark / as read-only in Fedora Atomic#1762
Disk (Linux): Don't mark / as read-only in Fedora Atomic#1762ledif wants to merge 1 commit intofastfetch-cli:devfrom
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR adjusts read-only detection for Btrfs mounts on Fedora Atomic systems by checking all mount points for a device before marking it as read-only, preventing the main Btrfs partition from being hidden when only one subvolume is ro.
- Added
isReadOnly()helper that scans/proc/mountsfor R/W instances of the same Btrfs device - Switched
detectType()to useisReadOnly()instead of a directrooption check
Comments suppressed due to low confidence (1)
src/detection/disk/disk_linux.c:221
- Introduce unit tests for
isReadOnly(), especially to verify behavior when the same Btrfs device has both read-only and read-write mounts.
static bool isReadOnly(FFDisk* currentDisk, struct mntent* device)
| return false; | ||
|
|
||
| // For BTRFS on Fedora Atomic, check if there are other R/W mount points for the same device | ||
| if (ffStrbufEqualS(¤tDisk->filesystem, "btrfs")) |
There was a problem hiding this comment.
[nitpick] Avoid using the literal string "btrfs"; consider defining a constant or using an enum for filesystem types to improve readability and reduce risk of typos.
| if (ffStrbufEqualS(¤tDisk->filesystem, "btrfs")) | |
| if (ffStrbufEqualS(¤tDisk->filesystem, FILESYSTEM_BTRFS)) |
There was a problem hiding this comment.
There is no FILESYSTEM_BTRFS enum defined anywhere and I do not believe it makes sense to create such an enum for an unbounded list of filesystem types.
| FILE* mountsFile = setmntent("/proc/mounts", "r"); | ||
| if (mountsFile != NULL) | ||
| { | ||
| struct mntent* otherDev; | ||
| while ((otherDev = getmntent(mountsFile))) | ||
| { | ||
| // If same device but not read-only, then this device has R/W access | ||
| if (ffStrEquals(otherDev->mnt_fsname, deviceName) && | ||
| !hasmntopt(otherDev, MNTOPT_RO)) | ||
| { | ||
| endmntent(mountsFile); | ||
| return false; | ||
| } | ||
| } | ||
| endmntent(mountsFile); | ||
| } |
There was a problem hiding this comment.
[nitpick] Opening and scanning /proc/mounts on every call could add I/O overhead; consider caching the mounts list once per scan or reusing the open file between disk checks.
| FILE* mountsFile = setmntent("/proc/mounts", "r"); | |
| if (mountsFile != NULL) | |
| { | |
| struct mntent* otherDev; | |
| while ((otherDev = getmntent(mountsFile))) | |
| { | |
| // If same device but not read-only, then this device has R/W access | |
| if (ffStrEquals(otherDev->mnt_fsname, deviceName) && | |
| !hasmntopt(otherDev, MNTOPT_RO)) | |
| { | |
| endmntent(mountsFile); | |
| return false; | |
| } | |
| } | |
| endmntent(mountsFile); | |
| } | |
| static struct mntent** cachedMounts = NULL; | |
| static size_t cachedMountsCount = 0; | |
| if (cachedMounts == NULL) | |
| { | |
| FILE* mountsFile = setmntent("/proc/mounts", "r"); | |
| if (mountsFile != NULL) | |
| { | |
| struct mntent* entry; | |
| size_t count = 0; | |
| while ((entry = getmntent(mountsFile))) | |
| count++; | |
| rewind(mountsFile); | |
| cachedMounts = malloc(count * sizeof(struct mntent*)); | |
| cachedMountsCount = count; | |
| count = 0; | |
| while ((entry = getmntent(mountsFile))) | |
| { | |
| cachedMounts[count] = malloc(sizeof(struct mntent)); | |
| *cachedMounts[count] = *entry; | |
| count++; | |
| } | |
| endmntent(mountsFile); | |
| } | |
| } | |
| for (size_t i = 0; i < cachedMountsCount; i++) | |
| { | |
| struct mntent* otherDev = cachedMounts[i]; | |
| // If same device but not read-only, then this device has R/W access | |
| if (ffStrEquals(otherDev->mnt_fsname, deviceName) && | |
| !hasmntopt(otherDev, MNTOPT_RO)) | |
| { | |
| return false; | |
| } | |
| } |
There was a problem hiding this comment.
Although I agree that this patch potentially introduces an additional overhead where under certain conditions, the /proc/mounts file will be processed multiple times, I would argue that this situation only occurs in systems where a device is mounted read-only which itself is a rare condition and occurs most consistently for immutable-type distributions such as Fedora Atomic.
If we denote the number of /proc/mount entries as n and the number of such entries that are read-only as k, this patch increases the asymptotic complexity of this function from O(n) to O(n*(k+1)). However, k is usually 0 for most non-immutable systems and this patch would introduce no overhead. Creating a static cache of mount entries in my opinion is overkill for such a rare scenario.
|
Please upload your |
|
This is my full |
|
So your real requirement is to hide the overlay partition. However because fastfetch doesn't have a option to hide a specific partition, you come up with a idea which is to hide read-only partitions. And because the btrfs partition is also detected as read-only but you don't want to hide it, you created this PR to make the btrfs partition not read-only somehow.
Mountpoint The better option is to use Anyway, this PR seems a dirty hack for a very specific distro and a very specific reason. I don't like it. |
|
This is what it looks like by setting a This looks good in the sense that it doesn't show the composefs parititon, but in my opinion, it is more confusing in other ways. Namely:
Perhaps a different approach could be one where we can use both a Btrfs module and a Disks module and somehow hide the Btrfs partitions in the Disks module. Is that possible? If not, does it make sense to implement something like that? |
Both can be used to hide the |


Fedora Atomic and its derivatives such as Bazzite use a mix of composefs for the system mount and btrfs for variable read-write data. The composefs mount is correctly marked as read-only but the btrfs partition is also marked as read-only because the partition is mounted in several different places with a mix of read-write and read-only.
As an example:
The main btrfs partition should not be considered read-only because it happens to contain a read-only subvolume. This PR enhances the read-only detection logic to see if any of the mounts for the same device are read-write and if so mark the whole device as read-write.
Screenshots
Current default Bazzite fastfetch:
Bazzite's fastfetch with the read-only mounts hidden. Notice that it hides both the composefs mount (which we want to hide) and the main btrfs mount (which we do not want to hide):

Bazzite's fastfetch with this patch and read-only mounts hidden. Notice the main btrfs mount is there as expected: