From 53ab7fc1e22913c82897231eb2175c4c835df579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imobach=20Gonz=C3=A1lez=20Sosa?= Date: Mon, 1 Oct 2018 14:23:49 +0100 Subject: [PATCH] Backport BlkDevice#component_of method --- src/lib/y2storage/blk_device.rb | 31 ++++++++++ test/y2storage/blk_device_test.rb | 97 +++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/src/lib/y2storage/blk_device.rb b/src/lib/y2storage/blk_device.rb index bf7cdea267..03409bad3f 100644 --- a/src/lib/y2storage/blk_device.rb +++ b/src/lib/y2storage/blk_device.rb @@ -361,6 +361,21 @@ def direct_md descendants.detect { |dev| dev.is?(:md) && dev.devices.include?(self) } end + # DM arrays defined on top of the device + # + # @return [Array] empty if the device is not used by any DM RAID + # device + def dm_raids + children.select { |dev| dev.is?(:dm_raid) } + end + + # Multipath device defined on top of the device + # + # @return [Multipath, nil] nil if the device is not part of any multipath + def multipath + children.find { |dev| dev.is?(:multipath) } + end + # Whether the device forms part of an LVM or MD RAID # # @return [Boolean] @@ -368,6 +383,22 @@ def part_of_lvm_or_md? !lvm_pv.nil? || !md.nil? end + # Devices built on top of this device, to be used mainly by the Partitioner + # to display which devices are using this one as its base. + # + # This does not include all the descendants, but only those multi-device + # devices for which this is one of the components. For example, it will + # include any LVM VG for which this device is one of its physical volumes + # (directly or through an encryption) or any RAID having this device as + # one of its members. + # + # @return [Array] a collection of MD RAIDs, DM RAIDs, volume groups, + # and multipath devices + def component_of + vg = lvm_pv ? lvm_pv.lvm_vg : nil + (dm_raids + [vg] + [md] + [multipath]).compact + end + # Label of the filesystem, if any # @return [String, nil] def filesystem_label diff --git a/test/y2storage/blk_device_test.rb b/test/y2storage/blk_device_test.rb index baf64bbcc8..b94f47fca7 100644 --- a/test/y2storage/blk_device_test.rb +++ b/test/y2storage/blk_device_test.rb @@ -678,6 +678,103 @@ end end + describe "#component_of" do + context "for a device not used in an LVM or in a RAID or in multipath" do + let(:scenario) { "mixed_disks" } + let(:device_name) { "/dev/sda1" } + + it "returns an empty array" do + expect(device.component_of).to eq [] + end + end + + context "for a device that is part of several DM RAIDs" do + let(:scenario) { "empty-dm_raids.xml" } + let(:device_name) { "/dev/sdb" } + + it "returns an array with all the corresponding DM RAIDs" do + expect(device.component_of.size).to eq 2 + expect(device.component_of).to all(be_a(Y2Storage::DmRaid)) + expect(device.component_of.map(&:name)).to contain_exactly( + "/dev/mapper/isw_ddgdcbibhd_test1", "/dev/mapper/isw_ddgdcbibhd_test2" + ) + end + end + + context "for a device directly used in an LVM" do + let(:scenario) { "complex-lvm-encrypt" } + let(:device_name) { "/dev/sde2" } + + it "returns an array with the LVM VG" do + expect(device.component_of.size).to eq 1 + expect(device.component_of.first).to be_a Y2Storage::LvmVg + expect(device.component_of.first.name).to eq "/dev/vg1" + end + end + + context "for an encrypted device directly used in an LVM" do + let(:scenario) { "complex-lvm-encrypt" } + let(:device_name) { "/dev/sde1" } + + it "returns an array with the LVM VG" do + expect(device.component_of.size).to eq 1 + expect(device.component_of.first).to be_a Y2Storage::LvmVg + expect(device.component_of.first.name).to eq "/dev/vg0" + end + end + + context "for a disk used indirectly (through its partitions) in an LVM" do + let(:scenario) { "complex-lvm-encrypt" } + let(:device_name) { "/dev/sde" } + + it "returns an empty array" do + expect(device.component_of).to eq [] + end + end + + context "for a device directly used in an MD RAID" do + let(:scenario) { "subvolumes-and-empty-md.xml" } + let(:device_name) { "/dev/sda4" } + + it "returns an array with the MD RAID" do + expect(device.component_of.size).to eq 1 + expect(device.component_of.first).to be_a Y2Storage::Md + expect(device.component_of.first.name).to eq "/dev/md/strip0" + end + end + + context "for an encrypted device directly used in an MD RAID" do + let(:scenario) { "subvolumes-and-empty-md.xml" } + let(:device_name) { "/dev/sda5" } + + it "returns an array with the MD RAID" do + expect(device.component_of.size).to eq 1 + expect(device.component_of.first).to be_a Y2Storage::Md + expect(device.component_of.first.name).to eq "/dev/md/strip0" + end + end + + context "for a disk used indirectly (through its partitions) in an MD RAID" do + let(:scenario) { "subvolumes-and-empty-md.xml" } + let(:device_name) { "/dev/sda" } + + it "returns an empty array" do + expect(device.component_of).to eq [] + end + end + + context "for a disk that is part of a multipath setup" do + let(:scenario) { "multipath-formatted.xml" } + let(:device_name) { "/dev/sda" } + + it "returns an array with the multipath device" do + expect(device.component_of.size).to eq 1 + expect(device.component_of.first).to be_a Y2Storage::Multipath + expect(device.component_of.first.name).to eq "/dev/mapper/0QEMU_QEMU_HARDDISK_mpath1" + end + end + end + describe "#hwinfo" do let(:device_name) { "/dev/sda" }