From: Kris Van Hees <kris.van.hees@oracle.com>
To: dtrace@lists.linux.dev, dtrace-devel@oss.oracle.com
Subject: [PATCH 11/20] libdtrace: cache missing kernel CTF archives until paths change
Date: Fri, 30 Oct 2026 19:36:47 +0000 [thread overview]
Message-ID: <24b4b0f9f1f1b21146f37d5f08386734@oracle.com> (raw)
---
libdtrace/dt_impl.h | 1 +
libdtrace/dt_module.c | 16 +++++++++++--
libdtrace/dt_options.c | 3 +++
test/triggers/Build | 1 +
test/triggers/shared-ctf.c | 49 ++++++++++++++++++++++++++++++++++++++
5 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
index 972fceaf..5487bfcf 100644
--- a/libdtrace/dt_impl.h
+++ b/libdtrace/dt_impl.h
@@ -310,6 +310,7 @@ struct dtrace_hdl {
dt_list_t dt_modlist; /* linked list of dt_module_t's */
dt_htab_t *dt_mods; /* hash table of dt_module_t's */
dt_htab_t *dt_kernsyms; /* htab of kernel symbol names */
+ int dt_ctfa_missing; /* cached ENOENT/ENOTDIR for the archive */
char *dt_ctfa_path; /* path to vmlinux.ctfa */
ctf_archive_t *dt_ctfa; /* ctf archive for the entire kernel tree */
void *dt_ctfa_data; /* backing data for dt_ctfa */
diff --git a/libdtrace/dt_module.c b/libdtrace/dt_module.c
index ad43e815..f381bdcd 100644
--- a/libdtrace/dt_module.c
+++ b/libdtrace/dt_module.c
@@ -1329,16 +1329,28 @@ dt_kern_module_find_ctf(dtrace_hdl_t *dtp, dt_module_t *dmp)
if (dtp->dt_ctfa_path == NULL) {
ctfa_name = malloc(strlen(dtp->dt_module_path) +
strlen("/kernel/vmlinux.ctfa") + 1);
+ if (ctfa_name == NULL) {
+ dt_set_errno(dtp, EDT_NOMEM);
+ return;
+ }
to = stpcpy(ctfa_name, dtp->dt_module_path);
stpcpy(to, "/kernel/vmlinux.ctfa");
} else
ctfa_name = dtp->dt_ctfa_path;
+ /* Cache absence, but retry allocation, permission, and I/O errors. */
+ if (dtp->dt_ctfa_missing)
+ dtp->dt_ctferr = dtp->dt_ctfa_missing;
+ else {
#ifdef HAVE_LIBCTF
- dtp->dt_ctfa = dt_ctfa_open(dtp, ctfa_name);
+ dtp->dt_ctfa = dt_ctfa_open(dtp, ctfa_name);
#else
- dtp->dt_ctfa = ctf_arc_open(ctfa_name, &dtp->dt_ctferr);
+ dtp->dt_ctfa = ctf_arc_open(ctfa_name, &dtp->dt_ctferr);
#endif
+ if (dtp->dt_ctfa == NULL &&
+ (dtp->dt_ctferr == ENOENT || dtp->dt_ctferr == ENOTDIR))
+ dtp->dt_ctfa_missing = dtp->dt_ctferr;
+ }
if (dtp->dt_ctfa != NULL) {
/*
* Load in the shared CTF immediately.
diff --git a/libdtrace/dt_options.c b/libdtrace/dt_options.c
index 78ff23e5..2b75d3c0 100644
--- a/libdtrace/dt_options.c
+++ b/libdtrace/dt_options.c
@@ -320,6 +320,7 @@ dt_opt_btf_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
free(dtp->dt_btf_path);
dtp->dt_btf_path = btf;
+ dtp->dt_ctfa_missing = 0;
return 0;
}
@@ -340,6 +341,7 @@ dt_opt_ctfa_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
free(dtp->dt_ctfa_path);
dtp->dt_ctfa_path = ctfa;
+ dtp->dt_ctfa_missing = 0;
return 0;
}
@@ -425,6 +427,7 @@ dt_opt_module_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
free(dtp->dt_module_path);
dtp->dt_module_path = proc;
+ dtp->dt_ctfa_missing = 0;
return 0;
}
diff --git a/test/triggers/Build b/test/triggers/Build
index 607ea00b..8d648bab 100644
--- a/test/triggers/Build
+++ b/test/triggers/Build
@@ -267,6 +267,7 @@ module-discovery_LIBS := $(objdir)/build-libdtrace.a $(objdir)/build-libproc.a \
$(objdir)/build-libcommon.a $(objdir)/build-libport.a $(libdtrace_LIBS)
# Exercise shared dictionary ownership using libdtrace's private module APIs.
+shared-ctf_LDFLAGS := -Wl,--wrap=open64
shared-ctf_CFLAGS := -Ilibproc -Ilibdtrace -Ilibcommon -Wno-pedantic
shared-ctf_DEPS := build-libdtrace.a build-libproc.a libcommon.a libport.a
shared-ctf_LIBS := $(objdir)/build-libdtrace.a $(objdir)/build-libproc.a \
diff --git a/test/triggers/shared-ctf.c b/test/triggers/shared-ctf.c
index 79aeeda5..74c55c44 100644
--- a/test/triggers/shared-ctf.c
+++ b/test/triggers/shared-ctf.c
@@ -4,6 +4,8 @@
* http://oss.oracle.com/licenses/upl.
*/
+#include <errno.h>
+#include <stdarg.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
@@ -12,6 +14,34 @@
#include <dt_module.h>
#include <dt_kernel_module.h>
+static const char *watched_archive;
+static int archive_opens, archive_io_error;
+
+extern int __real_open64(const char *, int, ...);
+
+int
+__wrap_open64(const char *path, int flags, ...)
+{
+ mode_t mode = 0;
+
+ if (flags & O_CREAT) {
+ va_list ap;
+
+ va_start(ap, flags);
+ mode = va_arg(ap, int);
+ va_end(ap);
+ }
+ if (watched_archive && strcmp(path, watched_archive) == 0) {
+ archive_opens++;
+ if (archive_io_error) {
+ archive_io_error = 0;
+ errno = EIO;
+ return -1;
+ }
+ }
+ return __real_open64(path, flags, mode);
+}
+
#ifdef HAVE_LIBCTF
#define CHECK(expr) do { \
if (!(expr)) { \
@@ -227,7 +257,26 @@ check_embedded(const char *missing, const char *embedded)
dtp->dt_kernpaths = NULL;
CHECK(dt_kern_path_create(dtp, strdup("shared_ctf_test"), strdup(missing)) != NULL);
CHECK((shared = dt_module_create(dtp, "shared_ctf")) != NULL);
+ /* Transient errors retry; confirmed absence is cached until a path changes. */
+ watched_archive = missing;
+ archive_opens = 0;
+ archive_io_error = 1;
+ CHECK(dt_module_getctf(dtp, shared) == NULL);
+ CHECK(archive_opens == 1);
+ CHECK(dt_module_getctf(dtp, shared) == NULL);
+ CHECK(archive_opens == 2);
+ CHECK(dt_module_getctf(dtp, shared) == NULL);
+ CHECK(archive_opens == 2);
+ CHECK(dtrace_setopt(dtp, "ctfpath", missing) == 0);
+ CHECK(dt_module_getctf(dtp, shared) == NULL);
+ CHECK(archive_opens == 3);
+ CHECK(dtrace_setopt(dtp, "btfpath", "none") == 0);
+ CHECK(dt_module_getctf(dtp, shared) == NULL);
+ CHECK(archive_opens == 4);
+ CHECK(dtrace_setopt(dtp, "modpath", dtp->dt_module_path) == 0);
CHECK(dt_module_getctf(dtp, shared) == NULL);
+ CHECK(archive_opens == 5);
+ watched_archive = NULL;
CHECK(dtrace_errno(dtp) == EDT_NOCTF);
CHECK(dt_module_shared_ctf(dtp) == NULL);
--
2.52.0
next reply other threads:[~2026-10-30 19:38 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-30 19:36 Kris Van Hees [this message]
2026-11-06 13:00 ` [PATCH 11/20] libdtrace: cache missing kernel CTF archives until paths change Nick Alcock
2026-11-06 21:24 ` Kris Van Hees
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=24b4b0f9f1f1b21146f37d5f08386734@oracle.com \
--to=kris.van.hees@oracle.com \
--cc=dtrace-devel@oss.oracle.com \
--cc=dtrace@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox