Skip to content
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

mount: Handle multi-device with 1 device node #245

Closed

Conversation

tasleson
Copy link

Instead of requiring the user to supply all the device nodes for a multi-device FS, allow them to specifiy 1 of them. We then fetch the UUID for the FS and then find all the disks on the system that match this UUID.

This allows me to bring up a bcachefs FS in /etc/fstab by using a UUID. This works because it appears the mount command looks up the UUID, finds an entry in /dev/disk/by-uuid and then passes that found device node to mount.bcachefs which fails with insufficient_devices_to_start as bcachefs is expecting a list of devices with a ":" between them. This behavior is preserved if a user specifies a list of all the needed device nodes to bring up the FS.

Notes:

  • Maybe this isn't the correct approach, but I think the logic should be here instead of util-linux even if this isn't implemented well.
  • I'm using a release candidate util-linux, ref. https://github.com/util-linux/util-linux/archive/refs/tags/v2.40-rc1.tar.gz running on Fedora 39 with 6.7.5-200 Fedora kernel.
  • I'm not sure why the existing bcachefs user-space doesn't leverage the udev db more, but that might be due to the fact that we maynot have full udev db information populated with current systems with existing util-linux/blkid functionality.
  • I'm not sure why the current code dumps the following out the terminal when mounting via UUID= eg.
# bcachefs mount UUID=11f32f1f-016d-41c2-afd4-cd341c26f133 /mnt/bcachefs_2_dev
bcachefs (/dev/sda): error reading default superblock: Not a bcachefs superblock (got magic 00000000-0000-0000-0000-000000000000)
bcachefs (/dev/sda): error reading superblock: Not a bcachefs superblock layout
bcachefs (/dev/sda1): error reading default superblock: Not a bcachefs superblock (got magic 00000000-0000-0000-0000-000000000000)
bcachefs (/dev/sda1): error reading superblock: Not a bcachefs superblock layout
bcachefs (/dev/sda2): error reading default superblock: Not a bcachefs superblock (got magic cd69a632-d51f-4ecc-0000-000000000000)
bcachefs (/dev/sda2): error reading superblock: Not a bcachefs superblock layout
bcachefs (/dev/sda3): error reading default superblock: Not a bcachefs superblock (got magic f676ecf2-df1f-6474-0000-000000000000)
bcachefs (/dev/sda3): error reading superblock: Not a bcachefs superblock layout
bcachefs (/dev/sdb): error reading default superblock: Not a bcachefs superblock (got magic 00100000-0000-0000-00f0-0f0000000000)
bcachefs (/dev/sdb): error reading superblock: Not a bcachefs superblock layout
bcachefs (/dev/sdc): error reading default superblock: Not a bcachefs superblock (got magic 00100000-0000-0000-00f0-0f0000000000)
bcachefs (/dev/sdc): error reading superblock: Not a bcachefs superblock layout
bcachefs (/dev/zram0): error reading default superblock: Not a bcachefs superblock (got magic 00000000-0000-0000-0000-000000000000)
bcachefs (/dev/zram0): error reading superblock: IO error: -5
bcachefs (/dev/dm-0): error reading default superblock: Not a bcachefs superblock (got magic 18000000-0000-0000-0100-000000000000)
bcachefs (/dev/dm-0): error reading superblock: Not a bcachefs superblock layout
bcachefs (/dev/dm-1): error reading default superblock: Not a bcachefs superblock (got magic 00000000-0000-0000-0000-000000000000)
bcachefs (/dev/dm-1): error reading superblock: Not a bcachefs superblock layout
bcachefs (/dev/dm-2): error reading default superblock: Not a bcachefs superblock (got magic 00000000-0000-0000-0000-000000000000)
bcachefs (/dev/dm-2): error reading superblock: Not a bcachefs superblock layout
bcachefs (/dev/dm-3): error reading default superblock: Not a bcachefs superblock (got magic 00000000-0000-0000-0000-000000000000)
bcachefs (/dev/dm-3): error reading superblock: Not a bcachefs superblock layout
bcachefs (/dev/dm-4): error reading default superblock: Not a bcachefs superblock (got magic 00000000-0000-0000-0000-000000000000)
bcachefs (/dev/dm-4): error reading superblock: Not a bcachefs superblock layout
bcachefs (/dev/dm-5): error reading default superblock: Not a bcachefs superblock (got magic 00000000-0000-0000-0000-000000000000)
bcachefs (/dev/dm-5): error reading superblock: Not a bcachefs superblock layout

