Skip to content

Commit

Permalink
storage: add document about shrinking devices
Browse files Browse the repository at this point in the history
  • Loading branch information
joseivanlopez committed Jul 8, 2024
1 parent a4a9436 commit 8d4d7c2
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 0 deletions.
133 changes: 133 additions & 0 deletions doc/shrinking_devices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Shrinking Devices

This document describes all the considerations to decide whether a device can be safely shrunk.

## Resizing information at Y2Storage (and libstorage-ng) level

In `Y2Storage` every device is associated to a `ResizeInfo` object:

~~~
@!method resize_ok?
Whether is possible to resize the device
@return [Boolean]
@!method min_size
Minimal size the device can be resized to
Note this is not aligned.
@return [DiskSize]
@!method reasons
Reasons blocking a resize as an array of symbols such
as :RB_MIN_SIZE_FOR_FILESYSTEM etc.;
see also FreeInfo.h in libstorage-ng.
@return [Array<Symbol>]
@!method reason_texts
Reasons blocking a resize in text form.
@return [Array<String>]
~~~

Additionally, the objects of the `BlkFilesystem` class offer the following methods:

~~~
#supports_shrink?
#supports_grow?
#supports_resize?
~~~

The latest is obviously just an OR combination of the other two offered for convenience.

### How ResizeInfo works at libstorage-ng

* Apparently, `#resize_ok` is only *false* if both growing and shrinking are impossible. For
example, if a device cannot be shrunk but can be grown then `#resize_ok` is true.

* There is no equivalent boolean attribute to ask only about shrinking.

* There are 20 so-called reasons to block resize operations:
* 5 of them block growing but not shrinking.
* 7 of them block shrinking but not growing.
* 8 of them block both operations.


### Filesystem info at libstorage-ng

Apart from `ResizeInfo`, *libstorage-ng* offers information about resizing at file system level.
The `BlkFilesystem` objects offer these boolean methods:

~~~
#supports_shrink
#supports_grow
#supports_mounted_shrink
#supports_mounted_grow
#supports_unmounted_shrink
#supports_unmounted_grow
~~~

The methods `#supports_shrink` and `#supports_grow` are used as the main criteria to add the
corresponding reasons `RB_SHRINK_NOT_SUPPORTED_BY_FILESYSTEM` and
`RB_GROW_NOT_SUPPORTED_BY_FILESYSTEM` to `ResizeInfo`.

### What does the *Expert Partitioner* do?

* It discourages to resize devices with no descendants in the *devicegraph*. It cannot be ensured
whether the device contains something, see [resize_blk_device.rb#L88](https://github.com/yast/yast-storage-ng/blob/0e39eba1e111101ec528d8cc7c4430f66faee764/src/lib/y2partitioner/actions/resize_blk_device.rb#L88).

* It also discourages to resize thin LVM snapshots, see [resize_blk_device.rb#L119](https://github.com/yast/yast-storage-ng/blob/0e39eba1e111101ec528d8cc7c4430f66faee764/src/lib/y2partitioner/actions/resize_blk_device.rb#L119).
This check looks kind of redundant with a *libstorage-ng* one, but maybe it is not[^1].

* It includes an specific check to forbid resizing devices containing file systems of certain types
based on `BlkFilesystem#supports_resize?`, see [resize_blk_device.rb#L161](https://github.com/yast/yast-storage-ng/blob/0e39eba1e111101ec528d8cc7c4430f66faee764/src/lib/y2partitioner/actions/resize_blk_device.rb#L142).
This check may be redundant with the one done by `libstorage-ng` (see above).

* It forbids to resize a device when it’s a component of another device (e.g., LVM or MD RAID). The
user must delete the LVM/RAID before, see [resize_blk_device.rb#L142](https://github.com/yast/yast-storage-ng/blob/0e39eba1e111101ec528d8cc7c4430f66faee764/src/lib/y2partitioner/actions/resize_blk_device.rb#L142).
This check is partially redundant with a *libstorage-ng one*[^2].

* It also forbids to resize devices based on `resize_info.resize_ok?`. It displays the reasons
(`resize_info.reasons`), see [resize_blk_device.rb#L172](https://github.com/yast/yast-storage-ng/blob/0e39eba1e111101ec528d8cc7c4430f66faee764/src/lib/y2partitioner/actions/resize_blk_device.rb#L172).

[^1]: Reading *libstorage-ng* code it could be expected `RB_RESIZE_NOT_SUPPORTED_FOR_LVM_LV_TYPE` to
be reported when trying to resize an LVM thin snapshot. But it does not seem to happen.

[^2]: Reading the description of `RB_RESIZE_NOT_SUPPORTED_BY_DEVICE` it could be
expected that reason applies to all components:
_The device or one of its descendants that also needs resizing does not support resizing._”.
But it seems that *libstorage-ng* allows growing a partition that is a PV. It does not allow
shrinking it though (see below).

### Shrinking in some special cases

Note: all this refer to devices that are already at disk. Resizing devices that only exist at the
staging *devicegraph* is way more flexible.

* Shrinking a partition that is an LVM PV is not allowed by *libstorage-ng*. That is achieved by
doing `resize_info.min_size = get_size()`.
* Shrinking partitions that are part of a RAID is not allowed either. `#resize_ok` returns *false*
with the reason `RB_RESIZE_NOT_SUPPORTED_BY_DEVICE`.

### Additional notes

Looks like in order to check whether an NTFS is resizable it must be unmounted. For the time being,
it can be considered as granted, see [resize_blk_device.rb#L187](https://github.com/yast/yast-storage-ng/blob/0e39eba1e111101ec528d8cc7c4430f66faee764/src/lib/y2partitioner/actions/resize_blk_device.rb#L187).

## Shrinking devices in Agama

*Agama* checks several things to decide whether a partition can be shrunk by the proposal:

1. Whether there are descendants in the *devicegraph*. If not, it’s better to not offer resizing
(is actually more dangerous that it looks). Delete or nothing.
2. Whether the `#resize_info` of the device contains any of the reasons that prevents resizing
(checking for `#resize_ok?` is not enough).
3. Whether the minimum size is smaller than the current size. Sometimes *libstorage-ng* sets
`min == current` as a way to prevent shrinking without really reporting a reason.
4. Whether the minimum size is zero. Probably it only happens when there is no descendants.

### The influence of reusing devices

The proposal will never delete or resize partitions that are being reused or that are necessary for
a reused device. For example, if an LV is being reused, none of the partitions that are PVs for the
same VG would be deleted or resized, no matter what the space actions say.

It would be good to present that circumstance to the user instead of allowing to select an action
and then ignore it.
1 change: 1 addition & 0 deletions service/lib/agama/storage/device_shrinking.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
module Agama
module Storage
# Generates information about shrinking a block device.
# See doc/shrinking_devices.md.
class DeviceShrinking
include Yast::I18n

Expand Down

0 comments on commit 8d4d7c2

Please sign in to comment.