[parted-devel] [PATCH 2/2] Add test to detect race between parted and systemd
Gulam Mohamed
gulam.mohamed at oracle.com
Wed Jan 22 09:25:52 GMT 2025
When parted commands like print, delete and others along with create
command, are run continuously, at some point of time a race has been
noticed between the create command and systemd. This test case will test
the fix for the race issue by spawing two separate threads. One thread
creates the partitions on a loop device using parted command and the
other thread will continuously print the partitions.
Signed-off-by: Gulam Mohamed <gulam.mohamed at oracle.com>
---
tests/t9070-parted-systemd-race.sh | 159 +++++++++++++++++++++++++++++
1 file changed, 159 insertions(+)
create mode 100755 tests/t9070-parted-systemd-race.sh
diff --git a/tests/t9070-parted-systemd-race.sh b/tests/t9070-parted-systemd-race.sh
new file mode 100755
index 000000000000..7d4e7f125349
--- /dev/null
+++ b/tests/t9070-parted-systemd-race.sh
@@ -0,0 +1,159 @@
+#!/bin/bash
+
+# Test to detect the race between parted command and systemd. When parted
+# commands like print, delete and others along with create command, are run
+# continuously, at some point of time a race has been noticed between the
+# create command and systemd
+
+# Copyright (C) 2025, Oracle and/or its affiliates.
+
+# 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 3 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../parted
+
+require_root_
+require_udevadm_settle_
+
+loop_device=""
+start_sector=64
+end_sector=512
+error_substring="but we have been unable to inform the kernel of the change"
+device_file=device_file-$$
+log_file="/tmp/messages.log"
+
+# Cleanup loop device and all its partitions after the test
+cleanup()
+{
+ partition=0
+ while [ 1 ];
+ do
+ ((partition=partition+1))
+ parted -s $loop_device rm $partition 2>/dev/null
+ if [ $? == 0 ]; then
+ continue
+ else
+ losetup -D
+ break
+ fi
+ done
+}
+
+# Create backing file and loop device
+test_configure()
+{
+ truncate --size 2g "${device_file}"
+ loop_device="$(losetup --partscan --find --show "${device_file}")"
+ parted --script "${loop_device}" mklabel gpt
+
+ udevadm settle
+
+ if [ ! -e "${loop_device}" ]; then
+ return 1
+ fi
+ return 0
+}
+
+# Create partitions on the loop device
+create_partition()
+{
+ part=1
+ while [ 1 ];
+ do
+ sector_1=${start_sector}s
+ sector_2=${end_sector}s
+ cmd_err=$(parted -a none -s "$loop_device" mkpart primary $sector_1 $sector_2 2>&1)
+ cmd_status=$?
+ if echo "$cmd_err" | grep -q "$error_substring";
+ then
+ echo "TEST FAILED" >> $log_file
+ echo "$cmd_err" >> $log_file
+ elif [ $part -gt "128" ];
+ then
+ echo "TEST PASSED" >> $log_file
+ break
+ elif [ $cmd_status -ne "0" ];
+ then
+ echo "PARTITION CREATE FAILED" >> $log_file
+ echo "Error: $cmd_err" >> $log_file
+ break
+ fi
+
+ ((start_sector=end_sector+1))
+ ((end_sector=start_sector+512))
+ ((part=part+1))
+
+ done
+}
+
+# Print the partitions of the loop device
+partition_print()
+{
+ while [ 1 ];
+ do
+ parted -s "$loop_device" unit s print 2>&1
+ done
+}
+
+# Spawn separate threads for creating partitions and print partitions and
+# monitor for the test failure
+part_test()
+{
+ echo "INIT" >> $log_file
+ test_configure
+ failed=$?
+ if (($failed == 1)); then
+ echo "Test Configure FAILED" >> $log_file
+ exit $failed
+ fi
+ sleep 1
+
+ create_partition &
+ create_pid=$!
+
+ partition_print &
+ print_pid=$!
+
+ sleep 1
+
+ echo "WAITING............" >> $log_file
+
+ failed=0
+ while [ 1 ];
+ do
+ if cat $log_file | grep -e "TEST FAILED"; then
+ failed=1
+ break
+ elif cat $log_file | grep -e "PARTITION CREATE FAILED"; then
+ failed=2
+ break
+ elif cat $log_file | grep -e "TEST PASSED"; then
+ break
+ fi
+
+ done
+
+
+ {
+ kill -9 $create_pid
+ kill -9 $print_pid
+ wait
+ sleep 1
+ rm -f $log_file
+ rm -f $device_file
+ } 2>/dev/null
+ cleanup
+ exit $failed
+}
+
+part_test
--
2.43.5
More information about the parted-devel
mailing list