Skip to content

Commit

Permalink
feat: Add support for setting stripe size for LVM RAID
Browse files Browse the repository at this point in the history
Custom stripe size is required for SAP HANA setups.
  • Loading branch information
vojtechtrefny committed May 23, 2023
1 parent cedb313 commit bfec922
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 15 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ When type is `raid` specifies RAID metadata version as a string, e.g.: '1.0'.
When type is `raid` specifies RAID chunk size as a string, e.g.: '512 KiB'.
Chunk size has to be multiple of 4 KiB.

##### `raid_stripe_size`
When type is `lvm` specifies LVM RAID stripe size as a string, e.g.: '512 KiB'.

##### `raid_disks`
Specifies which disks should be used for LVM RAID volume.
`raid_level` needs to be specified and volume has to have `storage_pools` parent with type `lvm`.
Expand Down
1 change: 1 addition & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ storage_volume_defaults:
raid_device_count: null
raid_spare_count: null
raid_chunk_size: null
raid_stripe_size: null
raid_metadata_version: null

encryption: false
Expand Down
7 changes: 6 additions & 1 deletion library/blivet.py
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,11 @@ def _get_params_lvmraid(self):
else:
pvs = parent_device.pvs

return dict(seg_type=self._volume['raid_level'], pvs=pvs)
# get stripe size
stripe_size = self._spec_dict.get("raid_stripe_size")
stripe_size = Size(stripe_size) if stripe_size is not None else None

return dict(seg_type=self._volume['raid_level'], pvs=pvs, stripe_size=stripe_size)

def _detach_cache(self):
""" Detach cache from the volume and remove the unused cache pool """
Expand Down Expand Up @@ -1755,6 +1759,7 @@ def run_module():
compression=dict(type='bool'),
deduplication=dict(type='bool'),
raid_disks=dict(type='list', elements='str', default=list()),
raid_stripe_size=dict(type='str'),
thin_pool_name=dict(type='str'),
thin_pool_size=dict(type='str'),
thin=dict(type='bool', default=False),
Expand Down
70 changes: 70 additions & 0 deletions tests/tests_create_raid_pool_then_remove.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,32 @@
- packages_installed
- service_facts

- name: Gather package facts
package_facts:

- name: Set blivet package name
set_fact:
blivet_pkg_name: "{{ ansible_facts.packages |
select('search', 'blivet') | select('search', 'python') | list }}"

- name: Set blivet package version
set_fact:
blivet_pkg_version: "{{
ansible_facts.packages[blivet_pkg_name[0]][0]['version'] +
'-' + ansible_facts.packages[blivet_pkg_name[0]][0]['release'] }}"

- name: Set distribution version
set_fact:
is_rhel9: "{{ (ansible_facts.distribution == 'CentOS' or
ansible_facts.distribution == 'Enterprise Linux' or
ansible_facts.distribution == 'RedHat') and
ansible_facts.distribution_major_version == '9' }}"
is_rhel8: "{{ (ansible_facts.distribution == 'CentOS' or
ansible_facts.distribution == 'Enterprise Linux' or
ansible_facts.distribution == 'RedHat') and
ansible_facts.distribution_major_version == '8' }}"
is_fedora: "{{ ansible_facts.distribution == 'Fedora' }}"

- name: Get unused disks
include_tasks: get_unused_disk.yml
vars:
Expand Down Expand Up @@ -217,3 +243,47 @@

- name: Verify role results
include_tasks: verify-role-results.yml

- name: Run test on supported platforms
when: ((is_fedora and blivet_pkg_version is version("3.7.1-2", ">=")) or
(is_rhel8 and blivet_pkg_version is version("3.6.0-5", ">=")) or
(is_rhel9 and blivet_pkg_version is version("3.6.0-6", ">=")))
block:
- name: Create a RAID0 lvm raid device with custom stripe size
include_role:
name: linux-system-roles.storage
vars:
storage_pools:
- name: vg1
disks: "{{ unused_disks }}"
type: lvm
state: present
volumes:
- name: lv1
size: "{{ volume1_size }}"
mount_point: "{{ mount_location1 }}"
raid_disks: "{{ [unused_disks[0], unused_disks[1]] }}"
raid_level: raid0
raid_stripe_size: "256 KiB"

- name: Verify role results
include_tasks: verify-role-results.yml

- name: Remove the device created above
include_role:
name: linux-system-roles.storage
vars:
storage_pools:
- name: vg1
disks: "{{ unused_disks }}"
type: lvm
state: absent
volumes:
- name: lv1
size: "{{ volume1_size }}"
mount_point: "{{ mount_location1 }}"
raid_level: raid0
raid_disks: "{{ [unused_disks[0], unused_disks[1]] }}"

- name: Verify role results
include_tasks: verify-role-results.yml
57 changes: 43 additions & 14 deletions tests/verify-pool-member-lvmraid.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,50 @@
- storage_test_pool.state != "absent"
- storage_test_lvmraid_volume.state != "absent"
block:
- name: Get information about LVM RAID
# yamllint disable rule:line-length
command: >-
lvs --noheading -o lv_name --select
'lv_name={{ storage_test_lvmraid_volume.name }}&&lv_layout={{ storage_test_lvmraid_volume.raid_level }}'
{{ storage_test_pool.name }}
register: storage_test_lvmraid_status
- name: Get information about the LV
command: >
lvs --noheadings --nameprefixes --units=b --nosuffix --unquoted
-o name,segtype,stripe_size
{{ storage_test_pool.name }}/{{ storage_test_lvmraid_volume.name }}
register: lvs
changed_when: false
# yamllint enable rule:line-length

- name: Check that volume is LVM RAID
- name: Set LV segment type
set_fact:
storage_test_lv_segtype: "{{ lvs.stdout |
regex_search('LVM2_SEGTYPE=(\\S+)', '\\1') }}"

- name: Check segment type
assert:
that: storage_test_lvmraid_status.stdout | trim ==
storage_test_lvmraid_volume.name
that: storage_test_lv_segtype[0] ==
storage_test_lvmraid_volume.raid_level
msg: >-
Unexpected segtype {{ storage_test_lv_segtype }}
for {{ storage_test_lvmraid_volume.name }}
- name: Set LV stripe size
set_fact:
storage_test_lv_stripe_size: "{{ lvs.stdout |
regex_search('LVM2_STRIPE_SIZE=(\\S+)', '\\1') }}"

- name: Parse the requested stripe size
bsize:
size: "{{ storage_test_lvmraid_volume.raid_stripe_size }}"
register: storage_test_requested_stripe_size
when: storage_test_lvmraid_volume.raid_stripe_size is not none

- name: Reset variable used by test
set_fact:
storage_test_lvmraid_status: null
- name: Set expected stripe size
set_fact:
storage_test_expected_stripe_size: "{{
storage_test_requested_stripe_size.bytes }}"
when: storage_test_lvmraid_volume.raid_stripe_size is not none

- name: Check stripe size
assert:
that: storage_test_expected_stripe_size | int ==
storage_test_lv_stripe_size[0] | int
msg: >
Unexpected stripe size, expected
{{ storage_test_expected_stripe_size }},
got {{ storage_test_lv_stripe_size[0] }}
when: storage_test_lvmraid_volume.raid_stripe_size is not none

0 comments on commit bfec922

Please sign in to comment.