Instead of requiring the user to supply all the device nodes for a
multi-device FS, allow them to specifiy 1 of them.  We then fetch
the UUID for the FS and then find all the disks on the system that
match this UUID.

This allows me to bring up a bcachefs FS in /etc/fstab by using a
UUID.  This works because it appears the mount command looks up
the UUID, finds an entry in /dev/disk/by-uuid and then passes that
found device node to mount.bcachefs which fails with
`insufficient_devices_to_start` as bcachefs is expecting a list of
devices with a ":" between them.  This behavior is preserved if a
user specifies a list of all the needed device nodes to bring up
the FS.

Signed-off-by: Tony Asleson <[email protected]>
@tasleson
Copy link
Author

tasleson commented Feb 27, 2024

Looks like this is similar to PR #142 , but different.

Copy link

@RlndVt RlndVt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, thanks for the PR: it would be very nice to be able to mount a array with /etc/fstab.

I've added some comments in the code; I'm very new to Rust so I'm trying to learn with these questions. Love to hear your thoughts.

}
}
}
Ok(None)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you return Ok() here?

If I'm reading the right we should only reach this if the device path provided does not match any of the disks in the udev scan. That should return an Err() IMO.

Copy link
Author

@tasleson tasleson Mar 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took the approach that the code should display the same error message when it can't find something that the user supplies. That message before this change is Fatal error: No device found from specified parameters. By returning Ok(None) we preserve the same error path progression which reports this error. We could certainly change this to return an error instead.

if let Some(bcache_fs_uuid) = uuid {
devs_str_sbs_from_uuid(bcache_fs_uuid.to_string())
} else {
Ok((String::new(), Vec::new()))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to my other question. The way I read the rest of the code is it returns Err() when the function could not provide the desired result.

IOW, should you not return Err() instead of special empty variables?
Better yet, return the Err() provided by devs_str_sbs_from_uuid?

Copy link
Author

@tasleson tasleson Mar 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When devs_str_sbs_from_uuid doesn't find block devices that match the specified uuid it doesn't return an error, it returns an empty tuple if I'm reading it correctly. This is preserving the same behavior.

Just verified, take existing code and try to mount a non-existent UUID, you end up in this:

if block_devices_to_mount.len() == 0 {
        Err(anyhow::anyhow!("No device found from specified parameters"))?;
}

tasleson added 3 commits March 5, 2024 14:22
Signed-off-by: Tony Asleson <[email protected]>
Signed-off-by: Tony Asleson <[email protected]>
When blkid changes with bcachefs are ubiquitous, we can simply
leverage the bcachefs information in the udev db instead of reading
the superblock on every disk.  Reduces the number of superblock reads
and removes messages pertaining to superblock reads for devices which
do not contain a bcachefs FS.

Note: this shouldn't be included until blkid changes have been released
and packaged.

Signed-off-by: Tony Asleson <[email protected]>
@koverstreet
Copy link
Owner

I had to think about this, and - I think this actually a pretty slick solution. This should help with systemd integration as well; we're trying to avoid systemd having to know which devices it has to wait for, and this helps with that.

@JohnRTitor
Copy link

And since systemd initrd still can not properly mount bcachefs on boot (systemd-udev can), I think it will fix that too.

@tasleson
Copy link
Author

The first commit in this PR was merged already.
The last commit in this PR has been re-worked in #254

@tasleson tasleson closed this Apr 17, 2024
@tasleson tasleson deleted the allow_multidev_mount_with_1_device branch May 8, 2024 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants