-
Notifications
You must be signed in to change notification settings - Fork 528
Disk (Linux): Don't mark / as read-only in Fedora Atomic #1762
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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/mounts
for R/W instances of the same Btrfs device - Switched
detectType()
to useisReadOnly()
instead of a directro
option 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[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)) |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[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; | |
} | |
} |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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: