Skip to content

Commit

Permalink
Merge pull request #486 from ancorgs/resize_info
Browse files Browse the repository at this point in the history
More object-oriented handling of partitions resizing
  • Loading branch information
ancorgs committed Jan 15, 2018
2 parents 3fcd97e + ef17ab7 commit 1831961
Show file tree
Hide file tree
Showing 18 changed files with 831 additions and 218 deletions.
9 changes: 9 additions & 0 deletions package/yast2-storage-ng.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
-------------------------------------------------------------------
Mon Jan 15 12:51:01 UTC 2018 - ancor@suse.com

- Some code reorganization regarding alignment and resizing.
- Added to several places in the API the possibilty of using other
alignment types, in addition to the optimal one.
- Added a (temporary) workaround to a possible bug in libstorage-ng
regarding alignment.

-------------------------------------------------------------------
Tue Jan 9 15:36:15 UTC 2018 - lslezak@suse.cz

Expand Down
48 changes: 6 additions & 42 deletions src/lib/y2partitioner/actions/resize_partition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ def initialize(partition)
textdomain "storage"

@partition = partition
@resize_info = partition.detect_resize_info
UIState.instance.select_row(partition)
end

Expand All @@ -59,15 +58,18 @@ def run
# @return [Y2Storage::Partition] partition to resize
attr_reader :partition

# Resize information of the partition to be resized
#
# @return [Y2Storage::ResizeInfo]
attr_reader :resize_info
def resize_info
partition.resize_info
end

# Runs the dialog to resize the partition
#
# @return [Symbol] :finish if the dialog returns :next; dialog result otherwise.
def resize
result = Dialogs::PartitionResize.run(partition, resize_info)
fix_end_alignment
result = Dialogs::PartitionResize.run(partition)

result == :next ? :finish : result
end
Expand All @@ -91,44 +93,6 @@ def validate

false
end

# After the partition's size was changed during resizing, make sure the
# new size meets all alignment requirements, but is still between
# min_size and max_size.
#
# @note This may change the partition's size (and region).
def fix_end_alignment
return if partition.nil? || partition.end_aligned?

ptable = partition.partition_table
region = ptable.align(partition.region, Y2Storage::AlignPolicy::ALIGN_END)
min_blocks = (resize_info.min_size.to_i / region.block_size.to_i)
max_blocks = (resize_info.max_size.to_i / region.block_size.to_i)
grain_blocks = (ptable.align_grain.to_i / region.block_size.to_i)

partition.region = fix_region_end(region, min_blocks, max_blocks, grain_blocks)
end

# Make sure a region's end is between min_blocks and max_blocks. If it
# is not, add or subtract blocks in grain_blocks increments. All sizes
# are specified in that region's block size.
#
# @note region parameter could be modified.
#
# @param region [Y2Storage::Region]
# @param min [Integer]
# @param max [Integer]
# @param grain [Integer]
#
# @return [Y2Storage::Region] adjusted region
def fix_region_end(region, min, max, grain)
if region.length < min
region.adjust_length(grain * ((min.to_f - region.length) / grain).ceil)
elsif region.length > max
region.adjust_length(grain * ((max.to_f - region.length) / grain).floor)
end
region
end
end
end
end
21 changes: 9 additions & 12 deletions src/lib/y2partitioner/dialogs/partition_resize.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ class PartitionResize < CWM::Dialog
# Constructor
#
# @param partition [Y2Storage::Partition] partition to resize
# @param resize_info [Y2Storage::ResizeInfo] partition resize info
def initialize(partition, resize_info)
def initialize(partition)
textdomain "storage"

@partition = partition
@resize_info = resize_info
detect_space_info
end

Expand All @@ -34,7 +32,7 @@ def title
def contents
HVSquash(
VBox(
SizeSelector.new(partition, resize_info),
SizeSelector.new(partition),
size_info
)
)
Expand All @@ -60,9 +58,6 @@ def should_open_dialog?
# @return [Y2Storage::Partition]
attr_reader :partition

# @return [Y2Storage::ResizeInfo]
attr_reader :resize_info

# @return [Y2Storage::SpaceInfo]
attr_reader :space_info

