Skip to content

feat: add LVM status controller#13295

Merged
talos-bot merged 1 commit into
siderolabs:mainfrom
shanduur:lvm
May 25, 2026
Merged

feat: add LVM status controller#13295
talos-bot merged 1 commit into
siderolabs:mainfrom
shanduur:lvm

Conversation

@shanduur
Copy link
Copy Markdown
Member

@shanduur shanduur commented May 7, 2026

Add resource types for physical volumes, volume groups, and logical
volumes to track LVM inventory and state. Provides read-only discovery
through the resource API for visibility into existing LVM setup.

Manual Testing

Creating LVM objects:

cat <<'EOF' | sudo -E _out/talosctl-linux-amd64 -n 172.20.0.6 debug docker.io/library/alpine:latest --args /bin/sh
set -e

NSENTER="nsenter --target 1 --mount --uts --ipc --net --pid"

echo "==> Creating PVs"
$NSENTER pvcreate -y /dev/vdb /dev/vdc /dev/vdd

echo "==> Creating VG"
$NSENTER vgcreate vgdata /dev/vdb /dev/vdc /dev/vdd

echo "==> Creating LV"
$NSENTER lvcreate -n lvdata -l 100%FREE vgdata

echo "==> Listing LVM state"
$NSENTER pvs
$NSENTER vgs
$NSENTER lvs
EOF

Removing LVM objects:

cat <<'EOF' | sudo -E _out/talosctl-linux-amd64 -n 172.20.0.6 debug docker.io/library/alpine:latest --args /bin/sh
set -e

NSENTER="nsenter --target 1 --mount --uts --ipc --net --pid"

echo "==> Removing logical volume"
$NSENTER lvremove -y /dev/vgdata/lvdata || true

echo "==> Removing volume group"
$NSENTER vgremove -y vgdata || true

echo "==> Wiping physical volumes"
$NSENTER pvremove -y /dev/vdb /dev/vdc /dev/vdd || true

echo "==> Done"
$NSENTER pvs || true
$NSENTER vgs || true
$NSENTER lvs || true
EOF

Signed-off-by: Mateusz Urbanek mateusz.urbanek@siderolabs.com

@github-project-automation github-project-automation Bot moved this to To Do in Planning May 7, 2026
@shanduur shanduur force-pushed the lvm branch 3 times, most recently from b286266 to 8e59fa6 Compare May 12, 2026 09:58
@shanduur shanduur added the integration/qemu Run QEMU integration tests (all variants) label May 12, 2026
@shanduur shanduur force-pushed the lvm branch 24 times, most recently from 3a6324e to e8b8c7a Compare May 14, 2026 13:28
@shanduur shanduur marked this pull request as ready for review May 14, 2026 13:49
@talos-bot talos-bot moved this from To Do to In Review in Planning May 14, 2026
@smira smira requested review from Copilot and smira May 14, 2026 15:58
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds three new read-only resources (LVMPhysicalVolumeStatus, LVMVolumeGroupStatus, LVMLogicalVolumeStatus) and corresponding controllers that periodically scan host LVM state via lvm pvs/vgs/lvs --reportformat json. Refactors the existing block.LVMActivationController into a new storage package backed by a shared internal/pkg/lvm helper, moves the TestLVMActivation integration test into a new StorageSuite, and adds a TestLVMStatus integration test. Includes generated proto/deep-copy/docs updates.

Changes:

  • New internal/pkg/lvm package wrapping lvm CLI (PV/VG/LV listing, vgchange, pvscan).
  • New storage resource types (machinery + proto + docs) and three polling controllers (30s interval).
  • Moves LVMActivationController from block to storage, threading the shared *lvm.LVM helper.

Reviewed changes

Copilot reviewed 30 out of 33 changed files in this pull request and generated no comments.

