From c668d9fe90f28e00d02cf6e3623b8dc0ec825b91 Mon Sep 17 00:00:00 2001 From: Xiaojie Chen Date: Mon, 23 Mar 2026 16:31:38 +0800 Subject: [PATCH] fix mdcheck service bug reference: https://src.fedoraproject.org/rpms/mdadm/c/a91fbc1088a22bb4524b3a807d1a5f3c82f9bfaa?branch=f38 --- ...g-files-in-mdcheck_start-continue-se.patch | 42 +++++ mdadm.spec | 11 +- mdcheck | 166 ++++++++++++++++++ 3 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch create mode 100644 mdcheck diff --git a/0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch b/0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch new file mode 100644 index 0000000..cb73179 --- /dev/null +++ b/0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch @@ -0,0 +1,42 @@ +From 76c224c6cfc8ff154bd041d30b9551faecd593c1 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 7 Apr 2023 08:45:28 +0800 +Subject: [PATCH 120/120] Remove the config files in mdcheck_start|continue + service + +We set MDADM_CHECK_DURATION in the mdcheck_start|continue.service files. +And mdcheck doesn't use any configs from the config file. So we can remove +the dependencies. + +Signed-off-by: Xiao Ni +Signed-off-by: Jes Sorensen +--- + systemd/mdcheck_continue.service | 2 -- + systemd/mdcheck_start.service | 2 -- + 2 files changed, 4 deletions(-) + +diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service +index f5324905..70892a1f 100644 +--- a/systemd/mdcheck_continue.service ++++ b/systemd/mdcheck_continue.service +@@ -13,6 +13,4 @@ Documentation=man:mdadm(8) + [Service] + Type=oneshot + Environment="MDADM_CHECK_DURATION=6 hours" +-EnvironmentFile=-/run/sysconfig/mdadm +-ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh + ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION} +diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service +index 703a6583..fc4fc438 100644 +--- a/systemd/mdcheck_start.service ++++ b/systemd/mdcheck_start.service +@@ -13,6 +13,4 @@ Documentation=man:mdadm(8) + [Service] + Type=oneshot + Environment="MDADM_CHECK_DURATION=6 hours" +-EnvironmentFile=-/run/sysconfig/mdadm +-ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh + ExecStart=/usr/share/mdadm/mdcheck --duration ${MDADM_CHECK_DURATION} +-- +2.38.1 + diff --git a/mdadm.spec b/mdadm.spec index 93508c0..bc230f0 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,7 +1,7 @@ Summary: Linux MD devices (Software RAID) management utility Name: mdadm Version: 4.2 -Release: 8%{?dist} +Release: 9%{?dist} License: GPLv2+ URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ Source0: http://www.kernel.org/pub/linux/utils/raid/mdadm/%{name}-%{version}.tar.xz @@ -13,6 +13,8 @@ Source5: mdmonitor.service Source6: mdadm_event.conf Source7: mdadm.conf Source8: mdadm.rules +Source9: mdcheck +Patch3000: 0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch Patch5000: 0001-Fix-an-uninitialized-use.patch BuildRequires: make systemd-rpm-macros gcc @@ -51,6 +53,9 @@ install -D -m 0644 %{SOURCE5} %{buildroot}%{_unitdir}/mdmonitor.service install -d -m 0710 %{buildroot}%{_rundir}/%{name} +mkdir -p -m 755 %{buildroot}/usr/share/mdadm +install -Dp -m 755 %{SOURCE9} %{buildroot}/usr/share/mdadm/mdcheck + %post %systemd_post mdmonitor.service raid-check.timer %{_bindir}/systemctl disable mdmonitor-takeover.service >/dev/null 2>&1 || : @@ -72,8 +77,12 @@ install -d -m 0710 %{buildroot}%{_rundir}/%{name} %dir %{_rundir}/%{name}/ %{_sbindir}/* %{_mandir}/man*/md* +/usr/share/mdadm/mdcheck %changelog +* Fri Mar 20 2026 Xiaojie Chen - 4.2-9 +- fix mdcheck service bug + * Sun Sep 29 2024 Xiaojie Chen - 4.2-8 - Fix an uninitialized use diff --git a/mdcheck b/mdcheck new file mode 100644 index 0000000..700c3e2 --- /dev/null +++ b/mdcheck @@ -0,0 +1,166 @@ +#!/bin/bash + +# Copyright (C) 2014-2017 Neil Brown +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# Author: Neil Brown +# Email: + +# This script should be run periodically to automatically +# perform a 'check' on any md arrays. +# +# It supports a 'time budget' such that any incomplete 'check' +# will be checkpointed when that time has expired. +# A subsequent invocation can allow the 'check' to continue. +# +# Options are: +# --continue Don't start new checks, only continue old ones. +# --duration This is passed to "date --date=$duration" to find out +# when to finish +# +# To support '--continue', arrays are identified by UUID and the 'sync_completed' +# value is stored in /var/lib/mdcheck/$UUID + +# convert a /dev/md name into /sys/.../md equivalent +sysname() { + set `ls -lLd $1` + maj=${5%,} + min=$6 + readlink -f /sys/dev/block/$maj:$min +} + +args=$(getopt -o hcd: -l help,continue,duration: -n mdcheck -- "$@") +rv=$? +if [ $rv -ne 0 ]; then exit $rv; fi + +eval set -- $args + +cont= +endtime= +while [ " $1" != " --" ] +do + case $1 in + --help ) + echo >&2 'Usage: mdcheck [--continue] [--duration time-offset]' + echo >&2 ' time-offset must be understood by "date --date"' + exit 0 + ;; + --continue ) cont=yes ;; + --duration ) shift; dur=$1 + endtime=$(date --date "$dur" "+%s") + ;; + esac + shift +done +shift + +# We need a temp file occasionally... +tmp=/var/lib/mdcheck/.md-check-$$ +trap 'rm -f "$tmp"' 0 2 3 15 + + +# firstly, clean out really old state files +mkdir -p /var/lib/mdcheck +find /var/lib/mdcheck -name "MD_UUID*" -type f -mtime +180 -exec rm {} \; + +# Now look at each md device. +cnt=0 +for dev in /dev/md?* +do + [ -e "$dev" ] || continue + sys=`sysname $dev` + if [ ! -f "$sys/md/sync_action" ] + then # cannot check this array + continue + fi + if [ "`cat $sys/md/sync_action`" != 'idle' ] + then # This array is busy + continue + fi + + mdadm --detail --export "$dev" | grep '^MD_UUID=' > $tmp || continue + source $tmp + fl="/var/lib/mdcheck/MD_UUID_$MD_UUID" + if [ -z "$cont" ] + then + start=0 + logger -p daemon.info mdcheck start checking $dev + elif [ -z "$MD_UUID" -o ! -f "$fl" ] + then + # Nothing to continue here + continue + else + start=`cat "$fl"` + logger -p daemon.info mdcheck continue checking $dev from $start + fi + + cnt=$[cnt+1] + eval MD_${cnt}_fl=\$fl + eval MD_${cnt}_sys=\$sys + eval MD_${cnt}_dev=\$dev + echo $start > $fl + echo $start > $sys/md/sync_min + echo check > $sys/md/sync_action +done + +if [ -z "$endtime" ] +then + exit 0 +fi + +while [ `date +%s` -lt $endtime ] +do + any= + for i in `eval echo {1..$cnt}` + do + eval fl=\$MD_${i}_fl + eval sys=\$MD_${i}_sys + eval dev=\$MD_${i}_dev + + if [ -z "$fl" ]; then continue; fi + + if [ "`cat $sys/md/sync_action`" != 'check' ] + then + logger -p daemon.info mdcheck finished checking $dev + eval MD_${i}_fl= + rm -f $fl + continue; + fi + read a rest < $sys/md/sync_completed + echo $a > $fl + any=yes + done + if [ -z "$any" ]; then exit 0; fi + sleep 120 +done + +# We've waited, and there are still checks running. +# Time to stop them. +for i in `eval echo {1..$cnt}` +do + eval fl=\$MD_${i}_fl + eval sys=\$MD_${i}_sys + eval dev=\$MD_${i}_dev + + if [ -z "$fl" ]; then continue; fi + + if [ "`cat $sys/md/sync_action`" != 'check' ] + then + eval MD_${i}_fl= + rm -f $fl + continue; + fi + echo idle > $sys/md/sync_action + cat $sys/md/sync_min > $fl + logger -p daemon.info pause checking $dev at `cat $fl` +done -- Gitee