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

btrfs plugin missing a check for minimum file system size for shrink #548

Open
cmurf opened this issue Jul 12, 2020 · 6 comments
Open

btrfs plugin missing a check for minimum file system size for shrink #548

cmurf opened this issue Jul 12, 2020 · 6 comments

Comments

@cmurf
Copy link

cmurf commented Jul 12, 2020

GNOME Disks lacks resize support for Btrfs. But libblockdev has it.
https://github.com/storaged-project/libblockdev/blob/master/src/plugins/btrfs.c#L876-L902

But it's missing a check for the minimum possible shrink size: 'btrfs inspect-internal min-dev-size'
And before it can, this btrfs-progs bug needs fixed.
kdave/btrfs-progs#271

Also, maybe there should be a better interface for libblockdev to use?

Also, in the multiple device case, if a device is not specified for resize, devid 1 is assumed. That suggests (a) fully supporting multiple device resizes; (b) a way to inhibit/block resize if it's a multiple device btrfs. How to know if it's multiple device? #244 probably needs a solution before knowing whether the device can be mounted as well as how many devices.

@vojtechtrefny
Copy link
Member

GNOME Disks lacks resize support for Btrfs. But libblockdev has it.
https://github.com/storaged-project/libblockdev/blob/master/src/plugins/btrfs.c#L876-L902

Even better, we have the Btrfs resize support in UDisks too -- http://storaged.org/doc/udisks2-api/latest/gdbus-org.freedesktop.UDisks2.Filesystem.BTRFS.html#gdbus-method-org-freedesktop-UDisks2-Filesystem-BTRFS.Resize (but it uses libblockdev so it has the same problems).

But it's missing a check for the minimum possible shrink size: 'btrfs inspect-internal min-dev-size'
And before it can, this btrfs-progs bug needs fixed.
kdave/btrfs-progs#271

We should probably add the min dev size to the Btrfs info.

Also, in the multiple device case, if a device is not specified for resize, devid 1 is assumed. That suggests (a) fully supporting multiple device resizes; (b) a way to inhibit/block resize if it's a multiple device btrfs. How to know if it's multiple device? #244 probably needs a solution before knowing whether the device can be mounted as well as how many devices.

Yes, multiple devices won't be easy. I'm open to suggestions, I've never really tried to resize a raid/complex btrfs volume.

@cmurf
Copy link
Author

cmurf commented Jul 17, 2020

Yes, multiple devices won't be easy. I'm open to suggestions, I've never really tried to resize a raid/complex btrfs volume.

One approach might be listing common use cases, and seeing if there are particular points of user confusion that a GUI could help avoid or resolve. Btrfs single device shrink and grow are straightforward. There is a rather old GNOME Disks issue, about Btrfs support generally, but there is recent activity including resize.

One angle might be to constrain multiple device support when the data profile is 'single', and metadata profile is 'single' or 'dup' or 'raid1'. The data 'single' and metadata 'raid1' case will be the mkfs.btrfs default, and will be the default outcome in Anaconda if the user chooses 2+ devices for Guided/Automatic partitioning path. What might users want to do with this post-install?

  • shrink either or both devices, by arbitrary amounts
  • remove or add devices
  • replace devices

Some of that is scope creep beyond just literal resize. But Btrfs makes it pretty easy to support it, if desired. The biggest leap is if the user wants to go from multiple devices, to single. Due to 'raid1' metadata, it's not possible in one step, Btrfs complains:

# btrfs device remove /dev/loop2 /media                              │
ERROR: error removing device '/dev/loop2': unable to go below two devices on raid1    │

But it's possible to first convert the metadata to 'single' (SSD) or 'dup' (HDD). And then device removal is permitted, which implies shrink. All of this is done while the fs is mounted and is handled by kernel code. The migration of data from the device being removed to the remaining device is functionally like LVM's pvmove. At the end, it wipes magic on the removed devices. It doesn't change MBR/GPT partitioning.

What I don't know much about is what kind of interface is preferred in libblockdev? Using ioctls directly, like the btrfs user space tools do? Or is it better to enhance libbtrfs so libblockdev has an API? I'm not qualified to assess the current state of libbtrfs but if that's where certain things belong, I'll help make the case to get that work done.

@cmurf
Copy link
Author

cmurf commented Oct 4, 2024

Circling back around to this...four years later.

Question: Does an application implementing shrink need to know the minimum size it can shrink to, in advance?

Why do I ask?

  • Per bogus min size estimates by 'btrfs inspect min' kdave/btrfs-progs#271 it might be difficult to get a useful estimate
  • We could just try to shrink. Shrink is expected to be fail safe.
  • Perhaps the only use case for minimum shrink are raw installation images, intended to be block copied to physical media of limited size
  • The use case of shrinking an existing file system, typically leaves significant headroom for future growth.

Therefore best effort shrink might be OK? But as a consequence, any tool would need to check the post-shrink result, rather than assume. And therefore it's a separate question if the actual result meets the requirements.

@vojtechtrefny
Copy link
Member

Does an application implementing shrink need to know the minimum size it can shrink to, in advance

I'd say it doesn't, but applications that allows shrinking generally somehow show the user how much the device can be shrunk. And this also includes GNOME Disks (and Anaconda and blivet-gui and I assume every storage management tool would do the same).

And I also don't think that "you can try to resize your partition to X, but it might fail if you choose wrong X which is too small" is a good user experience.

I agree that most people don't want to resize to the absolute minimum, but seeing that minimum is (at least for me) and important guideline when resizing a device.

@tbzatek
Copy link
Member

tbzatek commented Oct 22, 2024

Cc: @jelly as I'm not sure what approach Cockpit does take.

@jelly
Copy link
Contributor

jelly commented Oct 23, 2024

Cc: @jelly as I'm not sure what approach Cockpit does take.

At the moment Cockpit does not support resizing btrfs partitions yet, the current resizing in Cockpit happens "offline" and only for partitioned filesystems (we unmount, resize fs, resize partition, mount again).

Currently we allow users to specify a smaller then required size for ext4 and error out. (So the partition wouldn't have been resized)

image

This isn't the most user friendly way of resizing a filesystem, it would be great if we knew the minimum filesystem size at least (this can be useful in the filesystem creation dialog as well). For example xfs requires a 512MB min. size now, but these sizes are probably not exported for libblockdev to read?

And now to get more on-topic as I believe this is for an existing btrfs filesystem with data on it which needs to be resized, it would be nice if there was a generic way to obtain the min. fs size for any filesystems. (Blind assumption is that the used space is usually enough of an indication of the minimum except on CoW filesystems?)

If we think about how a user would resize filesystems I would imagine no user would resize their filesystem to the absolute minimum of what it can be but always leaves an X% of room for growth. So in practical sense:

I have a filesystem with 500GB used out of 1000GB, I would resize this to 600GB, and re-use the 400GB for something else. I assume those margins most likely "work" for btrfs?

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

No branches or pull requests

4 participants