From e86f60aae314d19c40b4197a245b1b04e381b11d Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sun, 2 Aug 2026 21:40:27 +1000 Subject: [PATCH] ceph: set OSD disk I/O scheduler to none via udev rule Ceph OSDs get no benefit from kernel I/O scheduling; the original intent was to set those disks to the noop scheduler. On the fleet's EL9 blk-mq kernels (AlmaLinux 9, kernel 5.14) the equivalent of noop is none. - add profiles::ceph::osd_scheduler, which renders a udev rule from the ceph_osd_devices fact pinning queue/scheduler to none on each OSD disk - reload udev and trigger the matched block devices so the change applies immediately, while the rule keeps it set across reboots and device re-add - no-op when the fact is absent/empty so VMs and non-OSD hosts are untouched - include the class from profiles::ceph::osd so it lands only on OSD hosts Claude-Session: https://claude.ai/code/session_01JUoARVdmhxKQHyyyp1pxeT --- site/profiles/manifests/ceph/osd.pp | 3 ++ site/profiles/manifests/ceph/osd_scheduler.pp | 32 +++++++++++++++++++ .../templates/ceph/osd-scheduler.rules.erb | 5 +++ 3 files changed, 40 insertions(+) create mode 100644 site/profiles/manifests/ceph/osd_scheduler.pp create mode 100644 site/profiles/templates/ceph/osd-scheduler.rules.erb diff --git a/site/profiles/manifests/ceph/osd.pp b/site/profiles/manifests/ceph/osd.pp index d56ff1d..c1e093c 100644 --- a/site/profiles/manifests/ceph/osd.pp +++ b/site/profiles/manifests/ceph/osd.pp @@ -2,6 +2,9 @@ class profiles::ceph::osd ( Boolean $ensure_running = true, ) { + # tune the I/O scheduler on the disks backing ceph OSDs + include profiles::ceph::osd_scheduler + if $ensure_running and $facts['is_ceph_osd'] { $facts['ceph_services']['osd'].each |String $svc| { service { $svc: diff --git a/site/profiles/manifests/ceph/osd_scheduler.pp b/site/profiles/manifests/ceph/osd_scheduler.pp new file mode 100644 index 0000000..5d19622 --- /dev/null +++ b/site/profiles/manifests/ceph/osd_scheduler.pp @@ -0,0 +1,32 @@ +class profiles::ceph::osd_scheduler ( + String[1] $scheduler = 'none', +) { + + $devices = $facts['ceph_osd_devices'] + + # no-op where the fact is absent/empty (VMs, non-OSD hosts have no ceph PVs) + if $devices =~ Array[String[1], 1] { + + # strip /dev/ so the rule matches the udev KERNEL sysname (e.g. sda) + $kernel_names = $devices.map |$dev| { regsubst($dev, '^.*/', '') } + $sysname_matches = $kernel_names.map |$name| { "--sysname-match=${name}" } + + file { '/etc/udev/rules.d/60-ceph-osd-scheduler.rules': + ensure => file, + owner => 'root', + group => 'root', + mode => '0644', + content => template('profiles/ceph/osd-scheduler.rules.erb'), + notify => Exec['ceph-osd-scheduler-reload'], + } + + # apply immediately; udev re-applies on reboot and device re-add + $trigger = "udevadm trigger --subsystem-match=block --action=change ${join($sysname_matches, ' ')}" + + exec { 'ceph-osd-scheduler-reload': + command => "udevadm control --reload-rules && ${trigger}", + path => ['/usr/bin', '/bin', '/usr/sbin', '/sbin'], + refreshonly => true, + } + } +} diff --git a/site/profiles/templates/ceph/osd-scheduler.rules.erb b/site/profiles/templates/ceph/osd-scheduler.rules.erb new file mode 100644 index 0000000..28f87fb --- /dev/null +++ b/site/profiles/templates/ceph/osd-scheduler.rules.erb @@ -0,0 +1,5 @@ +# Managed by puppet (profiles::ceph::osd_scheduler). +# Set the I/O scheduler to <%= @scheduler %> on ceph OSD block devices. +<% @kernel_names.sort.each do |dev| -%> +ACTION=="add|change", SUBSYSTEM=="block", KERNEL=="<%= dev %>", ATTR{queue/scheduler}="<%= @scheduler %>" +<% end -%>