selftests/user_events: Fix failures when user_events is not installed
authorBeau Belgrave <beaub@linux.microsoft.com>
Fri, 8 Sep 2023 20:19:16 +0000 (20:19 +0000)
committerShuah Khan <skhan@linuxfoundation.org>
Mon, 11 Sep 2023 23:04:11 +0000 (17:04 -0600)
When user_events is not installed the self tests currently fail. Now
that these self tests run by default we need to ensure they don't fail
when user_events was not enabled for the kernel being tested.

Add common methods to detect if tracefs and user_events is enabled. If
either is not enabled skip the test. If tracefs is enabled, but is not
mounted, mount tracefs and fail if there were any errors. Fail if not
run as root.

Fixes: 68b4d2d58389 ("selftests/user_events: Reenable build")
Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org>
Link: https://lore.kernel.org/all/CA+G9fYuugZ0OMeS6HvpSS4nuf_A3s455ecipGBvER0LJHojKZg@mail.gmail.com/
Signed-off-by: Beau Belgrave <beaub@linux.microsoft.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
tools/testing/selftests/user_events/abi_test.c
tools/testing/selftests/user_events/dyn_test.c
tools/testing/selftests/user_events/ftrace_test.c
tools/testing/selftests/user_events/perf_test.c
tools/testing/selftests/user_events/user_events_selftests.h [new file with mode: 0644]

index 5125c42efe6576e01fa873b561f8e8c8695ac1ad..22374d29ffdd4c0379bcd9fa82a9d0c6158c7afb 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/unistd.h>
 
 #include "../kselftest_harness.h"
+#include "user_events_selftests.h"
 
 const char *data_file = "/sys/kernel/tracing/user_events_data";
 const char *enable_file = "/sys/kernel/tracing/events/user_events/__abi_event/enable";
@@ -93,6 +94,8 @@ FIXTURE(user) {
 };
 
 FIXTURE_SETUP(user) {
+       USER_EVENT_FIXTURE_SETUP(return);
+
        change_event(false);
        self->check = 0;
 }
index 91a4444ad42b28381bf5b4d9d3ae41cdd204e598..32c827a52d7d82ec9b5c791f7b61753510622958 100644 (file)
@@ -15,6 +15,7 @@
 #include <unistd.h>
 
 #include "../kselftest_harness.h"
+#include "user_events_selftests.h"
 
 const char *abi_file = "/sys/kernel/tracing/user_events_data";
 const char *enable_file = "/sys/kernel/tracing/events/user_events/__test_event/enable";
@@ -146,6 +147,7 @@ FIXTURE(user) {
 };
 
 FIXTURE_SETUP(user) {
+       USER_EVENT_FIXTURE_SETUP(return);
 }
 
 FIXTURE_TEARDOWN(user) {
index 5beb0aef1d814910093001a22beba6935e4fd219..6a260caeeddc54ef194608bc9d82fba2892bdfcd 100644 (file)
@@ -16,6 +16,7 @@
 #include <unistd.h>
 
 #include "../kselftest_harness.h"
+#include "user_events_selftests.h"
 
 const char *data_file = "/sys/kernel/tracing/user_events_data";
 const char *status_file = "/sys/kernel/tracing/user_events_status";
@@ -206,6 +207,8 @@ FIXTURE(user) {
 };
 
 FIXTURE_SETUP(user) {
+       USER_EVENT_FIXTURE_SETUP(return);
+
        self->status_fd = open(status_file, O_RDONLY);
        ASSERT_NE(-1, self->status_fd);
 
index 8b09be566fa21a284810af53d05ef0f38a58da5d..f893398cda05a522a433c75cf2b2766be649bac7 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/unistd.h>
 
 #include "../kselftest_harness.h"
+#include "user_events_selftests.h"
 
 const char *data_file = "/sys/kernel/tracing/user_events_data";
 const char *id_file = "/sys/kernel/tracing/events/user_events/__test_event/id";
@@ -113,6 +114,8 @@ FIXTURE(user) {
 };
 
 FIXTURE_SETUP(user) {
+       USER_EVENT_FIXTURE_SETUP(return);
+
        self->data_fd = open(data_file, O_RDWR);
        ASSERT_NE(-1, self->data_fd);
 }
diff --git a/tools/testing/selftests/user_events/user_events_selftests.h b/tools/testing/selftests/user_events/user_events_selftests.h
new file mode 100644 (file)
index 0000000..6903789
--- /dev/null
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _USER_EVENTS_SELFTESTS_H
+#define _USER_EVENTS_SELFTESTS_H
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "../kselftest.h"
+
+static inline bool tracefs_enabled(char **message, bool *fail)
+{
+       struct stat buf;
+       int ret;
+
+       *message = "";
+       *fail = false;
+
+       /* Ensure tracefs is installed */
+       ret = stat("/sys/kernel/tracing", &buf);
+
+       if (ret == -1) {
+               *message = "Tracefs is not installed";
+               return false;
+       }
+
+       /* Ensure mounted tracefs */
+       ret = stat("/sys/kernel/tracing/README", &buf);
+
+       if (ret == -1 && errno == ENOENT) {
+               if (mount(NULL, "/sys/kernel/tracing", "tracefs", 0, NULL) != 0) {
+                       *message = "Cannot mount tracefs";
+                       *fail = true;
+                       return false;
+               }
+
+               ret = stat("/sys/kernel/tracing/README", &buf);
+       }
+
+       if (ret == -1) {
+               *message = "Cannot access tracefs";
+               *fail = true;
+               return false;
+       }
+
+       return true;
+}
+
+static inline bool user_events_enabled(char **message, bool *fail)
+{
+       struct stat buf;
+       int ret;
+
+       *message = "";
+       *fail = false;
+
+       if (getuid() != 0) {
+               *message = "Must be run as root";
+               *fail = true;
+               return false;
+       }
+
+       if (!tracefs_enabled(message, fail))
+               return false;
+
+       /* Ensure user_events is installed */
+       ret = stat("/sys/kernel/tracing/user_events_data", &buf);
+
+       if (ret == -1) {
+               switch (errno) {
+               case ENOENT:
+                       *message = "user_events is not installed";
+                       return false;
+
+               default:
+                       *message = "Cannot access user_events_data";
+                       *fail = true;
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+#define USER_EVENT_FIXTURE_SETUP(statement) do { \
+       char *message; \
+       bool fail; \
+       if (!user_events_enabled(&message, &fail)) { \
+               if (fail) { \
+                       TH_LOG("Setup failed due to: %s", message); \
+                       ASSERT_FALSE(fail); \
+               } \
+               SKIP(statement, "Skipping due to: %s", message); \
+       } \
+} while (0)
+
+#endif /* _USER_EVENTS_SELFTESTS_H */