Whamcloud - gitweb
LU-16763 obdclass: add unit tests for OBD life cycle 03/51103/7
authorTimothy Day <timday@amazon.com>
Fri, 12 May 2023 04:32:53 +0000 (04:32 +0000)
committerOleg Drokin <green@whamcloud.com>
Wed, 6 Sep 2023 06:17:43 +0000 (06:17 +0000)
Add some simple OBD life cycle tests. These tests
consist of a kernel module which defines a simple OBD
device, and a few sanity tests. The new OBD device
print logs validating that it has been loaded
correctly. Unlike other OBD devices, this one has
minimal side-effects. The new test OBD device has
been added to the test rpm and dkms.

sanity/55a aims to test that a device can loaded
properly and found by the various OBD device search
functions.

sanity/55b aims to load the maximum number of allowed
OBD devices, which is currently 8192. It also times how
long it takes to perform the loading and unloading. In
the future, this could be used to test for performance
regression.

The tests avoid using any userspace function, like lctl
or lfs, since I noticed bugs when using them with a large
number of devices. Follow-up patches will include fixes
and more testing.

I used a variation of these tests when debugging
sanity/60a failures, and when debugging removing
MAX_OBD_DEVICES.

This test (obd_test.c) and the llog test (llog_test.c)
should probably be moved to a different directory in a
follow-up patch.

Test-Parameters: trivial testlist=sanity env=ONLY=55,ONLY_REPEAT=25
Signed-off-by: Timothy Day <timday@amazon.com>
Change-Id: Ibc347ac962c59a4bbc26410c30f9cc5529e6c84d
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/51103
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Patrick Farrell <pfarrell@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre.spec.in
lustre/obdclass/Makefile.in
lustre/obdclass/autoMakefile.am
lustre/obdclass/obd_test.c [new file with mode: 0644]
lustre/scripts/dkms.mkconf
lustre/tests/sanity.sh
rpm/kmp-lustre-tests.files

index f6e11d3..71f99a5 100644 (file)
@@ -646,6 +646,7 @@ mv $basemodpath/fs/osd_zfs.ko $basemodpath-osd-zfs/fs/osd_zfs.ko
 %if %{with lustre_tests}
 mkdir -p $basemodpath-tests/fs
 mv $basemodpath/fs/llog_test.ko $basemodpath-tests/fs/llog_test.ko
+mv $basemodpath/fs/obd_test.ko $basemodpath-tests/fs/obd_test.ko
 mkdir -p $RPM_BUILD_ROOT%{_libdir}/lustre/tests/kernel/
 mv $basemodpath/fs/kinode.ko $RPM_BUILD_ROOT%{_libdir}/lustre/tests/kernel/
 %endif
index d51e089..5a4bb64 100644 (file)
@@ -1,4 +1,14 @@
-MODULES := obdclass llog_test
+# SPDX-License-Identifier: GPL-2.0
+
+#
+# This file is part of Lustre, http://www.lustre.org/
+#
+# lustre/obdclass/Makefile.in
+#
+# Makefile template for obdclass
+#
+
+MODULES := obdclass llog_test obd_test
 
 default: all
 
@@ -28,7 +38,7 @@ obdclass-objs := $(obdclass-all-objs)
 
 EXTRA_PRE_CFLAGS := -I@LINUX@/fs -I@LDISKFS_DIR@ -I@LDISKFS_DIR@/ldiskfs
 
-EXTRA_DIST = $(obdclass-all-objs:.o=.c) llog_test.c llog_internal.h
+EXTRA_DIST = $(obdclass-all-objs:.o=.c) llog_test.c obd_test.c llog_internal.h
 EXTRA_DIST += cl_internal.h local_storage.h
 EXTRA_DIST += range_lock.c interval_tree.c
 
