From c4ac60190b7ab858372d387df051ff91f0d7c5cc Mon Sep 17 00:00:00 2001 From: Ancor Gonzalez Sosa Date: Thu, 19 Oct 2023 15:47:56 +0200 Subject: [PATCH 1/3] Fix inconsistences in test devicegraph --- .../data/devicegraphs/autoyast_drive_examples.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/test/data/devicegraphs/autoyast_drive_examples.yml b/test/data/devicegraphs/autoyast_drive_examples.yml index 9293826fcd..b28e57c9ec 100644 --- a/test/data/devicegraphs/autoyast_drive_examples.yml +++ b/test/data/devicegraphs/autoyast_drive_examples.yml @@ -40,9 +40,9 @@ - partition: size: 1 GiB name: /dev/dasdb1 + id: swap file_system: swap - mount_point: swap - label: swap + label: swap_dasdb - partition: size: 6 GiB @@ -73,8 +73,7 @@ name: /dev/sdc2 id: swap file_system: swap - mount_point: swap - label: swap + label: swap_sdc - partition: size: 20 GiB @@ -162,7 +161,7 @@ type: logical id: swap file_system: swap - mount_point: swap + label: swap_sdd - partition: size: 10 GiB @@ -215,6 +214,7 @@ type: logical id: swap file_system: swap + label: swap_sdf - partition: size: 10 GiB @@ -265,8 +265,7 @@ name: /dev/sdaa2 id: swap file_system: swap - mount_point: swap - label: swap + label: swap_sdaa - partition: size: 20 GiB @@ -328,7 +327,7 @@ name: /dev/sdh3 id: swap file_system: swap - mount_point: swap + label: swap_sdh # Btrfs with default_subvolume set to "" - disk: From 4633c2de91e2de0f83dcb053fd72ac265d1f0a6c Mon Sep 17 00:00:00 2001 From: Ancor Gonzalez Sosa Date: Thu, 19 Oct 2023 16:44:45 +0200 Subject: [PATCH 2/3] [Proposal] New internal setting swap_reuse --- src/lib/y2storage/proposal/devices_planner.rb | 25 ++- src/lib/y2storage/proposal_settings.rb | 10 ++ test/y2storage/proposal_swap_reuse_test.rb | 147 ++++++++++++++++++ 3 files changed, 179 insertions(+), 3 deletions(-) create mode 100755 test/y2storage/proposal_swap_reuse_test.rb diff --git a/src/lib/y2storage/proposal/devices_planner.rb b/src/lib/y2storage/proposal/devices_planner.rb index 6cbedae0b5..4100dc1078 100644 --- a/src/lib/y2storage/proposal/devices_planner.rb +++ b/src/lib/y2storage/proposal/devices_planner.rb @@ -93,21 +93,40 @@ def planned_boot_devices(planned_devices) # @param required_size [DiskSize] # @return [Partition] def reusable_swap(required_size) - return nil if settings.use_lvm || settings.use_encryption + return nil if skip_swap_reuse? partitions = available_swap_partitions - partitions.select! { |part| part.size >= required_size } + partitions.select! { |part| can_be_reused?(part, required_size) } # Use #name in case of #size tie to provide stable sorting partitions.min_by { |part| [part.size, part.name] } end - # Returns all avaiable swap partitions + # Returns all available and acceptable swap partitions # # @return [Array] def available_swap_partitions devicegraph.partitions.select(&:swap?) end + # Whether reusing swap partitions is pointless + # + # @return [Boolean] + def skip_swap_reuse? + settings.use_lvm || settings.use_encryption || settings.swap_reuse == :none + end + + # Whether it is acceptable to reuse the given swap partition + # + # @param partition [Partition] + # @param required_size [DiskSize] + # @return [Boolean] + def can_be_reused?(partition, required_size) + return false if partition.size < required_size + return true unless settings.swap_reuse == :candidate + + settings.candidate_devices.include?(partition.partitionable.name) + end + # Delete shadowed subvolumes from each planned device # @param planned_devices [Array] devices that have been planned def remove_shadowed_subvolumes(planned_devices) diff --git a/src/lib/y2storage/proposal_settings.rb b/src/lib/y2storage/proposal_settings.rb index df50dff656..be6dc919a0 100644 --- a/src/lib/y2storage/proposal_settings.rb +++ b/src/lib/y2storage/proposal_settings.rb @@ -62,6 +62,15 @@ class ProposalSettings # available candidate devices. attr_accessor :multidisk_first + # Criteria to use if it is possible to reuse an existing swap partition + # + # * :any reuse a suitable swap partition from any disk, default historical behavior of YaST + # * :none do not reuse existing swap partitions + # * :candidate reuse a suitable partition only if it is located in a candidate disk + # + # @return [:any, :none, :candidate] + attr_accessor :swap_reuse + # Device name of the disk in which '/' must be placed. # # If it's set to nil and {#allocate_volume_mode} is :auto, the proposal will try @@ -388,6 +397,7 @@ def root_volume other_delete_mode: :ondemand, resize_windows: true, separate_vgs: false, + swap_reuse: :any, volumes: [], windows_delete_mode: :ondemand } diff --git a/test/y2storage/proposal_swap_reuse_test.rb b/test/y2storage/proposal_swap_reuse_test.rb new file mode 100755 index 0000000000..ac830a0a76 --- /dev/null +++ b/test/y2storage/proposal_swap_reuse_test.rb @@ -0,0 +1,147 @@ +#!/usr/bin/env rspec +# Copyright (c) [2023] SUSE LLC +# +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, contact SUSE LLC. +# +# To contact SUSE LLC about this file by physical or electronic mail, you may +# find current contact information at www.suse.com. + +require_relative "spec_helper" +require "storage" +require "y2storage" +require_relative "#{TEST_PATH}/support/proposal_examples" +require_relative "#{TEST_PATH}/support/proposal_context" + +describe Y2Storage::GuidedProposal do + describe "#propose in a system with pre-existing swap partitions" do + subject(:proposal) { described_class.new(settings: settings) } + + include_context "proposal" + let(:architecture) { :x86 } + let(:settings_format) { :ng } + let(:control_file_content) do + { "partitioning" => { "volumes" => volumes } } + end + + let(:scenario) { "autoyast_drive_examples" } + + let(:volumes) { [root_vol, swap_vol] } + let(:root_vol) do + { "mount_point" => "/", "fs_type" => "xfs", "min_size" => "5 GiB", "max_size" => "30 GiB" } + end + let(:swap_vol) do + { "mount_point" => "swap", "fs_type" => "swap", "min_size" => "500 MiB", "max_size" => "2 GiB" } + end + + RSpec.shared_examples "reuse best swap" do + it "reuses the pre-existing swap with more suitable size" do + proposal.propose + dasdb1 = proposal.devices.find_by_name("/dev/dasdb1") + expect(dasdb1.exists_in_probed?).to eq true + expect(dasdb1).to have_attributes( + # This proves is mounted as swap + filesystem_mountpoint: "swap", + # This proves is not re-formatted + filesystem_label: "swap_dasdb", + size: Y2Storage::DiskSize.GiB(1) + ) + end + end + + RSpec.shared_examples "new swap" do + it "creates a new swap partition" do + proposal.propose + swap = proposal.devices.partitions.find { |p| p.filesystem&.mount_path == "swap" } + expect(swap.exists_in_probed?).to eq false + # All preexisting partitions have some label + expect(swap.filesystem.label).to be_empty + end + end + + before { settings.candidate_devices = [candidate] } + + context "when swap_reuse is set to :any" do + before { settings.swap_reuse = :any } + + context "and there is no swap in the candidate devices" do + let(:candidate) { "/dev/sda" } + + include_examples "reuse best swap" + end + + context "and there is a swap device (not the best regarding size) in the candidate devices" do + let(:candidate) { "/dev/sdc" } + + include_examples "reuse best swap" + end + + context "and the best swap device in the candidate devices" do + let(:candidate) { "/dev/dasdb" } + + include_examples "reuse best swap" + end + end + + context "when swap_reuse is set to :none" do + before { settings.swap_reuse = :none } + + context "and there is no swap in the candidate devices" do + let(:candidate) { "/dev/sda" } + + include_examples "new swap" + end + + context "and there is a swap device (not the biggest one) in the candidate devices" do + let(:candidate) { "/dev/sdc" } + + include_examples "new swap" + end + + context "and the biggest swap device in the candidate devices" do + let(:candidate) { "/dev/dasdb" } + + include_examples "new swap" + end + end + + context "when swap_reuse is set to :candidate" do + before { settings.swap_reuse = :candidate } + + context "and there is no swap in the candidate devices" do + let(:candidate) { "/dev/sda" } + + include_examples "new swap" + end + + context "and there is a swap device (not the biggest one) in the candidate devices" do + let(:candidate) { "/dev/sdc" } + + it "reuses the swap partition from the candidate devices" do + proposal.propose + swap = proposal.devices.partitions.find { |p| p.filesystem&.mount_path == "swap" } + expect(swap.exists_in_probed?).to eq true + expect(swap.name).to eq "/dev/sdc2" + expect(swap.filesystem.label).to eq "swap_sdc" + end + end + + context "and the biggest swap device in the candidate devices" do + let(:candidate) { "/dev/dasdb" } + + include_examples "reuse best swap" + end + end + end +end From 10703fd31079786d1aa6e9def74ab87617bb20c7 Mon Sep 17 00:00:00 2001 From: Ancor Gonzalez Sosa Date: Thu, 19 Oct 2023 16:51:12 +0200 Subject: [PATCH 3/3] Version and changelog --- package/yast2-storage-ng.changes | 8 ++++++++ package/yast2-storage-ng.spec | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/package/yast2-storage-ng.changes b/package/yast2-storage-ng.changes index 6bdc43f07a..61e19f45f4 100644 --- a/package/yast2-storage-ng.changes +++ b/package/yast2-storage-ng.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Thu Oct 19 14:46:45 UTC 2023 - Ancor Gonzalez Sosa + +- GuidedProposal: new internal setting to control how existing + swap partitions are reused. Relevant for Agama and related to + bsc#1175535 and bsc#1215639. +- 5.0.3 + ------------------------------------------------------------------- Wed Oct 11 08:41:15 UTC 2023 - Ancor Gonzalez Sosa diff --git a/package/yast2-storage-ng.spec b/package/yast2-storage-ng.spec index 626062c8ef..6374816c77 100644 --- a/package/yast2-storage-ng.spec +++ b/package/yast2-storage-ng.spec @@ -16,7 +16,7 @@ # Name: yast2-storage-ng -Version: 5.0.2 +Version: 5.0.3 Release: 0 Summary: YaST2 - Storage Configuration License: GPL-2.0-only OR GPL-3.0-only