├── puppet ├── files │ ├── standby-check.sh │ ├── fence_legacy.pl │ └── ha_resource_anything.sh ├── manifests │ ├── mdadm.pp │ ├── params.pp │ ├── iscsi.pp │ ├── stonith.pp │ ├── init.pp │ ├── drbd.pp │ ├── packages.pp │ ├── network.pp │ ├── ssdtune │ │ └── server.pp │ ├── ha.pp │ └── ha_resource.pp ├── tempaltes │ ├── iscsi_settings.sh.erb │ ├── vm.pp │ └── lvm.conf.erb └── hiera_example.yaml ├── .whitesource ├── .eslintignore ├── .prettierignore ├── README.md ├── .github ├── workflows │ ├── todo.yml │ ├── codeball.yml │ ├── label-sync.yml │ ├── lint-pr-actions.yml │ ├── pr-labeller.yml │ ├── lint-pr-markdown.yml │ └── lint-pr-actions-skip.yml ├── PULL_REQUEST_TEMPLATE.md ├── renovate.json └── config │ ├── labels.yml │ └── labeller.yml ├── .editorconfig ├── LICENSE └── .gitignore /puppet/files/standby-check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | crm node show $HOSTNAME |grep -q 'standby=on' 4 | STANDBY_OFF=$? 5 | 6 | if [ $STANDBY_OFF -eq 1 ]; then 7 | echo "WARNING: This node is NOT in standby! Maybe you want to run crm node standby $HOSTNAME?" 8 | fi -------------------------------------------------------------------------------- /puppet/manifests/mdadm.pp: -------------------------------------------------------------------------------- 1 | class ixastorage::mdadm($arrays) { 2 | class { '::mdadm' : } 3 | 4 | create_resources('mdadm',$arrays) 5 | 6 | ## Speed up resync 7 | augeas::sysctl::conf { 8 | 'dev.raid.speed_limit_max': value => '999999999'; 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /.whitesource: -------------------------------------------------------------------------------- 1 | { 2 | "scanSettings": { 3 | "baseBranches": [] 4 | }, 5 | "checkRunSettings": { 6 | "vulnerableCheckRunConclusionLevel": "failure", 7 | "displayMode": "diff", 8 | "useMendCheckNames": true 9 | }, 10 | "issueSettings": { 11 | "minSeverityLevel": "MEDIUM", 12 | "issueType": "DEPENDENCY" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW #### 2 | 3 | .ide 4 | .idea 5 | .vscode 6 | **/__pycache__ 7 | **/__pypackages__ 8 | **/.bin 9 | **/.DS_Store 10 | **/.env.* 11 | **/.git 12 | **/.out 13 | **/.venv 14 | **/*.log 15 | **/*.tmp 16 | **/build 17 | **/cdk.out 18 | **/coverage 19 | **/dist 20 | **/global.setup.ts 21 | **/htmlcov 22 | **/logs 23 | **/node_modules 24 | **/public 25 | **/temp 26 | **/tmp 27 | **/venv 28 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW #### 2 | 3 | .ide 4 | .idea 5 | .vscode 6 | **/__pycache__ 7 | **/__pypackages__ 8 | **/.bin 9 | **/.DS_Store 10 | **/.env.* 11 | **/.git 12 | **/.out 13 | **/.venv 14 | **/*.log 15 | **/*.tmp 16 | **/build 17 | **/cdk.out 18 | **/coverage 19 | **/dist 20 | **/global.setup.ts 21 | **/htmlcov 22 | **/logs 23 | **/node_modules 24 | **/public 25 | **/temp 26 | **/tmp 27 | **/venv 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Open Source, Code Controlled, Enterprise Ready SSD Storage 2 | 3 | Coming soon - In the mean time you can read [my high-level post](http://smcleod.net/building-a-high-performance-ssd-san) on the project from earlier this year. 4 | 5 | [smcleod.net](https://smcleod.net) 6 | 7 | ![](http://everycity.co.uk/wp-content/uploads/2014/02/NVMe_Logo_White.jpg) 8 | ![img_5081](https://cloud.githubusercontent.com/assets/862951/7130857/5a7c2a80-e2ba-11e4-9eea-41102e15ceaf.jpg) 9 | -------------------------------------------------------------------------------- /puppet/manifests/params.pp: -------------------------------------------------------------------------------- 1 | # Class: ixastorage::params 2 | 3 | class ixastorage::params { 4 | 5 | ## Read data from Hiera 6 | $storage_group_hash=hiera_hash("storage_$storage_group") 7 | $network_settings=hiera_hash('network_storage') 8 | $storage_hostnames=keys($ixastorage::params::storage_group_hash['storage_hosts']) 9 | 10 | ## Merge host data to get a list of unicast ip addresses 11 | $storage_unicast_addresses=extracthashvals($storage_group_hash['storage_hosts'],'corosync_ip') 12 | $unicast_addresses=$storage_unicast_addresses 13 | 14 | } -------------------------------------------------------------------------------- /puppet/tempaltes/iscsi_settings.sh.erb: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Dodgy script to enable additional iSCSI settings 4 | # Can be removed when https://github.com/ClusterLabs/resource-agents/issues/610 is resolved. 5 | 6 | trap "exit 0" SIGTERM 7 | 8 | # Enable discard etc... 9 | nice -10 find /sys/kernel/config/target/core/ -regextype awk -regex '(.*)emulate_(tpu|3pc|caw)' -exec sh -c 'echo "1" > {}' \; 10 | 11 | # safety net incase anyone runs targetcli by hand 12 | nice -10 targetcli set global auto_save_on_exit=false 13 | 14 | while :; do 15 | nice -10 sleep 1 16 | done -------------------------------------------------------------------------------- /.github/workflows/todo.yml: -------------------------------------------------------------------------------- 1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW #### 2 | 3 | name: "Check for TODOs and create or update issues" 4 | 5 | on: ["push"] 6 | 7 | permissions: 8 | issues: write 9 | contents: read 10 | 11 | # One build per branch, cancel out of date builds 12 | concurrency: 13 | group: ${{ github.workflow }}-${{ github.ref }} 14 | cancel-in-progress: true 15 | 16 | jobs: 17 | todo-issues: 18 | runs-on: "ubuntu-latest" 19 | steps: 20 | - uses: "actions/checkout@v3" 21 | - name: "Check for TODOs and create or update issues" 22 | uses: "alstr/todo-to-issue-action@v4" 23 | id: "todo" 24 | -------------------------------------------------------------------------------- /.github/workflows/codeball.yml: -------------------------------------------------------------------------------- 1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW #### 2 | 3 | name: Codeball 4 | 5 | on: 6 | pull_request: 7 | workflow_dispatch: 8 | 9 | permissions: 10 | contents: read 11 | issues: write 12 | pull-requests: write 13 | checks: write 14 | 15 | jobs: 16 | codeball-review: 17 | runs-on: ubuntu-latest 18 | name: Run Codeball Code Review 19 | steps: 20 | - name: Codeball AI Actions 21 | uses: sturdy-dev/codeball-action@v2 22 | with: 23 | approvePullRequests: "false" 24 | labelPullRequestsWhenApproved: "true" 25 | labelPullRequestsWhenReviewNeeded: "true" 26 | failJobsWhenReviewNeeded: "false" 27 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW #### 2 | 3 | # EditorConfig https://EditorConfig.org 4 | 5 | # top-most EditorConfig file 6 | root = true 7 | 8 | # Unix-style newlines with a newline ending every file 9 | [*] 10 | end_of_line = lf 11 | insert_final_newline = true 12 | trim_trailing_whitespace = true 13 | charset = utf-8 14 | 15 | # Ensure we're standardising on 2 space soft-tabs for most files 16 | [*.md, *.markdown, *.yml, *.yaml, *.json, *.js, *.ts, *.tsx, *.sh] 17 | indent_style = space 18 | indent_size = 2 19 | 20 | # Makefile specific 21 | [Makefile] 22 | indent_style = tab 23 | indent_size = 4 24 | 25 | # Python specific 26 | [*.py, *.pyi] 27 | indent_style = space 28 | indent_size = 4 29 | -------------------------------------------------------------------------------- /.github/workflows/label-sync.yml: -------------------------------------------------------------------------------- 1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW #### 2 | 3 | name: "Sync Available Github Labels" 4 | 5 | on: 6 | workflow_dispatch: 7 | schedule: 8 | - cron: "30 4 * * *" 9 | 10 | permissions: 11 | pull-requests: write 12 | contents: read 13 | 14 | # One build per branch, cancel out of date builds 15 | concurrency: 16 | group: ${{ github.workflow }}-${{ github.ref }} 17 | cancel-in-progress: true 18 | 19 | jobs: 20 | sync-labels: 21 | name: Sync Github Labels 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v3 25 | - uses: EndBug/label-sync@v2 26 | with: 27 | delete-other-labels: true 28 | dry-run: false 29 | token: ${{ secrets.GITHUB_TOKEN }} 30 | config-file: .github/config/labels.yml 31 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. 4 | 5 | Fixes # 6 | 7 | ## Breaking Changes 8 | 9 | Are there any breaking changes in this PR, If yes, please list them. 10 | 11 | ## How Has This Been Tested? 12 | 13 | Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration 14 | 15 | - Test 1 16 | - Test 2 17 | 18 | ## Checklist 19 | 20 | - [ ] I have performed a self-review of my own code. 21 | - [ ] I have commented my code, particularly in hard-to-understand areas. 22 | - [ ] I have made corresponding changes to the documentation. 23 | - [ ] My changes generate no new warnings. 24 | -------------------------------------------------------------------------------- /.github/workflows/lint-pr-actions.yml: -------------------------------------------------------------------------------- 1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW #### 2 | 3 | name: "Lint Github Actions Workflows" 4 | on: 5 | pull_request: 6 | types: 7 | - opened 8 | - edited 9 | - reopened 10 | - synchronize 11 | branches: 12 | - "main" 13 | paths: 14 | - ".github/**" 15 | 16 | permissions: 17 | contents: read 18 | pull-requests: write 19 | checks: write 20 | 21 | jobs: 22 | lint-actions-workflows: 23 | name: Lint Actions Workflows 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v3 27 | - uses: reviewdog/action-actionlint@v1 28 | with: 29 | actionlint_flags: -color -ignore 'SC2086' -ignore 'SC2129' 30 | fail_on_error: false 31 | level: error 32 | reporter: github-pr-review 33 | env: 34 | REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} 35 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 36 | -------------------------------------------------------------------------------- /.github/workflows/pr-labeller.yml: -------------------------------------------------------------------------------- 1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW #### 2 | 3 | name: "Pull Request Labeller" 4 | on: 5 | pull_request: 6 | types: 7 | - opened 8 | - edited 9 | - reopened 10 | - synchronize 11 | - ready_for_review 12 | branches: 13 | - main 14 | - master 15 | issues: 16 | issue_comment: 17 | 18 | # One build per branch, cancel out of date builds 19 | concurrency: 20 | group: ${{ github.workflow }}-${{ github.ref }} 21 | cancel-in-progress: true 22 | 23 | permissions: 24 | issues: write 25 | pull-requests: write 26 | statuses: write 27 | checks: write 28 | contents: read 29 | 30 | jobs: 31 | pr-labeller: 32 | name: "Pull Request Labeller" 33 | runs-on: ubuntu-latest 34 | steps: 35 | - uses: fuxingloh/multi-labeler@v1 36 | id: pr-labeller 37 | with: 38 | github-token: ${{ secrets.GITHUB_TOKEN }} 39 | config-path: .github/config/labeller.yml 40 | -------------------------------------------------------------------------------- /.github/workflows/lint-pr-markdown.yml: -------------------------------------------------------------------------------- 1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW #### 2 | 3 | name: Lint Markdown Files 4 | 5 | # https://github.com/reviewdog/action-markdownlint 6 | 7 | on: 8 | pull_request: 9 | workflow_dispatch: 10 | 11 | permissions: 12 | contents: read 13 | checks: write 14 | pull-requests: write 15 | 16 | # One build per branch, cancel out of date builds 17 | concurrency: 18 | group: ${{ github.workflow }}-${{ github.ref }} 19 | cancel-in-progress: true 20 | 21 | jobs: 22 | lint-markdown: 23 | name: Lint Markdown 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v3 27 | - name: markdownlint 28 | uses: reviewdog/action-markdownlint@v0 29 | with: 30 | github_token: ${{ secrets.GITHUB_TOKEN }} 31 | reporter: github-pr-review 32 | level: error 33 | filter_mode: added 34 | fail_on_error: false 35 | ### Flags for markdownlint-cli ### 36 | # markdownlint_flags: . 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Sam McLeod 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /puppet/manifests/iscsi.pp: -------------------------------------------------------------------------------- 1 | class ixastorage::iscsi { 2 | include ixastorage::params 3 | 4 | ## ConfigFS for LIO iSCSI 5 | 6 | mount { '/sys/kernel/config': 7 | ensure => present, 8 | atboot => true, 9 | device => 'configfs', 10 | fstype => 'configfs', 11 | require => Package['targetcli'], 12 | } 13 | 14 | # Force targetcli to NOT create default portal, or else our more specific ones fail 15 | rclocal::script { 'dont-add-default-portal': 16 | priority => '12', 17 | content => "targetcli set global auto_add_default_portal=false \n", 18 | notify => Exec['dont-add-default-portal'], 19 | require => Package['targetcli'], 20 | } 21 | 22 | exec { 'dont-add-default-portal': # so it works without a reboot 23 | command => 'targetcli set global auto_add_default_portal=false', 24 | refreshonly => true, 25 | require => Package['targetcli'], 26 | } 27 | 28 | file { '/etc/modprobe.d/scsi_mod.conf': 29 | ensure => file, 30 | content => 'options scsi_mod use_blk_mq=Y', 31 | owner => 'root', 32 | group => 'root', 33 | mode => 0644, 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /.github/workflows/lint-pr-actions-skip.yml: -------------------------------------------------------------------------------- 1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW #### 2 | 3 | name: "Lint Github Actions Workflows" 4 | 5 | # This is a gross hack to allow PRs that don't require a specific workflow to run (e.g. don't lint files not touched) by providing a positive status check in their place. 6 | # This workflow runs on an inverse match using the paths-ignore filter, so it will only run if the PR doesn't touch any of the paths that the other linting workflow does 7 | # The "name:" must match the name of the workflow it's skipping. 8 | # As recommended by Github - https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks 9 | 10 | on: 11 | pull_request: 12 | types: 13 | - opened 14 | - edited 15 | - reopened 16 | - synchronize 17 | branches: 18 | - "main" 19 | paths-ignore: 20 | - ".github/**" 21 | 22 | jobs: 23 | lint-actions-workflows: 24 | name: Lint Actions Workflows 25 | runs-on: ubuntu-latest 26 | steps: 27 | - run: echo "This workflow is a placeholder for PRs that don't require linting of Github Actions workflows" 28 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["config:base"], 3 | "commitMessagePrefix": "chore(renovate):", 4 | "description": "This file is managed in template-repo", 5 | "packageRules": [ 6 | { 7 | "matchPackagePatterns": ["*"], 8 | "matchUpdateTypes": ["major"], 9 | "reviewersFromCodeOwners": true, 10 | "addLabels": ["renovatebot", "major", "version-update"], 11 | "commitMessagePrefix": "chore(renovate): major", 12 | "groupName": "major" 13 | }, 14 | { 15 | "matchPackagePatterns": ["*"], 16 | "matchUpdateTypes": ["minor"], 17 | "reviewersFromCodeOwners": true, 18 | "addLabels": ["renovatebot", "minor", "version-update"], 19 | "commitMessagePrefix": "chore(renovate): minor", 20 | "groupName": "minor" 21 | }, 22 | { 23 | "matchPackagePatterns": ["*"], 24 | "matchUpdateTypes": ["patch"], 25 | "reviewersFromCodeOwners": true, 26 | "addLabels": ["renovatebot", "patch", "version-update"], 27 | "commitMessagePrefix": "chore(renovate): patch", 28 | "groupName": "patch" 29 | }, 30 | { 31 | "matchPackagePatterns": ["*"], 32 | "matchUpdateTypes": ["pin", "digest"], 33 | "reviewersFromCodeOwners": true, 34 | "addLabels": ["renovatebot", "pin", "version-update"], 35 | "commitMessagePrefix": "chore(renovate): pin", 36 | "groupName": "pin" 37 | } 38 | ], 39 | "vulnerabilityAlerts": { 40 | "commitMessagePrefix": "chore(renovate): Security update", 41 | "labels": ["security"] 42 | }, 43 | "ignorePaths": ["files/**", "node_modules/**"] 44 | } 45 | -------------------------------------------------------------------------------- /puppet/tempaltes/vm.pp: -------------------------------------------------------------------------------- 1 | class ixastorage::ssdtune::vm inherits ixastorage::ssdtune { 2 | 3 | ## noop,readahead,rotational off 4 | file { '/etc/udev/rules.d/95-xentweaks.rules': 5 | ensure => present, 6 | content => "ACTION==\"add|change\" SUBSYSTEM==\"block\", DRIVERS==\"\", KERNEL==\"xvd[a-z]\", ATTR{queue/rotational}==\"0\", ATTR{queue/rq_affinity}=\"2\", ATTR{queue/scheduler}=\"noop\", ATTR{queue/read_ahead_kb}=\"2048\", ATTR{queue/nr_requests}=\"4096\"\n", 7 | notify => Exec['udevtrigger'], 8 | } 9 | 10 | file { '/etc/udev/rules.d/54-drbd.rules': 11 | ensure => present, 12 | content => "ACTION==\"add|change\" SUBSYSTEM==\"block\", DRIVERS==\"\", KERNEL==\"drbd*\", ATTR{queue/rotational}==\"0\", ATTR{queue/rq_affinity}=\"2\", ATTR{queue/nr_requests}=\"4096\"\n", 13 | notify => Exec['udevtrigger'], 14 | } 15 | 16 | file { '/etc/udev/rules.d/56-dm.rules': 17 | ensure => present, 18 | content => "ACTION==\"add|change\", SUBSYSTEM==\"block\", DRIVERS==\"\", KERNEL==\"dm-*\", ATTR{queue/rotational}==\"0\", ATTR{queue/rq_affinity}=\"2\", ATTR{queue/nr_requests}=\"4096\"\n", 19 | notify => Exec['udevtrigger'], 20 | } 21 | 22 | exec { 'udevtrigger': 23 | command => '/sbin/udevadm control --reload-rules && /sbin/udevadm trigger', 24 | refreshonly => true, 25 | user => root, 26 | require => File['/etc/udev/rules.d/95-xentweaks.rules'], 27 | } 28 | 29 | ################## 30 | ## UNTESTED ## 31 | ################## 32 | 33 | 34 | # Increase the maximum number of concurrent (non-blocking) async IO requests allowed from 64K to 1M 35 | augeas::sysctl::conf { 'fs.aio-max-nr': value => '262144'; } 36 | 37 | 38 | } -------------------------------------------------------------------------------- /puppet/manifests/stonith.pp: -------------------------------------------------------------------------------- 1 | # Define: ixastorage::stonith 2 | 3 | define ixastorage::stonith ($ipmi_ip, $ipmi_userid, $ipmi_passwd, $corosync_ip) { 4 | include corosync::reprobe 5 | $ipmi_host = $name 6 | $stonith_primitive = "stonith_${ipmi_host}" 7 | 8 | ####################################### 9 | ### STONITH definitions ### 10 | ####################################### 11 | 12 | cs_primitive { "$stonith_primitive": 13 | primitive_class => 'stonith', 14 | primitive_type => 'rcd_serial', 15 | parameters => { 'ttydev' => "/dev/ttyS0", 16 | 'dtr_rts' => "dtr", 17 | 'msduration' => "1000", 18 | 'hostlist' => "$ipmi_host", 19 | 'stonith-timeout' => '5s' 20 | }, 21 | require => File['/usr/sbin/fence_legacy'], 22 | } 23 | 24 | 25 | cs_location { "dont-run-${stonith_primitive}-on-${ipmi_host}": 26 | primitive => $stonith_primitive, 27 | node_name => $ipmi_host, 28 | score => '-INFINITY', 29 | require => Cs_primitive[$stonith_primitive], 30 | } 31 | 32 | 33 | # Disabled IPMI STONITH as we're using serial 34 | # 35 | # cs_primitive { "$stonith_primitive": 36 | # primitive_class => 'stonith', 37 | # primitive_type => 'external/ipmi', 38 | # parameters => { 'hostname' => "$ipmi_host", 39 | # 'ipaddr' => "$ipmi_ip", 40 | # 'userid' => "$ipmi_userid", 41 | # 'passwd' => "$ipmi_passwd", 42 | # }, 43 | # operations => { 'monitor' => { 'interval' => '30m'}}, 44 | # require => Package['ipmitool'], 45 | # } 46 | 47 | } -------------------------------------------------------------------------------- /puppet/manifests/init.pp: -------------------------------------------------------------------------------- 1 | # Sets up LVM, mdadm, iSCSI, DRBD, LACP 2 | 3 | class ixastorage { 4 | include ::lvm 5 | include rclocal 6 | include ixastorage::ssdtune::server 7 | include ixastorage::network 8 | include ixastorage::packages 9 | include ixastorage::params 10 | include ixastorage::iscsi 11 | include ixastorage::ha 12 | 13 | class { 'abrt': 14 | active => true, 15 | maxcrashreportssize => '1000', 16 | dumplocation => '/var/spool/abrt', 17 | deleteuploaded => 'no', 18 | opengpgcheck => 'no', 19 | blacklist => ['strace'], 20 | blacklistedpaths => ['/usr/share/doc/*'], 21 | processunpackaged => 'no', 22 | abrt_sosreport => false, 23 | abrt_backtrace => 'simple', 24 | } 25 | 26 | class { 'selinux': mode=>'permissive' } 27 | 28 | ## Setup RAID 29 | class { 'ixastorage::mdadm': arrays => $ixastorage::params::storage_group_hash['arrays'] } 30 | 31 | ## Create the cluster resources / primitives 32 | create_resources('lvm::volume_group',$ixastorage::params::storage_group_hash['volume_groups']) 33 | create_resources('ixastorage::drbd',$ixastorage::params::storage_group_hash['drbd']) 34 | create_resources('ixastorage::ha_resource',$ixastorage::params::storage_group_hash['ha_resources']) 35 | create_resources('ixastorage::stonith',$ixastorage::params::storage_group_hash['storage_hosts']) 36 | 37 | ## Setup DRBD 38 | 39 | class { '::drbd': 40 | require => [Class['ixastorage::mdadm'],Class['ixacommon::redhat::centos7::repos']], 41 | service_enable => false, 42 | } 43 | 44 | exec { 'drbd_reload_conf': 45 | command => '/sbin/drbdadm adjust all', 46 | refreshonly => true, 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /.github/config/labels.yml: -------------------------------------------------------------------------------- 1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW #### 2 | 3 | # .github/config/labels.yml 4 | 5 | - name: "Feat" 6 | color: "c52bff" 7 | aliases: ["Feature", "Features"] 8 | 9 | - name: "Fix" 10 | color: "125a29" 11 | aliases: ["bug", "bugfix", "patched", "Hotfix"] 12 | 13 | - name: "Chore" 14 | color: "293535" 15 | aliases: ["maintenance", "maint"] 16 | 17 | - name: "Docs" 18 | color: "7c9e9d" 19 | aliases: ["doco", Documentation'] 20 | 21 | - name: "CDK" 22 | color: "ce7e00" 23 | aliases: ["AWS", "cloudformation", "CFn"] 24 | 25 | - name: "Github" 26 | color: "ff1089" 27 | aliases: ["Actions", "Workflow"] 28 | 29 | - name: "Git" 30 | color: "3e6890" 31 | 32 | - name: "Test" 33 | color: "981f5c" 34 | aliases: ["testing", "tests", "Jest"] 35 | 36 | - name: "Style" 37 | color: "0018a8" 38 | aliases: ["lint", "formatting", "styling", "prettier", "eslint"] 39 | 40 | - name: "Database" 41 | color: "43e8d8" 42 | aliases: ["DB", "SQL", "Flyway", "Migrations"] 43 | 44 | - name: "Security" 45 | color: "f51100" 46 | aliases: ["sec", "vulnerability", "CVE", "vuln", "CODEOWNERS"] 47 | 48 | - name: "Performance" 49 | color: "ff825a" 50 | aliases: ["perf", "optimisation"] 51 | 52 | - name: "DO NOT MERGE" 53 | color: "d54360" 54 | aliases: ["DONT MERGE", "WIP", "Work In Progress"] 55 | 56 | - name: "renovatebot" 57 | color: "123000" 58 | aliases: ["Renovate"] 59 | 60 | - name: "minor" 61 | color: "123000" 62 | aliases: ["minor-update"] 63 | 64 | - name: "major" 65 | color: "123000" 66 | aliases: ["major-update"] 67 | 68 | - name: "patch" 69 | color: "123000" 70 | aliases: ["patch-update"] 71 | 72 | - name: "sync-files" 73 | color: "130000" 74 | 75 | - name: "codeball:needs-careful-review" 76 | color: "fde68a" 77 | description: "This PR needs careful review" 78 | aliases: ["codeball:needs-review"] 79 | 80 | - name: "codeball:approved" 81 | color: "86efac" 82 | description: "This PR has been approved by Codeball AI" 83 | -------------------------------------------------------------------------------- /puppet/manifests/drbd.pp: -------------------------------------------------------------------------------- 1 | # define: ixastorage::drbd 2 | # 3 | # 4 | define ixastorage::drbd( 5 | $host1 , 6 | $host2 , 7 | $host1_ip , 8 | $host2_ip , 9 | $device , 10 | $port , 11 | $logical_volume , 12 | $resource = $name, 13 | $verify_alg = 'crc32c', 14 | $manage = true, 15 | $initial_setup = true, 16 | $rate = '4194304K', 17 | $net_parameters = { 18 | 'max-epoch-size' => '16000', 19 | 'no-tcp-cork' => '', 20 | 'max-buffers' => '16000', 21 | 'unplug-watermark' => '32', 22 | 'sndbuf-size' => '0', 23 | 'after-sb-0pri' => 'discard-zero-changes', 24 | 'after-sb-1pri' => 'discard-secondary', 25 | 'after-sb-2pri' => 'disconnect', 26 | 'csums-alg' => 'crc32c', 27 | }, 28 | $syncer_parameters = { 29 | 'al-extents' => '3389', 30 | }, 31 | $disk_parameters = { 32 | 'disk-flushes' => 'no', 33 | 'md-flushes' => 'no', 34 | 'disk-barrier' => 'no', 35 | 'no-disk-flushes' => '', 36 | 'no-md-flushes' => '', 37 | 'no-disk-barrier' => '', 38 | 'c-plan-ahead' => '2', 39 | 'c-max-rate' => '1024M', 40 | 'c-min-rate' => '150M', 41 | 'c-fill-target' => '500k', 42 | 'fencing' => 'resource-only', 43 | 'on-io-error' => 'detach', 44 | }, 45 | $handler_parameters = { 46 | 'fence-peer' => '/usr/lib/drbd/crm-fence-peer.sh', 47 | 'after-resync-target' => '/usr/lib/drbd/crm-unfence-peer.sh', 48 | #'split-brain' => '/usr/lib/drbd/notify-split-brain.sh', 49 | }, 50 | ) { 51 | 52 | ::drbd::resource { "$resource": 53 | host1 => $host1, 54 | host2 => $host2, 55 | ip1 => $host1_ip, 56 | ip2 => $host2_ip, 57 | disk => $logical_volume, 58 | port => $port, 59 | device => $device, 60 | manage => $manage, 61 | verify_alg => $verify_alg, 62 | initial_setup => $initial_setup, 63 | net_parameters => $net_parameters, 64 | syncer_parameters => $syncer_parameters, 65 | disk_parameters => $disk_parameters, 66 | handler_parameters => $handler_parameters, 67 | notify => Exec['drbd_reload_conf'] #TODO And what happens if this fails? 68 | } 69 | 70 | 71 | 72 | 73 | } -------------------------------------------------------------------------------- /puppet/manifests/packages.pp: -------------------------------------------------------------------------------- 1 | class ixastorage::packages { 2 | 3 | package { ['irqbalance','gdisk','fio','numactl','lshw','smartmontools','OpenIPMI','quota','ledmon','mcelog', 4 | 'iftop','iperf','ipmitool','perl-Nagios-Plugin','make','perl-Digest-MD5','lvm2','cifs-utils','python-2.7.5']: 5 | ensure => latest, 6 | require => [Class['ixacommon::redhat::centos7::repos'],Exec['lock_puppet'],Yumrepo['mrmondo_pacemaker']], 7 | } 8 | 9 | # Required for STONITH 10 | package { ['cluster-glue','cluster-glue-libs','crmsh','nvme-cli','resource-agents']: 11 | ensure => present, 12 | install_options => [ {'--enablerepo' => 'mrmondo_pacemaker'} ], 13 | require => [Yumrepo['mrmondo_pacemaker'],Package['lvm2','python-2.7.5'],Class['ixacommon::redhat::centos7::repos']], 14 | notify => Exec['lock_drbd84_utils'], 15 | } 16 | 17 | # Lock DRBD utils package due to bug in 8.9.3 18 | exec { 'lock_drbd84_utils': 19 | command => '/usr/bin/yum versionlock drbd84-utils-8.9.2', 20 | unless => 'grep -q drbd84-utils-8.9.2 /etc/yum/pluginconf.d/versionlock.list', 21 | } 22 | 23 | # Required for iSCSI 24 | package { ['scsi-target-utils','targetcli']: 25 | ensure => present, 26 | require => Class['ixacommon::redhat::centos7::repos'], 27 | } 28 | 29 | # Repo for HA packages missing in CentOS 7 30 | yumrepo { 'mrmondo_pacemaker': 31 | descr => 'sams pacemaker packages with legacy stonith plugins', 32 | enabled => '1', 33 | gpgcheck => '0', 34 | gpgkey => 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-packagecloud_io', 35 | baseurl => 'https://packagecloud.io/mrmondo/pacemaker/el/7/x86_64/', 36 | proxy => 'https://proxy:3128', 37 | retries => '2', 38 | timeout => '5', 39 | priority => '1', 40 | protect => '1', 41 | mirrorlist => absent, 42 | } 43 | 44 | #CentOS resource-agents missing anything 45 | file { '/usr/lib/ocf/resource.d/heartbeat/anything': 46 | ensure => present, 47 | source => 'puppet:///modules/ixastorage/ha_resource_anything.sh', 48 | owner => root, 49 | group => root, 50 | mode => '0755', 51 | require => Package['resource-agents'], 52 | } 53 | 54 | #CentOS resource-agents missing fence_legacy 55 | file { '/usr/sbin/fence_legacy': 56 | ensure => present, 57 | source => 'puppet:///modules/ixastorage/fence_legacy.pl', 58 | owner => root, 59 | group => root, 60 | mode => '0755', 61 | require => Package['resource-agents'], 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /puppet/manifests/network.pp: -------------------------------------------------------------------------------- 1 | class ixastorage::network { 2 | include ixastorage::params 3 | 4 | class { '::network': 5 | interfaces_hash => $ixastorage::params::network_settings, 6 | config_file_notify => undef, 7 | require => Package['NetworkManager'], # Note this is just for ordering, NetworkManager is ensured absent! 8 | } 9 | 10 | 11 | ## Manage kernel modules at boot 12 | 13 | augeas{ 'lacpmodules' : 14 | context => '/files/etc/modules', 15 | changes => [ 'clear bonding', 'clear mii'] , 16 | } 17 | 18 | file { '/etc/modprobe.d/bonding.conf': 19 | ensure => file, 20 | source => 'puppet:///modules/ixabond/bonding.conf', 21 | owner => 'root', 22 | group => 'root', 23 | mode => 0644, 24 | } 25 | 26 | ## Network tuning 27 | ## http://www.chelsio.com/wp-content/uploads/resources/T5-Linux-Chelsio-vs-Niantic.pdf 28 | 29 | augeas::sysctl::conf { 30 | 'net.ipv4.tcp_timestamps': value => '1'; 31 | 'net.ipv4.tcp_sack': value => '0'; 32 | 'net.ipv4.tcp_low_latency': value => '1'; 33 | 'net.ipv4.tcp_window_scaling': value => '0'; 34 | 'net.ipv4.tcp_dsack': value => '0'; 35 | 'net.ipv4.tcp_tw_reuse': value => '1'; 36 | 'net.ipv4.tcp_tw_recycle': value => '1'; 37 | 'net.core.netdev_max_backlog': value => '250000'; 38 | 'net.core.rmem_max': value => '524287'; 39 | 'net.core.wmem_max': value => '524287'; 40 | 'net.core.rmem_default': value => '524287'; 41 | 'net.core.wmem_default': value => '524287'; 42 | 'net.core.optmem_max': value => '524287'; 43 | 'net.ipv4.tcp_rmem': value => '4096 87380 524287'; 44 | 'net.ipv4.tcp_wmem': value => '4096 65536 524287'; 45 | 'net.ipv4.udp_rmem_min': value => '8192'; 46 | 'net.ipv4.udp_wmem_min': value => '8192'; 47 | } 48 | 49 | ## Gross rclocal hacks 50 | 51 | # Remove non-existant bond0 so nagios is happy 52 | rclocal::script { 'goodbye-bond0': 53 | priority => '11', 54 | content => "echo '-bond0' > /sys/class/net/bonding_masters \n", 55 | } 56 | 57 | # Drop TCP RST packets so brief outages don't cause client abort TODO move to pre-up 58 | rclocal::script { 'drop-tcp-rst': 59 | priority => '10', 60 | content => "iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP \n", 61 | } 62 | 63 | file { '/etc/udev/rules.d/45-ixgbe.rules': 64 | content => "ACTION==\"add\", SUBSYSTEM==\"net\", DRIVERS==\"ixgbe\", RUN+=\"/usr/sbin/ethtool -K %k lro off \"\n", 65 | owner => 'root', 66 | group => 'root', 67 | mode => '0644', 68 | ensure => absent, 69 | } 70 | 71 | file { '/etc/udev/rules.d/45-ixgbe-drbd.rules': 72 | content => "ACTION==\"add\", SUBSYSTEM==\"net\", DRIVERS==\"\", KERNEL==\"drbd\", RUN+=\"/usr/sbin/ethtool -K %k lro off \"\n", 73 | owner => 'root', 74 | group => 'root', 75 | mode => '0644', 76 | } 77 | 78 | file { '/etc/udev/rules.d/45-ixgbe-storage.rules': 79 | content => "ACTION==\"add\", SUBSYSTEM==\"net\", DRIVERS==\"\", KERNEL==\"storage\", RUN+=\"/usr/sbin/ethtool -K %k lro off \"\n", 80 | owner => 'root', 81 | group => 'root', 82 | mode => '0644', 83 | } 84 | 85 | 86 | 87 | 88 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW #### 2 | 3 | # This is the same as ../.gitignore for JS/TS/Java/Python projects, except for the top block for files required by github-actions 4 | 5 | ### START GITHUB ACTIONS FILES ### 6 | 7 | !**/node_modules 8 | !**/dist 9 | 10 | ### END GITHUB ACTIONS FILES ### 11 | 12 | # Inverse matchs to ensure these aren't ignored 13 | !*.env.template 14 | !*.eslintrc.js 15 | !*.prettierrc.js 16 | !*.config.js 17 | 18 | # Typescipt and CDK 19 | **/*.cdk.staging 20 | **/*.d.ts 21 | **/*.tabl.json 22 | **/*.tsbuildinfo 23 | **/cdk.context.json 24 | **/cdk.out 25 | 26 | # NodeJS 27 | **/node_modules 28 | 29 | # Test and coverage output 30 | **/coverage/ 31 | **/test-report.xml 32 | .coverage.* 33 | htmlcov/ 34 | megalinter-reports/ 35 | 36 | # Editors 37 | .project 38 | .settings 39 | .springBeans 40 | **/.favorites.json 41 | **/.idea 42 | **/.vscode 43 | **/*.Session.vim 44 | **/*.sw[a-z] 45 | **/*.vim 46 | **/*.zwc 47 | **/*~ 48 | 49 | # OS generated files 50 | **/._* 51 | **/.AppleDouble 52 | **/.dccache 53 | **/.dropbox 54 | **/.dropbox.attr 55 | **/.dropbox.cache 56 | **/.DS_Store 57 | **/.DS_STORE 58 | **/.lnk 59 | **/.LSOverride 60 | **/$RECYCLE.BIN/ 61 | **/Desktop.ini 62 | **/ehthumbs.db 63 | **/Thumbs.db 64 | 65 | # Files that might appear in the root of a volume 66 | **/.com.apple.timemachine.donotpresent 67 | **/.DocumentRevisions-V100 68 | **/.fseventsd 69 | **/.Spotlight-V100 70 | **/.TemporaryItems 71 | **/.Trashes 72 | **/.VolumeIcon.icns 73 | 74 | # Directories potentially created on remote AFP share 75 | **/.apdisk 76 | **/.AppleDB 77 | **/.AppleDesktop 78 | **/Network Trash Folder 79 | **/Temporary Items 80 | 81 | # Temp files 82 | **/.temp 83 | **/.tmp 84 | tmp/ 85 | 86 | # Files that commonly contain secrets 87 | **/*.key 88 | **/*.pem 89 | **/*.pfx 90 | **/*.p12 91 | **/*.jks 92 | **/*.keystore 93 | **/*.pkcs12 94 | **/*.pkcs8 95 | **/*.pkpass 96 | **/*.secrets 97 | 98 | # git mu-repo 99 | **/.mu_repo 100 | 101 | # Local state files / misc 102 | .dynamodb/ 103 | .eslintcache 104 | .fusebox/ 105 | .grunt 106 | .lock-wscript 107 | .next 108 | .node_repl_history 109 | .npm 110 | .nuxt 111 | .nyc_output 112 | .serverless/ 113 | .vuepress/dist 114 | .yarn-integrity 115 | *.seed 116 | *.tgz 117 | **/.BUILD_COMPLETED 118 | **/.cache 119 | **/.filesystem 120 | **/.LAST_BUILD 121 | **/.local-npm 122 | **/.nyc_output 123 | **/.nycrc 124 | **/.tools 125 | **/.webassets-cache 126 | **/*.lock 127 | **/*.lock.hcl 128 | **/*.pid 129 | **/db.sqlite3 130 | **/db.sqlite3-journal 131 | bower_components 132 | jspm_packages/ 133 | lib-cov 134 | 135 | # Logs 136 | **/*.log 137 | 138 | # Build directories 139 | **/_build/ 140 | **/dist 141 | build/ 142 | out/ 143 | target/ 144 | 145 | # Python 146 | __pycache__/ 147 | __pypackages__/ 148 | .ipynb_checkpoints 149 | *$py.class 150 | celerybeat-schedule 151 | develop-eggs/ 152 | dmypy.json 153 | eggs/ 154 | ipython_config.py 155 | local_settings.py 156 | pip-delete-this-directory.txt 157 | pip-log.txt 158 | pip-wheel-metadata/ 159 | venv 160 | 161 | # Jekyll 162 | _site 163 | .jekyll-cache 164 | .jekyll-metadata 165 | .sass-cache 166 | Gemfile.lock 167 | 168 | # Windows Installer files 169 | *.cab 170 | *.msi 171 | *.msm 172 | *.msp 173 | 174 | # Bootstrap files 175 | *private*.rc 176 | redo_aliases 177 | 178 | # Docker 179 | **/docker-compose.override.y*ml 180 | -------------------------------------------------------------------------------- /puppet/hiera_example.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | storage_alpha: 3 | 4 | storage_hosts: 5 | s1-san5: 6 | corosync_ip: '172.30.1.5' 7 | ipmi_ip: '10.51.100.205' 8 | ipmi_userid: 'ADMIN' 9 | ipmi_passwd: 'AsIfIdPostThisOnGithub' 10 | 11 | s1-san6: 12 | corosync_ip: '172.30.1.6' 13 | ipmi_ip: '10.51.100.206' 14 | ipmi_userid: 'ADMIN' 15 | ipmi_passwd: 'AsIfIdPostThisOnGithub' 16 | 17 | arrays: 18 | '/dev/md480': 19 | ensure: created 20 | devices: 21 | - /dev/sda1 22 | - /dev/sdb1 23 | - /dev/sdc1 24 | - /dev/sdd1 25 | - /dev/sde1 26 | - /dev/sdf1 27 | - /dev/sdg1 28 | - /dev/sdh1 29 | level: 10 30 | force: false 31 | options: '--layout=f2 --chunk=512K' 32 | bitmap: 'internal' 33 | metadata: '1.2' 34 | '/dev/md200': 35 | ensure: created 36 | devices: 37 | - /dev/nvme0n1p1 38 | - /dev/nvme1n1p1 39 | level: 1 40 | options: '--chunk=512K' 41 | metadata: '1.2' 42 | force: false 43 | bitmap: 'internal' 44 | 45 | volume_groups: 46 | nvme: 47 | physical_volumes: 48 | - /dev/md200 49 | logical_volumes: 50 | tierone: 51 | size: '1.09T' 52 | sandisk: 53 | physical_volumes: 54 | - /dev/md480 55 | logical_volumes: 56 | tiertwo: 57 | size: '1.74T' 58 | 59 | drbd: 60 | 'r0': 61 | host1: 's1-san5' 62 | host2: 's1-san6' 63 | host1_ip: '172.30.1.5' 64 | host2_ip: '172.30.1.6' 65 | device: '/dev/drbd0' 66 | port: '7789' 67 | initial_setup: true 68 | rate: '4194304K' 69 | logical_volume: '/dev/mapper/nvme-tierone' 70 | manage: false 71 | 'r1': 72 | host1: 's1-san5' 73 | host2: 's1-san6' 74 | host1_ip: '172.30.1.5' 75 | host2_ip: '172.30.1.6' 76 | device: '/dev/drbd1' 77 | port: '7889' 78 | initial_setup: true 79 | rate: '4194304K' 80 | logical_volume: '/dev/mapper/sandisk-tiertwo' 81 | manage: false 82 | 83 | ha_resources: 84 | r0: 85 | iscsi_vip: 10.51.40.55 86 | iscsi_vip_nm: 24 87 | iscsi_iqn: 'iqn.2003-01.org.linux-iscsi.s1-san5.x8664:sn.b50bc7bf74a6' 88 | master_node: s1-san5 89 | r1: 90 | iscsi_vip: 10.51.40.65 91 | iscsi_vip_nm: 24 92 | iscsi_iqn: 'iqn.2003-01.org.linux-iscsi.s1-san5.x8664:sn.ab518058d445' 93 | master_node: s1-san6 94 | 95 | allowed_initiators: 96 | - 'iqn.2015-05.com.example:5a6a2f8c' #server 1 97 | - 'iqn.2015-06.com.example:1f2e2f2c' #server 2 98 | 99 | 100 | network_storage: 101 | eno1: 102 | nm_controlled: 'no' 103 | master: 'drbd' 104 | mtu: '9000' 105 | slave: 'yes' 106 | eno2: 107 | nm_controlled: 'no' 108 | master: 'drbd' 109 | mtu: '9000' 110 | slave: 'yes' 111 | ens2f0: 112 | nm_controlled: 'no' 113 | master: 'storage' 114 | mtu: '9000' 115 | slave: 'yes' 116 | ens2f1: 117 | nm_controlled: 'no' 118 | master: 'storage' 119 | mtu: '9000' 120 | slave: 'yes' 121 | storage: 122 | name: storage 123 | nm_controlled: 'no' 124 | bonding_opts: 'miimon=100 updelay=0 downdelay=0 mode=802.3ad lacp_rate=1' 125 | netmask: '255.255.255.0' 126 | mtu: '9000' 127 | type: 'Bond' 128 | gateway: '10.51.40.1' 129 | dns1: '10.51.10.235' 130 | manage_order: '30' 131 | drbd: 132 | name: drbd 133 | nm_controlled: 'no' 134 | bonding_opts: 'miimon=100 updelay=0 downdelay=0 mode=1' 135 | netmask: '255.255.255.0' 136 | mtu: '9000' 137 | type: 'Bond' 138 | manage_order: '20' 139 | -------------------------------------------------------------------------------- /puppet/manifests/ssdtune/server.pp: -------------------------------------------------------------------------------- 1 | class ixastorage::ssdtune::server inherits ixastorage::ssdtune { 2 | 3 | ## noop,readahead,rotational off 4 | file { '/etc/udev/rules.d/52-ssd.rules': 5 | ensure => present, 6 | content => "ACTION==\"add|change\", KERNEL==\"sd[a-z]\", ATTR{queue/rotational}==\"0\", ATTR{queue/scheduler}=\"noop\", ATTR{queue/read_ahead_kb}=\"4096\", ATTR{queue/nr_requests}=\"4096\"\n", 7 | notify => Exec['udevtrigger'], 8 | } 9 | 10 | file { '/etc/udev/rules.d/51-nvme.rules': 11 | ensure => present, 12 | content => "ACTION==\"add|change\", KERNEL==\"nvme[0-9]n[0-9]\", ATTR{queue/rotational}==\"0\", ATTR{queue/rq_affinity}=\"2\", ATTR{queue/scheduler}=\"noop\", ATTR{queue/read_ahead_kb}=\"0\"\n", 13 | notify => Exec['udevtrigger'], 14 | } 15 | 16 | file { '/etc/udev/rules.d/54-drbd.rules': 17 | ensure => present, 18 | content => "ACTION==\"add|change\", KERNEL==\"drbd*\", ATTR{queue/rotational}==\"0\", ATTR{queue/rq_affinity}=\"2\", ATTR{queue/scheduler}=\"noop\", ATTR{queue/read_ahead_kb}=\"0\"\n", 19 | notify => Exec['udevtrigger'], 20 | } 21 | 22 | file { '/etc/udev/rules.d/56-dm.rules': 23 | ensure => present, 24 | content => "ACTION==\"add|change\", KERNEL==\"dm-*\", ATTR{queue/rotational}==\"0\", ATTR{queue/rq_affinity}=\"2\", ATTR{queue/scheduler}=\"noop\", ATTR{queue/read_ahead_kb}=\"0\"\n", 25 | notify => Exec['udevtrigger'], 26 | } 27 | 28 | file { '/etc/udev/rules.d/53-mdadm.rules': 29 | ensure => present, 30 | content => "ACTION==\"add|change\", KERNEL==\"md*\", ATTR{queue/rotational}==\"0\", ATTR{queue/rq_affinity}=\"2\", ATTR{queue/scheduler}=\"noop\", ATTR{queue/read_ahead_kb}=\"0\"\n", 31 | notify => Exec['udevtrigger'], 32 | } 33 | 34 | # exec { 'udevtrigger': 35 | # command => '/sbin/udevadm trigger', 36 | # refreshonly => true, 37 | # } 38 | 39 | # Increase the maximum number of concurrent (non-blocking) async IO requests allowed from 64K to 1M 40 | augeas::sysctl::conf { 'fs.aio-max-nr': value => '1048576'; } 41 | 42 | # Fix bug for NVMe Hotplug 43 | exec { 'enable-pcie_bus_perf': 44 | command => "sed -i 's/GRUB_CMDLINE_LINUX=\"\(.*\)\"/GRUB_CMDLINE_LINUX=\"\1 pci=pcie_bus_safe\"/' /etc/default/grub", 45 | unless => "grep -q \"pci=pcie_bus_safe\" /etc/default/grub", 46 | notify => Exec['grub2-mkconfig'], 47 | } 48 | 49 | # pcie_bus_tune_off [X86] Disable PCI-E MPS turning and using 50 | # the BIOS configured MPS defaults. 51 | # pcie_bus_safe [X86] Use the smallest common denominator MPS 52 | # of the entire tree below a root complex for every device 53 | # on that fabric. Can avoid inconsistent mps problem caused 54 | # by hotplug. 55 | # pcie_bus_perf [X86] Configure pcie device MPS to the largest 56 | # allowable MPS based on its parent bus.Improve performance 57 | # as much as possible. 58 | # pcie_bus_peer2peer [X86] Make the system wide MPS the smallest 59 | # possible value (128B).This configuration could prevent it 60 | # from working by having the MPS on one root port different 61 | # than the MPS on another. 62 | 63 | ## Setup LVM with discard for SSDs 64 | 65 | file { '/etc/lvm': 66 | ensure => directory, 67 | } 68 | 69 | file { '/etc/lvm/lvm.conf': 70 | ensure => present, 71 | content => template('ixastorage/lvm.conf.erb'), 72 | owner => 'root', 73 | group => 'root', 74 | mode => '0644', 75 | require => file['/etc/lvm'], 76 | } 77 | 78 | ## Ensure nvme loads before LVM on boot 79 | file { '/etc/dracut.conf': 80 | ensure => file, 81 | content => "add_drivers+=\"nvme\"", 82 | notify => Exec['grub2-mkconfig'], 83 | } 84 | 85 | # Update SMARTs database 86 | cron { 'update_smart_drivedb': 87 | command => 'http_proxy=http://proxy:3128 /usr/sbin/update-smart-drivedb', 88 | user => 'root', 89 | month => '*', 90 | monthday => '3', 91 | hour => '11', 92 | minute => '0', 93 | } 94 | 95 | 96 | } -------------------------------------------------------------------------------- /.github/config/labeller.yml: -------------------------------------------------------------------------------- 1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW #### 2 | 3 | # .github/config/labeller.yml 4 | 5 | version: v1 6 | 7 | labels: 8 | - label: "Feat" 9 | sync: true 10 | matcher: 11 | title: ".*(feat:|(IF-[0-9]+ -- (feat))).*/i" 12 | body: "(feat:.*|feature:.*)/i" 13 | branch: "(^feat\/.*)/i" 14 | baseBranch: "(^feat\/.*)/i" 15 | commits: "(^feat:.*|(IF-[0-9]+ -- (feat))).*/i" 16 | 17 | - label: "Fix" 18 | sync: true 19 | matcher: 20 | title: "(^hotfix:.*|^fix:.*|(IF-[0-9]+ -- (fix|hotfix).*))/i" 21 | body: "(hotfix:.*|fix:.*|bug:.*)/i" 22 | branch: "(^hotfix\/.*|^fix\/.*)/i" 23 | baseBranch: "(^hotfix\/.*|^fix\/.*)/i" 24 | commits: "(^hotfix:.*|^fix:.*|(IF-[0-9]+ -- (fix|hotfix).*))/i" 25 | 26 | - label: "Chore" 27 | sync: true 28 | matcher: 29 | title: "(^chore:.*|(IF-[0-9]+ -- chore.*))/i" 30 | body: "(hotfix:.*|fix:.*|bug:.*)/i" 31 | branch: "(^chore\/.*)/i" 32 | baseBranch: "(^chore\/.*)/i" 33 | commits: "(^chore:.*|(IF-[0-9]+ -- chore.*))/i" 34 | author: 35 | - "renovatebot" 36 | - "renovatebot[bot]" 37 | 38 | - label: "Docs" 39 | sync: true 40 | matcher: 41 | title: "(^docs:.*|(IF-[0-9]+ -- docs.*))/i" 42 | body: "(docs:.*|documentation:)/i" 43 | branch: "(^docs\/.*)/i" 44 | baseBranch: "(^docs\/.*)/i" 45 | commits: "(^docs:.*|(IF-[0-9]+ -- docs.*))/i" 46 | files: 47 | any: 48 | [ 49 | "**/docs/**", 50 | "**/doc/**", 51 | "**/*.md", 52 | "**/*.markdown", 53 | "**/*.rst", 54 | "**/*.txt", 55 | ] 56 | count: 57 | gte: 1 58 | lte: 1000 59 | 60 | - label: "CDK" 61 | sync: true 62 | matcher: 63 | title: "(.*cdk|(IF-[0-9]+ -- cdk).*)/i" 64 | body: ".*(cdk:|cloudformation:).*/i" 65 | branch: "(.*cdk\/.*)/i" 66 | baseBranch: "(.*cdk\/.*)/i" 67 | commits: "(.*cdk:|(IF-[0-9]+ -- cdk)).*/i" 68 | files: 69 | any: ["**/cdk/**", "**/cloudformation/**", "**/*.cdk.*", "**/*.stack.*"] 70 | count: 71 | gte: 1 72 | lte: 1000 73 | 74 | - label: "Github" 75 | sync: true 76 | matcher: 77 | title: "(^actions:.*|(IF-[0-9]+ -- actions.*)|^workflow:.*|(IF-[0-9]+ -- workflow.*)|.*github:.*|(IF-[0-9]+ -- github.*))/i" 78 | body: ".*(actions:.*|github-actions:|github:|workflow:).*/i" 79 | branch: "(^actions\/.*|^github\/.*^workflow\/.*)/i" 80 | baseBranch: "(^actions\/.*|^github\/.*^workflow\/.*)/i" 81 | commits: "(^actions:.*|(IF-[0-9]+ -- actions.*)|^workflow:.*|(IF-[0-9]+ -- workflow.*)|^github:.*|(IF-[0-9]+ -- github.*))/i" 82 | files: 83 | any: [".github\/*", "CODEOWNERS"] 84 | count: 85 | gte: 1 86 | lte: 1000 87 | 88 | - label: "Test" 89 | sync: true 90 | matcher: 91 | title: "(^test|(IF-[0-9]+ -- test)|jest).*/i" 92 | body: ".*(tests:|test:|testing:|jest:).*/i" 93 | branch: "(^test\/.*)/i" 94 | baseBranch: "(^test\/.*)/i" 95 | commits: "(^tests:.*|^test:.*|(IF-[0-9]+ -- test.*))/i" 96 | files: 97 | any: ["**/.*(test|.spec).*", "**/.*jest.*"] 98 | count: 99 | gte: 1 100 | lte: 1000 101 | 102 | - label: "Performance" 103 | sync: true 104 | matcher: 105 | title: "(^perf:|(IF-[0-9]+ -- perf)).*/i" 106 | body: "(perf:|performance:).*/i" 107 | branch: "(^perf\/.*)/i" 108 | baseBranch: "(^perf\/.*)/i" 109 | commits: "(^perf:|(IF-[0-9]+ -- perf)).*/i" 110 | 111 | - label: "Style" 112 | sync: true 113 | matcher: 114 | title: ".*(style:|(IF-[0-9]+ -- (style|lint)|lint)).*/i" 115 | body: ".*(style:|styling:|lint:|linting|format:|formatting).*/i" 116 | branch: "(^style\/.*)/i" 117 | baseBranch: "(^style\/.*)/i" 118 | commits: ".*(style:|(IF-[0-9]+ -- style)|lint|formatting.*)/i" 119 | files: 120 | any: 121 | [ 122 | "**/.*prettier.*", 123 | "**/.*eslint.*", 124 | "**/.*stylelint.*", 125 | "**/.*style.*", 126 | "**/.*lint.*", 127 | "**/.*editorconfig.*", 128 | ] 129 | count: 130 | gte: 1 131 | lte: 1000 132 | 133 | - label: "Database" 134 | sync: true 135 | matcher: 136 | title: "(^db:.*|.*sql.*|(IF-[0-9]+ -- db.*))/i" 137 | body: ".*(db:|database:).*/i" 138 | branch: "(^db\/.*)/i" 139 | baseBranch: "(^db\/.*)/i" 140 | commits: "(^db:.*|.*sql|(IF-[0-9]+ -- db.*))/i" 141 | files: 142 | # regex glob to match a file with extension .sql in any directory recursively 143 | any: 144 | [ 145 | "**/*.sql", 146 | "**/*.db", 147 | "**/db/**", 148 | "**/flyway.*", 149 | "**/migrations/**", 150 | "**/*.sqlite.*", 151 | ] 152 | count: 153 | gte: 1 154 | lte: 1000 155 | 156 | - label: "Security" 157 | sync: true 158 | matcher: 159 | title: ".*(CVE|sec:|security).*/i" 160 | body: ".*(CVE|sec:|security).*/i/i" 161 | branch: ".*(CVE|sec:|security).*/i" 162 | baseBranch: ".*(CVE|sec:|security).*/i" 163 | commits: ".*(CVE|sec:|security).*/i" 164 | files: 165 | any: 166 | [ 167 | "CODEOWNERS", 168 | "SECURITY.*", 169 | ".github/settings.yml", 170 | "**/*.pem", 171 | "**/*.crt", 172 | "**/.*password.*", 173 | "**/.*secret.*", 174 | "**/.*token.*", 175 | "**/.*key.*", 176 | ] 177 | count: 178 | gte: 1 179 | lte: 1000 180 | 181 | - label: "Git" 182 | sync: true 183 | matcher: 184 | title: ".*git.*/i" 185 | files: 186 | any: ["**/.git.*", "**/.husky/*"] 187 | count: 188 | gte: 1 189 | lte: 1000 190 | 191 | - label: "Sync-Files" 192 | sync: true 193 | matcher: 194 | title: ".*Sync-Files.*/i" 195 | 196 | - label: "DO NOT MERGE" 197 | sync: true 198 | matcher: 199 | title: ".*(DO NOT MERGE|DONT MERGE|DON'T MERGE).*" 200 | body: ".*(DO NOT MERGE|DONT MERGE|DON'T MERGE).*" 201 | commits: ".*(DO NOT MERGE|DONT MERGE|DON'T MERGE).*" 202 | 203 | checks: 204 | - context: "Merge check" 205 | description: "Disable merging when 'DO NOT MERGE' label is set" 206 | labels: 207 | none: ["DO NOT MERGE"] 208 | -------------------------------------------------------------------------------- /puppet/files/fence_legacy.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use Getopt::Long; 4 | 5 | my $ME = $0; 6 | 7 | END { 8 | defined fileno STDOUT or return; 9 | close STDOUT and return; 10 | warn "$ME: failed to close standard output: $!\n"; 11 | $? ||= 1; 12 | } 13 | 14 | # Get the program name from $0 and strip directory names 15 | $_=$0; 16 | s/.*\///; 17 | my $pname = $_; 18 | 19 | $opt_o = 'reset'; # Default fence action 20 | $opt_s = 'stonith'; # Default fence binary 21 | $opt_t = 'none'; # Default fence type 22 | $extra_args = '-E'; 23 | 24 | sub usage 25 | { 26 | print "Helper that presents a RHCS-style interface for Linux-HA stonith plugins\n\n"; 27 | print "Should never need to use invoked by the user directly\n\n"; 28 | print "\n"; 29 | print "Usage: $pname [options]\n"; 30 | print "\n"; 31 | print "Options:\n"; 32 | print " -h usage\n"; 33 | print " -t sub agent\n"; 34 | print " -n nodename\n"; 35 | print " -o Action: on | off | reset (default) | stat | hostlist\n"; 36 | print " -s stonith command\n"; 37 | print " -q quiet mode\n"; 38 | print " -V version\n"; 39 | 40 | exit 0; 41 | } 42 | 43 | sub print_metadata 44 | { 45 | print ' 46 | 47 | 48 | Should never need to use invoked by the user directly and should only 49 | be configured in cluster.conf, not directly in Pacemaker. 50 | 51 | http://www.clusterlabs.org 52 | 53 | 54 | 55 | 56 | Fencing Action 57 | 58 | 59 | 60 | 61 | Physical plug number or name of virtual machine 62 | 63 | 64 | 65 | 66 | Display help and exit 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | '; 80 | } 81 | 82 | sub fail 83 | { 84 | ($msg) = @_; 85 | print $msg."\n" unless defined $opt_q; 86 | $t->close if defined $t; 87 | exit 1; 88 | } 89 | 90 | sub fail_usage 91 | { 92 | ($msg)=@_; 93 | print STDERR $msg."\n" if $msg; 94 | print STDERR "Please use '-h' for usage.\n"; 95 | exit 1; 96 | } 97 | 98 | sub version 99 | { 100 | print "1.0.0\n"; 101 | 102 | exit 0; 103 | } 104 | 105 | sub get_options_stdin 106 | { 107 | my $opt; 108 | my $line = 0; 109 | while( defined($in = <>) ) 110 | { 111 | $_ = $in; 112 | chomp; 113 | 114 | # strip leading and trailing whitespace 115 | s/^\s*//; 116 | s/\s*$//; 117 | 118 | # skip comments 119 | next if /^#/; 120 | 121 | $line+=1; 122 | $opt=$_; 123 | next unless $opt; 124 | 125 | ($name,$val)=split /\s*=\s*/, $opt, 2; 126 | 127 | if ( $name eq "" ) 128 | { 129 | print STDERR "parse error: illegal name in option $line\n"; 130 | exit 2; 131 | } 132 | 133 | # DO NOTHING -- this field is used by fenced 134 | elsif ($name eq "agent" ) {} 135 | 136 | elsif ($name eq "plugin" ) 137 | { 138 | $opt_t = $val; 139 | } 140 | elsif ($name eq "option" || $name eq "action" ) 141 | { 142 | $opt_o = $val; 143 | } 144 | elsif ($name eq "nodename" ) 145 | { 146 | $opt_n = $val; 147 | $ENV{$name} = $val; 148 | } 149 | elsif ($name eq "stonith" ) 150 | { 151 | $opt_s = $val; 152 | } 153 | else 154 | { 155 | $ENV{$name} = $val; 156 | } 157 | 158 | } 159 | } 160 | 161 | ######################################################################33 162 | # MAIN 163 | 164 | if (@ARGV > 0) { 165 | GetOptions("t=s"=>\$opt_t, 166 | "n=s"=>\$opt_n, 167 | "o=s"=>\$opt_o, 168 | "s=s"=>\$opt_s, 169 | "q" =>\$opt_q, 170 | "V" =>\$opt_V, 171 | "version" =>\$opt_V, 172 | "help" =>\$opt_h, 173 | "h" =>\$opt_h) || fail_usage; 174 | foreach (@ARGV) { 175 | print "$_\n"; 176 | } 177 | # getopts("ht:n:o:s:qV") || fail_usage ; 178 | 179 | usage if defined $opt_h; 180 | version if defined $opt_V; 181 | 182 | fail_usage "Unknown parameter." if (@ARGV > 0); 183 | } 184 | 185 | get_options_stdin(); 186 | 187 | if ((defined $opt_o) && ($opt_o =~ /metadata/i)) { 188 | print_metadata(); 189 | exit 0; 190 | } 191 | 192 | $opt_o=lc($opt_o); 193 | fail "failed: unrecognised action: $opt_o" 194 | unless $opt_o =~ /^(on|off|reset|reboot|stat|status|monitor|list|hostlist|poweroff|poweron)$/; 195 | 196 | if ( $pid=fork() == 0 ) 197 | { 198 | if ( $opt_o eq "reboot" ) 199 | { 200 | $opt_o="reset"; 201 | } 202 | elsif ( $opt_o eq "poweron" ) 203 | { 204 | $opt_o="on"; 205 | } 206 | elsif ( $opt_o eq "poweroff" ) 207 | { 208 | $opt_o="off"; 209 | } 210 | 211 | if ( $opt_o eq "hostlist"|| $opt_o eq "list" ) 212 | { 213 | exec "$opt_s -t $opt_t $extra_args -l" or die "failed to exec \"$opt_s\"\n"; 214 | } 215 | elsif ( $opt_o eq "monitor" || $opt_o eq "stat" || $opt_o eq "status" ) 216 | { 217 | print "Performing: $opt_s -t $opt_t -S\n" unless defined $opt_q; 218 | exec "$opt_s -t $opt_t $extra_args -S" or die "failed to exec \"$opt_s\"\n"; 219 | } 220 | else 221 | { 222 | print "Performing: $opt_s -t $opt_t -T $opt_o $opt_n\n" unless defined $opt_q; 223 | fail "failed: no plug number" unless defined $opt_n; 224 | exec "$opt_s -t $opt_t $extra_args -T $opt_o $opt_n" or die "failed to exec \"$opt_s\"\n"; 225 | } 226 | } 227 | 228 | wait; 229 | $status=$?/256; 230 | 231 | print (($status == 0 ? "success":"failed") . ": $opt_n $status\n") 232 | unless defined $opt_q; 233 | 234 | exit ($status == 0 ? 0 : 1 ); 235 | -------------------------------------------------------------------------------- /puppet/manifests/ha.pp: -------------------------------------------------------------------------------- 1 | # Class: ixastorage::ha 2 | # Corosync / pacemaker Setup 3 | 4 | class ixastorage::ha { 5 | include ixastorage::params 6 | include corosync::reprobe 7 | 8 | $unicast_addresses=$ixastorage::params::unicast_addresses 9 | $storage_gateway=$ixastorage::params::network_settings['storage']['gateway'] 10 | 11 | # This is useful for the first setup if you want to true or false some values based on if the unit is in production yet 12 | case $being_setup { 13 | true: { 14 | $setup_bool_inverse = false 15 | $setup_ensure = present 16 | } 17 | default: { 18 | $setup_bool_inverse = true 19 | $setup_ensure = absent 20 | } 21 | } 22 | 23 | file { '/root/cluster_bootstrap.sh': 24 | ensure => $setup_ensure, 25 | source => 'puppet:///modules/ixastorage/cluster_bootstrap.sh', 26 | mode => '0755', 27 | owner => 'root', 28 | group => 'root', 29 | } 30 | 31 | ####################################### 32 | ### Debugging configuration ### 33 | ####################################### 34 | 35 | # http://blog.clusterlabs.org/blog/2013/pacemaker-logging/ 36 | # Set to 'all' to enable 37 | augeas { 'PCMK_blackbox': 38 | context => "/files/etc/sysconfig/pacemaker", 39 | changes => "set PCMK_blackbox yes", 40 | } 41 | 42 | # Change log to warn 43 | augeas { 'PCMK_logpriority': 44 | context => "/files/etc/sysconfig/pacemaker", 45 | changes => "set PCMK_logpriority warning", 46 | } 47 | 48 | # Change debug to off 49 | augeas { 'PCMK_debug': 50 | context => "/files/etc/sysconfig/pacemaker", 51 | changes => "set PCMK_debug off", 52 | } 53 | 54 | ####################################### 55 | ### Corosync Configuration ### 56 | ####################################### 57 | 58 | class { 'corosync': 59 | enable_secauth => false, 60 | multicast_address => 'broadcast', 61 | bind_address => '172.30.1.0', 62 | debug => $being_setup, 63 | force_online => false, 64 | set_votequorum => true, 65 | quorum_members => $unicast_addresses, 66 | two_node => true, 67 | token_retransmits_before_loss_const => '20', 68 | require => [Yumrepo['mrmondo_pacemaker'],Class['ixacommon::redhat::centos7::repos'],Package['lvm2']], 69 | } 70 | 71 | corosync::service { 'pacemaker': 72 | version => '1', 73 | } 74 | 75 | logrotate::rule { 'corosync': 76 | path => '/var/log/cluster/corosync.log', 77 | rotate_every => 'daily', 78 | rotate => 7, 79 | compress => true, 80 | delaycompress => true, 81 | missingok => true, 82 | ifempty => false, 83 | copytruncate => true, 84 | require => Class['corosync'], 85 | } 86 | 87 | ####################################### 88 | ### Pacemaker Global Defaults ### 89 | ####################################### 90 | 91 | cs_property { 'no-quorum-policy': value => 'ignore' } 92 | cs_property { 'stonith-enabled': value => $setup_bool_inverse } 93 | cs_property { 'cluster-recheck-interval': value => '0' } 94 | cs_property { 'start-failure-is-fatal': value => 'false' } 95 | #cs_property { 'migration-limit': value => '1' } 96 | 97 | 98 | #http://clusterlabs.org/doc/en-US/Pacemaker/1.1/html/Pacemaker_Explained/s-failure-migration.html 99 | # Indicates that the resource will move to a new node after failures and wait seconds before failing the resource back. 100 | #cs_rsc_defaults { 'migration-threshold': value => '5' } 101 | #cs_rsc_defaults { 'resource-stickiness': value => '20' } 102 | #cs_rsc_defaults { 'allow-migrate': value => 'true' } 103 | #cs_rsc_defaults { 'failure-timeout': value => '15s' } 104 | 105 | 106 | ################################################## 107 | ### Services Managed by Pacemaker / Corosync ### 108 | ################################################## 109 | 110 | service { 'target': 111 | ensure => undef, 112 | enable => false, 113 | require => [Package['pacemaker'],Class['corosync'],Class['ixacommon::redhat::centos7::repos']], 114 | } 115 | 116 | service { 'pacemaker': 117 | ensure => undef, 118 | enable => true, 119 | require => [Package['pacemaker'],Class['corosync'],Class['ixacommon::redhat::centos7::repos']], 120 | } 121 | 122 | 123 | ####################################### 124 | ### Single resources for each host ### 125 | ####################################### 126 | 127 | ## TODO ensure if disabled manually puppet doesn't start 128 | 129 | ## Storage network monitor 130 | 131 | cs_primitive { "ping_gateway": 132 | primitive_class => 'ocf', 133 | primitive_type => 'ping', 134 | provided_by => 'pacemaker', 135 | parameters => { 'host_list' => "$storage_gateway", 136 | 'dampen' => '20s' }, 137 | operations => { 'monitor' => { 'interval' => '10s', 'timeout' => '10s', 'attempts' => '3' } }, # Recommended intervals 138 | require => [Cs_property['stonith-enabled'],Service['pacemaker']], 139 | } 140 | 141 | cs_clone { "ping_gateway-clone": 142 | primitive => "ping_gateway", 143 | require => [Cs_primitive['ping_gateway'],Service['pacemaker']], 144 | } 145 | 146 | 147 | ####################################### 148 | ### Backup Configuration ### 149 | ####################################### 150 | 151 | cron { 'backup_pacemaker_cib': 152 | command => '/usr/sbin/crm configure show > /var/log/cluster/backup_cib_$(date +"\%F").log', 153 | user => 'root', 154 | month => '*', 155 | monthday => '*', 156 | hour => 7, 157 | minute => 0, 158 | } 159 | 160 | cron { 'backup_mdadm_config': 161 | command => '/usr/bin/cat /proc/mdstat > /var/log/cluster/backup_mdadm_$(date +"\%F").log; /usr/sbin/mdadm --detail --scan >> /var/log/cluster/backup_mdadm_$(date +"\%F").log', 162 | user => 'root', 163 | month => '*', 164 | monthday => '*', 165 | hour => 7, 166 | minute => 0, 167 | } 168 | 169 | logrotate::rule { 'backup_pacemaker_cib': 170 | path => '/var/log/cluster/backup*.log', 171 | rotate_every => 'day', 172 | rotate => '90', 173 | compress => true, 174 | delaycompress => true, 175 | missingok => true, 176 | ifempty => false, 177 | copytruncate => true, 178 | require => Cron['backup_mdadm_config'], 179 | } 180 | 181 | 182 | ## Notify if you're shutting down a node without putting it in standby 183 | 184 | file { '/etc/confirmfirst.d': 185 | ensure => 'directory', 186 | } 187 | 188 | file { '/etc/confirmfirst.d/standby-check': 189 | ensure => present, 190 | source => 'puppet:///modules/ixastorage/standby-check.sh', 191 | owner => root, 192 | group => root, 193 | mode => '0755', 194 | require => File['/etc/confirmfirst.d'], 195 | } 196 | 197 | } -------------------------------------------------------------------------------- /puppet/manifests/ha_resource.pp: -------------------------------------------------------------------------------- 1 | # Define: ixastorage::ha_resource 2 | # Parameters: 3 | # arguments 4 | # 5 | define ixastorage::ha_resource ($iscsi_vip, $iscsi_vip_nm, $iscsi_iqn, $master_node) { 6 | include ixastorage::params 7 | include corosync::reprobe 8 | $drbd_resource = $name 9 | $drbd_primitive = "drbd_${drbd_resource}" 10 | $drbd_path = $ixastorage::params::storage_group_hash['drbd'][$drbd_resource]['device'] 11 | $ip_primitive = "ip_${drbd_resource}" 12 | $ms_resource = "ms_${drbd_primitive}" 13 | $iscsi_target_primitive = "iscsi_target_${drbd_resource}" 14 | $iscsi_lun_primitive = "iscsi_lun_${drbd_resource}" 15 | $iscsi_conf_primitive = "iscsi_conf_${drbd_resource}" 16 | $iscsi_conf_bin = "/usr/sbin/iscsi_${iscsi_conf_primitive}.sh" 17 | $allowed_initiators = join($ixastorage::params::storage_group_hash['allowed_initiators'],' ') 18 | 19 | ####################################### 20 | ### Resource definitons ### 21 | ####################################### 22 | 23 | ## DRBD 24 | 25 | cs_primitive { "$drbd_primitive": 26 | primitive_class => 'ocf', 27 | provided_by => 'linbit', 28 | primitive_type => 'drbd', 29 | parameters => { 'drbd_resource' => "$drbd_resource" }, 30 | ms_metadata => { 31 | 'clone-max' => '2', 32 | 'clone-node-max' => '1', 33 | 'master-max' => '1', 34 | 'master-node-max' => '1', 35 | 'notify' => 'true', 36 | 'globally-unique' => 'false', 37 | #'migration-threshold' => '5', 38 | 'failure-timeout' => '30s', 39 | }, 40 | operations => { 'monitor' => { 'interval' => '12s', 'role' => 'Slave', 'timeout' => '20','on-fail' => "restart"}, #reducing interval from 21 #http://lists.linux-ha.org/pipermail/linux-ha/2013-February/046536.html 41 | 'monitor' => { 'interval' => '6s', 'role' => 'Master', 'timeout' => '20','on-fail' => "restart"}, #reducing interval from 10s 42 | 'start' => { 'interval' => '0', 'timeout' => '60s', 'on-fail' => "restart"}, 43 | 'stop' => { 'interval' => '0', 'timeout' => '20s', 'on-fail' => "restart"}, 44 | 'promote' => { 'interval' => '0', 'timeout' => '60s', 'on-fail' => "restart"}, 45 | 'demote' => { 'interval' => '0', 'timeout' => '30s', 'on-fail' => "restart"}, 46 | 'notify' => { 'interval' => '0', 'timeout' => '60s', 'on-fail' => "restart"}, 47 | }, 48 | promotable => true, 49 | require => [Cs_property['stonith-enabled'],Package['drbd84-utils-8.9.2'],Service['pacemaker']], 50 | } 51 | 52 | 53 | ## VIRTUAL IP 54 | 55 | cs_primitive { "$ip_primitive": 56 | primitive_class => 'ocf', 57 | primitive_type => 'IPaddr2', 58 | provided_by => 'heartbeat', 59 | parameters => { 'ip' => "$iscsi_vip", 60 | 'cidr_netmask' => "$iscsi_vip_nm", 61 | 'flush_routes' => 'true', 62 | 'iflabel' => "iscsi${drbd_resource}"}, 63 | operations => { 'monitor' => { 'interval' => '6s', 'timeout' => '20s','on-fail' => "restart"}, #reducing interval from 21s 64 | 'start' => { 'interval' => '0', 'timeout' => '20s','on-fail' => "restart"}, 65 | 'stop' => { 'interval' => '0', 'timeout' => '20s','on-fail' => "restart"}, 66 | }, 67 | require => [Cs_primitive["$drbd_primitive"],Service['pacemaker']], 68 | } 69 | 70 | cs_location { "require_ping_gateway_${drbd_resource}": 71 | primitive => "$ms_resource", 72 | rules => [{'boolean' => 'or', 73 | 'score' => '-INFINITY', 74 | 'expressions' => [ {'attribute' => 'pingd', 'operation' => 'not_defined'}, 75 | {'attribute' => 'pingd', 'operation' => 'lte', 'value' => 0} ] 76 | }], 77 | score => false, 78 | require => [Cs_primitive["$drbd_primitive"],Cs_primitive["ping_gateway"],Service['pacemaker']], 79 | } 80 | 81 | 82 | ## ISCSI 83 | 84 | cs_primitive { "$iscsi_target_primitive": 85 | primitive_class => 'ocf', 86 | primitive_type => 'iSCSITarget', 87 | provided_by => 'heartbeat', 88 | parameters => { 'iqn' => "$iscsi_iqn", 89 | 'portals' => "${iscsi_vip}:3260", # got error saying it created default portal and then failed to make another 90 | 'implementation' => 'lio-t', 91 | 'additional_parameters' => 'MaxConnections=100 AuthMethod=None InitialR2T=No MaxOutstandingR2T=64', 92 | }, 93 | operations => { 'monitor' => { 'timeout' => '20s', 'interval' => '30s','on-fail' => "restart"}, 94 | 'start' => { 'timeout' => '20s', 'interval' => '0','on-fail' => "restart"}, 95 | 'stop' => { 'timeout' => '20s', 'interval' => '0','on-fail' => "restart"}, 96 | }, 97 | require => [Cs_primitive["$ip_primitive"],Package['targetcli'],Service['pacemaker']], 98 | } 99 | 100 | # http://serverfault.com/a/622110 101 | # emulate_3pc=1,emultate_tpu=1,emulate_caw=1 102 | 103 | # https://github.com/ClusterLabs/resource-agents/issues/610 104 | 105 | cs_primitive { "$iscsi_lun_primitive": 106 | primitive_class => 'ocf', 107 | primitive_type => 'iSCSILogicalUnit', 108 | provided_by => 'heartbeat', 109 | parameters => { 'target_iqn' => "$iscsi_iqn", 110 | 'lun' => "1", 111 | 'path' => $drbd_path, 112 | 'allowed_initiators' => $allowed_initiators, 113 | 'implementation' => 'lio-t'}, 114 | operations => { 'monitor' => { 'timeout' => '10s', 'interval' => '30s','on-fail' => "restart" }, #reducing interval from 20s 115 | 'start' => { 'timeout' => '20s', 'interval' => '0' ,'on-fail' => "restart" }, 116 | 'stop' => { 'timeout' => '20s', 'interval' => '0' ,'on-fail' => "restart" }, 117 | }, 118 | require => [Cs_primitive["$iscsi_target_primitive"],Service['pacemaker']], 119 | } 120 | 121 | ## Additional iSCSI settings 122 | # See https://github.com/ClusterLabs/resource-agents/issues/610 123 | 124 | file { "$iscsi_conf_bin": 125 | ensure => present, 126 | content => template('ixastorage/iscsi_settings.sh.erb'), 127 | owner => 'root', 128 | group => 'root', 129 | mode => '0755', 130 | } 131 | 132 | cs_primitive { "$iscsi_conf_primitive": 133 | primitive_class => 'ocf', 134 | primitive_type => 'anything', 135 | provided_by => 'heartbeat', 136 | parameters => { 'binfile' => $iscsi_conf_bin, 137 | 'stop_timeout' => "3"}, 138 | require => [Cs_primitive["$iscsi_target_primitive"],File["$iscsi_conf_bin"],Service['pacemaker'],File['/usr/lib/ocf/resource.d/heartbeat/anything']], 139 | } 140 | 141 | ####################################### 142 | ### Resource Ordering and Locations ### 143 | ####################################### 144 | 145 | # DRBD Master -> IP -> Target -> Lun -> Conf 146 | 147 | cs_order { "ip_after_drbd_${drbd_resource}": 148 | first => "${ms_resource}:promote", 149 | second => "${ip_primitive}:start", 150 | require => [Cs_primitive["$ip_primitive"],Cs_primitive["$drbd_primitive"],Service['pacemaker']], 151 | } 152 | 153 | cs_order { "target_after_ip_${drbd_resource}": 154 | first => "${ip_primitive}:start", 155 | second => "${iscsi_target_primitive}:start", 156 | require => [Cs_primitive["$ip_primitive"],Cs_primitive["$iscsi_lun_primitive"],Service['pacemaker']], 157 | } 158 | 159 | cs_order { "lun_after_target_${drbd_resource}": 160 | first => "${iscsi_target_primitive}:start", 161 | second => "${iscsi_lun_primitive}:start", 162 | require => [Cs_primitive["$iscsi_lun_primitive"],Cs_primitive["$iscsi_target_primitive"],Service['pacemaker']], 163 | } 164 | 165 | cs_order { "conf_after_lun_${drbd_resource}": 166 | first => "${iscsi_lun_primitive}:start", 167 | second => "${iscsi_conf_primitive}:start", 168 | require => [Cs_primitive["$iscsi_lun_primitive"], Cs_primitive["$iscsi_conf_primitive"],Service['pacemaker']], 169 | } 170 | 171 | # Make sure all required resources are together 172 | 173 | cs_colocation { "ip_with_drbd_${drbd_resource}": 174 | primitives => ["${ms_resource}:Master","$ip_primitive"], 175 | require => [Cs_order["conf_after_lun_${drbd_resource}"]], 176 | } 177 | 178 | cs_colocation { "target_with_ip_${drbd_resource}": 179 | primitives => ["$ip_primitive","$iscsi_target_primitive"], 180 | require => [Cs_order["conf_after_lun_${drbd_resource}"]], 181 | } 182 | 183 | cs_colocation { "lun_with_target_${drbd_resource}": 184 | primitives => ["$iscsi_target_primitive","$iscsi_lun_primitive"], 185 | require => [Cs_order["conf_after_lun_${drbd_resource}"]], 186 | } 187 | 188 | cs_colocation { "conf_with_lun_${drbd_resource}": 189 | primitives => ["$iscsi_lun_primitive","$iscsi_conf_primitive"], 190 | require => [Cs_order["conf_after_lun_${drbd_resource}"]], 191 | } 192 | 193 | # Run the colocated resources on the designated master 194 | 195 | cs_location { "prefer_${drbd_resource}_${master_node}": 196 | primitive => "${ms_resource}", 197 | node_name => "$master_node", 198 | score => '2', 199 | require => [Cs_primitive["$drbd_primitive"],Service['pacemaker']], 200 | } 201 | 202 | } -------------------------------------------------------------------------------- /puppet/files/ha_resource_anything.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # OCF Resource Agent compliant resource script. 4 | # 5 | # Copyright (c) 2009 IN-telegence GmbH & Co. KG, Dominik Klein 6 | # All Rights Reserved. 7 | # 8 | # This program is free software; you can redistribute it and/or modify 9 | # it under the terms of version 2 of the GNU General Public License as 10 | # published by the Free Software Foundation. 11 | # 12 | # This program is distributed in the hope that it would be useful, but 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 | # 16 | # Further, this software is distributed without any warranty that it is 17 | # free of the rightful claim of any third person regarding infringement 18 | # or the like. Any license provided herein, whether implied or 19 | # otherwise, applies only to this software file. Patent licenses, if 20 | # any, provided herein do not apply to combinations of this program with 21 | # other software, or any other product whatsoever. 22 | # 23 | # You should have received a copy of the GNU General Public License 24 | # along with this program; if not, write the Free Software Foundation, 25 | # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 26 | 27 | # OCF instance parameters 28 | # OCF_RESKEY_binfile 29 | # OCF_RESKEY_cmdline_options 30 | # OCF_RESKEY_workdir 31 | # OCF_RESKEY_pidfile 32 | # OCF_RESKEY_logfile 33 | # OCF_RESKEY_errlogfile 34 | # OCF_RESKEY_user 35 | # OCF_RESKEY_monitor_hook 36 | # OCF_RESKEY_stop_timeout 37 | # 38 | # This RA starts $binfile with $cmdline_options as $user in $workdir and writes a $pidfile from that. 39 | # If you want it to, it logs: 40 | # - stdout to $logfile, stderr to $errlogfile or 41 | # - stdout and stderr to $logfile 42 | # - or to will be captured by lrmd if these options are omitted. 43 | # Monitoring is done through $pidfile or your custom $monitor_hook script. 44 | # The RA expects the program to keep running "daemon-like" and 45 | # not just quit and exit. So this is NOT (yet - feel free to 46 | # enhance) a way to just run a single one-shot command which just 47 | # does something and then exits. 48 | 49 | # Initialization: 50 | : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} 51 | . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs 52 | 53 | getpid() { 54 | grep -o '[0-9]*' $1 55 | } 56 | 57 | anything_status() { 58 | if test -f "$pidfile" 59 | then 60 | if pid=`getpid $pidfile` && [ "$pid" ] && kill -s 0 $pid 61 | then 62 | return $OCF_SUCCESS 63 | else 64 | # pidfile w/o process means the process died 65 | return $OCF_ERR_GENERIC 66 | fi 67 | else 68 | return $OCF_NOT_RUNNING 69 | fi 70 | } 71 | 72 | anything_start() { 73 | if ! anything_status 74 | then 75 | if [ -n "$logfile" -a -n "$errlogfile" ] 76 | then 77 | # We have logfile and errlogfile, so redirect STDOUT und STDERR to different files 78 | cmd="su - $user -c \"cd $workdir; nohup $binfile $cmdline_options >> $logfile 2>> $errlogfile & \"'echo \$!' " 79 | else 80 | # We only have logfile so redirect STDOUT and STDERR to the same file 81 | cmd="su - $user -c \"cd $workdir; nohup $binfile $cmdline_options >> $logfile 2>&1 & \"'echo \$!' " 82 | fi 83 | ocf_log debug "Starting $process: $cmd" 84 | # Execute the command as created above 85 | eval $cmd > $pidfile 86 | if anything_status 87 | then 88 | ocf_log debug "$process: $cmd started successfully" 89 | return $OCF_SUCCESS 90 | else 91 | ocf_log err "$process: $cmd could not be started" 92 | return $OCF_ERR_GENERIC 93 | fi 94 | else 95 | # If already running, consider start successful 96 | ocf_log debug "$process: $cmd is already running" 97 | return $OCF_SUCCESS 98 | fi 99 | } 100 | 101 | anything_stop() { 102 | local rc=$OCF_SUCCESS 103 | 104 | if [ -n "$OCF_RESKEY_stop_timeout" ] 105 | then 106 | stop_timeout=$OCF_RESKEY_stop_timeout 107 | elif [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then 108 | # Allow 2/3 of the action timeout for the orderly shutdown 109 | # (The origin unit is ms, hence the conversion) 110 | stop_timeout=$((OCF_RESKEY_CRM_meta_timeout/1500)) 111 | else 112 | stop_timeout=10 113 | fi 114 | if anything_status 115 | then 116 | pid=`getpid $pidfile` 117 | kill $pid 118 | i=0 119 | while [ $i -lt $stop_timeout ] 120 | do 121 | if ! anything_status 122 | then 123 | rm -f $pidfile 124 | return $OCF_SUCCESS 125 | fi 126 | sleep 1 127 | i=$((i+1)) 128 | done 129 | ocf_log warn "Stop with SIGTERM failed/timed out, now sending SIGKILL." 130 | kill -s 9 $pid 131 | while : 132 | do 133 | if ! anything_status 134 | then 135 | ocf_log warn "SIGKILL did the job." 136 | rc=$OCF_SUCCESS 137 | break 138 | fi 139 | ocf_log info "The job still hasn't stopped yet. Waiting..." 140 | sleep 1 141 | done 142 | fi 143 | rm -f $pidfile 144 | return $rc 145 | } 146 | 147 | anything_monitor() { 148 | anything_status 149 | ret=$? 150 | if [ $ret -eq $OCF_SUCCESS ] 151 | then 152 | if [ -n "$OCF_RESKEY_monitor_hook" ]; then 153 | eval "$OCF_RESKEY_monitor_hook" 154 | if [ $? -ne $OCF_SUCCESS ]; then 155 | return ${OCF_ERR_GENERIC} 156 | fi 157 | return $OCF_SUCCESS 158 | else 159 | true 160 | fi 161 | else 162 | return $ret 163 | fi 164 | } 165 | 166 | # FIXME: Attributes special meaning to the resource id 167 | process="$OCF_RESOURCE_INSTANCE" 168 | binfile="$OCF_RESKEY_binfile" 169 | cmdline_options="$OCF_RESKEY_cmdline_options" 170 | workdir="$OCF_RESKEY_workdir" 171 | pidfile="$OCF_RESKEY_pidfile" 172 | [ -z "$pidfile" ] && pidfile=${HA_VARRUN}/anything_${process}.pid 173 | logfile="${OCF_RESKEY_logfile:-/dev/null}" 174 | errlogfile="$OCF_RESKEY_errlogfile" 175 | user="$OCF_RESKEY_user" 176 | [ -z "$user" ] && user=root 177 | 178 | anything_validate() { 179 | if ! su - $user -c "test -x $binfile" 180 | then 181 | ocf_log err "binfile $binfile does not exist or is not executable by $user." 182 | exit $OCF_ERR_INSTALLED 183 | fi 184 | if ! getent passwd $user >/dev/null 2>&1 185 | then 186 | ocf_log err "user $user does not exist." 187 | exit $OCF_ERR_INSTALLED 188 | fi 189 | for logfilename in "$logfile" "$errlogfile" 190 | do 191 | if [ -n "$logfilename" ]; then 192 | mkdir -p `dirname $logfilename` || { 193 | ocf_log err "cannot create $(dirname $logfilename)" 194 | exit $OCF_ERR_INSTALLED 195 | } 196 | fi 197 | done 198 | [ "x$workdir" != x -a ! -d "$workdir" ] && { 199 | ocf_log err "working directory $workdir doesn't exist" 200 | exit $OCF_ERR_INSTALLED 201 | } 202 | return $OCF_SUCCESS 203 | } 204 | 205 | anything_meta() { 206 | cat < 208 | 209 | 210 | 1.0 211 | 212 | This is a generic OCF RA to manage almost anything. 213 | 214 | Manages an arbitrary service 215 | 216 | 217 | 218 | 219 | The full name of the binary to be executed. This is expected to keep running with the same pid and not just do something and exit. 220 | 221 | Full path name of the binary to be executed 222 | 223 | 224 | 225 | 226 | Command line options to pass to the binary 227 | 228 | Command line options 229 | 230 | 231 | 232 | 233 | The path from where the binfile will be executed. 234 | 235 | Full path name of the work directory 236 | 237 | 238 | 239 | 240 | File to read/write the PID from/to. 241 | 242 | File to write STDOUT to 243 | 244 | 245 | 246 | 247 | File to write STDOUT to 248 | 249 | File to write STDOUT to 250 | 251 | 252 | 253 | 254 | File to write STDERR to 255 | 256 | File to write STDERR to 257 | 258 | 259 | 260 | 261 | User to run the command as 262 | 263 | User to run the command as 264 | 265 | 266 | 267 | 268 | Command to run in monitor operation 269 | 270 | Command to run in monitor operation 271 | 272 | 273 | 274 | 275 | In the stop operation: Seconds to wait for kill -TERM to succeed 276 | before sending kill -SIGKILL. Defaults to 2/3 of the stop operation timeout. 277 | 278 | Seconds to wait after having sent SIGTERM before sending SIGKILL in stop operation 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | END 291 | exit 0 292 | } 293 | 294 | case "$1" in 295 | meta-data|metadata|meta_data) 296 | anything_meta 297 | ;; 298 | start) 299 | anything_start 300 | ;; 301 | stop) 302 | anything_stop 303 | ;; 304 | monitor) 305 | anything_monitor 306 | ;; 307 | validate-all) 308 | anything_validate 309 | ;; 310 | *) 311 | ocf_log err "$0 was called with unsupported arguments: $*" 312 | exit $OCF_ERR_UNIMPLEMENTED 313 | ;; 314 | esac 315 | -------------------------------------------------------------------------------- /puppet/tempaltes/lvm.conf.erb: -------------------------------------------------------------------------------- 1 | # This is an example configuration file for the LVM2 system. 2 | # It contains the default settings that would be used if there was no 3 | # /etc/lvm/lvm.conf file. 4 | # 5 | # Refer to 'man lvm.conf' for further information including the file layout. 6 | # 7 | # To put this file in a different directory and override /etc/lvm set 8 | # the environment variable LVM_SYSTEM_DIR before running the tools. 9 | # 10 | # N.B. Take care that each setting only appears once if uncommenting 11 | # example settings in this file. 12 | 13 | # This section allows you to set the way the configuration settings are handled. 14 | config { 15 | 16 | # If enabled, any LVM2 configuration mismatch is reported. 17 | # This implies checking that the configuration key is understood 18 | # by LVM2 and that the value of the key is of a proper type. 19 | # If disabled, any configuration mismatch is ignored and default 20 | # value is used instead without any warning (a message about the 21 | # configuration key not being found is issued in verbose mode only). 22 | checks = 1 23 | 24 | # If enabled, any configuration mismatch aborts the LVM2 process. 25 | abort_on_errors = 0 26 | 27 | # Directory where LVM looks for configuration profiles. 28 | profile_dir = "/etc/lvm/profile" 29 | } 30 | 31 | # This section allows you to configure which block devices should 32 | # be used by the LVM system. 33 | devices { 34 | 35 | # Where do you want your volume groups to appear ? 36 | dir = "/dev" 37 | 38 | # An array of directories that contain the device nodes you wish 39 | # to use with LVM2. 40 | scan = [ "/dev" ] 41 | 42 | # If set, the cache of block device nodes with all associated symlinks 43 | # will be constructed out of the existing udev database content. 44 | # This avoids using and opening any inapplicable non-block devices or 45 | # subdirectories found in the device directory. This setting is applied 46 | # to udev-managed device directory only, other directories will be scanned 47 | # fully. LVM2 needs to be compiled with udev support for this setting to 48 | # take effect. N.B. Any device node or symlink not managed by udev in 49 | # udev directory will be ignored with this setting on. 50 | obtain_device_list_from_udev = 1 51 | 52 | # If several entries in the scanned directories correspond to the 53 | # same block device and the tools need to display a name for device, 54 | # all the pathnames are matched against each item in the following 55 | # list of regular expressions in turn and the first match is used. 56 | 57 | # By default no preferred names are defined. 58 | # preferred_names = [ ] 59 | 60 | # Try to avoid using undescriptive /dev/dm-N names, if present. 61 | preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ] 62 | 63 | # In case no prefererred name matches or if preferred_names are not 64 | # defined at all, builtin rules are used to determine the preference. 65 | # 66 | # The first builtin rule checks path prefixes and it gives preference 67 | # based on this ordering (where "dev" depends on devices/dev setting): 68 | # /dev/mapper > /dev/disk > /dev/dm-* > /dev/block 69 | # 70 | # If the ordering above cannot be applied, the path with fewer slashes 71 | # gets preference then. 72 | # 73 | # If the number of slashes is the same, a symlink gets preference. 74 | # 75 | # Finally, if all the rules mentioned above are not applicable, 76 | # lexicographical order is used over paths and the smallest one 77 | # of all gets preference. 78 | 79 | 80 | # A filter that tells LVM2 to only use a restricted set of devices. 81 | # The filter consists of an array of regular expressions. These 82 | # expressions can be delimited by a character of your choice, and 83 | # prefixed with either an 'a' (for accept) or 'r' (for reject). 84 | # The first expression found to match a device name determines if 85 | # the device will be accepted or rejected (ignored). Devices that 86 | # don't match any patterns are accepted. 87 | 88 | # Be careful if there there are symbolic links or multiple filesystem 89 | # entries for the same device as each name is checked separately against 90 | # the list of patterns. The effect is that if the first pattern in the 91 | # list to match a name is an 'a' pattern for any of the names, the device 92 | # is accepted; otherwise if the first pattern in the list to match a name 93 | # is an 'r' pattern for any of the names it is rejected; otherwise it is 94 | # accepted. 95 | 96 | # Don't have more than one filter line active at once: only one gets used. 97 | 98 | # Run vgscan after you change this parameter to ensure that 99 | # the cache file gets regenerated (see below). 100 | # If it doesn't do what you expect, check the output of 'vgscan -vvvv'. 101 | 102 | # If lvmetad is used, then see "A note about device filtering while 103 | # lvmetad is used" comment that is attached to global/use_lvmetad setting. 104 | 105 | # By default we accept every block device: 106 | # filter = [ "a/.*/" ] 107 | 108 | # Exclude the cdrom drive 109 | # filter = [ "r|/dev/cdrom|" ] 110 | 111 | # When testing I like to work with just loopback devices: 112 | # filter = [ "a/loop/", "r/.*/" ] 113 | 114 | # Or maybe all loops and ide drives except hdc: 115 | # filter =[ "a|loop|", "r|/dev/hdc|", "a|/dev/ide|", "r|.*|" ] 116 | 117 | # Use anchors if you want to be really specific 118 | # filter = [ "a|^/dev/hda8$|", "r/.*/" ] 119 | 120 | # Since "filter" is often overridden from command line, it is not suitable 121 | # for system-wide device filtering (udev rules, lvmetad). To hide devices 122 | # from LVM-specific udev processing and/or from lvmetad, you need to set 123 | # global_filter. The syntax is the same as for normal "filter" 124 | # above. Devices that fail the global_filter are not even opened by LVM. 125 | 126 | # global_filter = [] 127 | 128 | # The results of the filtering are cached on disk to avoid 129 | # rescanning dud devices (which can take a very long time). 130 | # By default this cache is stored in the /etc/lvm/cache directory 131 | # in a file called '.cache'. 132 | # It is safe to delete the contents: the tools regenerate it. 133 | # (The old setting 'cache' is still respected if neither of 134 | # these new ones is present.) 135 | # N.B. If obtain_device_list_from_udev is set to 1 the list of 136 | # devices is instead obtained from udev and any existing .cache 137 | # file is removed. 138 | cache_dir = "/etc/lvm/cache" 139 | cache_file_prefix = "" 140 | 141 | # You can turn off writing this cache file by setting this to 0. 142 | write_cache_state = 1 143 | 144 | # Advanced settings. 145 | 146 | # List of pairs of additional acceptable block device types found 147 | # in /proc/devices with maximum (non-zero) number of partitions. 148 | # types = [ "fd", 16 ] 149 | 150 | # If sysfs is mounted (2.6 kernels) restrict device scanning to 151 | # the block devices it believes are valid. 152 | # 1 enables; 0 disables. 153 | sysfs_scan = 1 154 | 155 | # By default, LVM2 will ignore devices used as component paths 156 | # of device-mapper multipath devices. 157 | # 1 enables; 0 disables. 158 | multipath_component_detection = 1 159 | 160 | # By default, LVM2 will ignore devices used as components of 161 | # software RAID (md) devices by looking for md superblocks. 162 | # 1 enables; 0 disables. 163 | md_component_detection = 1 164 | 165 | # By default, if a PV is placed directly upon an md device, LVM2 166 | # will align its data blocks with the md device's stripe-width. 167 | # 1 enables; 0 disables. 168 | md_chunk_alignment = 1 169 | 170 | # Default alignment of the start of a data area in MB. If set to 0, 171 | # a value of 64KB will be used. Set to 1 for 1MiB, 2 for 2MiB, etc. 172 | # default_data_alignment = 1 173 | 174 | # By default, the start of a PV's data area will be a multiple of 175 | # the 'minimum_io_size' or 'optimal_io_size' exposed in sysfs. 176 | # - minimum_io_size - the smallest request the device can perform 177 | # w/o incurring a read-modify-write penalty (e.g. MD's chunk size) 178 | # - optimal_io_size - the device's preferred unit of receiving I/O 179 | # (e.g. MD's stripe width) 180 | # minimum_io_size is used if optimal_io_size is undefined (0). 181 | # If md_chunk_alignment is enabled, that detects the optimal_io_size. 182 | # This setting takes precedence over md_chunk_alignment. 183 | # 1 enables; 0 disables. 184 | data_alignment_detection = 1 185 | 186 | # Alignment (in KB) of start of data area when creating a new PV. 187 | # md_chunk_alignment and data_alignment_detection are disabled if set. 188 | # Set to 0 for the default alignment (see: data_alignment_default) 189 | # or page size, if larger. 190 | data_alignment = 0 191 | 192 | # By default, the start of the PV's aligned data area will be shifted by 193 | # the 'alignment_offset' exposed in sysfs. This offset is often 0 but 194 | # may be non-zero; e.g.: certain 4KB sector drives that compensate for 195 | # windows partitioning will have an alignment_offset of 3584 bytes 196 | # (sector 7 is the lowest aligned logical block, the 4KB sectors start 197 | # at LBA -1, and consequently sector 63 is aligned on a 4KB boundary). 198 | # But note that pvcreate --dataalignmentoffset will skip this detection. 199 | # 1 enables; 0 disables. 200 | data_alignment_offset_detection = 1 201 | 202 | # If, while scanning the system for PVs, LVM2 encounters a device-mapper 203 | # device that has its I/O suspended, it waits for it to become accessible. 204 | # Set this to 1 to skip such devices. This should only be needed 205 | # in recovery situations. 206 | ignore_suspended_devices = 0 207 | 208 | # ignore_lvm_mirrors: Introduced in version 2.02.104 209 | # This setting determines whether logical volumes of "mirror" segment 210 | # type are scanned for LVM labels. This affects the ability of 211 | # mirrors to be used as physical volumes. If 'ignore_lvm_mirrors' 212 | # is set to '1', it becomes impossible to create volume groups on top 213 | # of mirror logical volumes - i.e. to stack volume groups on mirrors. 214 | # 215 | # Allowing mirror logical volumes to be scanned (setting the value to '0') 216 | # can potentially cause LVM processes and I/O to the mirror to become 217 | # blocked. This is due to the way that the "mirror" segment type handles 218 | # failures. In order for the hang to manifest itself, an LVM command must 219 | # be run just after a failure and before the automatic LVM repair process 220 | # takes place OR there must be failures in multiple mirrors in the same 221 | # volume group at the same time with write failures occurring moments 222 | # before a scan of the mirror's labels. 223 | # 224 | # Note that these scanning limitations do not apply to the LVM RAID 225 | # types, like "raid1". The RAID segment types handle failures in a 226 | # different way and are not subject to possible process or I/O blocking. 227 | # 228 | # It is encouraged that users set 'ignore_lvm_mirrors' to 1 if they 229 | # are using the "mirror" segment type. Users that require volume group 230 | # stacking on mirrored logical volumes should consider using the "raid1" 231 | # segment type. The "raid1" segment type is not available for 232 | # active/active clustered volume groups. 233 | # 234 | # Set to 1 to disallow stacking and thereby avoid a possible deadlock. 235 | ignore_lvm_mirrors = 1 236 | 237 | # During each LVM operation errors received from each device are counted. 238 | # If the counter of a particular device exceeds the limit set here, no 239 | # further I/O is sent to that device for the remainder of the respective 240 | # operation. Setting the parameter to 0 disables the counters altogether. 241 | disable_after_error_count = 0 242 | 243 | # Allow use of pvcreate --uuid without requiring --restorefile. 244 | require_restorefile_with_uuid = 1 245 | 246 | # Minimum size (in KB) of block devices which can be used as PVs. 247 | # In a clustered environment all nodes must use the same value. 248 | # Any value smaller than 512KB is ignored. 249 | 250 | # Ignore devices smaller than 2MB such as floppy drives. 251 | pv_min_size = 2048 252 | 253 | # The original built-in setting was 512 up to and including version 2.02.84. 254 | # pv_min_size = 512 255 | 256 | # Issue discards to a logical volumes's underlying physical volume(s) when 257 | # the logical volume is no longer using the physical volumes' space (e.g. 258 | # lvremove, lvreduce, etc). Discards inform the storage that a region is 259 | # no longer in use. Storage that supports discards advertise the protocol 260 | # specific way discards should be issued by the kernel (TRIM, UNMAP, or 261 | # WRITE SAME with UNMAP bit set). Not all storage will support or benefit 262 | # from discards but SSDs and thinly provisioned LUNs generally do. If set 263 | # to 1, discards will only be issued if both the storage and kernel provide 264 | # support. 265 | # 1 enables; 0 disables. 266 | issue_discards = 1 267 | } 268 | 269 | # This section allows you to configure the way in which LVM selects 270 | # free space for its Logical Volumes. 271 | allocation { 272 | 273 | # When searching for free space to extend an LV, the "cling" 274 | # allocation policy will choose space on the same PVs as the last 275 | # segment of the existing LV. If there is insufficient space and a 276 | # list of tags is defined here, it will check whether any of them are 277 | # attached to the PVs concerned and then seek to match those PV tags 278 | # between existing extents and new extents. 279 | # Use the special tag "@*" as a wildcard to match any PV tag. 280 | 281 | # Example: LVs are mirrored between two sites within a single VG. 282 | # PVs are tagged with either @site1 or @site2 to indicate where 283 | # they are situated. 284 | 285 | # cling_tag_list = [ "@site1", "@site2" ] 286 | # cling_tag_list = [ "@*" ] 287 | 288 | # Changes made in version 2.02.85 extended the reach of the 'cling' 289 | # policies to detect more situations where data can be grouped 290 | # onto the same disks. Set this to 0 to revert to the previous 291 | # algorithm. 292 | maximise_cling = 1 293 | 294 | # Whether to use blkid library instead of native LVM2 code to detect 295 | # any existing signatures while creating new Physical Volumes and 296 | # Logical Volumes. LVM2 needs to be compiled with blkid wiping support 297 | # for this setting to take effect. 298 | # 299 | # LVM2 native detection code is currently able to recognize these signatures: 300 | # - MD device signature 301 | # - swap signature 302 | # - LUKS signature 303 | # To see the list of signatures recognized by blkid, check the output 304 | # of 'blkid -k' command. The blkid can recognize more signatures than 305 | # LVM2 native detection code, but due to this higher number of signatures 306 | # to be recognized, it can take more time to complete the signature scan. 307 | use_blkid_wiping = 1 308 | 309 | # Set to 1 to wipe any signatures found on newly-created Logical Volumes 310 | # automatically in addition to zeroing of the first KB on the LV 311 | # (controlled by the -Z/--zero y option). 312 | # The command line option -W/--wipesignatures takes precedence over this 313 | # setting. 314 | # The default is to wipe signatures when zeroing. 315 | # 316 | wipe_signatures_when_zeroing_new_lvs = 1 317 | 318 | # Set to 1 to guarantee that mirror logs will always be placed on 319 | # different PVs from the mirror images. This was the default 320 | # until version 2.02.85. 321 | mirror_logs_require_separate_pvs = 0 322 | 323 | # Set to 1 to guarantee that cache_pool metadata will always be 324 | # placed on different PVs from the cache_pool data. 325 | cache_pool_metadata_require_separate_pvs = 0 326 | 327 | # Specify the minimal chunk size (in kiB) for cache pool volumes. 328 | # Using a chunk_size that is too large can result in wasteful use of 329 | # the cache, where small reads and writes can cause large sections of 330 | # an LV to be mapped into the cache. However, choosing a chunk_size 331 | # that is too small can result in more overhead trying to manage the 332 | # numerous chunks that become mapped into the cache. The former is 333 | # more of a problem than the latter in most cases, so we default to 334 | # a value that is on the smaller end of the spectrum. Supported values 335 | # range from 32(kiB) to 1048576 in multiples of 32. 336 | # cache_pool_chunk_size = 64 337 | 338 | # Specify the default cache mode used for new cache pools. 339 | # Possible options are: 340 | # "writethrough" - Data blocks are immediately written from 341 | # the cache to disk. 342 | # "writeback" - Data blocks are written from the cache 343 | # back to disk after some delay to improve 344 | # performance. 345 | # cache_pool_cachemode = "writethrough" 346 | 347 | # Set to 1 to guarantee that thin pool metadata will always 348 | # be placed on different PVs from the pool data. 349 | thin_pool_metadata_require_separate_pvs = 0 350 | 351 | # Specify chunk size calculation policy for thin pool volumes. 352 | # Possible options are: 353 | # "generic" - if thin_pool_chunk_size is defined, use it. 354 | # Otherwise, calculate the chunk size based on 355 | # estimation and device hints exposed in sysfs: 356 | # the minimum_io_size. The chunk size is always 357 | # at least 64KiB. 358 | # 359 | # "performance" - if thin_pool_chunk_size is defined, use it. 360 | # Otherwise, calculate the chunk size for 361 | # performance based on device hints exposed in 362 | # sysfs: the optimal_io_size. The chunk size is 363 | # always at least 512KiB. 364 | # thin_pool_chunk_size_policy = "generic" 365 | 366 | # Specify the minimal chunk size (in KB) for thin pool volumes. 367 | # Use of the larger chunk size may improve performance for plain 368 | # thin volumes, however using them for snapshot volumes is less efficient, 369 | # as it consumes more space and takes extra time for copying. 370 | # When unset, lvm tries to estimate chunk size starting from 64KB 371 | # Supported values are in range from 64 to 1048576. 372 | # thin_pool_chunk_size = 64 373 | 374 | # Specify discards behaviour of the thin pool volume. 375 | # Select one of "ignore", "nopassdown", "passdown" 376 | # thin_pool_discards = "passdown" 377 | 378 | # Set to 0, to disable zeroing of thin pool data chunks before their 379 | # first use. 380 | # N.B. zeroing larger thin pool chunk size degrades performance. 381 | # thin_pool_zero = 1 382 | 383 | # Default physical extent size to use for newly created VGs (in KB). 384 | # physical_extent_size = 4096 385 | } 386 | 387 | # This section that allows you to configure the nature of the 388 | # information that LVM2 reports. 389 | log { 390 | 391 | # Controls the messages sent to stdout or stderr. 392 | # There are three levels of verbosity, 3 being the most verbose. 393 | verbose = 0 394 | 395 | # Set to 1 to suppress all non-essential messages from stdout. 396 | # This has the same effect as -qq. 397 | # When this is set, the following commands still produce output: 398 | # dumpconfig, lvdisplay, lvmdiskscan, lvs, pvck, pvdisplay, 399 | # pvs, version, vgcfgrestore -l, vgdisplay, vgs. 400 | # Non-essential messages are shifted from log level 4 to log level 5 401 | # for syslog and lvm2_log_fn purposes. 402 | # Any 'yes' or 'no' questions not overridden by other arguments 403 | # are suppressed and default to 'no'. 404 | silent = 0 405 | 406 | # Should we send log messages through syslog? 407 | # 1 is yes; 0 is no. 408 | syslog = 1 409 | 410 | # Should we log error and debug messages to a file? 411 | # By default there is no log file. 412 | #file = "/var/log/lvm2.log" 413 | 414 | # Should we overwrite the log file each time the program is run? 415 | # By default we append. 416 | overwrite = 0 417 | 418 | # What level of log messages should we send to the log file and/or syslog? 419 | # There are 6 syslog-like log levels currently in use - 2 to 7 inclusive. 420 | # 7 is the most verbose (LOG_DEBUG). 421 | level = 0 422 | 423 | # Format of output messages 424 | # Whether or not (1 or 0) to indent messages according to their severity 425 | indent = 1 426 | 427 | # Whether or not (1 or 0) to display the command name on each line output 428 | command_names = 0 429 | 430 | # A prefix to use before the message text (but after the command name, 431 | # if selected). Default is two spaces, so you can see/grep the severity 432 | # of each message. 433 | prefix = " " 434 | 435 | # To make the messages look similar to the original LVM tools use: 436 | # indent = 0 437 | # command_names = 1 438 | # prefix = " -- " 439 | 440 | # Set this if you want log messages during activation. 441 | # Don't use this in low memory situations (can deadlock). 442 | # activation = 0 443 | 444 | # Some debugging messages are assigned to a class and only appear 445 | # in debug output if the class is listed here. 446 | # Classes currently available: 447 | # memory, devices, activation, allocation, lvmetad, metadata, cache, 448 | # locking 449 | # Use "all" to see everything. 450 | debug_classes = [ "memory", "devices", "activation", "allocation", 451 | "lvmetad", "metadata", "cache", "locking" ] 452 | } 453 | 454 | # Configuration of metadata backups and archiving. In LVM2 when we 455 | # talk about a 'backup' we mean making a copy of the metadata for the 456 | # *current* system. The 'archive' contains old metadata configurations. 457 | # Backups are stored in a human readable text format. 458 | backup { 459 | 460 | # Should we maintain a backup of the current metadata configuration ? 461 | # Use 1 for Yes; 0 for No. 462 | # Think very hard before turning this off! 463 | backup = 1 464 | 465 | # Where shall we keep it ? 466 | # Remember to back up this directory regularly! 467 | backup_dir = "/etc/lvm/backup" 468 | 469 | # Should we maintain an archive of old metadata configurations. 470 | # Use 1 for Yes; 0 for No. 471 | # On by default. Think very hard before turning this off. 472 | archive = 1 473 | 474 | # Where should archived files go ? 475 | # Remember to back up this directory regularly! 476 | archive_dir = "/etc/lvm/archive" 477 | 478 | # What is the minimum number of archive files you wish to keep ? 479 | retain_min = 10 480 | 481 | # What is the minimum time you wish to keep an archive file for ? 482 | retain_days = 30 483 | } 484 | 485 | # Settings for the running LVM2 in shell (readline) mode. 486 | shell { 487 | 488 | # Number of lines of history to store in ~/.lvm_history 489 | history_size = 100 490 | } 491 | 492 | 493 | # Miscellaneous global LVM2 settings 494 | global { 495 | # The file creation mask for any files and directories created. 496 | # Interpreted as octal if the first digit is zero. 497 | umask = 077 498 | 499 | # Allow other users to read the files 500 | #umask = 022 501 | 502 | # Enabling test mode means that no changes to the on disk metadata 503 | # will be made. Equivalent to having the -t option on every 504 | # command. Defaults to off. 505 | test = 0 506 | 507 | # Default value for --units argument 508 | units = "h" 509 | 510 | # Since version 2.02.54, the tools distinguish between powers of 511 | # 1024 bytes (e.g. KiB, MiB, GiB) and powers of 1000 bytes (e.g. 512 | # KB, MB, GB). 513 | # If you have scripts that depend on the old behaviour, set this to 0 514 | # temporarily until you update them. 515 | si_unit_consistency = 1 516 | 517 | # Whether or not to display unit suffix for sizes. This setting has 518 | # no effect if the units are in human-readable form (global/units="h") 519 | # in which case the suffix is always displayed. 520 | suffix = 1 521 | 522 | # Whether or not to communicate with the kernel device-mapper. 523 | # Set to 0 if you want to use the tools to manipulate LVM metadata 524 | # without activating any logical volumes. 525 | # If the device-mapper kernel driver is not present in your kernel 526 | # setting this to 0 should suppress the error messages. 527 | activation = 1 528 | 529 | # If we can't communicate with device-mapper, should we try running 530 | # the LVM1 tools? 531 | # This option only applies to 2.4 kernels and is provided to help you 532 | # switch between device-mapper kernels and LVM1 kernels. 533 | # The LVM1 tools need to be installed with .lvm1 suffices 534 | # e.g. vgscan.lvm1 and they will stop working after you start using 535 | # the new lvm2 on-disk metadata format. 536 | # The default value is set when the tools are built. 537 | # fallback_to_lvm1 = 0 538 | 539 | # The default metadata format that commands should use - "lvm1" or "lvm2". 540 | # The command line override is -M1 or -M2. 541 | # Defaults to "lvm2". 542 | # format = "lvm2" 543 | 544 | # Location of proc filesystem 545 | proc = "/proc" 546 | 547 | # Type of locking to use. Defaults to local file-based locking (1). 548 | # Turn locking off by setting to 0 (dangerous: risks metadata corruption 549 | # if LVM2 commands get run concurrently). 550 | # Type 2 uses the external shared library locking_library. 551 | # Type 3 uses built-in clustered locking. 552 | # Type 4 uses read-only locking which forbids any operations that might 553 | # change metadata. 554 | # Type 5 offers dummy locking for tools that do not need any locks. 555 | # You should not need to set this directly: the tools will select when 556 | # to use it instead of the configured locking_type. Do not use lvmetad or 557 | # the kernel device-mapper driver with this locking type. 558 | # It is used by the --readonly option that offers read-only access to 559 | # Volume Group metadata that cannot be locked safely because it belongs to 560 | # an inaccessible domain and might be in use, for example a virtual machine 561 | # image or a disk that is shared by a clustered machine. 562 | # 563 | # N.B. Don't use lvmetad with locking type 3 as lvmetad is not yet 564 | # supported in clustered environment. If use_lvmetad=1 and locking_type=3 565 | # is set at the same time, LVM always issues a warning message about this 566 | # and then it automatically disables lvmetad use. 567 | locking_type = 1 568 | 569 | # Set to 0 to fail when a lock request cannot be satisfied immediately. 570 | wait_for_locks = 1 571 | 572 | # If using external locking (type 2) and initialisation fails, 573 | # with this set to 1 an attempt will be made to use the built-in 574 | # clustered locking. 575 | # If you are using a customised locking_library you should set this to 0. 576 | fallback_to_clustered_locking = 1 577 | 578 | # If an attempt to initialise type 2 or type 3 locking failed, perhaps 579 | # because cluster components such as clvmd are not running, with this set 580 | # to 1 an attempt will be made to use local file-based locking (type 1). 581 | # If this succeeds, only commands against local volume groups will proceed. 582 | # Volume Groups marked as clustered will be ignored. 583 | fallback_to_local_locking = 1 584 | 585 | # Local non-LV directory that holds file-based locks while commands are 586 | # in progress. A directory like /tmp that may get wiped on reboot is OK. 587 | locking_dir = "/run/lock/lvm" 588 | 589 | # Whenever there are competing read-only and read-write access requests for 590 | # a volume group's metadata, instead of always granting the read-only 591 | # requests immediately, delay them to allow the read-write requests to be 592 | # serviced. Without this setting, write access may be stalled by a high 593 | # volume of read-only requests. 594 | # NB. This option only affects locking_type = 1 viz. local file-based 595 | # locking. 596 | prioritise_write_locks = 1 597 | 598 | # Other entries can go here to allow you to load shared libraries 599 | # e.g. if support for LVM1 metadata was compiled as a shared library use 600 | # format_libraries = "liblvm2format1.so" 601 | # Full pathnames can be given. 602 | 603 | # Search this directory first for shared libraries. 604 | # library_dir = "/lib" 605 | 606 | # The external locking library to load if locking_type is set to 2. 607 | # locking_library = "liblvm2clusterlock.so" 608 | 609 | # Treat any internal errors as fatal errors, aborting the process that 610 | # encountered the internal error. Please only enable for debugging. 611 | abort_on_internal_errors = 0 612 | 613 | # Check whether CRC is matching when parsed VG is used multiple times. 614 | # This is useful to catch unexpected internal cached volume group 615 | # structure modification. Please only enable for debugging. 616 | detect_internal_vg_cache_corruption = 0 617 | 618 | # If set to 1, no operations that change on-disk metadata will be permitted. 619 | # Additionally, read-only commands that encounter metadata in need of repair 620 | # will still be allowed to proceed exactly as if the repair had been 621 | # performed (except for the unchanged vg_seqno). 622 | # Inappropriate use could mess up your system, so seek advice first! 623 | metadata_read_only = 0 624 | 625 | # 'mirror_segtype_default' defines which segtype will be used when the 626 | # shorthand '-m' option is used for mirroring. The possible options are: 627 | # 628 | # "mirror" - The original RAID1 implementation provided by LVM2/DM. It is 629 | # characterized by a flexible log solution (core, disk, mirrored) 630 | # and by the necessity to block I/O while reconfiguring in the 631 | # event of a failure. 632 | # 633 | # There is an inherent race in the dmeventd failure handling 634 | # logic with snapshots of devices using this type of RAID1 that 635 | # in the worst case could cause a deadlock. 636 | # Ref: https://bugzilla.redhat.com/show_bug.cgi?id=817130#c10 637 | # 638 | # "raid1" - This implementation leverages MD's RAID1 personality through 639 | # device-mapper. It is characterized by a lack of log options. 640 | # (A log is always allocated for every device and they are placed 641 | # on the same device as the image - no separate devices are 642 | # required.) This mirror implementation does not require I/O 643 | # to be blocked in the kernel in the event of a failure. 644 | # This mirror implementation is not cluster-aware and cannot be 645 | # used in a shared (active/active) fashion in a cluster. 646 | # 647 | # Specify the '--type ' option to override this default 648 | # setting. 649 | mirror_segtype_default = "raid1" 650 | 651 | # 'raid10_segtype_default' determines the segment types used by default 652 | # when the '--stripes/-i' and '--mirrors/-m' arguments are both specified 653 | # during the creation of a logical volume. 654 | # Possible settings include: 655 | # 656 | # "raid10" - This implementation leverages MD's RAID10 personality through 657 | # device-mapper. 658 | # 659 | # "mirror" - LVM will layer the 'mirror' and 'stripe' segment types. It 660 | # will do this by creating a mirror on top of striped sub-LVs; 661 | # effectively creating a RAID 0+1 array. This is suboptimal 662 | # in terms of providing redundancy and performance. Changing to 663 | # this setting is not advised. 664 | # Specify the '--type ' option to override this default 665 | # setting. 666 | raid10_segtype_default = "raid10" 667 | 668 | # 'sparse_segtype_default' defines which segtype will be used when the 669 | # shorthand '-V and -L' option is used for sparse volume creation. 670 | # 671 | # "snapshot" - The original snapshot implementation provided by LVM2/DM. 672 | # It is using old snashot that mixes data and metadata within 673 | # a single COW storage volume and has poor performs when 674 | # the size of stored data passes hundereds of MB. 675 | # 676 | # "thin" - Newer implementation leverages thin provisioning target. 677 | # It has bigger minimal chunk size (64KiB) and uses separate volume 678 | # for metadata. It has better performance especially in case of 679 | # bigger data uses. This device type has also full snapshot support. 680 | # 681 | # Specify the '--type ' option to override this default 682 | # setting. 683 | sparse_segtype_default = "thin" 684 | 685 | 686 | # The default format for displaying LV names in lvdisplay was changed 687 | # in version 2.02.89 to show the LV name and path separately. 688 | # Previously this was always shown as /dev/vgname/lvname even when that 689 | # was never a valid path in the /dev filesystem. 690 | # Set to 1 to reinstate the previous format. 691 | # 692 | # lvdisplay_shows_full_device_path = 0 693 | 694 | # Whether to use (trust) a running instance of lvmetad. If this is set to 695 | # 0, all commands fall back to the usual scanning mechanisms. When set to 1 696 | # *and* when lvmetad is running (automatically instantiated by making use of 697 | # systemd's socket-based service activation or run as an initscripts service 698 | # or run manually), the volume group metadata and PV state flags are obtained 699 | # from the lvmetad instance and no scanning is done by the individual 700 | # commands. In a setup with lvmetad, lvmetad udev rules *must* be set up for 701 | # LVM to work correctly. Without proper udev rules, all changes in block 702 | # device configuration will be *ignored* until a manual 'pvscan --cache' 703 | # is performed. These rules are installed by default. 704 | # 705 | # If lvmetad has been running while use_lvmetad was 0, it MUST be stopped 706 | # before changing use_lvmetad to 1 and started again afterwards. 707 | # 708 | # If using lvmetad, volume activation is also switched to automatic 709 | # event-based mode. In this mode, the volumes are activated based on 710 | # incoming udev events that automatically inform lvmetad about new PVs that 711 | # appear in the system. Once a VG is complete (all the PVs are present), it 712 | # is auto-activated. The activation/auto_activation_volume_list setting 713 | # controls which volumes are auto-activated (all by default). 714 | 715 | # A note about device filtering while lvmetad is used: 716 | 717 | # When lvmetad is updated (either automatically based on udev events or 718 | # directly by a pvscan --cache call), devices/filter is ignored and 719 | # all devices are scanned by default -- lvmetad always keeps unfiltered 720 | # information which is then provided to LVM commands and then each LVM 721 | # command does the filtering based on devices/filter setting itself. This 722 | # does not apply to non-regexp filters though: component filters such as 723 | # multipath and MD are checked at pvscan --cache time. 724 | 725 | # In order to completely prevent LVM from scanning a device, even when using 726 | # lvmetad, devices/global_filter must be used. 727 | 728 | # N.B. Don't use lvmetad with locking type 3 as lvmetad is not yet 729 | # supported in clustered environment. If use_lvmetad=1 and locking_type=3 730 | # is set at the same time, LVM always issues a warning message about this 731 | # and then it automatically disables use_lvmetad. 732 | 733 | use_lvmetad = 1 734 | 735 | # Full path of the utility called to check that a thin metadata device 736 | # is in a state that allows it to be used. 737 | # Each time a thin pool needs to be activated or after it is deactivated 738 | # this utility is executed. The activation will only proceed if the utility 739 | # has an exit status of 0. 740 | # Set to "" to skip this check. (Not recommended.) 741 | # The thin tools are available as part of the device-mapper-persistent-data 742 | # package from https://github.com/jthornber/thin-provisioning-tools. 743 | # 744 | # thin_check_executable = "/usr/sbin/thin_check" 745 | 746 | # Array of string options passed with thin_check command. By default, 747 | # option "-q" is for quiet output. 748 | # With thin_check version 2.1 or newer you can add "--ignore-non-fatal-errors" 749 | # to let it pass through ignorable errors and fix them later. 750 | # With thin_check version 3.2 or newer you should add 751 | # "--clear-needs-check-flag". 752 | # 753 | # thin_check_options = [ "-q", "--clear-needs-check-flag" ] 754 | 755 | # Full path of the utility called to repair a thin metadata device 756 | # is in a state that allows it to be used. 757 | # Each time a thin pool needs repair this utility is executed. 758 | # See thin_check_executable how to obtain binaries. 759 | # 760 | # thin_repair_executable = "/usr/sbin/thin_repair" 761 | 762 | # Array of extra string options passed with thin_repair command. 763 | # thin_repair_options = [ "" ] 764 | 765 | # Full path of the utility called to dump thin metadata content. 766 | # See thin_check_executable how to obtain binaries. 767 | # 768 | # thin_dump_executable = "/usr/sbin/thin_dump" 769 | 770 | # If set, given features are not used by thin driver. 771 | # This can be helpful not just for testing, but i.e. allows to avoid 772 | # using problematic implementation of some thin feature. 773 | # Features: 774 | # block_size 775 | # discards 776 | # discards_non_power_2 777 | # external_origin 778 | # metadata_resize 779 | # external_origin_extend 780 | # error_if_no_space 781 | # 782 | # thin_disabled_features = [ "discards", "block_size" ] 783 | 784 | # Full path of the utility called to check that a cache metadata device 785 | # is in a state that allows it to be used. 786 | # Each time a cached LV needs to be used or after it is deactivated 787 | # this utility is executed. The activation will only proceed if the utility 788 | # has an exit status of 0. 789 | # Set to "" to skip this check. (Not recommended.) 790 | # The cache tools are available as part of the device-mapper-persistent-data 791 | # package from https://github.com/jthornber/thin-provisioning-tools. 792 | # 793 | # cache_check_executable = "/usr/sbin/cache_check" 794 | 795 | # Array of string options passed with cache_check command. By default, 796 | # option "-q" is for quiet output. 797 | # 798 | # cache_check_options = [ "-q" ] 799 | 800 | # Full path of the utility called to repair a cache metadata device. 801 | # Each time a cache metadata needs repair this utility is executed. 802 | # See cache_check_executable how to obtain binaries. 803 | # 804 | # cache_repair_executable = "/usr/sbin/cache_repair" 805 | 806 | # Array of extra string options passed with cache_repair command. 807 | # cache_repair_options = [ "" ] 808 | 809 | # Full path of the utility called to dump cache metadata content. 810 | # See cache_check_executable how to obtain binaries. 811 | # 812 | # cache_dump_executable = "/usr/sbin/cache_dump" 813 | } 814 | 815 | activation { 816 | # Set to 1 to perform internal checks on the operations issued to 817 | # libdevmapper. Useful for debugging problems with activation. 818 | # Some of the checks may be expensive, so it's best to use this 819 | # only when there seems to be a problem. 820 | checks = 0 821 | 822 | # Set to 0 to disable udev synchronisation (if compiled into the binaries). 823 | # Processes will not wait for notification from udev. 824 | # They will continue irrespective of any possible udev processing 825 | # in the background. You should only use this if udev is not running 826 | # or has rules that ignore the devices LVM2 creates. 827 | # The command line argument --nodevsync takes precedence over this setting. 828 | # If set to 1 when udev is not running, and there are LVM2 processes 829 | # waiting for udev, run 'dmsetup udevcomplete_all' manually to wake them up. 830 | udev_sync = 1 831 | 832 | # Set to 0 to disable the udev rules installed by LVM2 (if built with 833 | # --enable-udev_rules). LVM2 will then manage the /dev nodes and symlinks 834 | # for active logical volumes directly itself. 835 | # N.B. Manual intervention may be required if this setting is changed 836 | # while any logical volumes are active. 837 | udev_rules = 1 838 | 839 | # Set to 1 for LVM2 to verify operations performed by udev. This turns on 840 | # additional checks (and if necessary, repairs) on entries in the device 841 | # directory after udev has completed processing its events. 842 | # Useful for diagnosing problems with LVM2/udev interactions. 843 | verify_udev_operations = 0 844 | 845 | # If set to 1 and if deactivation of an LV fails, perhaps because 846 | # a process run from a quick udev rule temporarily opened the device, 847 | # retry the operation for a few seconds before failing. 848 | retry_deactivation = 1 849 | 850 | # How to fill in missing stripes if activating an incomplete volume. 851 | # Using "error" will make inaccessible parts of the device return 852 | # I/O errors on access. You can instead use a device path, in which 853 | # case, that device will be used to in place of missing stripes. 854 | # But note that using anything other than "error" with mirrored 855 | # or snapshotted volumes is likely to result in data corruption. 856 | missing_stripe_filler = "error" 857 | 858 | # The linear target is an optimised version of the striped target 859 | # that only handles a single stripe. Set this to 0 to disable this 860 | # optimisation and always use the striped target. 861 | use_linear_target = 1 862 | 863 | # How much stack (in KB) to reserve for use while devices suspended 864 | # Prior to version 2.02.89 this used to be set to 256KB 865 | reserved_stack = 64 866 | 867 | # How much memory (in KB) to reserve for use while devices suspended 868 | reserved_memory = 8192 869 | 870 | # Nice value used while devices suspended 871 | process_priority = -18 872 | 873 | # If volume_list is defined, each LV is only activated if there is a 874 | # match against the list. 875 | # 876 | # "vgname" and "vgname/lvname" are matched exactly. 877 | # "@tag" matches any tag set in the LV or VG. 878 | # "@*" matches if any tag defined on the host is also set in the LV or VG 879 | # 880 | # If any host tags exist but volume_list is not defined, a default 881 | # single-entry list containing "@*" is assumed. 882 | # 883 | # volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ] 884 | 885 | # If auto_activation_volume_list is defined, each LV that is to be 886 | # activated with the autoactivation option (--activate ay/-a ay) is 887 | # first checked against the list. There are two scenarios in which 888 | # the autoactivation option is used: 889 | # 890 | # - automatic activation of volumes based on incoming PVs. If all the 891 | # PVs making up a VG are present in the system, the autoactivation 892 | # is triggered. This requires lvmetad (global/use_lvmetad=1) and udev 893 | # to be running. In this case, "pvscan --cache -aay" is called 894 | # automatically without any user intervention while processing 895 | # udev events. Please, make sure you define auto_activation_volume_list 896 | # properly so only the volumes you want and expect are autoactivated. 897 | # 898 | # - direct activation on command line with the autoactivation option. 899 | # In this case, the user calls "vgchange --activate ay/-a ay" or 900 | # "lvchange --activate ay/-a ay" directly. 901 | # 902 | # By default, the auto_activation_volume_list is not defined and all 903 | # volumes will be activated either automatically or by using --activate ay/-a ay. 904 | # 905 | # N.B. The "activation/volume_list" is still honoured in all cases so even 906 | # if the VG/LV passes the auto_activation_volume_list, it still needs to 907 | # pass the volume_list for it to be activated in the end. 908 | 909 | # If auto_activation_volume_list is defined but empty, no volumes will be 910 | # activated automatically and --activate ay/-a ay will do nothing. 911 | # 912 | # auto_activation_volume_list = [] 913 | 914 | # If auto_activation_volume_list is defined and it's not empty, only matching 915 | # volumes will be activated either automatically or by using --activate ay/-a ay. 916 | # 917 | # "vgname" and "vgname/lvname" are matched exactly. 918 | # "@tag" matches any tag set in the LV or VG. 919 | # "@*" matches if any tag defined on the host is also set in the LV or VG 920 | # 921 | # auto_activation_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ] 922 | 923 | # If read_only_volume_list is defined, each LV that is to be activated 924 | # is checked against the list, and if it matches, it as activated 925 | # in read-only mode. (This overrides '--permission rw' stored in the 926 | # metadata.) 927 | # 928 | # "vgname" and "vgname/lvname" are matched exactly. 929 | # "@tag" matches any tag set in the LV or VG. 930 | # "@*" matches if any tag defined on the host is also set in the LV or VG 931 | # 932 | # read_only_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ] 933 | 934 | # Each LV can have an 'activation skip' flag stored persistently against it. 935 | # During activation, this flag is used to decide whether such an LV is skipped. 936 | # The 'activation skip' flag can be set during LV creation and by default it 937 | # is automatically set for thin snapshot LVs. The 'auto_set_activation_skip' 938 | # enables or disables this automatic setting of the flag while LVs are created. 939 | # auto_set_activation_skip = 1 940 | 941 | # Control error behavior when provisioned device becomes full. 942 | # Set to 1 to instant error when there is missing free space in device. 943 | # error_when_full = 0 944 | 945 | # For RAID or 'mirror' segment types, 'raid_region_size' is the 946 | # size (in KiB) of each: 947 | # - synchronization operation when initializing 948 | # - each copy operation when performing a 'pvmove' (using 'mirror' segtype) 949 | # This setting has replaced 'mirror_region_size' since version 2.02.99 950 | raid_region_size = 512 951 | 952 | # Setting to use when there is no readahead value stored in the metadata. 953 | # 954 | # "none" - Disable readahead. 955 | # "auto" - Use default value chosen by kernel. 956 | readahead = "auto" 957 | 958 | # 'raid_fault_policy' defines how a device failure in a RAID logical 959 | # volume is handled. This includes logical volumes that have the following 960 | # segment types: raid1, raid4, raid5*, and raid6*. 961 | # 962 | # In the event of a failure, the following policies will determine what 963 | # actions are performed during the automated response to failures (when 964 | # dmeventd is monitoring the RAID logical volume) and when 'lvconvert' is 965 | # called manually with the options '--repair' and '--use-policies'. 966 | # 967 | # "warn" - Use the system log to warn the user that a device in the RAID 968 | # logical volume has failed. It is left to the user to run 969 | # 'lvconvert --repair' manually to remove or replace the failed 970 | # device. As long as the number of failed devices does not 971 | # exceed the redundancy of the logical volume (1 device for 972 | # raid4/5, 2 for raid6, etc) the logical volume will remain 973 | # usable. 974 | # 975 | # "allocate" - Attempt to use any extra physical volumes in the volume 976 | # group as spares and replace faulty devices. 977 | # 978 | raid_fault_policy = "warn" 979 | 980 | # 'mirror_image_fault_policy' and 'mirror_log_fault_policy' define 981 | # how a device failure affecting a mirror (of "mirror" segment type) is 982 | # handled. A mirror is composed of mirror images (copies) and a log. 983 | # A disk log ensures that a mirror does not need to be re-synced 984 | # (all copies made the same) every time a machine reboots or crashes. 985 | # 986 | # In the event of a failure, the specified policy will be used to determine 987 | # what happens. This applies to automatic repairs (when the mirror is being 988 | # monitored by dmeventd) and to manual lvconvert --repair when 989 | # --use-policies is given. 990 | # 991 | # "remove" - Simply remove the faulty device and run without it. If 992 | # the log device fails, the mirror would convert to using 993 | # an in-memory log. This means the mirror will not 994 | # remember its sync status across crashes/reboots and 995 | # the entire mirror will be re-synced. If a 996 | # mirror image fails, the mirror will convert to a 997 | # non-mirrored device if there is only one remaining good 998 | # copy. 999 | # 1000 | # "allocate" - Remove the faulty device and try to allocate space on 1001 | # a new device to be a replacement for the failed device. 1002 | # Using this policy for the log is fast and maintains the 1003 | # ability to remember sync state through crashes/reboots. 1004 | # Using this policy for a mirror device is slow, as it 1005 | # requires the mirror to resynchronize the devices, but it 1006 | # will preserve the mirror characteristic of the device. 1007 | # This policy acts like "remove" if no suitable device and 1008 | # space can be allocated for the replacement. 1009 | # 1010 | # "allocate_anywhere" - Not yet implemented. Useful to place the log device 1011 | # temporarily on same physical volume as one of the mirror 1012 | # images. This policy is not recommended for mirror devices 1013 | # since it would break the redundant nature of the mirror. This 1014 | # policy acts like "remove" if no suitable device and space can 1015 | # be allocated for the replacement. 1016 | 1017 | mirror_log_fault_policy = "allocate" 1018 | mirror_image_fault_policy = "remove" 1019 | 1020 | # 'snapshot_autoextend_threshold' and 'snapshot_autoextend_percent' define 1021 | # how to handle automatic snapshot extension. The former defines when the 1022 | # snapshot should be extended: when its space usage exceeds this many 1023 | # percent. The latter defines how much extra space should be allocated for 1024 | # the snapshot, in percent of its current size. 1025 | # 1026 | # For example, if you set snapshot_autoextend_threshold to 70 and 1027 | # snapshot_autoextend_percent to 20, whenever a snapshot exceeds 70% usage, 1028 | # it will be extended by another 20%. For a 1G snapshot, using up 700M will 1029 | # trigger a resize to 1.2G. When the usage exceeds 840M, the snapshot will 1030 | # be extended to 1.44G, and so on. 1031 | # 1032 | # Setting snapshot_autoextend_threshold to 100 disables automatic 1033 | # extensions. The minimum value is 50 (A setting below 50 will be treated 1034 | # as 50). 1035 | 1036 | snapshot_autoextend_threshold = 100 1037 | snapshot_autoextend_percent = 20 1038 | 1039 | # 'thin_pool_autoextend_threshold' and 'thin_pool_autoextend_percent' define 1040 | # how to handle automatic pool extension. The former defines when the 1041 | # pool should be extended: when its space usage exceeds this many 1042 | # percent. The latter defines how much extra space should be allocated for 1043 | # the pool, in percent of its current size. 1044 | # 1045 | # For example, if you set thin_pool_autoextend_threshold to 70 and 1046 | # thin_pool_autoextend_percent to 20, whenever a pool exceeds 70% usage, 1047 | # it will be extended by another 20%. For a 1G pool, using up 700M will 1048 | # trigger a resize to 1.2G. When the usage exceeds 840M, the pool will 1049 | # be extended to 1.44G, and so on. 1050 | # 1051 | # Setting thin_pool_autoextend_threshold to 100 disables automatic 1052 | # extensions. The minimum value is 50 (A setting below 50 will be treated 1053 | # as 50). 1054 | 1055 | thin_pool_autoextend_threshold = 100 1056 | thin_pool_autoextend_percent = 20 1057 | 1058 | # While activating devices, I/O to devices being (re)configured is 1059 | # suspended, and as a precaution against deadlocks, LVM2 needs to pin 1060 | # any memory it is using so it is not paged out. Groups of pages that 1061 | # are known not to be accessed during activation need not be pinned 1062 | # into memory. Each string listed in this setting is compared against 1063 | # each line in /proc/self/maps, and the pages corresponding to any 1064 | # lines that match are not pinned. On some systems locale-archive was 1065 | # found to make up over 80% of the memory used by the process. 1066 | # mlock_filter = [ "locale/locale-archive", "gconv/gconv-modules.cache" ] 1067 | 1068 | # Set to 1 to revert to the default behaviour prior to version 2.02.62 1069 | # which used mlockall() to pin the whole process's memory while activating 1070 | # devices. 1071 | use_mlockall = 0 1072 | 1073 | # Monitoring is enabled by default when activating logical volumes. 1074 | # Set to 0 to disable monitoring or use the --ignoremonitoring option. 1075 | monitoring = 1 1076 | 1077 | # When pvmove or lvconvert must wait for the kernel to finish 1078 | # synchronising or merging data, they check and report progress 1079 | # at intervals of this number of seconds. The default is 15 seconds. 1080 | # If this is set to 0 and there is only one thing to wait for, there 1081 | # are no progress reports, but the process is awoken immediately the 1082 | # operation is complete. 1083 | polling_interval = 15 1084 | 1085 | # 'activation_mode' determines how Logical Volumes are activated if 1086 | # any devices are missing. Possible settings are: 1087 | # 1088 | # "complete" - Only allow activation of an LV if all of the Physical 1089 | # Volumes it uses are present. Other PVs in the Volume 1090 | # Group may be missing. 1091 | # 1092 | # "degraded" - Like "complete", but additionally RAID Logical Volumes of 1093 | # segment type raid1, raid4, raid5, radid6 and raid10 will 1094 | # be activated if there is no data loss, i.e. they have 1095 | # sufficient redundancy to present the entire addressable 1096 | # range of the Logical Volume. 1097 | # 1098 | # "partial" - Allows the activation of any Logical Volume even if 1099 | # a missing or failed PV could cause data loss with a 1100 | # portion of the Logical Volume inaccessible. 1101 | # This setting should not normally be used, but may 1102 | # sometimes assist with data recovery. 1103 | # 1104 | # This setting was introduced in LVM version 2.02.108. It corresponds 1105 | # with the '--activationmode' option for lvchange and vgchange. 1106 | activation_mode = "degraded" 1107 | } 1108 | 1109 | # Report settings. 1110 | # 1111 | # report { 1112 | # If compact output is enabled, fields which don't have value 1113 | # set for any of the rows reported are skipped on output. Compact 1114 | # output is applicable only if report is buffered (report/buffered=1). 1115 | # compact_output=0 1116 | 1117 | # Align columns on report output. 1118 | # aligned=1 1119 | 1120 | # When buffered reporting is used, the report's content is appended 1121 | # incrementally to include each object being reported until the report 1122 | # is flushed to output which normally happens at the end of command 1123 | # execution. Otherwise, if buffering is not used, each object is 1124 | # reported as soon as its processing is finished. 1125 | # buffered=1 1126 | 1127 | # Show headings for columns on report. 1128 | # headings=1 1129 | 1130 | # A separator to use on report after each field. 1131 | # separator=" " 1132 | 1133 | # A separator to use for list items when reported. 1134 | # list_item_separator="," 1135 | 1136 | # Use a field name prefix for each field reported. 1137 | # prefixes=0 1138 | 1139 | # Quote field values when using field name prefixes. 1140 | # quoted=1 1141 | 1142 | # Output each column as a row. If set, this also implies report/prefixes=1. 1143 | # colums_as_rows=0 1144 | 1145 | # Use binary values "0" or "1" instead of descriptive literal values for 1146 | # columns that have exactly two valid values to report (not counting the 1147 | # "unknown" value which denotes that the value could not be determined). 1148 | # 1149 | # binary_values_as_numeric = 0 1150 | 1151 | # Comma separated list of columns to sort by when reporting 'lvm devtypes' command. 1152 | # See 'lvm devtypes -o help' for the list of possible fields. 1153 | # devtypes_sort="devtype_name" 1154 | 1155 | # Comma separated list of columns to report for 'lvm devtypes' command. 1156 | # See 'lvm devtypes -o help' for the list of possible fields. 1157 | # devtypes_cols="devtype_name,devtype_max_partitions,devtype_description" 1158 | 1159 | # Comma separated list of columns to report for 'lvm devtypes' command in verbose mode. 1160 | # See 'lvm devtypes -o help' for the list of possible fields. 1161 | # devtypes_cols_verbose="devtype_name,devtype_max_partitions,devtype_description" 1162 | 1163 | # Comma separated list of columns to sort by when reporting 'lvs' command. 1164 | # See 'lvs -o help' for the list of possible fields. 1165 | # lvs_sort="vg_name,lv_name" 1166 | 1167 | # Comma separated list of columns to report for 'lvs' command. 1168 | # See 'lvs -o help' for the list of possible fields. 1169 | # lvs_cols="lv_name,vg_name,lv_attr,lv_size,pool_lv,origin,data_percent,metadata_percent,move_pv,mirror_log,copy_percent,convert_lv" 1170 | 1171 | # Comma separated list of columns to report for 'lvs' command in verbose mode. 1172 | # See 'lvs -o help' for the list of possible fields. 1173 | # lvs_cols_verbose="lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,lv_kernel_major,lv_kernel_minor,pool_lv,origin,data_percent,metadata_percent,move_pv,copy_percent,mirror_log,convert 1174 | 1175 | # Comma separated list of columns to sort by when reporting 'vgs' command. 1176 | # See 'vgs -o help' for the list of possible fields. 1177 | # vgs_sort="vg_name" 1178 | 1179 | # Comma separated list of columns to report for 'vgs' command. 1180 | # See 'vgs -o help' for the list of possible fields. 1181 | # vgs_cols="vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free" 1182 | 1183 | # Comma separated list of columns to report for 'vgs' command in verbose mode. 1184 | # See 'vgs -o help' for the list of possible fields. 1185 | # vgs_cols_verbose="vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid,vg_profile" 1186 | 1187 | # Comma separated list of columns to sort by when reporting 'pvs' command. 1188 | # See 'pvs -o help' for the list of possible fields. 1189 | # pvs_sort="pv_name" 1190 | 1191 | # Comma separated list of columns to report for 'pvs' command. 1192 | # See 'pvs -o help' for the list of possible fields. 1193 | # pvs_cols="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free" 1194 | 1195 | # Comma separated list of columns to report for 'pvs' command in verbose mode. 1196 | # See 'pvs -o help' for the list of possible fields. 1197 | # pvs_cols_verbose="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,dev_size,pv_uuid" 1198 | 1199 | # Comma separated list of columns to sort by when reporting 'lvs --segments' command. 1200 | # See 'lvs --segments -o help' for the list of possible fields. 1201 | # segs_sort="vg_name,lv_name,seg_start" 1202 | 1203 | # Comma separated list of columns to report for 'lvs --segments' command. 1204 | # See 'lvs --segments -o help' for the list of possible fields. 1205 | # segs_cols="lv_name,vg_name,lv_attr,stripes,segtype,seg_size" 1206 | 1207 | # Comma separated list of columns to report for 'lvs --segments' command in verbose mode. 1208 | # See 'lvs --segments -o help' for the list of possible fields. 1209 | # segs_cols_verbose="lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize" 1210 | 1211 | # Comma separated list of columns to sort by when reporting 'pvs --segments' command. 1212 | # See 'pvs --segments -o help' for the list of possible fields. 1213 | # pvsegs_sort="pv_name,pvseg_start" 1214 | 1215 | # Comma separated list of columns to sort by when reporting 'pvs --segments' command. 1216 | # See 'pvs --segments -o help' for the list of possible fields. 1217 | # pvsegs_cols="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size" 1218 | 1219 | # Comma separated list of columns to sort by when reporting 'pvs --segments' command in verbose mode. 1220 | # See 'pvs --segments -o help' for the list of possible fields. 1221 | # pvsegs_cols_verbose="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size,lv_name,seg_start_pe,segtype,seg_pe_ranges" 1222 | #} 1223 | 1224 | #################### 1225 | # Advanced section # 1226 | #################### 1227 | 1228 | # Metadata settings 1229 | # 1230 | # metadata { 1231 | # Default number of copies of metadata to hold on each PV. 0, 1 or 2. 1232 | # You might want to override it from the command line with 0 1233 | # when running pvcreate on new PVs which are to be added to large VGs. 1234 | 1235 | # pvmetadatacopies = 1 1236 | 1237 | # Default number of copies of metadata to maintain for each VG. 1238 | # If set to a non-zero value, LVM automatically chooses which of 1239 | # the available metadata areas to use to achieve the requested 1240 | # number of copies of the VG metadata. If you set a value larger 1241 | # than the the total number of metadata areas available then 1242 | # metadata is stored in them all. 1243 | # The default value of 0 ("unmanaged") disables this automatic 1244 | # management and allows you to control which metadata areas 1245 | # are used at the individual PV level using 'pvchange 1246 | # --metadataignore y/n'. 1247 | 1248 | # vgmetadatacopies = 0 1249 | 1250 | # Approximate default size of on-disk metadata areas in sectors. 1251 | # You should increase this if you have large volume groups or 1252 | # you want to retain a large on-disk history of your metadata changes. 1253 | 1254 | # pvmetadatasize = 255 1255 | 1256 | # List of directories holding live copies of text format metadata. 1257 | # These directories must not be on logical volumes! 1258 | # It's possible to use LVM2 with a couple of directories here, 1259 | # preferably on different (non-LV) filesystems, and with no other 1260 | # on-disk metadata (pvmetadatacopies = 0). Or this can be in 1261 | # addition to on-disk metadata areas. 1262 | # The feature was originally added to simplify testing and is not 1263 | # supported under low memory situations - the machine could lock up. 1264 | # 1265 | # Never edit any files in these directories by hand unless you 1266 | # you are absolutely sure you know what you are doing! Use 1267 | # the supplied toolset to make changes (e.g. vgcfgrestore). 1268 | 1269 | # dirs = [ "/etc/lvm/metadata", "/mnt/disk2/lvm/metadata2" ] 1270 | #} 1271 | 1272 | # Event daemon 1273 | # 1274 | dmeventd { 1275 | # mirror_library is the library used when monitoring a mirror device. 1276 | # 1277 | # "libdevmapper-event-lvm2mirror.so" attempts to recover from 1278 | # failures. It removes failed devices from a volume group and 1279 | # reconfigures a mirror as necessary. If no mirror library is 1280 | # provided, mirrors are not monitored through dmeventd. 1281 | 1282 | mirror_library = "libdevmapper-event-lvm2mirror.so" 1283 | 1284 | # snapshot_library is the library used when monitoring a snapshot device. 1285 | # 1286 | # "libdevmapper-event-lvm2snapshot.so" monitors the filling of 1287 | # snapshots and emits a warning through syslog when the use of 1288 | # the snapshot exceeds 80%. The warning is repeated when 85%, 90% and 1289 | # 95% of the snapshot is filled. 1290 | 1291 | snapshot_library = "libdevmapper-event-lvm2snapshot.so" 1292 | 1293 | # thin_library is the library used when monitoring a thin device. 1294 | # 1295 | # "libdevmapper-event-lvm2thin.so" monitors the filling of 1296 | # pool and emits a warning through syslog when the use of 1297 | # the pool exceeds 80%. The warning is repeated when 85%, 90% and 1298 | # 95% of the pool is filled. 1299 | 1300 | thin_library = "libdevmapper-event-lvm2thin.so" 1301 | 1302 | # Full path of the dmeventd binary. 1303 | # 1304 | # executable = "/usr/sbin/dmeventd" 1305 | } --------------------------------------------------------------------------------