Expand Down Expand Up @@ -139,12 +134,10 @@ class SizeSelector < Widgets::ControllerRadioButtons
# Constructor
#
# @param partition [Y2Storage::Partition]
# @param resize_info [Y2Storage::ResizeInfo]
def initialize(partition, resize_info)
def initialize(partition)
textdomain "storage"

@partition = partition
@resize_info = resize_info
end

# @macro seeAbstractWidget
Expand Down Expand Up @@ -182,7 +175,7 @@ def init
# @macro seeAbstractWidget
# Updates the partition with the new size
def store
partition.size = current_widget.size
partition.resize(current_widget.size)
end

# @macro seeAbstractWidget
Expand Down Expand Up @@ -220,8 +213,12 @@ def validate
# @return [Y2Storage::Partition]
attr_reader :partition

# Resize information of the partition to be resized
#
# @return [Y2Storage::ResizeInfo]
attr_reader :resize_info
def resize_info
partition.resize_info
end

# Min possible size
#
Expand Down
4 changes: 4 additions & 0 deletions src/lib/y2storage/align_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
module Y2Storage
# Class to represent all the possible align types implemented by libstorage
#
# AlignType::REQUIRED can be used to align only to hard requirements.
# AlignType::OPTIMAL implies aligning to both hard requirements and topology
# information, which optimizes performance.
#
# This is a wrapper for the Storage::AlignType enum
class AlignType
include StorageEnumWrapper
Expand Down
12 changes: 12 additions & 0 deletions src/lib/y2storage/blk_device.rb
Original file line number Diff line number Diff line change
Expand Up @@ -397,5 +397,17 @@ def basename
def hwinfo
Y2Storage::HWInfoReader.instance.for_device(name)
end

# Size of the space that could be theoretically reclaimed by shrinking the
# device
#
# It does not guarantee the new free space can really be used. Other
# restrictions (like alignment or the max number of partitions) may apply.
#
# @return [DiskSize]
def recoverable_size
return DiskSize.zero unless resize_info.resize_ok?
size - resize_info.min_size
end
end
end
40 changes: 39 additions & 1 deletion src/lib/y2storage/device.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ class Device
# If the device has any children, they are also taken into account;
# the result of this method is the combined information about this device
# and all its children.
#
# Note that the minimal and maximal are not aligned.
#
# If the device already exists on the disk (i.e., in the probed
# devicegraph), this operation can be expensive. Thus, consider using
# {#resize_info} or any other caching mechanism.
#
# @see can_resize?
#
# @return [ResizeInfo]
Expand Down Expand Up @@ -206,6 +213,37 @@ def potential_orphans
[]
end

# Information about the possibility of resizing a given device.
#
# This method relies on {#detect_resize_info}, caching the result for the
# whole lifecycle of this object.
#
# Take into account that the lifecycle of a Y2Storage::Device object is
# usually sorter than the one of its corresponding libstorage-ng C++ object.
# Due to the nature of SWIG, every query to the devicegraph will return a
# new Y2Storage::Device object. This is actually convenient in this case to
# control the lifetime of the caching.
#
# @example Caching the #detect_resize_info result
#
# partition1 = disk.partitions.first
#
# partition1.resize_info # This calls #detect_resize_info
# @same_part = partition1
# @same_part.resize_info # Don't call #detect_resize_info, use cached
#
# disk.partitions.first.resize_info # This calls #detect_resize_info
# # because disk.partitions.first returns a new object representing
# # the same device than partition1 (but not the same object).
#
# @see #detect_resize_info
def resize_info
@resize_info ||= begin
log.info "Calling #detect_resize_info"
detect_resize_info
end
end

# Check if the device can be resized.
#
# If the device has any children, they are also taken into account;
Expand All @@ -218,7 +256,7 @@ def potential_orphans
#
# @return [Boolean] true if the device can be resized, false if not.
def can_resize?
detect_resize_info.resize_ok?
resize_info.resize_ok?
end

# Checks whether the device is a concrete kind(s) of device.
Expand Down
Loading

0 comments on commit 1831961

Please sign in to comment.