summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-19 10:44:49 +0200
committerPaul Buetow <paul@buetow.org>2026-03-19 10:44:49 +0200
commit7c33a6b86127e7a69f57f89913639926aa652a9e (patch)
treefe7e6a77a489ce99c8c5e07b87c910cee9924afe
parent59ddf9fbf4b4cfa379ec57e6479a24b8b3400aea (diff)
fix: resolve dirfd-relative capture paths (task 462)
-rw-r--r--AGENTS.md218
-rw-r--r--scripts/syscall_matrix.c248
-rw-r--r--systemtap/src/ioriot.stp101
-rw-r--r--systemtap/src/javaioriot.stp101
-rw-r--r--systemtap/src/targetedioriot.stp101
5 files changed, 724 insertions, 45 deletions
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..3ab36b5
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,218 @@
+# Agent Notes
+
+## Syscall Matrix End-to-End Test
+
+Use this procedure when you need a reproducible end-to-end test that exercises
+the supported capture/generate/replay syscall surface with a controlled
+workload.
+
+### Preconditions
+
+- Run from the repository root: `/home/paul/git/ioriot`.
+- Use a base directory under `/home`, not `/tmp`. This project filters some
+ file systems during replay generation, and `/tmp` may be `tmpfs`.
+- The helper below is intentionally dirfd-heavy so it catches path-resolution
+ bugs in `*at` syscalls as well as normal file I/O.
+- `readdir` is intentionally excluded. Generation handles it, but replay does
+ not currently have a `READDIR` implementation.
+
+### 1. Rebuild, test, and install
+
+```bash
+make clean all test
+sudo make install
+```
+
+### 2. Prepare a unique run directory and compile the helper
+
+```bash
+stamp=$(date +%Y%m%d_%H%M%S)
+run_root=/tmp/ioriot-syscall-e2e-$stamp
+user_name=${SUDO_USER:-$USER}
+base_dir=/home/$user_name/ioriot-syscall-matrix-src-$stamp
+helper_bin=$run_root/syscall_matrix
+
+mkdir -p "$run_root"
+cc -Wall -Wextra -O2 -o "$helper_bin" scripts/syscall_matrix.c
+
+pid_file=$run_root/syscall_matrix.pid
+go_file=$run_root/syscall_matrix.go
+capture_file=$run_root/syscall_matrix.capture
+replay_file=$run_root/syscall_matrix.replay
+stats_file=$run_root/syscall_matrix.stats
+strace_file=$run_root/replay.strace
+test_name=e2e_syscall_matrix_$stamp
+```
+
+### 3. Start the helper in a paused state
+
+Run this in terminal A:
+
+```bash
+sudo "$helper_bin" "$pid_file" "$go_file" "$base_dir" "$user_name"
+```
+
+The helper writes its real PID into `"$pid_file"` and then waits until
+`"$go_file"` exists.
+
+### 4. Attach targeted capture before releasing the helper
+
+Run this in terminal B after `"$pid_file"` exists:
+
+```bash
+helper_pid=$(cat "$pid_file")
+sudo /opt/ioriot/bin/ioriot -c "$capture_file" -x "$helper_pid"
+```
+
+Wait until `staprun` reports that `targetedioriot.ko` has been inserted.
+
+### 5. Release the helper and stop capture after it exits
+
+Back in terminal A, release the workload:
+
+```bash
+touch "$go_file"
+```
+
+When the helper exits, stop capture in terminal B with `Ctrl+C`.
+
+### 6. Generate the replay file
+
+```bash
+sudo /opt/ioriot/bin/ioriot \
+ -c "$capture_file" \
+ -r "$replay_file" \
+ -u "$user_name" \
+ -n "$test_name" \
+ -w /home/$user_name/.ioriot-wd
+```
+
+### 7. Sanity-check capture and replay contents
+
+List the captured syscall names:
+
+```bash
+python - "$capture_file" <<'PY'
+import re
+import sys
+ops=set()
+for line in open(sys.argv[1]):
+ m=re.search(r';:,o=([^;]+);:,', line)
+ if m:
+ ops.add(m.group(1))
+for op in sorted(ops):
+ print(op)
+PY
+```
+
+List the replay operation names:
+
+```bash
+python - "$replay_file" <<'PY'
+import re
+import sys
+ops=set()
+for line in open(sys.argv[1]):
+ m=re.search(r'\|([a-z0-9_]+)@[0-9]+\|\s*$', line)
+ if m:
+ ops.add(m.group(1))
+for op in sorted(ops):
+ print(op)
+PY
+```
+
+Verify the replay file contains expected workload paths:
+
+```bash
+rg -n 'head-renamed|openat|creat|link-open|emptydir' "$replay_file"
+```
+
+Architecture note:
+
+- On modern x86_64 systems, some operations may surface as modern entry points
+ rather than legacy ones. For example, `open` may appear as `openat`, and
+ `stat` / `lstat` may appear as `newfstatat` in `strace`.
+- Some replay entries are intentionally no-ops today: `statfs`, `fstatfs`,
+ `readahead`, `readlink`, `readlinkat`, `sync`, `syncfs`, and
+ `sync_file_range`.
+
+### 8. Initialize the replay tree
+
+```bash
+sudo /opt/ioriot/bin/ioriot \
+ -i "$replay_file" \
+ -w /home/$user_name/.ioriot-wd
+```
+
+### 9. Replay single-threaded under strace
+
+```bash
+sudo strace -f -o "$strace_file" \
+ /opt/ioriot/bin/ioriot \
+ -D \
+ -r "$replay_file" \
+ -p 1 \
+ -t 1 \
+ -S "$stats_file"
+```
+
+### 10. Verify replay activity and resulting state
+
+Check stats:
+
+```bash
+cat "$stats_file"
+```
+
+Inspect replay syscalls touching the target tree:
+
+```bash
+rg -n "/home/\\.ioriot/$test_name/" "$strace_file"
+```
+
+Useful follow-up checks:
+
+```bash
+find "/home/.ioriot/$test_name" -maxdepth 6 \
+ \( -name 'head-renamed.bin' -o -name 'open*.txt' -o -name 'creat*.txt' \
+ -o -name 'link-open.txt' -o -name 'emptydir' \) | sort
+```
+
+```bash
+python - "$test_name" "$user_name" "$stamp" <<'PY'
+from pathlib import Path
+import sys
+
+test_name, user_name, stamp = sys.argv[1:]
+root = Path(f"/home/.ioriot/{test_name}/{user_name}")
+base = root / f"ioriot-syscall-matrix-src-{stamp}"
+
+paths = [
+ base / "open-renamed.txt",
+ base / "emptydir",
+ base / "dirA" / "openat-renamed.txt",
+]
+for p in paths:
+ print(f"{p}: exists={p.exists()} is_dir={p.is_dir()}")
+PY
+```
+
+### Expected coverage
+
+The helper in [scripts/syscall_matrix.c](/home/paul/git/ioriot/scripts/syscall_matrix.c)
+attempts to exercise these operations:
+
+- `creat`, `openat`, `close`
+- `read`, `readv`, `write`, `writev`
+- `fstat`, `fstatat`, `statfs`, `fstatfs`
+- `fcntl`, `readahead`, `sync`, `syncfs`, `sync_file_range`
+- `getdents`, `lseek`, `llseek` when available
+- `mkdir`, `mkdirat`, `rename`, `renameat`, `renameat2`
+- `unlink`, `unlinkat`, `rmdir`
+- `readlink`, `readlinkat`
+- `chmod`, `fchmod`, `fchmodat`
+- `chown`, `fchown`, `fchownat`, `lchown`
+
+If the generated replay only contains the header and `#INIT`, or the replay
+paths escape the intended test tree, investigate capture tokenization and
+dirfd-relative path handling first.
diff --git a/scripts/syscall_matrix.c b/scripts/syscall_matrix.c
new file mode 100644
index 0000000..df7311a
--- /dev/null
+++ b/scripts/syscall_matrix.c
@@ -0,0 +1,248 @@
+#define _GNU_SOURCE
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
+static void
+die(const char *msg)
+{
+ perror(msg);
+ exit(1);
+}
+
+static void
+must(bool ok, const char *msg)
+{
+ if (!ok)
+ die(msg);
+}
+
+static void
+must_eq(long rc, const char *msg)
+{
+ if (rc == -1)
+ die(msg);
+}
+
+static void
+write_pid_file(const char *path)
+{
+ FILE *fp = fopen(path, "w");
+
+ must(fp != NULL, "fopen pid file");
+ fprintf(fp, "%ld\n", (long)getpid());
+ fclose(fp);
+}
+
+static void
+wait_for_go(const char *path)
+{
+ while (access(path, F_OK) != 0)
+ usleep(10000);
+}
+
+static void
+write_full(int fd, const char *buf, size_t len)
+{
+ while (len > 0) {
+ ssize_t written = write(fd, buf, len);
+
+ must_eq(written, "write");
+ buf += written;
+ len -= (size_t)written;
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ if (argc != 5) {
+ fprintf(stderr, "usage: %s PID_FILE GO_FILE BASE_DIR USER\n", argv[0]);
+ return 2;
+ }
+
+ const char *pid_file = argv[1];
+ const char *go_file = argv[2];
+ const char *base = argv[3];
+ const char *user = argv[4];
+
+ struct passwd *pw = getpwnam(user);
+
+ must(pw != NULL, "getpwnam");
+
+ write_pid_file(pid_file);
+ wait_for_go(go_file);
+
+ char path_open[1024];
+ char path_renamed[1024];
+ char path_creat[1024];
+ char path_link[1024];
+ char path_emptydir[1024];
+
+ snprintf(path_open, sizeof(path_open), "%s/open.txt", base);
+ snprintf(path_renamed, sizeof(path_renamed), "%s/open-renamed.txt", base);
+ snprintf(path_creat, sizeof(path_creat), "%s/creat.txt", base);
+ snprintf(path_link, sizeof(path_link), "%s/link-open.txt", base);
+ snprintf(path_emptydir, sizeof(path_emptydir), "%s/emptydir", base);
+
+ must_eq(mkdir(base, 0777), "mkdir base");
+
+ int basefd = open(base, O_RDONLY | O_DIRECTORY);
+
+ must_eq(basefd, "open base dir");
+ must_eq(mkdirat(basefd, "dirA", 0777), "mkdirat dirA");
+ must_eq(mkdirat(basefd, "emptydir", 0777), "mkdirat emptydir");
+
+ int dirfd = openat(basefd, "dirA", O_RDONLY | O_DIRECTORY);
+
+ must_eq(dirfd, "openat dirA");
+ must_eq(mkdirat(dirfd, "nested", 0777), "mkdirat nested");
+
+ int fd_open = open(path_open, O_CREAT | O_RDWR | O_TRUNC, 0644);
+
+ must_eq(fd_open, "open open.txt");
+ write_full(fd_open, "alpha", 5);
+ must_eq(fsync(fd_open), "fsync open.txt");
+ must_eq(fdatasync(fd_open), "fdatasync open.txt");
+ must_eq(lseek(fd_open, 0, SEEK_SET), "lseek open.txt");
+
+ char read_buf[64];
+
+ must_eq(read(fd_open, read_buf, 5), "read open.txt");
+
+ struct iovec write_iov[2] = {
+ {.iov_base = "beta", .iov_len = 4},
+ {.iov_base = "gamma", .iov_len = 5},
+ };
+
+ must_eq(writev(fd_open, write_iov, 2), "writev open.txt");
+ must_eq(lseek(fd_open, 0, SEEK_SET), "lseek open.txt again");
+
+ char readv_a[5] = {0};
+ char readv_b[10] = {0};
+ struct iovec read_iov[2] = {
+ {.iov_base = readv_a, .iov_len = sizeof(readv_a) - 1},
+ {.iov_base = readv_b, .iov_len = sizeof(readv_b) - 1},
+ };
+
+ must_eq(readv(fd_open, read_iov, 2), "readv open.txt");
+
+ struct stat st;
+
+ must_eq(fstat(fd_open, &st), "fstat open.txt");
+ must_eq(stat(path_open, &st), "stat open.txt");
+ must_eq(fstatat(basefd, "open.txt", &st, 0), "fstatat open.txt");
+
+ struct statfs sfs;
+
+ must_eq(statfs(base, &sfs), "statfs base");
+ must_eq(fstatfs(fd_open, &sfs), "fstatfs open.txt");
+
+ int flags = fcntl(fd_open, F_GETFL);
+
+ must_eq(flags, "fcntl getfl");
+ must_eq(fcntl(fd_open, F_SETFL, flags | O_APPEND), "fcntl setfl");
+
+#ifdef SYS_readahead
+ syscall(SYS_readahead, fd_open, 0, 8);
+#endif
+
+#ifdef SYS_sync_file_range
+ syscall(SYS_sync_file_range, fd_open, 0, 8, 0);
+#endif
+
+#if defined(SYS_llseek)
+ long long llseek_result = 0;
+ syscall(SYS_llseek, fd_open, 0UL, 0UL, &llseek_result, SEEK_END);
+#elif defined(SYS__llseek)
+ long long llseek_result = 0;
+ syscall(SYS__llseek, fd_open, 0UL, 0UL, &llseek_result, SEEK_END);
+#endif
+
+ must_eq(syncfs(fd_open), "syncfs");
+ sync();
+
+ int fd_openat = openat(dirfd, "openat.txt", O_CREAT | O_RDWR | O_TRUNC,
+ 0640);
+
+ must_eq(fd_openat, "openat openat.txt");
+ write_full(fd_openat, "openat-data", 11);
+ must_eq(lseek(fd_openat, 0, SEEK_SET), "lseek openat.txt");
+ must_eq(read(fd_openat, read_buf, 4), "read openat.txt");
+
+ int fd_creat = creat(path_creat, 0644);
+
+ must_eq(fd_creat, "creat creat.txt");
+ write_full(fd_creat, "creat", 5);
+ must_eq(close(fd_creat), "close creat.txt");
+
+ int fd_nested = openat(dirfd, "nested", O_RDONLY | O_DIRECTORY);
+
+ must_eq(fd_nested, "open nested dir");
+
+ int fd_nested_file = openat(fd_nested, "head.bin",
+ O_CREAT | O_RDWR | O_TRUNC, 0644);
+
+ must_eq(fd_nested_file, "open nested file");
+ write_full(fd_nested_file, "head-data", 9);
+ must_eq(close(fd_nested_file), "close nested file");
+
+#ifdef SYS_getdents
+ char dents_buf[4096];
+ syscall(SYS_getdents, dirfd, dents_buf, sizeof(dents_buf));
+#endif
+
+ must_eq(symlink(path_open, path_link), "symlink");
+ must_eq(lstat(path_link, &st), "lstat link");
+ must_eq(readlink(path_link, read_buf, sizeof(read_buf)), "readlink");
+ must_eq(readlinkat(basefd, "link-open.txt", read_buf, sizeof(read_buf)),
+ "readlinkat");
+
+ must_eq(chmod(path_open, 0640), "chmod");
+ must_eq(fchmod(fd_open, 0600), "fchmod");
+ must_eq(fchmodat(basefd, "open.txt", 0644, 0), "fchmodat");
+
+ must_eq(chown(path_open, pw->pw_uid, pw->pw_gid), "chown");
+ must_eq(fchown(fd_open, pw->pw_uid, pw->pw_gid), "fchown");
+ must_eq(fchownat(basefd, "open.txt", pw->pw_uid, pw->pw_gid, 0),
+ "fchownat");
+ must_eq(lchown(path_link, pw->pw_uid, pw->pw_gid), "lchown");
+
+ must_eq(rename(path_open, path_renamed), "rename");
+ must_eq(renameat(dirfd, "openat.txt", dirfd, "openat-renamed.txt"),
+ "renameat");
+
+#ifdef SYS_renameat2
+ must_eq(syscall(SYS_renameat2, basefd, "creat.txt", basefd,
+ "creat-renamed.txt", 0), "renameat2");
+#endif
+
+ must_eq(unlink(path_renamed), "unlink");
+ must_eq(unlinkat(dirfd, "openat-renamed.txt", 0), "unlinkat");
+ must_eq(unlinkat(basefd, "creat-renamed.txt", 0), "unlinkat creat");
+
+ must_eq(renameat(fd_nested, "head.bin", dirfd, "head-renamed.bin"),
+ "renameat nested");
+
+ must_eq(close(fd_nested), "close nested dir");
+ must_eq(rmdir(path_emptydir), "rmdir emptydir");
+
+ must_eq(close(fd_openat), "close openat");
+ must_eq(close(fd_open), "close open");
+ must_eq(close(dirfd), "close dirA");
+ must_eq(close(basefd), "close base");
+
+ return 0;
+}
diff --git a/systemtap/src/ioriot.stp b/systemtap/src/ioriot.stp
index 1e12574..9bdf440 100644
--- a/systemtap/src/ioriot.stp
+++ b/systemtap/src/ioriot.stp
@@ -30,6 +30,7 @@ global PROBE_ENTRY_TIMES%[8096]
global ENTRY_PATH%[8096]
global ENTRY_PATH2%[8096]
global ENTRY_FD%[8096]
+global ENTRY_FD2%[8096]
global ENTRY_FLAGS%[8096]
global ENTRY_MODE%[8096]
global ENTRY_OFFSET%[8096]
@@ -64,6 +65,34 @@ function absolute_path:string (path:string) {
return task_dentry_path(tc, pwd_dentry, pwd_mnt) . "/" . path;
}
+function task_file_handle_d_path:string (task:long, fd:long) {
+ path = ""
+
+ try {
+ file = task_fd_lookup(task, fd)
+ if (file)
+ path = fullpath_struct_file(task, file)
+ } catch {
+ }
+
+ return path
+}
+
+function absolute_path_at:string (path:string, dirfd:long) {
+ if (substr(path,0,1) == "/")
+ return path;
+
+ if (dirfd == @const("AT_FDCWD"))
+ return absolute_path(path);
+
+ tc = task_current();
+ dir_path = task_file_handle_d_path(tc, dirfd);
+ if (strlen(dir_path) > 0)
+ return dir_path . "/" . path;
+
+ return absolute_path(path);
+}
+
# Stop probing after 1h (for safety)
probe timer.s(3600) {
exit();
@@ -73,9 +102,9 @@ probe begin {
printf("#|capture_version=%d|\n", 3);
}
-# --- open/openat ---
+# --- open ---
# Tapset entry vars: filename_unquoted, flags, mode
-probe syscall.open, syscall.openat {
+probe syscall.open {
if (execname() != "stapio") {
PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
ENTRY_PATH[tid(),name] = filename_unquoted
@@ -84,7 +113,7 @@ probe syscall.open, syscall.openat {
}
}
-probe syscall.open.return, syscall.openat.return {
+probe syscall.open.return {
if (execname() != "stapio") {
ns = gettimeofday_ns()
printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,d=%d;:,p=%s;:,f=%d;:,m=%d;:,\n",
@@ -101,6 +130,36 @@ probe syscall.open.return, syscall.openat.return {
}
}
+# --- openat ---
+# Tapset entry vars: dfd, filename_unquoted, flags, mode
+probe syscall.openat {
+ if (execname() != "stapio") {
+ PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
+ ENTRY_FD[tid(),name] = dfd
+ ENTRY_PATH[tid(),name] = filename_unquoted
+ ENTRY_FLAGS[tid(),name] = flags
+ ENTRY_MODE[tid(),name] = mode
+ }
+}
+
+probe syscall.openat.return {
+ if (execname() != "stapio") {
+ ns = gettimeofday_ns()
+ printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,d=%d;:,p=%s;:,f=%d;:,m=%d;:,\n",
+ ns, ns-PROBE_ENTRY_TIMES[tid(),name],
+ pid(), tid(), name,
+ retval,
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
+ ENTRY_FLAGS[tid(),name],
+ ENTRY_MODE[tid(),name]);
+ delete PROBE_ENTRY_TIMES[tid(),name]
+ delete ENTRY_FD[tid(),name]
+ delete ENTRY_PATH[tid(),name]
+ delete ENTRY_FLAGS[tid(),name]
+ delete ENTRY_MODE[tid(),name]
+ }
+}
+
# --- lseek ---
# Tapset entry vars: fildes, offset, whence
probe syscall.lseek {
@@ -272,7 +331,7 @@ probe syscall.unlinkat.return {
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
ENTRY_FD[tid(),name],
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
ENTRY_FLAGS[tid(),name],
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
@@ -308,10 +367,12 @@ probe syscall.rename.return {
}
# --- renameat/renameat2 ---
-# Tapset entry vars: oldname_str_unquoted, newname_str_unquoted
+# Tapset entry vars: olddfd, oldname_str_unquoted, newdfd, newname_str_unquoted
probe syscall.renameat, syscall.renameat2 {
if (execname() != "stapio") {
PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
+ ENTRY_FD[tid(),name] = olddfd
+ ENTRY_FD2[tid(),name] = newdfd
ENTRY_PATH[tid(),name] = oldname_str_unquoted
ENTRY_PATH2[tid(),name] = newname_str_unquoted
}
@@ -323,10 +384,14 @@ probe syscall.renameat.return, syscall.renameat2.return {
printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,p=%s;:,P=%s;:,s=%d;:,\n",
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
- absolute_path(ENTRY_PATH[tid(),name]),
- absolute_path(ENTRY_PATH2[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name],
+ ENTRY_FD[tid(),name]),
+ absolute_path_at(ENTRY_PATH2[tid(),name],
+ ENTRY_FD2[tid(),name]),
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
+ delete ENTRY_FD[tid(),name]
+ delete ENTRY_FD2[tid(),name]
delete ENTRY_PATH[tid(),name]
delete ENTRY_PATH2[tid(),name]
}
@@ -427,10 +492,11 @@ probe syscall.readlink.return {
}
# --- readlinkat ---
-# Tapset entry vars: path_unquoted
+# Tapset entry vars: dfd, path_unquoted
probe syscall.readlinkat {
if (execname() != "stapio") {
PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
+ ENTRY_FD[tid(),name] = dfd
ENTRY_PATH[tid(),name] = path_unquoted
}
}
@@ -441,9 +507,10 @@ probe syscall.readlinkat.return {
printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,p=%s;:,s=%d;:,\n",
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
+ delete ENTRY_FD[tid(),name]
delete ENTRY_PATH[tid(),name]
}
}
@@ -650,7 +717,7 @@ probe syscall.mkdirat.return {
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
ENTRY_FD[tid(),name],
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
ENTRY_MODE[tid(),name],
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
@@ -788,7 +855,7 @@ probe syscall.fstatat.return {
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
ENTRY_FD[tid(),name],
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
ENTRY_FLAGS[tid(),name],
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
@@ -824,10 +891,11 @@ probe syscall.chmod.return {
}
# --- fchmodat ---
-# Tapset entry vars: pathname_unquoted, mode
+# Tapset entry vars: dirfd, pathname_unquoted, mode
probe syscall.fchmodat {
if (execname() != "stapio") {
PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
+ ENTRY_FD[tid(),name] = dirfd
ENTRY_PATH[tid(),name] = pathname_unquoted
ENTRY_MODE[tid(),name] = mode
}
@@ -839,10 +907,11 @@ probe syscall.fchmodat.return {
printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,p=%s;:,m=%d;:,s=%d;:,\n",
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
ENTRY_MODE[tid(),name],
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
+ delete ENTRY_FD[tid(),name]
delete ENTRY_PATH[tid(),name]
delete ENTRY_MODE[tid(),name]
}
@@ -934,10 +1003,11 @@ probe syscall.fchown.return {
}
# --- fchownat ---
-# Tapset entry vars: pathname_unquoted, owner, group, flags
+# Tapset entry vars: dirfd, pathname_unquoted, owner, group, flags
probe syscall.fchownat {
if (execname() != "stapio") {
PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
+ ENTRY_FD[tid(),name] = dirfd
ENTRY_PATH[tid(),name] = pathname_unquoted
ENTRY_OWNER[tid(),name] = owner
ENTRY_GROUP[tid(),name] = group
@@ -951,12 +1021,13 @@ probe syscall.fchownat.return {
printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,p=%s;:,O=%d;:,G=%d;:,f=%d;:,s=%d;:,\n",
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
ENTRY_OWNER[tid(),name],
ENTRY_GROUP[tid(),name],
ENTRY_FLAGS[tid(),name],
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
+ delete ENTRY_FD[tid(),name]
delete ENTRY_PATH[tid(),name]
delete ENTRY_OWNER[tid(),name]
delete ENTRY_GROUP[tid(),name]
diff --git a/systemtap/src/javaioriot.stp b/systemtap/src/javaioriot.stp
index 3d54b19..cf7e797 100644
--- a/systemtap/src/javaioriot.stp
+++ b/systemtap/src/javaioriot.stp
@@ -30,6 +30,7 @@ global PROBE_ENTRY_TIMES%[8096]
global ENTRY_PATH%[8096]
global ENTRY_PATH2%[8096]
global ENTRY_FD%[8096]
+global ENTRY_FD2%[8096]
global ENTRY_FLAGS%[8096]
global ENTRY_MODE%[8096]
global ENTRY_OFFSET%[8096]
@@ -64,6 +65,34 @@ function absolute_path:string (path:string) {
return task_dentry_path(tc, pwd_dentry, pwd_mnt) . "/" . path;
}
+function task_file_handle_d_path:string (task:long, fd:long) {
+ path = ""
+
+ try {
+ file = task_fd_lookup(task, fd)
+ if (file)
+ path = fullpath_struct_file(task, file)
+ } catch {
+ }
+
+ return path
+}
+
+function absolute_path_at:string (path:string, dirfd:long) {
+ if (substr(path,0,1) == "/")
+ return path;
+
+ if (dirfd == @const("AT_FDCWD"))
+ return absolute_path(path);
+
+ tc = task_current();
+ dir_path = task_file_handle_d_path(tc, dirfd);
+ if (strlen(dir_path) > 0)
+ return dir_path . "/" . path;
+
+ return absolute_path(path);
+}
+
# Stop probing after 1h (for safety)
probe timer.s(3600) {
exit();
@@ -73,9 +102,9 @@ probe begin {
printf("#|capture_version=%d|\n", 3);
}
-# --- open/openat ---
+# --- open ---
# Tapset entry vars: filename_unquoted, flags, mode
-probe syscall.open, syscall.openat {
+probe syscall.open {
if (execname() == "java") {
PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
ENTRY_PATH[tid(),name] = filename_unquoted
@@ -84,7 +113,7 @@ probe syscall.open, syscall.openat {
}
}
-probe syscall.open.return, syscall.openat.return {
+probe syscall.open.return {
if (execname() == "java") {
ns = gettimeofday_ns()
printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,d=%d;:,p=%s;:,f=%d;:,m=%d;:,\n",
@@ -101,6 +130,36 @@ probe syscall.open.return, syscall.openat.return {
}
}
+# --- openat ---
+# Tapset entry vars: dfd, filename_unquoted, flags, mode
+probe syscall.openat {
+ if (execname() == "java") {
+ PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
+ ENTRY_FD[tid(),name] = dfd
+ ENTRY_PATH[tid(),name] = filename_unquoted
+ ENTRY_FLAGS[tid(),name] = flags
+ ENTRY_MODE[tid(),name] = mode
+ }
+}
+
+probe syscall.openat.return {
+ if (execname() == "java") {
+ ns = gettimeofday_ns()
+ printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,d=%d;:,p=%s;:,f=%d;:,m=%d;:,\n",
+ ns, ns-PROBE_ENTRY_TIMES[tid(),name],
+ pid(), tid(), name,
+ retval,
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
+ ENTRY_FLAGS[tid(),name],
+ ENTRY_MODE[tid(),name]);
+ delete PROBE_ENTRY_TIMES[tid(),name]
+ delete ENTRY_FD[tid(),name]
+ delete ENTRY_PATH[tid(),name]
+ delete ENTRY_FLAGS[tid(),name]
+ delete ENTRY_MODE[tid(),name]
+ }
+}
+
# --- lseek ---
# Tapset entry vars: fildes, offset, whence
probe syscall.lseek {
@@ -272,7 +331,7 @@ probe syscall.unlinkat.return {
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
ENTRY_FD[tid(),name],
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
ENTRY_FLAGS[tid(),name],
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
@@ -308,10 +367,12 @@ probe syscall.rename.return {
}
# --- renameat/renameat2 ---
-# Tapset entry vars: oldname_str_unquoted, newname_str_unquoted
+# Tapset entry vars: olddfd, oldname_str_unquoted, newdfd, newname_str_unquoted
probe syscall.renameat, syscall.renameat2 {
if (execname() == "java") {
PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
+ ENTRY_FD[tid(),name] = olddfd
+ ENTRY_FD2[tid(),name] = newdfd
ENTRY_PATH[tid(),name] = oldname_str_unquoted
ENTRY_PATH2[tid(),name] = newname_str_unquoted
}
@@ -323,10 +384,14 @@ probe syscall.renameat.return, syscall.renameat2.return {
printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,p=%s;:,P=%s;:,s=%d;:,\n",
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
- absolute_path(ENTRY_PATH[tid(),name]),
- absolute_path(ENTRY_PATH2[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name],
+ ENTRY_FD[tid(),name]),
+ absolute_path_at(ENTRY_PATH2[tid(),name],
+ ENTRY_FD2[tid(),name]),
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
+ delete ENTRY_FD[tid(),name]
+ delete ENTRY_FD2[tid(),name]
delete ENTRY_PATH[tid(),name]
delete ENTRY_PATH2[tid(),name]
}
@@ -427,10 +492,11 @@ probe syscall.readlink.return {
}
# --- readlinkat ---
-# Tapset entry vars: path_unquoted
+# Tapset entry vars: dfd, path_unquoted
probe syscall.readlinkat {
if (execname() == "java") {
PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
+ ENTRY_FD[tid(),name] = dfd
ENTRY_PATH[tid(),name] = path_unquoted
}
}
@@ -441,9 +507,10 @@ probe syscall.readlinkat.return {
printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,p=%s;:,s=%d;:,\n",
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
+ delete ENTRY_FD[tid(),name]
delete ENTRY_PATH[tid(),name]
}
}
@@ -650,7 +717,7 @@ probe syscall.mkdirat.return {
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
ENTRY_FD[tid(),name],
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
ENTRY_MODE[tid(),name],
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
@@ -788,7 +855,7 @@ probe syscall.fstatat.return {
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
ENTRY_FD[tid(),name],
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
ENTRY_FLAGS[tid(),name],
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
@@ -824,10 +891,11 @@ probe syscall.chmod.return {
}
# --- fchmodat ---
-# Tapset entry vars: pathname_unquoted, mode
+# Tapset entry vars: dirfd, pathname_unquoted, mode
probe syscall.fchmodat {
if (execname() == "java") {
PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
+ ENTRY_FD[tid(),name] = dirfd
ENTRY_PATH[tid(),name] = pathname_unquoted
ENTRY_MODE[tid(),name] = mode
}
@@ -839,10 +907,11 @@ probe syscall.fchmodat.return {
printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,p=%s;:,m=%d;:,s=%d;:,\n",
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
ENTRY_MODE[tid(),name],
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
+ delete ENTRY_FD[tid(),name]
delete ENTRY_PATH[tid(),name]
delete ENTRY_MODE[tid(),name]
}
@@ -934,10 +1003,11 @@ probe syscall.fchown.return {
}
# --- fchownat ---
-# Tapset entry vars: pathname_unquoted, owner, group, flags
+# Tapset entry vars: dirfd, pathname_unquoted, owner, group, flags
probe syscall.fchownat {
if (execname() == "java") {
PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
+ ENTRY_FD[tid(),name] = dirfd
ENTRY_PATH[tid(),name] = pathname_unquoted
ENTRY_OWNER[tid(),name] = owner
ENTRY_GROUP[tid(),name] = group
@@ -951,12 +1021,13 @@ probe syscall.fchownat.return {
printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,p=%s;:,O=%d;:,G=%d;:,f=%d;:,s=%d;:,\n",
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
ENTRY_OWNER[tid(),name],
ENTRY_GROUP[tid(),name],
ENTRY_FLAGS[tid(),name],
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
+ delete ENTRY_FD[tid(),name]
delete ENTRY_PATH[tid(),name]
delete ENTRY_OWNER[tid(),name]
delete ENTRY_GROUP[tid(),name]
diff --git a/systemtap/src/targetedioriot.stp b/systemtap/src/targetedioriot.stp
index b93b21c..dccfe4c 100644
--- a/systemtap/src/targetedioriot.stp
+++ b/systemtap/src/targetedioriot.stp
@@ -30,6 +30,7 @@ global PROBE_ENTRY_TIMES%[8096]
global ENTRY_PATH%[8096]
global ENTRY_PATH2%[8096]
global ENTRY_FD%[8096]
+global ENTRY_FD2%[8096]
global ENTRY_FLAGS%[8096]
global ENTRY_MODE%[8096]
global ENTRY_OFFSET%[8096]
@@ -64,6 +65,34 @@ function absolute_path:string (path:string) {
return task_dentry_path(tc, pwd_dentry, pwd_mnt) . "/" . path;
}
+function task_file_handle_d_path:string (task:long, fd:long) {
+ path = ""
+
+ try {
+ file = task_fd_lookup(task, fd)
+ if (file)
+ path = fullpath_struct_file(task, file)
+ } catch {
+ }
+
+ return path
+}
+
+function absolute_path_at:string (path:string, dirfd:long) {
+ if (substr(path,0,1) == "/")
+ return path;
+
+ if (dirfd == @const("AT_FDCWD"))
+ return absolute_path(path);
+
+ tc = task_current();
+ dir_path = task_file_handle_d_path(tc, dirfd);
+ if (strlen(dir_path) > 0)
+ return dir_path . "/" . path;
+
+ return absolute_path(path);
+}
+
# Stop probing after 1h (for safety)
probe timer.s(3600) {
exit();
@@ -73,9 +102,9 @@ probe begin {
printf("#|capture_version=%d|\n", 3);
}
-# --- open/openat ---
+# --- open ---
# Tapset entry vars: filename_unquoted, flags, mode
-probe syscall.open, syscall.openat {
+probe syscall.open {
if (pid() == target()) {
PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
ENTRY_PATH[tid(),name] = filename_unquoted
@@ -84,7 +113,7 @@ probe syscall.open, syscall.openat {
}
}
-probe syscall.open.return, syscall.openat.return {
+probe syscall.open.return {
if (pid() == target()) {
ns = gettimeofday_ns()
printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,d=%d;:,p=%s;:,f=%d;:,m=%d;:,\n",
@@ -101,6 +130,36 @@ probe syscall.open.return, syscall.openat.return {
}
}
+# --- openat ---
+# Tapset entry vars: dfd, filename_unquoted, flags, mode
+probe syscall.openat {
+ if (pid() == target()) {
+ PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
+ ENTRY_FD[tid(),name] = dfd
+ ENTRY_PATH[tid(),name] = filename_unquoted
+ ENTRY_FLAGS[tid(),name] = flags
+ ENTRY_MODE[tid(),name] = mode
+ }
+}
+
+probe syscall.openat.return {
+ if (pid() == target()) {
+ ns = gettimeofday_ns()
+ printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,d=%d;:,p=%s;:,f=%d;:,m=%d;:,\n",
+ ns, ns-PROBE_ENTRY_TIMES[tid(),name],
+ pid(), tid(), name,
+ retval,
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
+ ENTRY_FLAGS[tid(),name],
+ ENTRY_MODE[tid(),name]);
+ delete PROBE_ENTRY_TIMES[tid(),name]
+ delete ENTRY_FD[tid(),name]
+ delete ENTRY_PATH[tid(),name]
+ delete ENTRY_FLAGS[tid(),name]
+ delete ENTRY_MODE[tid(),name]
+ }
+}
+
# --- lseek ---
# Tapset entry vars: fildes, offset, whence
probe syscall.lseek {
@@ -272,7 +331,7 @@ probe syscall.unlinkat.return {
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
ENTRY_FD[tid(),name],
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
ENTRY_FLAGS[tid(),name],
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
@@ -308,10 +367,12 @@ probe syscall.rename.return {
}
# --- renameat/renameat2 ---
-# Tapset entry vars: oldname_str_unquoted, newname_str_unquoted
+# Tapset entry vars: olddfd, oldname_str_unquoted, newdfd, newname_str_unquoted
probe syscall.renameat, syscall.renameat2 {
if (pid() == target()) {
PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
+ ENTRY_FD[tid(),name] = olddfd
+ ENTRY_FD2[tid(),name] = newdfd
ENTRY_PATH[tid(),name] = oldname_str_unquoted
ENTRY_PATH2[tid(),name] = newname_str_unquoted
}
@@ -323,10 +384,14 @@ probe syscall.renameat.return, syscall.renameat2.return {
printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,p=%s;:,P=%s;:,s=%d;:,\n",
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
- absolute_path(ENTRY_PATH[tid(),name]),
- absolute_path(ENTRY_PATH2[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name],
+ ENTRY_FD[tid(),name]),
+ absolute_path_at(ENTRY_PATH2[tid(),name],
+ ENTRY_FD2[tid(),name]),
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
+ delete ENTRY_FD[tid(),name]
+ delete ENTRY_FD2[tid(),name]
delete ENTRY_PATH[tid(),name]
delete ENTRY_PATH2[tid(),name]
}
@@ -427,10 +492,11 @@ probe syscall.readlink.return {
}
# --- readlinkat ---
-# Tapset entry vars: path_unquoted
+# Tapset entry vars: dfd, path_unquoted
probe syscall.readlinkat {
if (pid() == target()) {
PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
+ ENTRY_FD[tid(),name] = dfd
ENTRY_PATH[tid(),name] = path_unquoted
}
}
@@ -441,9 +507,10 @@ probe syscall.readlinkat.return {
printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,p=%s;:,s=%d;:,\n",
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
+ delete ENTRY_FD[tid(),name]
delete ENTRY_PATH[tid(),name]
}
}
@@ -650,7 +717,7 @@ probe syscall.mkdirat.return {
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
ENTRY_FD[tid(),name],
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
ENTRY_MODE[tid(),name],
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
@@ -788,7 +855,7 @@ probe syscall.fstatat.return {
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
ENTRY_FD[tid(),name],
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
ENTRY_FLAGS[tid(),name],
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
@@ -824,10 +891,11 @@ probe syscall.chmod.return {
}
# --- fchmodat ---
-# Tapset entry vars: pathname_unquoted, mode
+# Tapset entry vars: dirfd, pathname_unquoted, mode
probe syscall.fchmodat {
if (pid() == target()) {
PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
+ ENTRY_FD[tid(),name] = dirfd
ENTRY_PATH[tid(),name] = pathname_unquoted
ENTRY_MODE[tid(),name] = mode
}
@@ -839,10 +907,11 @@ probe syscall.fchmodat.return {
printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,p=%s;:,m=%d;:,s=%d;:,\n",
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
ENTRY_MODE[tid(),name],
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
+ delete ENTRY_FD[tid(),name]
delete ENTRY_PATH[tid(),name]
delete ENTRY_MODE[tid(),name]
}
@@ -934,10 +1003,11 @@ probe syscall.fchown.return {
}
# --- fchownat ---
-# Tapset entry vars: pathname_unquoted, owner, group, flags
+# Tapset entry vars: dirfd, pathname_unquoted, owner, group, flags
probe syscall.fchownat {
if (pid() == target()) {
PROBE_ENTRY_TIMES[tid(),name] = gettimeofday_ns()
+ ENTRY_FD[tid(),name] = dirfd
ENTRY_PATH[tid(),name] = pathname_unquoted
ENTRY_OWNER[tid(),name] = owner
ENTRY_GROUP[tid(),name] = group
@@ -951,12 +1021,13 @@ probe syscall.fchownat.return {
printf("t=%ld;:,D=%ld;:,i=%d:%d;:,o=%s;:,p=%s;:,O=%d;:,G=%d;:,f=%d;:,s=%d;:,\n",
ns, ns-PROBE_ENTRY_TIMES[tid(),name],
pid(), tid(), name,
- absolute_path(ENTRY_PATH[tid(),name]),
+ absolute_path_at(ENTRY_PATH[tid(),name], ENTRY_FD[tid(),name]),
ENTRY_OWNER[tid(),name],
ENTRY_GROUP[tid(),name],
ENTRY_FLAGS[tid(),name],
retval);
delete PROBE_ENTRY_TIMES[tid(),name]
+ delete ENTRY_FD[tid(),name]
delete ENTRY_PATH[tid(),name]
delete ENTRY_OWNER[tid(),name]
delete ENTRY_GROUP[tid(),name]