Skip to content

Commit

Permalink
softraid: make lvm2 activate the degraded raid in initramfs
Browse files Browse the repository at this point in the history
Patch for a known limitation of lvm2:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1018730
in prevision of debian 12.

Signed-off-by: Florent CARLI <florent.carli@rte-france.com>
  • Loading branch information
insatomcat committed Aug 17, 2023
1 parent 7afa2f6 commit 5f97b21
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 2 deletions.
1 change: 0 additions & 1 deletion playbooks/cluster_setup_keys.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
- name: Configure ssh keys between hosts
hosts: cluster_machines
become: true
gather_facts: yes
tasks:
- name: generate SSH key
user:
Expand Down
1 change: 1 addition & 0 deletions playbooks/cluster_setup_prerequisdebian.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
- name: Prerequis machine debian
gather_facts: True
hosts:
- cluster_machines
- standalone_machine
Expand Down
9 changes: 8 additions & 1 deletion roles/debian/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,14 @@
dest: /etc/initramfs-tools/scripts/init-premount/lvm_snapshot_rebooter
mode: '0755'
register: lvm_snapshot_rebooter
- name: "add udev rules for lvm2 limitation"
ansible.builtin.copy:
src: ../src/debian/69-lvm.rules
dest: /etc/udev/rules.d/69-lvm.rules
mode: '0644'
when: ansible_distribution == 'Debian' and ansible_distribution_version | int >= 12
register: udevlvm
- name: "rebuild initramfs if necessary"
command:
cmd: /usr/sbin/update-initramfs -u
when: lvm_snapshot_rebooter.changed
when: udevlvm.changed or lvm_snapshot_rebooter.changed
94 changes: 94 additions & 0 deletions src/debian/69-lvm.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Copyright (C) 2012,2021 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM.
#
# This rule requires blkid to be called on block devices before so only devices
# used as LVM PVs are processed (ID_FS_TYPE="LVM2_member").

SUBSYSTEM!="block", GOTO="lvm_end"


ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="lvm_end"

# Only process devices already marked as a PV - this requires blkid to be called before.
ENV{ID_FS_TYPE}!="LVM2_member", GOTO="lvm_end"
ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="lvm_end"
ACTION=="remove", GOTO="lvm_end"

# Create /dev/disk/by-id/lvm-pv-uuid-<PV_UUID> symlink for each PV
ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-id/lvm-pv-uuid-$env{ID_FS_UUID_ENC}"

# If the PV is a special device listed below, scan only if the device is
# properly activated. These devices are not usable after an ADD event,
# but they require an extra setup and they are ready after a CHANGE event.
# Also support coldplugging with ADD event but only if the device is already
# properly activated.
# This logic should be eventually moved to rules where those particular
# devices are processed primarily (MD and loop).

# DM device:
KERNEL!="dm-[0-9]*", GOTO="next"
ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}=="1", GOTO="lvm_scan"
GOTO="lvm_end"

# MD device:
LABEL="next"
KERNEL!="md[0-9]*", GOTO="next"
IMPORT{db}="LVM_MD_PV_ACTIVATED"
ACTION=="add", ENV{LVM_MD_PV_ACTIVATED}=="1", GOTO="lvm_scan"
ACTION=="change", ENV{LVM_MD_PV_ACTIVATED}!="1", TEST=="md/array_state", ENV{LVM_MD_PV_ACTIVATED}="1", GOTO="lvm_scan"
ACTION=="add", KERNEL=="md[0-9]*p[0-9]*", GOTO="lvm_scan"
ENV{LVM_MD_PV_ACTIVATED}!="1", ENV{SYSTEMD_READY}="0"
GOTO="lvm_end"

# Loop device:
LABEL="next"
KERNEL!="loop[0-9]*", GOTO="next"
ACTION=="add", ENV{LVM_LOOP_PV_ACTIVATED}=="1", GOTO="lvm_scan"
ACTION=="change", ENV{LVM_LOOP_PV_ACTIVATED}!="1", TEST=="loop/backing_file", ENV{LVM_LOOP_PV_ACTIVATED}="1", GOTO="lvm_scan"
ENV{LVM_LOOP_PV_ACTIVATED}!="1", ENV{SYSTEMD_READY}="0"
GOTO="lvm_end"

LABEL="next"
ACTION!="add", GOTO="lvm_end"

LABEL="lvm_scan"

ENV{SYSTEMD_READY}="1"

# pvscan will check if this device completes a VG,
# i.e. all PVs in the VG are now present with the
# arrival of this PV. If so, it prints to stdout:
# LVM_VG_NAME_COMPLETE='foo'
#
# When the VG is complete it can be activated, so
# vgchange -aay <vgname> is run. It is run via
# systemd since it can take longer to run than
# udev wants to block when processing rules.
# (if there are hundreds of LVs to activate,
# the vgchange can take many seconds.)
#
# pvscan only reads the single device specified,
# and uses temp files under /run/lvm to check if
# other PVs in the VG are present.
#
# If event_activation=0 in lvm.conf, this pvscan
# (using checkcomplete) will do nothing, so that
# no event-based autoactivation will be happen.
#
# TODO: adjust the output of vgchange -aay so that
# it's better suited to appearing in the journal.

IMPORT{program}="/sbin/lvm pvscan --cache --listvg --checkcomplete --vgonline --autoactivation event --udevoutput --journal=output $env{DEVNAME}"
TEST!="/run/systemd/system", GOTO="lvm_direct_vgchange"

ENV{LVM_VG_NAME_COMPLETE}=="?*", RUN+="/usr/bin/systemd-run --no-block --property DefaultDependencies=no --unit lvm-activate-$env{LVM_VG_NAME_COMPLETE} /sbin/lvm vgchange -aay --autoactivation event $env{LVM_VG_NAME_COMPLETE}"
GOTO="lvm_end"

LABEL="lvm_direct_vgchange"
ENV{LVM_VG_NAME_COMPLETE}=="?*", RUN+="/sbin/lvm vgchange -aay --autoactivation event $env{LVM_VG_NAME_COMPLETE}"
TEST!="/run/initramfs", GOTO="lvm_end"
ENV{LVM_VG_NAME_INCOMPLETE}=="?*", RUN+="/sbin/lvm vgchange --sysinit -aay --activation degraded $env{LVM_VG_NAME_INCOMPLETE}"
GOTO="lvm_end"

LABEL="lvm_end"

0 comments on commit 5f97b21

Please sign in to comment.