Show a summary per file
File Description
internal/pkg/lvm/{lvm,pv,vg,lv,activate}.go New helper wrapping lvm binary, JSON report decoding, udev parsing.
internal/pkg/lvm/lvm_test.go + testdata/* Unit tests covering pvs/vgs/lvs JSON parsing and Tags unmarshalling.
pkg/machinery/resources/storage/*.go New LVMPhysicalVolumeStatus / LVMVolumeGroupStatus / LVMLogicalVolumeStatus resources, deep-copy, registration test.
pkg/machinery/api/resource/definitions/storage/storage.pb.go + api/.../storage.proto Generated protobuf bindings for the new specs.
internal/app/machined/pkg/controllers/storage/*.go New status controllers + relocated LVMActivationController.
internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_{controller,state}.go Wires new controllers and registers new resource types; constructs shared lvm.New().
internal/integration/api/{storage,volumes,selinux}.go Adds StorageSuite with TestLVMStatus and relocated TestLVMActivation; expects /run/lock/lvm SELinux label.
website/content/v1.14/reference/api.md Auto-generated API documentation for new specs.
hack/release.toml Release note describing new LVM status resources.
Files not reviewed (2)
  • pkg/machinery/api/resource/definitions/storage/storage.pb.go: Language not supported
  • pkg/machinery/resources/storage/deep_copy.generated.go: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

//go:generate go tool github.com/siderolabs/deep-copy -type LVMLogicalVolumeStatusSpec -type LVMPhysicalVolumeStatusSpec -type LVMVolumeGroupStatusSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go .

// NamespaceName contains storage resources.
const NamespaceName resource.Namespace = v1alpha1.NamespaceName
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could probably actually use proper namespace name, it was a bug when I originally started block that I put it to the wrong namespace, but it was too late when I discovered it

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

// pollInterval is how often the LVM status controllers re-scan the system in
// the absence of input events. LVM has no inotify-style change feed, so a
// poll is the only way to catch attribute changes (e.g. grow operations).
const pollInterval = 30 * time.Second
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how bad it is to poll on interval? would it e.g. wake up a sleeping disk just to check LVM metadata?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pvs -a enumerates every block device so it will open each and read sector 0 / PV label region to check for LVM signature. On spun-down HDDs that wakes the disk every poll - so could probably significantly increase the wear of the device.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll fix that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dropped the polling.

case <-ctx.Done():
return nil
case <-r.EventCh():
case <-ticker.C:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can a PV change without ever writing to blockdevice? we have a flow which goes into DiscoverdVolumes and it notifies on any process opening a blockdevice for write, we could feed it here?

(happy to discuss more)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PV not, but some kernel DM states can - e.g. active/inactive, suspended, open-count, kernel major/minor - lives in device-mapper, not on disk. So thing slike lvchange -ay/-an, dmsetup suspend, mount/umount can flip these w/o touching PV metadata. Reflected in lv_active/lv_suspended/lv_device_open columns.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but I guess that would trigger DM blockdevice changes? We also listen for these (we listen for all blockdevice events).

@shanduur shanduur self-assigned this May 18, 2026
@shanduur shanduur force-pushed the lvm branch 4 times, most recently from ae26831 to 95df045 Compare May 20, 2026 09:33
@shanduur shanduur requested a review from smira May 20, 2026 09:33
case <-r.EventCh():
}

if err := safe.WriterModify(
Copy link
Copy Markdown
Member

@smira smira May 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should throttle this (the easiest way possible is to add something like this after this line):

This way we would coalesce multiple updates into a single event, as e.g. BlockDevice -> Disk -> DV will always propagate in a sequence

select {
case <-time.After(time.Second): // or something bigger
case <-ctx.Done():
  return nil
}

@github-project-automation github-project-automation Bot moved this from In Review to Approved in Planning May 20, 2026
@shanduur shanduur force-pushed the lvm branch 2 times, most recently from 88f7c92 to a751d2e Compare May 21, 2026 12:36
Add resource types for physical volumes, volume groups, and logical
volumes to track LVM inventory and state. Provides read-only discovery
through the resource API for visibility into existing LVM setup.

Signed-off-by: Mateusz Urbanek <mateusz.urbanek@siderolabs.com>
@shanduur
Copy link
Copy Markdown
Member Author

/m

@talos-bot talos-bot merged commit d71edee into siderolabs:main May 25, 2026
119 of 120 checks passed
@github-project-automation github-project-automation Bot moved this from Approved to Done in Planning May 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

integration/qemu Run QEMU integration tests (all variants)

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

4 participants