index 962a416..b566f4e 100644 (file)
@@ -1,9 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0
+
+#
+# This file is part of Lustre, http://www.lustre.org/
+#
+# lustre/obdclass/autoMakefile.am
+#
+# autoMakefile for obdclass
+#
+
 if MODULES
 
 if LINUX
 modulefs_DATA = obdclass$(KMODEXT)
 if TESTS
 modulefs_DATA += llog_test$(KMODEXT)
+modulefs_DATA += obd_test$(KMODEXT)
 endif # TESTS
 endif # LINUX
 
diff --git a/lustre/obdclass/obd_test.c b/lustre/obdclass/obd_test.c
new file mode 100644 (file)
index 0000000..117b5e8
--- /dev/null
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Copyright (c) 2023, Amazon and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ *
+ * lustre/obdclass/obd_test.c
+ *
+ * Simple OBD device for:
+ *   1) testing OBD device lifecycle management
+ *   2) demonstrating a simple OBD device
+ *
+ * Author: Timothy Day <timday@amazon.com>
+ *
+ */
+
+#include <linux/module.h>
+
+#include <obd_class.h>
+
+static int verbose;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "Set the logging level for the module");
+
+static int obd_test_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
+{
+       if (verbose >= 1)
+               pr_info("Lustre: OBD: %s", __func__);
+
+       if (verbose >= 2) {
+               int obd_minor_found;
+
+               pr_info("Lustre: OBD: obd_name: %s, obd_num: %i, obd_uuid: %s",
+                      obd->obd_name, obd->obd_minor, obd->obd_uuid.uuid);
+
+               obd_minor_found = class_name2dev(obd->obd_name);
+               pr_info("Lustre: OBD: class_name2dev(): %i, %s",
+                      obd_minor_found,
+                      obd_minor_found == obd->obd_minor ? "PASS" : "FAIL");
+
+               obd_minor_found = class_uuid2dev(&obd->obd_uuid);
+               pr_info("Lustre: OBD: class_uuid2dev(): %i, %s",
+                      obd_minor_found,
+                      obd_minor_found == obd->obd_minor ? "PASS" : "FAIL");
+
+               obd_minor_found = class_name2obd(obd->obd_name)->obd_minor;
+               pr_info("Lustre: OBD: class_name2obd(): %i, %s",
+                      obd_minor_found,
+                      obd_minor_found == obd->obd_minor ? "PASS" : "FAIL");
+
+               obd_minor_found = class_uuid2obd(&obd->obd_uuid)->obd_minor;
+               pr_info("Lustre: OBD: class_uuid2obd(): %i, %s",
+                      obd_minor_found,
+                      obd_minor_found == obd->obd_minor ? "PASS" : "FAIL");
+       }
+
+       return 0;
+}
+
+static int obd_test_cleanup(struct obd_device *obd)
+{
+       if (verbose >= 1)
+               pr_info("Lustre: OBD: %s", __func__);
+
+       return 0;
+}
+
+static const struct obd_ops obd_test_obd_ops = {
+       .o_owner       = THIS_MODULE,
+       .o_setup       = obd_test_setup,
+       .o_cleanup     = obd_test_cleanup,
+};
+
+static int __init obd_test_init(void)
+{
+       return class_register_type(&obd_test_obd_ops, NULL, false,
+                                  "obd_test", NULL);
+}
+
+static void __exit obd_test_exit(void)
+{
+       class_unregister_type("obd_test");
+}
+
+MODULE_AUTHOR("Amazon, Inc. <timday@amazon.com>");
+MODULE_DESCRIPTION("Lustre OBD test module");
+MODULE_VERSION(LUSTRE_VERSION_STRING);
+MODULE_LICENSE("GPL");
+
+module_init(obd_test_init);
+module_exit(obd_test_exit);
index ae481d1..1917ad1 100755 (executable)
@@ -133,6 +133,9 @@ DEST_MODULE_LOCATION[\${#DEST_MODULE_LOCATION[@]}]="/${kmoddir}/lustre/"
 BUILT_MODULE_NAME[\${#BUILT_MODULE_NAME[@]}]="llog_test"
 BUILT_MODULE_LOCATION[\${#BUILT_MODULE_LOCATION[@]}]="lustre/obdclass/"
 DEST_MODULE_LOCATION[\${#DEST_MODULE_LOCATION[@]}]="/${kmoddir}/lustre/"
+BUILT_MODULE_NAME[\${#BUILT_MODULE_NAME[@]}]="obd_test"
+BUILT_MODULE_LOCATION[\${#BUILT_MODULE_LOCATION[@]}]="lustre/obdclass/"
+DEST_MODULE_LOCATION[\${#DEST_MODULE_LOCATION[@]}]="/${kmoddir}/lustre/"
 BUILT_MODULE_NAME[\${#BUILT_MODULE_NAME[@]}]="lod"
 BUILT_MODULE_LOCATION[\${#BUILT_MODULE_LOCATION[@]}]="lustre/lod/"
 DEST_MODULE_LOCATION[\${#DEST_MODULE_LOCATION[@]}]="/${kmoddir}/lustre/"
index 6425fc4..bbd5a91 100755 (executable)
@@ -6336,6 +6336,64 @@ test_54e() {
 }
 run_test 54e "console/tty device works in lustre ======================"
 
+test_55a() {
+       local dev_path="/sys/kernel/debug/lustre/devices"
+
+       load_module obdclass/obd_test verbose=2 || error "load_module failed"
+
+       # This must be run in iteractive mode, since attach and setup
+       # are stateful
+       eval "$LCTL <<-EOF || error 'OBD device creation failed'
+               attach obd_test obd_name obd_uuid
+               setup obd_test
+       EOF"
+
+       echo "Devices:"
+       cat "$dev_path" | tail -n 10
+
+       $LCTL --device "obd_name" cleanup
+       $LCTL --device "obd_name" detach
+
+       dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
+               error "OBD unit test failed"
+
+       rmmod -v obd_test ||
+               error "rmmod failed (may trigger a failure in a later test)"
+}
+run_test 55a "OBD device life cycle unit tests"
+
+test_55b() {
+       local dev_path="/sys/kernel/debug/lustre/devices"
+       local dev_count="$(wc -l $dev_path | awk '{print $1}')"
+       local num_dev_to_create="$((8192 - $dev_count))"
+
+       load_module obdclass/obd_test || error "load_module failed"
+
+       local start=$SECONDS
+
+       # This must be run in iteractive mode, since attach and setup
+       # are stateful
+       for ((i = 1; i <= num_dev_to_create; i++)); do
+               echo "attach obd_test obd_name_$i obd_uuid_$i"
+               echo "setup obd_test_$i"
+       done | $LCTL || error "OBD device creation failed"
+
+       echo "Load time: $((SECONDS - start))"
+       echo "Devices:"
+       cat "$dev_path" | tail -n 10
+
+       for ((i = 1; i <= num_dev_to_create; i++)); do
+               echo "--device obd_name_$i cleanup"
+               echo "--device obd_name_$i detach"
+       done | $LCTL || error "OBD device cleanup failed"
+
+       echo "Unload time: $((SECONDS - start))"
+
+       rmmod -v obd_test ||
+               error "rmmod failed (may trigger a failure in a later test)"
+}
+run_test 55b "Load and unload max OBD devices"
+
 test_56a() {
        local numfiles=3
        local numdirs=2
index fd7aed8..bc1838e 100644 (file)
@@ -1,3 +1,4 @@
 %dir %{modules_fs_path}/%{lustre_name}-tests
 %dir %{modules_fs_path}/%{lustre_name}-tests/fs
 %{modules_fs_path}/%{lustre_name}-tests/fs/llog_test.ko
+%{modules_fs_path}/%{lustre_name}-tests/fs/obd_test.ko