All of lore.kernel.org
 help / color / mirror / Atom feed
* [pseudo] [PATCH v3 0/6] Add open_tree() wrapper
@ 2026-09-07 11:18 frezidok1
  2026-09-07 11:18 ` [pseudo] [PATCH v3 1/6] ports/linux/guts: Add open_tree wrapper frezidok1
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: frezidok1 @ 2026-09-07 11:18 UTC (permalink / raw)
  To: yocto-patches; +Cc: Dmitry Sakhonchik

From: Dmitry Sakhonchik <frezidok1@gmail.com>

v2:
- Handle relative paths correctly in the open_tree wrapper
- Add fallback to SYS_open_tree when libc function is absent
- Add tests coverage with relative paths (dirfd != AT_FDCWD)
- Add support and tests for syscall(SYS_open_tree, ...)

v3:
- Add open_tree_attr wrapper
- Add open_tree_attr syscall test

Dmitry Sakhonchik (6):
  ports/linux/guts: Add open_tree wrapper
  test: Add open_tree test
  ports/linux/pseudo_wrappers.c: Add syscall support for open_tree()
    wrapper
  test: Add open_tree syscall test
  test: Add open_tree_attr syscall test
  ports/linux/guts: Add open_tree_attr wrapper

 ports/linux/guts/open_tree.c        |  46 ++++++++
 ports/linux/guts/open_tree_attr.c   |  48 ++++++++
 ports/linux/portdefs.h              |  18 +++
 ports/linux/pseudo_wrappers.c       |  30 +++++
 ports/linux/wrapfuncs.in            |   2 +
 pseudo_wrappers.c                   |   1 +
 test/test-open_tree-syscall.c       | 152 +++++++++++++++++++++++++
 test/test-open_tree-syscall.sh      |   5 +
 test/test-open_tree.c               | 139 +++++++++++++++++++++++
 test/test-open_tree.sh              |   5 +
 test/test-open_tree_attr-syscall.c  | 165 ++++++++++++++++++++++++++++
 test/test-open_tree_attr-syscall.sh |   5 +
 12 files changed, 616 insertions(+)
 create mode 100644 ports/linux/guts/open_tree.c
 create mode 100644 ports/linux/guts/open_tree_attr.c
 create mode 100644 test/test-open_tree-syscall.c
 create mode 100755 test/test-open_tree-syscall.sh
 create mode 100644 test/test-open_tree.c
 create mode 100755 test/test-open_tree.sh
 create mode 100644 test/test-open_tree_attr-syscall.c
 create mode 100755 test/test-open_tree_attr-syscall.sh



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [pseudo] [PATCH v3 1/6] ports/linux/guts: Add open_tree wrapper
  2026-09-07 11:18 [pseudo] [PATCH v3 0/6] Add open_tree() wrapper frezidok1
@ 2026-09-07 11:18 ` frezidok1
  2026-09-21  9:28   ` Paul Barker
  2026-09-07 11:18 ` [pseudo] [PATCH v3 2/6] test: Add open_tree test frezidok1
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: frezidok1 @ 2026-09-07 11:18 UTC (permalink / raw)
  To: yocto-patches; +Cc: Dmitry Sakhonchik

From: Dmitry Sakhonchik <frezidok1@gmail.com>

[YOCTO #16379]

OPEN_TREE_CLONE is not handled since it requires CAP_SYS_ADMIN and is outside the common pseudo use case.

Signed-off-by: Dmitry Sakhonchik <frezidok1@gmail.com>
---
 ports/linux/guts/open_tree.c | 46 ++++++++++++++++++++++++++++++++++++
 ports/linux/portdefs.h       |  9 +++++++
 ports/linux/wrapfuncs.in     |  1 +
 3 files changed, 56 insertions(+)
 create mode 100644 ports/linux/guts/open_tree.c

diff --git a/ports/linux/guts/open_tree.c b/ports/linux/guts/open_tree.c
new file mode 100644
index 0000000..6c2aad9
--- /dev/null
+++ b/ports/linux/guts/open_tree.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2026 Yocto Project
+ * guts/COPYRIGHT for information.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * int open_tree(int dirfd, const char *path, unsigned int flags)
+ *	int rc = -1;
+ */
+
+	struct stat64 buf;
+	int save_errno;
+	char *pseudo_path;
+
+	if (real_open_tree) {
+		pseudo_debug(PDBGF_SYSCALL, "open_tree, calling open_tree.\n");
+		rc = real_open_tree(dirfd, path, flags);
+	} else {
+		pseudo_debug(PDBGF_SYSCALL, "open_tree, calling syscall.\n");
+		rc = real_syscall(SYS_open_tree, dirfd, path, flags);
+	}
+
+	pseudo_path = pseudo_root_path(__func__, __LINE__, dirfd, path, 0);
+
+	if (rc != -1) {
+		save_errno = errno;
+		int stat_rc;
+
+		stat_rc = real___fxstatat64(_STAT_VER, dirfd, pseudo_path, &buf, (flags & AT_SYMLINK_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0);
+
+		pseudo_debug(PDBGF_FILE, "open_tree(path %s), flags %o, stat rc %d, stat mode %o\n",
+			pseudo_path, flags, stat_rc, buf.st_mode);
+
+		if (stat_rc != -1) {
+			pseudo_client_op(OP_OPEN, 0, rc, dirfd, pseudo_path, &buf);
+		} else {
+			pseudo_debug(PDBGF_FILE, "open_tree(fd %d, path %d/%s, flags %d) succeeded, but stat failed (%s).\n",
+				rc, dirfd, pseudo_path, flags, strerror(errno));
+			pseudo_client_op(OP_OPEN, 0, rc, dirfd, pseudo_path, 0);
+		}
+		errno = save_errno;
+	}
+
+/*	return rc;
+ * }
+ */
diff --git a/ports/linux/portdefs.h b/ports/linux/portdefs.h
index 1f1a41a..565fed9 100644
--- a/ports/linux/portdefs.h
+++ b/ports/linux/portdefs.h
@@ -82,3 +82,12 @@ extern int unshare(int flags);
 
 #define SYS_openat2 __NR_openat2
 #endif
+
+#ifndef SYS_open_tree
+
+#ifndef __NR_open_tree
+#define __NR_open_tree 428
+#endif
+
+#define SYS_open_tree __NR_open_tree
+#endif
diff --git a/ports/linux/wrapfuncs.in b/ports/linux/wrapfuncs.in
index 3cea20a..a51e9a0 100644
--- a/ports/linux/wrapfuncs.in
+++ b/ports/linux/wrapfuncs.in
@@ -10,6 +10,7 @@ int lchown(const char *path, uid_t owner, gid_t group); /* flags=AT_SYMLINK_NOFO
 int __fxstatat(int ver, int dirfd, const char *path, struct stat *buf, int flags);
 int openat(int dirfd, const char *path, int flags, ...{mode_t mode}); /* flags=((flags&O_NOFOLLOW)||((flags&(O_CREAT|O_EXCL))==(O_CREAT|O_EXCL))), noignore_path=1 */
 int __openat_2(int dirfd, const char *path, int flags); /* flags=((flags&O_NOFOLLOW)||((flags&(O_CREAT|O_EXCL))==(O_CREAT|O_EXCL))), noignore_path=1 */
+int open_tree(int dirfd, const char *path, unsigned int flags); /* noignore_path=1 */
 int mknod(const char *path, mode_t mode, dev_t dev); /* real_func=pseudo_mknod */
 int mknodat(int dirfd, const char *path, mode_t mode, dev_t dev); /* real_func=pseudo_mknodat */
 int __xmknod(int ver, const char *path, mode_t mode, dev_t *dev); /* flags=AT_SYMLINK_NOFOLLOW */


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [pseudo] [PATCH v3 2/6] test: Add open_tree test
  2026-09-07 11:18 [pseudo] [PATCH v3 0/6] Add open_tree() wrapper frezidok1
  2026-09-07 11:18 ` [pseudo] [PATCH v3 1/6] ports/linux/guts: Add open_tree wrapper frezidok1
@ 2026-09-07 11:18 ` frezidok1
  2026-09-21  9:09   ` Paul Barker
  2026-09-07 11:18 ` [pseudo] [PATCH v3 3/6] ports/linux/pseudo_wrappers.c: Add syscall support for open_tree() wrapper frezidok1
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: frezidok1 @ 2026-09-07 11:18 UTC (permalink / raw)
  To: yocto-patches; +Cc: Dmitry Sakhonchik

From: Dmitry Sakhonchik <frezidok1@gmail.com>

[YOCTO #16379]

Covers basic open_tree wrapper functionality and the AT_EMPTY_PATH case.

Signed-off-by: Dmitry Sakhonchik <frezidok1@gmail.com>
---
 test/test-open_tree.c  | 139 +++++++++++++++++++++++++++++++++++++++++
 test/test-open_tree.sh |   5 ++
 2 files changed, 144 insertions(+)
 create mode 100644 test/test-open_tree.c
 create mode 100755 test/test-open_tree.sh

diff --git a/test/test-open_tree.c b/test/test-open_tree.c
new file mode 100644
index 0000000..0fc02f4
--- /dev/null
+++ b/test/test-open_tree.c
@@ -0,0 +1,139 @@
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+
+#define TEST_DIR "test-open-tree-dir"
+#define TEST_FILE "test-open-tree-file"
+
+static int test_no_flags(void) {
+    int treefd = -1;
+    int fd = -1;
+    int rc = 1;
+
+    treefd = open_tree(AT_FDCWD, TEST_DIR, 0);
+    if (treefd == -1) {
+        perror("open_tree");
+        goto out;
+    }
+
+    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
+    if (fd < 0) {
+        perror("openat");
+        goto out;
+    }
+
+    rc = 0;
+out:
+    if (treefd != -1) {
+        close(treefd);
+    }
+    if (fd != -1) {
+        close(fd);
+    }
+    return rc;
+}
+
+static int test_relative_dirfd(void) {
+    int basefd = -1;
+    int treefd = -1;
+    int fd = -1;
+    int rc = 1;
+
+    basefd = open(".", O_PATH | O_DIRECTORY);
+    if (basefd < 0) {
+        perror("open");
+        goto out;
+    }
+
+    treefd = open_tree(basefd, TEST_DIR, 0);
+    if (treefd < 0) {
+        perror("open_tree");
+        goto out;
+    }
+
+    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
+    if (fd < 0) {
+        perror("openat");
+        goto out;
+    }
+
+    rc = 0;
+out:
+    if (basefd != -1) {
+        close(basefd);
+    }
+    if (treefd != -1) {
+        close(treefd);
+    }
+    if (fd != -1) {
+        close(fd);
+    }
+    return rc;
+}
+
+static int test_at_empty_path(void) {
+    int treefd = -1;
+    int dirfd = -1;
+    int fd = -1;
+    int rc = 1;
+
+    dirfd = open(TEST_DIR, O_PATH | O_DIRECTORY);
+    if (dirfd < 0) {
+        perror("open");
+        goto out;
+    }
+
+    treefd = open_tree(dirfd, "", AT_EMPTY_PATH);
+    if (treefd == -1) {
+        perror("open_tree");
+        goto out;
+    }
+
+    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
+    if (fd < 0) {
+        perror("openat");
+        goto out;
+    }
+
+    rc = 0;
+out:
+    if (dirfd != -1) {
+        close(dirfd);
+    }
+    if (treefd != -1) {
+        close(treefd);
+    }
+    if (fd != -1) {
+        close(fd);
+    }
+    return rc;
+}
+
+static void cleanup(void) {
+    if (unlink(TEST_DIR "/" TEST_FILE) == -1 && errno != ENOENT) {
+        perror("unlink");
+    }
+    if (rmdir(TEST_DIR) == -1 && errno != ENOENT) {
+        perror("rmdir");
+    }
+}
+
+int main(void) {
+    cleanup();
+
+    if (mkdir(TEST_DIR, 0777) == -1) {
+        perror("mkdir");
+        return 1;
+    }
+
+    int rc = test_no_flags() || test_at_empty_path() || test_relative_dirfd();
+
+    cleanup();
+
+    return rc;
+}
diff --git a/test/test-open_tree.sh b/test/test-open_tree.sh
new file mode 100755
index 0000000..1654a0b
--- /dev/null
+++ b/test/test-open_tree.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./test/test-open_tree
+
+PSEUDO_IGNORE_PATHS=/ ./test/test-open_tree
\ No newline at end of file


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [pseudo] [PATCH v3 3/6] ports/linux/pseudo_wrappers.c: Add syscall support for open_tree() wrapper
  2026-09-07 11:18 [pseudo] [PATCH v3 0/6] Add open_tree() wrapper frezidok1
  2026-09-07 11:18 ` [pseudo] [PATCH v3 1/6] ports/linux/guts: Add open_tree wrapper frezidok1
  2026-09-07 11:18 ` [pseudo] [PATCH v3 2/6] test: Add open_tree test frezidok1
@ 2026-09-07 11:18 ` frezidok1
  2026-09-21  9:10   ` Paul Barker
  2026-09-07 11:18 ` [pseudo] [PATCH v3 4/6] test: Add open_tree syscall test frezidok1
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: frezidok1 @ 2026-09-07 11:18 UTC (permalink / raw)
  To: yocto-patches; +Cc: Dmitry Sakhonchik

From: Dmitry Sakhonchik <frezidok1@gmail.com>

[YOCTO #16379]

Signed-off-by: Dmitry Sakhonchik <frezidok1@gmail.com>
---
 ports/linux/pseudo_wrappers.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/ports/linux/pseudo_wrappers.c b/ports/linux/pseudo_wrappers.c
index b920cb2..33cba2d 100644
--- a/ports/linux/pseudo_wrappers.c
+++ b/ports/linux/pseudo_wrappers.c
@@ -102,6 +102,20 @@ syscall(long number, ...) {
 #error SYS_openat2 not defined
 #endif
 
+#ifdef SYS_open_tree
+	if (number == SYS_open_tree) {
+		pseudo_debug(PDBGF_SYSCALL, "syscall, faking open_tree.\n");
+		va_start(ap, number);
+		int dirfd = va_arg(ap, int);
+		const char *path = va_arg(ap, const char*);
+		unsigned int flags = va_arg(ap, unsigned int);
+
+		return wrap_open_tree(dirfd, path, flags);
+	}
+#else
+#error SYS_open_tree not defined
+#endif
+
 #ifdef SYS_renameat2
         /* Call out wrapper, expanding the variable arguments first */
 	if (number == SYS_renameat2) {


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [pseudo] [PATCH v3 4/6] test: Add open_tree syscall test
  2026-09-07 11:18 [pseudo] [PATCH v3 0/6] Add open_tree() wrapper frezidok1
                   ` (2 preceding siblings ...)
  2026-09-07 11:18 ` [pseudo] [PATCH v3 3/6] ports/linux/pseudo_wrappers.c: Add syscall support for open_tree() wrapper frezidok1
@ 2026-09-07 11:18 ` frezidok1
  2026-09-07 11:18 ` [pseudo] [PATCH v3 5/6] test: Add open_tree_attr " frezidok1
  2026-09-07 11:18 ` [pseudo] [PATCH v3 6/6] ports/linux/guts: Add open_tree_attr wrapper frezidok1
  5 siblings, 0 replies; 14+ messages in thread
From: frezidok1 @ 2026-09-07 11:18 UTC (permalink / raw)
  To: yocto-patches; +Cc: Dmitry Sakhonchik

From: Dmitry Sakhonchik <frezidok1@gmail.com>

[YOCTO #16379]

Covers basic wrapper functionality when using syscall(SYS_open_tree, ...), also tests AT_EMPTY_PATH flag and related paths using dirfd != AT_FDCWD.

Signed-off-by: Dmitry Sakhonchik <frezidok1@gmail.com>
---
 test/test-open_tree-syscall.c  | 152 +++++++++++++++++++++++++++++++++
 test/test-open_tree-syscall.sh |   5 ++
 2 files changed, 157 insertions(+)
 create mode 100644 test/test-open_tree-syscall.c
 create mode 100755 test/test-open_tree-syscall.sh

diff --git a/test/test-open_tree-syscall.c b/test/test-open_tree-syscall.c
new file mode 100644
index 0000000..03f5618
--- /dev/null
+++ b/test/test-open_tree-syscall.c
@@ -0,0 +1,152 @@
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/stat.h>
+
+#define TEST_DIR "test-open-tree-dir"
+#define TEST_FILE "test-open-tree-file"
+
+static int do_open_tree_syscall(int dirfd, const char *path,
+                unsigned int flags)
+{
+#ifdef SYS_open_tree
+    return syscall(SYS_open_tree, dirfd, path, flags);
+#elif defined(__NR_open_tree)
+    return syscall(__NR_open_tree, dirfd, path, flags);
+#else
+    errno = ENOSYS;
+    return -1;
+#endif
+}
+
+static int test_no_flags(void) {
+    int treefd = -1;
+    int fd = -1;
+    int rc = 1;
+
+    treefd = do_open_tree_syscall(AT_FDCWD, TEST_DIR, 0);
+    if (treefd == -1) {
+        perror("open_tree");
+        goto out;
+    }
+
+    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
+    if (fd < 0) {
+        perror("openat");
+        goto out;
+    }
+
+    rc = 0;
+out:
+    if (treefd != -1) {
+        close(treefd);
+    }
+    if (fd != -1) {
+        close(fd);
+    }
+    return rc;
+}
+
+static int test_relative_dirfd(void) {
+    int basefd = -1;
+    int treefd = -1;
+    int fd = -1;
+    int rc = 1;
+
+    basefd = open(".", O_PATH | O_DIRECTORY);
+    if (basefd < 0) {
+        perror("open");
+        goto out;
+    }
+
+    treefd = do_open_tree_syscall(basefd, TEST_DIR, 0);
+    if (treefd < 0) {
+        perror("open_tree");
+        goto out;
+    }
+
+    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
+    if (fd < 0) {
+        perror("openat");
+        goto out;
+    }
+
+    rc = 0;
+    out:
+        if (basefd != -1) {
+            close(basefd);
+        }
+    if (treefd != -1) {
+        close(treefd);
+    }
+    if (fd != -1) {
+        close(fd);
+    }
+    return rc;
+}
+
+static int test_at_empty_path(void) {
+    int treefd = -1;
+    int dirfd = -1;
+    int fd = -1;
+    int rc = 1;
+
+    dirfd = open(TEST_DIR, O_PATH | O_DIRECTORY);
+    if (dirfd < 0) {
+        perror("open");
+        goto out;
+    }
+
+    treefd = do_open_tree_syscall(dirfd, "", AT_EMPTY_PATH);
+    if (treefd == -1) {
+        perror("open_tree");
+        goto out;
+    }
+
+    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
+    if (fd < 0) {
+        perror("openat");
+        goto out;
+    }
+
+    rc = 0;
+out:
+    if (dirfd != -1) {
+        close(dirfd);
+    }
+    if (treefd != -1) {
+        close(treefd);
+    }
+    if (fd != -1) {
+        close(fd);
+    }
+    return rc;
+}
+
+static void cleanup(void) {
+    if (unlink(TEST_DIR "/" TEST_FILE) == -1 && errno != ENOENT) {
+        perror("unlink");
+    }
+    if (rmdir(TEST_DIR) == -1 && errno != ENOENT) {
+        perror("rmdir");
+    }
+}
+
+int main(void) {
+    cleanup();
+
+    if (mkdir(TEST_DIR, 0777) == -1) {
+        perror("mkdir");
+        return 1;
+    }
+
+    int rc = test_no_flags() || test_at_empty_path() || test_relative_dirfd();
+
+    cleanup();
+
+    return rc;
+}
diff --git a/test/test-open_tree-syscall.sh b/test/test-open_tree-syscall.sh
new file mode 100755
index 0000000..3cb4d96
--- /dev/null
+++ b/test/test-open_tree-syscall.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./test/test-open_tree-syscall
+
+PSEUDO_IGNORE_PATHS=/ ./test/test-open_tree-syscall
\ No newline at end of file


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [pseudo] [PATCH v3 5/6] test: Add open_tree_attr syscall test
  2026-09-07 11:18 [pseudo] [PATCH v3 0/6] Add open_tree() wrapper frezidok1
                   ` (3 preceding siblings ...)
  2026-09-07 11:18 ` [pseudo] [PATCH v3 4/6] test: Add open_tree syscall test frezidok1
@ 2026-09-07 11:18 ` frezidok1
  2026-09-07 11:18 ` [pseudo] [PATCH v3 6/6] ports/linux/guts: Add open_tree_attr wrapper frezidok1
  5 siblings, 0 replies; 14+ messages in thread
From: frezidok1 @ 2026-09-07 11:18 UTC (permalink / raw)
  To: yocto-patches; +Cc: Dmitry Sakhonchik

From: Dmitry Sakhonchik <frezidok1@gmail.com>

[YOCTO #16379]

Covers basic wrapper functionality when using syscall(SYS_open_tree_attr, ...), also tests AT_EMPTY_PATH flag and related paths using dirfd != AT_FDCWD.
The test uses attr == NULL, because using mount_attr in this call starts mount-specific privilege checks which end up with EPERM.

Signed-off-by: Dmitry Sakhonchik <frezidok1@gmail.com>
---
 test/test-open_tree_attr-syscall.c  | 165 ++++++++++++++++++++++++++++
 test/test-open_tree_attr-syscall.sh |   5 +
 2 files changed, 170 insertions(+)
 create mode 100644 test/test-open_tree_attr-syscall.c
 create mode 100755 test/test-open_tree_attr-syscall.sh

diff --git a/test/test-open_tree_attr-syscall.c b/test/test-open_tree_attr-syscall.c
new file mode 100644
index 0000000..4b656cb
--- /dev/null
+++ b/test/test-open_tree_attr-syscall.c
@@ -0,0 +1,165 @@
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <linux/mount.h>
+#include <sys/stat.h>
+
+#ifndef SYS_open_tree_attr
+
+#ifndef __NR_open_tree_attr
+#define __NR_open_tree_attr 467
+#endif
+
+#define SYS_open_tree_attr __NR_open_tree_attr
+#endif
+
+#define TEST_DIR "test-open-tree-dir"
+#define TEST_FILE "test-open-tree-file"
+
+static int do_open_tree_attr_syscall(int dirfd, const char *path,
+                unsigned int flags)
+{
+    /* Using mount_attr in this call starts mount-specific privilege checks
+     * which end up with EPERM.
+     * The functionality when using attr == NULL is equivalent to open_tree() */
+#ifdef SYS_open_tree_attr
+    return syscall(SYS_open_tree_attr, dirfd, path, flags, NULL, 0);
+#elif defined(__NR_open_tree_attr)
+    return syscall(__NR_open_tree_attr, dirfd, path, flags, NULL, 0);
+#else
+    errno = ENOSYS;
+    return -1;
+#endif
+}
+
+static int test_no_flags(void) {
+    int treefd = -1;
+    int fd = -1;
+    int rc = 1;
+
+    treefd = do_open_tree_attr_syscall(AT_FDCWD, TEST_DIR, 0);
+    if (treefd == -1) {
+        perror("open_tree_attr");
+        goto out;
+    }
+
+    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
+    if (fd < 0) {
+        perror("openat");
+        goto out;
+    }
+
+    rc = 0;
+out:
+    if (treefd != -1) {
+        close(treefd);
+    }
+    if (fd != -1) {
+        close(fd);
+    }
+    return rc;
+}
+
+static int test_relative_dirfd(void) {
+    int basefd = -1;
+    int treefd = -1;
+    int fd = -1;
+    int rc = 1;
+
+    basefd = open(".", O_PATH | O_DIRECTORY);
+    if (basefd < 0) {
+        perror("open");
+        goto out;
+    }
+
+    treefd = do_open_tree_attr_syscall(basefd, TEST_DIR, 0);
+    if (treefd < 0) {
+        perror("open_tree_attr");
+        goto out;
+    }
+
+    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
+    if (fd < 0) {
+        perror("openat");
+        goto out;
+    }
+
+    rc = 0;
+    out:
+        if (basefd != -1) {
+            close(basefd);
+        }
+    if (treefd != -1) {
+        close(treefd);
+    }
+    if (fd != -1) {
+        close(fd);
+    }
+    return rc;
+}
+
+static int test_at_empty_path(void) {
+    int treefd = -1;
+    int dirfd = -1;
+    int fd = -1;
+    int rc = 1;
+
+    dirfd = open(TEST_DIR, O_PATH | O_DIRECTORY);
+    if (dirfd < 0) {
+        perror("open");
+        goto out;
+    }
+
+    treefd = do_open_tree_attr_syscall(dirfd, "", AT_EMPTY_PATH);
+    if (treefd == -1) {
+        perror("open_tree_attr");
+        goto out;
+    }
+
+    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
+    if (fd < 0) {
+        perror("openat");
+        goto out;
+    }
+
+    rc = 0;
+out:
+    if (dirfd != -1) {
+        close(dirfd);
+    }
+    if (treefd != -1) {
+        close(treefd);
+    }
+    if (fd != -1) {
+        close(fd);
+    }
+    return rc;
+}
+
+static void cleanup(void) {
+    if (unlink(TEST_DIR "/" TEST_FILE) == -1 && errno != ENOENT) {
+        perror("unlink");
+    }
+    if (rmdir(TEST_DIR) == -1 && errno != ENOENT) {
+        perror("rmdir");
+    }
+}
+
+int main(void) {
+    cleanup();
+
+    if (mkdir(TEST_DIR, 0777) == -1) {
+        perror("mkdir");
+        return 1;
+    }
+
+    int rc = test_no_flags() || test_at_empty_path() || test_relative_dirfd();
+
+    cleanup();
+
+    return rc;
+}
diff --git a/test/test-open_tree_attr-syscall.sh b/test/test-open_tree_attr-syscall.sh
new file mode 100755
index 0000000..3e50ebe
--- /dev/null
+++ b/test/test-open_tree_attr-syscall.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./test/test-open_tree_attr-syscall
+
+PSEUDO_IGNORE_PATHS=/ ./test/test-open_tree_attr-syscall


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [pseudo] [PATCH v3 6/6] ports/linux/guts: Add open_tree_attr wrapper
  2026-09-07 11:18 [pseudo] [PATCH v3 0/6] Add open_tree() wrapper frezidok1
                   ` (4 preceding siblings ...)
  2026-09-07 11:18 ` [pseudo] [PATCH v3 5/6] test: Add open_tree_attr " frezidok1
@ 2026-09-07 11:18 ` frezidok1
  5 siblings, 0 replies; 14+ messages in thread
From: frezidok1 @ 2026-09-07 11:18 UTC (permalink / raw)
  To: yocto-patches; +Cc: Dmitry Sakhonchik

From: Dmitry Sakhonchik <frezidok1@gmail.com>

[YOCTO #16379]

It mostly mirrors open_tree, with the additional
mount attribute arguments passed to the underlying syscall.

Signed-off-by: Dmitry Sakhonchik <frezidok1@gmail.com>
---
 ports/linux/guts/open_tree_attr.c | 48 +++++++++++++++++++++++++++++++
 ports/linux/portdefs.h            |  9 ++++++
 ports/linux/pseudo_wrappers.c     | 16 +++++++++++
 ports/linux/wrapfuncs.in          |  1 +
 pseudo_wrappers.c                 |  1 +
 5 files changed, 75 insertions(+)
 create mode 100644 ports/linux/guts/open_tree_attr.c

diff --git a/ports/linux/guts/open_tree_attr.c b/ports/linux/guts/open_tree_attr.c
new file mode 100644
index 0000000..da0315c
--- /dev/null
+++ b/ports/linux/guts/open_tree_attr.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2026 Yocto Project
+ * guts/COPYRIGHT for information.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * int open_tree_attr(int dirfd, const char *path, unsigned int flags, struct mount_attr *attr, size_t size)
+ *	int rc = -1;
+ */
+
+	/* Mostly based on open_tree wrapper */
+
+	struct stat64 buf;
+	int save_errno;
+	char *pseudo_path;
+
+	if (real_open_tree_attr) {
+		pseudo_debug(PDBGF_SYSCALL, "open_tree_attr, calling open_tree_attr.\n");
+		rc = real_open_tree_attr(dirfd, path, flags, attr, size);
+	} else {
+		pseudo_debug(PDBGF_SYSCALL, "open_tree_attr, calling syscall.\n");
+		rc = real_syscall(SYS_open_tree_attr, dirfd, path, flags, attr, size);
+	}
+
+	pseudo_path = pseudo_root_path(__func__, __LINE__, dirfd, path, 0);
+
+	if (rc != -1) {
+		save_errno = errno;
+		int stat_rc;
+
+		stat_rc = real___fxstatat64(_STAT_VER, dirfd, pseudo_path, &buf, (flags & AT_SYMLINK_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0);
+
+		pseudo_debug(PDBGF_FILE, "open_tree_attr(path %s), flags %o, stat rc %d, stat mode %o\n",
+			pseudo_path, flags, stat_rc, buf.st_mode);
+
+		if (stat_rc != -1) {
+			pseudo_client_op(OP_OPEN, 0, rc, dirfd, pseudo_path, &buf);
+		} else {
+			pseudo_debug(PDBGF_FILE, "open_tree_attr(fd %d, path %d/%s, flags %d) succeeded, but stat failed (%s).\n",
+				rc, dirfd, pseudo_path, flags, strerror(errno));
+			pseudo_client_op(OP_OPEN, 0, rc, dirfd, pseudo_path, 0);
+		}
+		errno = save_errno;
+	}
+
+/*	return rc;
+ * }
+ */
diff --git a/ports/linux/portdefs.h b/ports/linux/portdefs.h
index 565fed9..af8b8e8 100644
--- a/ports/linux/portdefs.h
+++ b/ports/linux/portdefs.h
@@ -91,3 +91,12 @@ extern int unshare(int flags);
 
 #define SYS_open_tree __NR_open_tree
 #endif
+
+#ifndef SYS_open_tree_attr
+
+#ifndef __NR_open_tree_attr
+#define __NR_open_tree_attr 467
+#endif
+
+#define SYS_open_tree_attr __NR_open_tree_attr
+#endif
diff --git a/ports/linux/pseudo_wrappers.c b/ports/linux/pseudo_wrappers.c
index 33cba2d..4141556 100644
--- a/ports/linux/pseudo_wrappers.c
+++ b/ports/linux/pseudo_wrappers.c
@@ -116,6 +116,22 @@ syscall(long number, ...) {
 #error SYS_open_tree not defined
 #endif
 
+#ifdef SYS_open_tree_attr
+	if (number == SYS_open_tree_attr) {
+		pseudo_debug(PDBGF_SYSCALL, "syscall, faking open_tree_attr.\n");
+		va_start(ap, number);
+		int dirfd = va_arg(ap, int);
+		const char *path = va_arg(ap, const char*);
+		unsigned int flags = va_arg(ap, unsigned int);
+		struct mount_attr *attr = va_arg(ap, struct mount_attr*);
+		size_t size = va_arg(ap, size_t);
+
+		return wrap_open_tree_attr(dirfd, path, flags, attr, size);
+	}
+#else
+#error SYS_open_tree_attr not defined
+#endif
+
 #ifdef SYS_renameat2
         /* Call out wrapper, expanding the variable arguments first */
 	if (number == SYS_renameat2) {
diff --git a/ports/linux/wrapfuncs.in b/ports/linux/wrapfuncs.in
index a51e9a0..639d9a5 100644
--- a/ports/linux/wrapfuncs.in
+++ b/ports/linux/wrapfuncs.in
@@ -11,6 +11,7 @@ int __fxstatat(int ver, int dirfd, const char *path, struct stat *buf, int flags
 int openat(int dirfd, const char *path, int flags, ...{mode_t mode}); /* flags=((flags&O_NOFOLLOW)||((flags&(O_CREAT|O_EXCL))==(O_CREAT|O_EXCL))), noignore_path=1 */
 int __openat_2(int dirfd, const char *path, int flags); /* flags=((flags&O_NOFOLLOW)||((flags&(O_CREAT|O_EXCL))==(O_CREAT|O_EXCL))), noignore_path=1 */
 int open_tree(int dirfd, const char *path, unsigned int flags); /* noignore_path=1 */
+int open_tree_attr(int dirfd, const char *path, unsigned int flags, struct mount_attr *attr, size_t size); /* noignore_path=1 */
 int mknod(const char *path, mode_t mode, dev_t dev); /* real_func=pseudo_mknod */
 int mknodat(int dirfd, const char *path, mode_t mode, dev_t dev); /* real_func=pseudo_mknodat */
 int __xmknod(int ver, const char *path, mode_t mode, dev_t *dev); /* flags=AT_SYMLINK_NOFOLLOW */
diff --git a/pseudo_wrappers.c b/pseudo_wrappers.c
index 112239b..78cdecf 100644
--- a/pseudo_wrappers.c
+++ b/pseudo_wrappers.c
@@ -37,6 +37,7 @@
 #include <grp.h>
 #include <pwd.h>
 #include <utime.h>
+#include <sys/mount.h>
 #ifdef PSEUDO_PORT_LINUX_STATVFS
 #include <sys/statvfs.h>
 #endif


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [pseudo] [PATCH v3 2/6] test: Add open_tree test
  2026-09-07 11:18 ` [pseudo] [PATCH v3 2/6] test: Add open_tree test frezidok1
@ 2026-09-21  9:09   ` Paul Barker
  2026-09-21  9:38     ` Dmitry Sakhonchik
  0 siblings, 1 reply; 14+ messages in thread
From: Paul Barker @ 2026-09-21  9:09 UTC (permalink / raw)
  To: frezidok1, yocto-patches

On Mon, 2026-09-07 at 14:18 +0300, frezidok1@gmail.com wrote:
> From: Dmitry Sakhonchik <frezidok1@gmail.com>
> 
> [YOCTO #16379]
> 
> Covers basic open_tree wrapper functionality and the AT_EMPTY_PATH case.
> 
> Signed-off-by: Dmitry Sakhonchik <frezidok1@gmail.com>
> ---
>  test/test-open_tree.c  | 139 +++++++++++++++++++++++++++++++++++++++++
>  test/test-open_tree.sh |   5 ++
>  2 files changed, 144 insertions(+)
>  create mode 100644 test/test-open_tree.c
>  create mode 100755 test/test-open_tree.sh
> 
> diff --git a/test/test-open_tree.c b/test/test-open_tree.c
> new file mode 100644
> index 0000000..0fc02f4
> --- /dev/null
> +++ b/test/test-open_tree.c
> @@ -0,0 +1,139 @@
> +#define _GNU_SOURCE
> +
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <sys/stat.h>
> +#include <sys/mount.h>
> +
> +#define TEST_DIR "test-open-tree-dir"
> +#define TEST_FILE "test-open-tree-file"
> +
> +static int test_no_flags(void) {
> +    int treefd = -1;
> +    int fd = -1;
> +    int rc = 1;
> +
> +    treefd = open_tree(AT_FDCWD, TEST_DIR, 0);
> +    if (treefd == -1) {
> +        perror("open_tree");
> +        goto out;
> +    }
> +
> +    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
> +    if (fd < 0) {
> +        perror("openat");
> +        goto out;
> +    }
> +
> +    rc = 0;
> +out:
> +    if (treefd != -1) {
> +        close(treefd);
> +    }
> +    if (fd != -1) {
> +        close(fd);
> +    }
> +    return rc;
> +}
> +
> +static int test_relative_dirfd(void) {
> +    int basefd = -1;
> +    int treefd = -1;
> +    int fd = -1;
> +    int rc = 1;
> +
> +    basefd = open(".", O_PATH | O_DIRECTORY);
> +    if (basefd < 0) {
> +        perror("open");
> +        goto out;
> +    }
> +
> +    treefd = open_tree(basefd, TEST_DIR, 0);
> +    if (treefd < 0) {
> +        perror("open_tree");
> +        goto out;
> +    }
> +
> +    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
> +    if (fd < 0) {
> +        perror("openat");
> +        goto out;
> +    }
> +
> +    rc = 0;
> +out:
> +    if (basefd != -1) {
> +        close(basefd);
> +    }
> +    if (treefd != -1) {
> +        close(treefd);
> +    }
> +    if (fd != -1) {
> +        close(fd);
> +    }
> +    return rc;
> +}
> +
> +static int test_at_empty_path(void) {
> +    int treefd = -1;
> +    int dirfd = -1;
> +    int fd = -1;
> +    int rc = 1;
> +
> +    dirfd = open(TEST_DIR, O_PATH | O_DIRECTORY);
> +    if (dirfd < 0) {
> +        perror("open");
> +        goto out;
> +    }
> +
> +    treefd = open_tree(dirfd, "", AT_EMPTY_PATH);
> +    if (treefd == -1) {
> +        perror("open_tree");
> +        goto out;
> +    }
> +
> +    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
> +    if (fd < 0) {
> +        perror("openat");
> +        goto out;
> +    }
> +
> +    rc = 0;
> +out:
> +    if (dirfd != -1) {
> +        close(dirfd);
> +    }
> +    if (treefd != -1) {
> +        close(treefd);
> +    }
> +    if (fd != -1) {
> +        close(fd);
> +    }
> +    return rc;
> +}
> +
> +static void cleanup(void) {
> +    if (unlink(TEST_DIR "/" TEST_FILE) == -1 && errno != ENOENT) {
> +        perror("unlink");
> +    }
> +    if (rmdir(TEST_DIR) == -1 && errno != ENOENT) {
> +        perror("rmdir");
> +    }
> +}
> +
> +int main(void) {
> +    cleanup();
> +
> +    if (mkdir(TEST_DIR, 0777) == -1) {
> +        perror("mkdir");
> +        return 1;
> +    }
> +
> +    int rc = test_no_flags() || test_at_empty_path() || test_relative_dirfd();

This will short-circuit on the first failing test. We should run all
test cases and accumulate the pass/fail results.

> +
> +    cleanup();

Do we need to run cleanup() between test cases? Or at least cleanup
TEST_FILE between test cases?

> +
> +    return rc;
> +}
> diff --git a/test/test-open_tree.sh b/test/test-open_tree.sh
> new file mode 100755
> index 0000000..1654a0b
> --- /dev/null
> +++ b/test/test-open_tree.sh
> @@ -0,0 +1,5 @@
> +#!/bin/sh
> +
> +./test/test-open_tree
> +
> +PSEUDO_IGNORE_PATHS=/ ./test/test-open_tree
> \ No newline at end of file

This runs test-open_tree twice but the script exit code only depends on
the second invocation. We should or these two results together.

Nitpick: Missing newline at end of file.

Best regards,

-- 
Paul Barker



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [pseudo] [PATCH v3 3/6] ports/linux/pseudo_wrappers.c: Add syscall support for open_tree() wrapper
  2026-09-07 11:18 ` [pseudo] [PATCH v3 3/6] ports/linux/pseudo_wrappers.c: Add syscall support for open_tree() wrapper frezidok1
@ 2026-09-21  9:10   ` Paul Barker
  0 siblings, 0 replies; 14+ messages in thread
From: Paul Barker @ 2026-09-21  9:10 UTC (permalink / raw)
  To: frezidok1, yocto-patches

On Mon, 2026-09-07 at 14:18 +0300, frezidok1@gmail.com wrote:
> From: Dmitry Sakhonchik <frezidok1@gmail.com>
> 
> [YOCTO #16379]
> 
> Signed-off-by: Dmitry Sakhonchik <frezidok1@gmail.com>

The commit message needs to explain why a syscall intercept is needed
for SYS_open_tree. We don't do this for all system calls.

> ---
>  ports/linux/pseudo_wrappers.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/ports/linux/pseudo_wrappers.c b/ports/linux/pseudo_wrappers.c
> index b920cb2..33cba2d 100644
> --- a/ports/linux/pseudo_wrappers.c
> +++ b/ports/linux/pseudo_wrappers.c
> @@ -102,6 +102,20 @@ syscall(long number, ...) {
>  #error SYS_openat2 not defined
>  #endif
>  
> +#ifdef SYS_open_tree
> +	if (number == SYS_open_tree) {
> +		pseudo_debug(PDBGF_SYSCALL, "syscall, faking open_tree.\n");
> +		va_start(ap, number);
> +		int dirfd = va_arg(ap, int);
> +		const char *path = va_arg(ap, const char*);
> +		unsigned int flags = va_arg(ap, unsigned int);
> +
> +		return wrap_open_tree(dirfd, path, flags);
> +	}
> +#else
> +#error SYS_open_tree not defined
> +#endif
> +
>  #ifdef SYS_renameat2
>          /* Call out wrapper, expanding the variable arguments first */
>  	if (number == SYS_renameat2) {
> 

Best regards,

-- 
Paul Barker



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [pseudo] [PATCH v3 1/6] ports/linux/guts: Add open_tree wrapper
  2026-09-07 11:18 ` [pseudo] [PATCH v3 1/6] ports/linux/guts: Add open_tree wrapper frezidok1
@ 2026-09-21  9:28   ` Paul Barker
  2026-09-21 11:12     ` Dmitry Sakhonchik
  0 siblings, 1 reply; 14+ messages in thread
From: Paul Barker @ 2026-09-21  9:28 UTC (permalink / raw)
  To: frezidok1, yocto-patches

On Mon, 2026-09-07 at 14:18 +0300, frezidok1@gmail.com wrote:
> From: Dmitry Sakhonchik <frezidok1@gmail.com>
> 
> [YOCTO #16379]
> 
> OPEN_TREE_CLONE is not handled since it requires CAP_SYS_ADMIN and is outside the common pseudo use case.

We should at least log an error if OPEN_TREE_CLONE is seen instead of
silently ignoring it.

> 
> Signed-off-by: Dmitry Sakhonchik <frezidok1@gmail.com>
> ---
>  ports/linux/guts/open_tree.c | 46 ++++++++++++++++++++++++++++++++++++
>  ports/linux/portdefs.h       |  9 +++++++
>  ports/linux/wrapfuncs.in     |  1 +
>  3 files changed, 56 insertions(+)
>  create mode 100644 ports/linux/guts/open_tree.c
> 
> diff --git a/ports/linux/guts/open_tree.c b/ports/linux/guts/open_tree.c
> new file mode 100644
> index 0000000..6c2aad9
> --- /dev/null
> +++ b/ports/linux/guts/open_tree.c
> @@ -0,0 +1,46 @@
> +/*
> + * Copyright (c) 2026 Yocto Project
> + * guts/COPYRIGHT for information.
> + *
> + * SPDX-License-Identifier: LGPL-2.1-only
> + *
> + * int open_tree(int dirfd, const char *path, unsigned int flags)
> + *	int rc = -1;
> + */
> +
> +	struct stat64 buf;
> +	int save_errno;
> +	char *pseudo_path;
> +
> +	if (real_open_tree) {
> +		pseudo_debug(PDBGF_SYSCALL, "open_tree, calling open_tree.\n");
> +		rc = real_open_tree(dirfd, path, flags);
> +	} else {
> +		pseudo_debug(PDBGF_SYSCALL, "open_tree, calling syscall.\n");
> +		rc = real_syscall(SYS_open_tree, dirfd, path, flags);
> +	}

The commit message or a comment should briefly explain why we need to
handle both ways of invoking the real open_tree syscall.

> +
> +	pseudo_path = pseudo_root_path(__func__, __LINE__, dirfd, path, 0);

This should be after the (rc != -1) conditional, as this call could
clobber errno.

> +
> +	if (rc != -1) {

Nitpick: To save indentation, we can check for (rc == -1) and return early.

> +		save_errno = errno;
> +		int stat_rc;
> +
> +		stat_rc = real___fxstatat64(_STAT_VER, dirfd, pseudo_path, &buf, (flags & AT_SYMLINK_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0);
> +
> +		pseudo_debug(PDBGF_FILE, "open_tree(path %s), flags %o, stat rc %d, stat mode %o\n",
> +			pseudo_path, flags, stat_rc, buf.st_mode);
> +
> +		if (stat_rc != -1) {
> +			pseudo_client_op(OP_OPEN, 0, rc, dirfd, pseudo_path, &buf);
> +		} else {
> +			pseudo_debug(PDBGF_FILE, "open_tree(fd %d, path %d/%s, flags %d) succeeded, but stat failed (%s).\n",
> +				rc, dirfd, pseudo_path, flags, strerror(errno));
> +			pseudo_client_op(OP_OPEN, 0, rc, dirfd, pseudo_path, 0);
> +		}
> +		errno = save_errno;
> +	}
> +
> +/*	return rc;
> + * }
> + */
> diff --git a/ports/linux/portdefs.h b/ports/linux/portdefs.h
> index 1f1a41a..565fed9 100644
> --- a/ports/linux/portdefs.h
> +++ b/ports/linux/portdefs.h
> @@ -82,3 +82,12 @@ extern int unshare(int flags);
>  
>  #define SYS_openat2 __NR_openat2
>  #endif
> +
> +#ifndef SYS_open_tree
> +
> +#ifndef __NR_open_tree
> +#define __NR_open_tree 428
> +#endif
> +
> +#define SYS_open_tree __NR_open_tree
> +#endif
> diff --git a/ports/linux/wrapfuncs.in b/ports/linux/wrapfuncs.in
> index 3cea20a..a51e9a0 100644
> --- a/ports/linux/wrapfuncs.in
> +++ b/ports/linux/wrapfuncs.in
> @@ -10,6 +10,7 @@ int lchown(const char *path, uid_t owner, gid_t group); /* flags=AT_SYMLINK_NOFO
>  int __fxstatat(int ver, int dirfd, const char *path, struct stat *buf, int flags);
>  int openat(int dirfd, const char *path, int flags, ...{mode_t mode}); /* flags=((flags&O_NOFOLLOW)||((flags&(O_CREAT|O_EXCL))==(O_CREAT|O_EXCL))), noignore_path=1 */
>  int __openat_2(int dirfd, const char *path, int flags); /* flags=((flags&O_NOFOLLOW)||((flags&(O_CREAT|O_EXCL))==(O_CREAT|O_EXCL))), noignore_path=1 */
> +int open_tree(int dirfd, const char *path, unsigned int flags); /* noignore_path=1 */

Does this need preserve_paths=1 (similar to openat2())?

That would require us to account for a possible chroot in the
open_tree() guts, but it would avoid us running pseudo_root_path() on an
already canonicalized path which may introduce problems under a chroot.

>  int mknod(const char *path, mode_t mode, dev_t dev); /* real_func=pseudo_mknod */
>  int mknodat(int dirfd, const char *path, mode_t mode, dev_t dev); /* real_func=pseudo_mknodat */
>  int __xmknod(int ver, const char *path, mode_t mode, dev_t *dev); /* flags=AT_SYMLINK_NOFOLLOW */
> 

-- 
Paul Barker



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [pseudo] [PATCH v3 2/6] test: Add open_tree test
  2026-09-21  9:09   ` Paul Barker
@ 2026-09-21  9:38     ` Dmitry Sakhonchik
  2026-10-02 12:16       ` Paul Barker
  0 siblings, 1 reply; 14+ messages in thread
From: Dmitry Sakhonchik @ 2026-09-21  9:38 UTC (permalink / raw)
  To: Paul Barker; +Cc: yocto-patches

[-- Attachment #1: Type: text/plain, Size: 5139 bytes --]

пн, 21 сент. 2026 г. в 12:09, Paul Barker <paul@pbarker.dev>:

> On Mon, 2026-09-07 at 14:18 +0300, frezidok1@gmail.com wrote:
> > From: Dmitry Sakhonchik <frezidok1@gmail.com>
> >
> > [YOCTO #16379]
> >
> > Covers basic open_tree wrapper functionality and the AT_EMPTY_PATH case.
> >
> > Signed-off-by: Dmitry Sakhonchik <frezidok1@gmail.com>
> > ---
> >  test/test-open_tree.c  | 139 +++++++++++++++++++++++++++++++++++++++++
> >  test/test-open_tree.sh |   5 ++
> >  2 files changed, 144 insertions(+)
> >  create mode 100644 test/test-open_tree.c
> >  create mode 100755 test/test-open_tree.sh
> >
> > diff --git a/test/test-open_tree.c b/test/test-open_tree.c
> > new file mode 100644
> > index 0000000..0fc02f4
> > --- /dev/null
> > +++ b/test/test-open_tree.c
> > @@ -0,0 +1,139 @@
> > +#define _GNU_SOURCE
> > +
> > +#include <errno.h>
> > +#include <fcntl.h>
> > +#include <stdio.h>
> > +#include <unistd.h>
> > +#include <sys/stat.h>
> > +#include <sys/mount.h>
> > +
> > +#define TEST_DIR "test-open-tree-dir"
> > +#define TEST_FILE "test-open-tree-file"
> > +
> > +static int test_no_flags(void) {
> > +    int treefd = -1;
> > +    int fd = -1;
> > +    int rc = 1;
> > +
> > +    treefd = open_tree(AT_FDCWD, TEST_DIR, 0);
> > +    if (treefd == -1) {
> > +        perror("open_tree");
> > +        goto out;
> > +    }
> > +
> > +    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
> > +    if (fd < 0) {
> > +        perror("openat");
> > +        goto out;
> > +    }
> > +
> > +    rc = 0;
> > +out:
> > +    if (treefd != -1) {
> > +        close(treefd);
> > +    }
> > +    if (fd != -1) {
> > +        close(fd);
> > +    }
> > +    return rc;
> > +}
> > +
> > +static int test_relative_dirfd(void) {
> > +    int basefd = -1;
> > +    int treefd = -1;
> > +    int fd = -1;
> > +    int rc = 1;
> > +
> > +    basefd = open(".", O_PATH | O_DIRECTORY);
> > +    if (basefd < 0) {
> > +        perror("open");
> > +        goto out;
> > +    }
> > +
> > +    treefd = open_tree(basefd, TEST_DIR, 0);
> > +    if (treefd < 0) {
> > +        perror("open_tree");
> > +        goto out;
> > +    }
> > +
> > +    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
> > +    if (fd < 0) {
> > +        perror("openat");
> > +        goto out;
> > +    }
> > +
> > +    rc = 0;
> > +out:
> > +    if (basefd != -1) {
> > +        close(basefd);
> > +    }
> > +    if (treefd != -1) {
> > +        close(treefd);
> > +    }
> > +    if (fd != -1) {
> > +        close(fd);
> > +    }
> > +    return rc;
> > +}
> > +
> > +static int test_at_empty_path(void) {
> > +    int treefd = -1;
> > +    int dirfd = -1;
> > +    int fd = -1;
> > +    int rc = 1;
> > +
> > +    dirfd = open(TEST_DIR, O_PATH | O_DIRECTORY);
> > +    if (dirfd < 0) {
> > +        perror("open");
> > +        goto out;
> > +    }
> > +
> > +    treefd = open_tree(dirfd, "", AT_EMPTY_PATH);
> > +    if (treefd == -1) {
> > +        perror("open_tree");
> > +        goto out;
> > +    }
> > +
> > +    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
> > +    if (fd < 0) {
> > +        perror("openat");
> > +        goto out;
> > +    }
> > +
> > +    rc = 0;
> > +out:
> > +    if (dirfd != -1) {
> > +        close(dirfd);
> > +    }
> > +    if (treefd != -1) {
> > +        close(treefd);
> > +    }
> > +    if (fd != -1) {
> > +        close(fd);
> > +    }
> > +    return rc;
> > +}
> > +
> > +static void cleanup(void) {
> > +    if (unlink(TEST_DIR "/" TEST_FILE) == -1 && errno != ENOENT) {
> > +        perror("unlink");
> > +    }
> > +    if (rmdir(TEST_DIR) == -1 && errno != ENOENT) {
> > +        perror("rmdir");
> > +    }
> > +}
> > +
> > +int main(void) {
> > +    cleanup();
> > +
> > +    if (mkdir(TEST_DIR, 0777) == -1) {
> > +        perror("mkdir");
> > +        return 1;
> > +    }
> > +
> > +    int rc = test_no_flags() || test_at_empty_path() ||
> test_relative_dirfd();
>
> This will short-circuit on the first failing test. We should run all
> test cases and accumulate the pass/fail results.
>
> > +
> > +    cleanup();
>
> Do we need to run cleanup() between test cases? Or at least cleanup
> TEST_FILE between test cases?
>

I don't think so. In every test case we always open TEST_DIR with open_tree
and then openat(TEST_FILE) with O_CREAT.
So I think removing this file is not necessary.

>
> > +
> > +    return rc;
> > +}
> > diff --git a/test/test-open_tree.sh b/test/test-open_tree.sh
> > new file mode 100755
> > index 0000000..1654a0b
> > --- /dev/null
> > +++ b/test/test-open_tree.sh
> > @@ -0,0 +1,5 @@
> > +#!/bin/sh
> > +
> > +./test/test-open_tree
> > +
> > +PSEUDO_IGNORE_PATHS=/ ./test/test-open_tree
> > \ No newline at end of file
>
> This runs test-open_tree twice but the script exit code only depends on
> the second invocation. We should or these two results together.
>
> Nitpick: Missing newline at end of file.
>
> Best regards,
>
> --
> Paul Barker
>
>

[-- Attachment #2: Type: text/html, Size: 7197 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [pseudo] [PATCH v3 1/6] ports/linux/guts: Add open_tree wrapper
  2026-09-21  9:28   ` Paul Barker
@ 2026-09-21 11:12     ` Dmitry Sakhonchik
  2026-10-02 12:15       ` Paul Barker
  0 siblings, 1 reply; 14+ messages in thread
From: Dmitry Sakhonchik @ 2026-09-21 11:12 UTC (permalink / raw)
  To: Paul Barker; +Cc: yocto-patches

[-- Attachment #1: Type: text/plain, Size: 5481 bytes --]

пн, 21 сент. 2026 г. в 12:28, Paul Barker <paul@pbarker.dev>:

> On Mon, 2026-09-07 at 14:18 +0300, frezidok1@gmail.com wrote:
> > From: Dmitry Sakhonchik <frezidok1@gmail.com>
> >
> > [YOCTO #16379]
> >
> > OPEN_TREE_CLONE is not handled since it requires CAP_SYS_ADMIN and is
> outside the common pseudo use case.
>
> We should at least log an error if OPEN_TREE_CLONE is seen instead of
> silently ignoring it.
>
> >
> > Signed-off-by: Dmitry Sakhonchik <frezidok1@gmail.com>
> > ---
> >  ports/linux/guts/open_tree.c | 46 ++++++++++++++++++++++++++++++++++++
> >  ports/linux/portdefs.h       |  9 +++++++
> >  ports/linux/wrapfuncs.in     |  1 +
> >  3 files changed, 56 insertions(+)
> >  create mode 100644 ports/linux/guts/open_tree.c
> >
> > diff --git a/ports/linux/guts/open_tree.c b/ports/linux/guts/open_tree.c
> > new file mode 100644
> > index 0000000..6c2aad9
> > --- /dev/null
> > +++ b/ports/linux/guts/open_tree.c
> > @@ -0,0 +1,46 @@
> > +/*
> > + * Copyright (c) 2026 Yocto Project
> > + * guts/COPYRIGHT for information.
> > + *
> > + * SPDX-License-Identifier: LGPL-2.1-only
> > + *
> > + * int open_tree(int dirfd, const char *path, unsigned int flags)
> > + *   int rc = -1;
> > + */
> > +
> > +     struct stat64 buf;
> > +     int save_errno;
> > +     char *pseudo_path;
> > +
> > +     if (real_open_tree) {
> > +             pseudo_debug(PDBGF_SYSCALL, "open_tree, calling
> open_tree.\n");
> > +             rc = real_open_tree(dirfd, path, flags);
> > +     } else {
> > +             pseudo_debug(PDBGF_SYSCALL, "open_tree, calling
> syscall.\n");
> > +             rc = real_syscall(SYS_open_tree, dirfd, path, flags);
> > +     }
>
> The commit message or a comment should briefly explain why we need to
> handle both ways of invoking the real open_tree syscall.
>
> > +
> > +     pseudo_path = pseudo_root_path(__func__, __LINE__, dirfd, path, 0);
>
> This should be after the (rc != -1) conditional, as this call could
> clobber errno.
>
> If we use preserve_path=1, then the absolute path must go through
pseudo_root_path before the real open_tree call so that a possible chroot
is handled correctly.
So I think these two cases need to be somehow handled separately rather
than moving pseudo_root_path() entirely below the rc != -1 check.
By the way, for some reason the openat2 wrapper is ok with the
pseudo_root_path outside of conditional.

> > +
> > +     if (rc != -1) {
>
> Nitpick: To save indentation, we can check for (rc == -1) and return early.
>
> > +             save_errno = errno;
> > +             int stat_rc;
> > +
> > +             stat_rc = real___fxstatat64(_STAT_VER, dirfd, pseudo_path,
> &buf, (flags & AT_SYMLINK_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0);
> > +
> > +             pseudo_debug(PDBGF_FILE, "open_tree(path %s), flags %o,
> stat rc %d, stat mode %o\n",
> > +                     pseudo_path, flags, stat_rc, buf.st_mode);
> > +
> > +             if (stat_rc != -1) {
> > +                     pseudo_client_op(OP_OPEN, 0, rc, dirfd,
> pseudo_path, &buf);
> > +             } else {
> > +                     pseudo_debug(PDBGF_FILE, "open_tree(fd %d, path
> %d/%s, flags %d) succeeded, but stat failed (%s).\n",
> > +                             rc, dirfd, pseudo_path, flags,
> strerror(errno));
> > +                     pseudo_client_op(OP_OPEN, 0, rc, dirfd,
> pseudo_path, 0);
> > +             }
> > +             errno = save_errno;
> > +     }
> > +
> > +/*   return rc;
> > + * }
> > + */
> > diff --git a/ports/linux/portdefs.h b/ports/linux/portdefs.h
> > index 1f1a41a..565fed9 100644
> > --- a/ports/linux/portdefs.h
> > +++ b/ports/linux/portdefs.h
> > @@ -82,3 +82,12 @@ extern int unshare(int flags);
> >
> >  #define SYS_openat2 __NR_openat2
> >  #endif
> > +
> > +#ifndef SYS_open_tree
> > +
> > +#ifndef __NR_open_tree
> > +#define __NR_open_tree 428
> > +#endif
> > +
> > +#define SYS_open_tree __NR_open_tree
> > +#endif
> > diff --git a/ports/linux/wrapfuncs.in b/ports/linux/wrapfuncs.in
> > index 3cea20a..a51e9a0 100644
> > --- a/ports/linux/wrapfuncs.in
> > +++ b/ports/linux/wrapfuncs.in
> > @@ -10,6 +10,7 @@ int lchown(const char *path, uid_t owner, gid_t
> group); /* flags=AT_SYMLINK_NOFO
> >  int __fxstatat(int ver, int dirfd, const char *path, struct stat *buf,
> int flags);
> >  int openat(int dirfd, const char *path, int flags, ...{mode_t mode});
> /*
> flags=((flags&O_NOFOLLOW)||((flags&(O_CREAT|O_EXCL))==(O_CREAT|O_EXCL))),
> noignore_path=1 */
> >  int __openat_2(int dirfd, const char *path, int flags); /*
> flags=((flags&O_NOFOLLOW)||((flags&(O_CREAT|O_EXCL))==(O_CREAT|O_EXCL))),
> noignore_path=1 */
> > +int open_tree(int dirfd, const char *path, unsigned int flags); /*
> noignore_path=1 */
>
> Does this need preserve_paths=1 (similar to openat2())?
>
> That would require us to account for a possible chroot in the
> open_tree() guts, but it would avoid us running pseudo_root_path() on an
> already canonicalized path which may introduce problems under a chroot.
>
> >  int mknod(const char *path, mode_t mode, dev_t dev); /*
> real_func=pseudo_mknod */
> >  int mknodat(int dirfd, const char *path, mode_t mode, dev_t dev); /*
> real_func=pseudo_mknodat */
> >  int __xmknod(int ver, const char *path, mode_t mode, dev_t *dev); /*
> flags=AT_SYMLINK_NOFOLLOW */
> >
>
> --
> Paul Barker
>
>

[-- Attachment #2: Type: text/html, Size: 7236 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [pseudo] [PATCH v3 1/6] ports/linux/guts: Add open_tree wrapper
  2026-09-21 11:12     ` Dmitry Sakhonchik
@ 2026-10-02 12:15       ` Paul Barker
  0 siblings, 0 replies; 14+ messages in thread
From: Paul Barker @ 2026-10-02 12:15 UTC (permalink / raw)
  To: Dmitry Sakhonchik; +Cc: yocto-patches

Hi Dmitry,

Apologies for the slow replies here, we're all busy and pseudo is
under-maintained.

On Mon, 2026-09-21 at 14:12 +0300, Dmitry Sakhonchik wrote:
> пн, 21 сент. 2026 г. в 12:28, Paul Barker <paul@pbarker.dev>:
> 
> > On Mon, 2026-09-07 at 14:18 +0300, frezidok1@gmail.com wrote:
> > > From: Dmitry Sakhonchik <frezidok1@gmail.com>
> > > 
> > > [YOCTO #16379]
> > > 
> > > OPEN_TREE_CLONE is not handled since it requires CAP_SYS_ADMIN and is
> > outside the common pseudo use case.
> > 
> > We should at least log an error if OPEN_TREE_CLONE is seen instead of
> > silently ignoring it.
> > 
> > > 
> > > Signed-off-by: Dmitry Sakhonchik <frezidok1@gmail.com>
> > > ---
> > >  ports/linux/guts/open_tree.c | 46 ++++++++++++++++++++++++++++++++++++
> > >  ports/linux/portdefs.h       |  9 +++++++
> > >  ports/linux/wrapfuncs.in     |  1 +
> > >  3 files changed, 56 insertions(+)
> > >  create mode 100644 ports/linux/guts/open_tree.c
> > > 
> > > diff --git a/ports/linux/guts/open_tree.c b/ports/linux/guts/open_tree.c
> > > new file mode 100644
> > > index 0000000..6c2aad9
> > > --- /dev/null
> > > +++ b/ports/linux/guts/open_tree.c
> > > @@ -0,0 +1,46 @@
> > > +/*
> > > + * Copyright (c) 2026 Yocto Project
> > > + * guts/COPYRIGHT for information.
> > > + *
> > > + * SPDX-License-Identifier: LGPL-2.1-only
> > > + *
> > > + * int open_tree(int dirfd, const char *path, unsigned int flags)
> > > + *   int rc = -1;
> > > + */
> > > +
> > > +     struct stat64 buf;
> > > +     int save_errno;
> > > +     char *pseudo_path;
> > > +
> > > +     if (real_open_tree) {
> > > +             pseudo_debug(PDBGF_SYSCALL, "open_tree, calling
> > open_tree.\n");
> > > +             rc = real_open_tree(dirfd, path, flags);
> > > +     } else {
> > > +             pseudo_debug(PDBGF_SYSCALL, "open_tree, calling
> > syscall.\n");
> > > +             rc = real_syscall(SYS_open_tree, dirfd, path, flags);
> > > +     }
> > 
> > The commit message or a comment should briefly explain why we need to
> > handle both ways of invoking the real open_tree syscall.
> > 
> > > +
> > > +     pseudo_path = pseudo_root_path(__func__, __LINE__, dirfd, path, 0);
> > 
> > This should be after the (rc != -1) conditional, as this call could
> > clobber errno.
> > 
> > If we use preserve_path=1, then the absolute path must go through
> pseudo_root_path before the real open_tree call so that a possible chroot
> is handled correctly.
> So I think these two cases need to be somehow handled separately rather
> than moving pseudo_root_path() entirely below the rc != -1 check.
> By the way, for some reason the openat2 wrapper is ok with the
> pseudo_root_path outside of conditional.

The problem is that the real open_tree() call could set errno if it
fails, and calling pseudo_root_path() after this before returning the
error could overwrite errno. It is safe to call pseudo_root_path()
before calling the real open_tree(), or to only call it if the real
open_tree() call succeeds.

Best regards,

-- 
Paul Barker



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [pseudo] [PATCH v3 2/6] test: Add open_tree test
  2026-09-21  9:38     ` Dmitry Sakhonchik
@ 2026-10-02 12:16       ` Paul Barker
  0 siblings, 0 replies; 14+ messages in thread
From: Paul Barker @ 2026-10-02 12:16 UTC (permalink / raw)
  To: Dmitry Sakhonchik; +Cc: yocto-patches

On Mon, 2026-09-21 at 12:38 +0300, Dmitry Sakhonchik wrote:
> пн, 21 сент. 2026 г. в 12:09, Paul Barker <paul@pbarker.dev>:
> 
> > On Mon, 2026-09-07 at 14:18 +0300, frezidok1@gmail.com wrote:
> > > From: Dmitry Sakhonchik <frezidok1@gmail.com>
> > > 
> > > [YOCTO #16379]
> > > 
> > > Covers basic open_tree wrapper functionality and the AT_EMPTY_PATH case.
> > > 
> > > Signed-off-by: Dmitry Sakhonchik <frezidok1@gmail.com>
> > > ---
> > >  test/test-open_tree.c  | 139 +++++++++++++++++++++++++++++++++++++++++
> > >  test/test-open_tree.sh |   5 ++
> > >  2 files changed, 144 insertions(+)
> > >  create mode 100644 test/test-open_tree.c
> > >  create mode 100755 test/test-open_tree.sh
> > > 
> > > diff --git a/test/test-open_tree.c b/test/test-open_tree.c
> > > new file mode 100644
> > > index 0000000..0fc02f4
> > > --- /dev/null
> > > +++ b/test/test-open_tree.c
> > > @@ -0,0 +1,139 @@
> > > +#define _GNU_SOURCE
> > > +
> > > +#include <errno.h>
> > > +#include <fcntl.h>
> > > +#include <stdio.h>
> > > +#include <unistd.h>
> > > +#include <sys/stat.h>
> > > +#include <sys/mount.h>
> > > +
> > > +#define TEST_DIR "test-open-tree-dir"
> > > +#define TEST_FILE "test-open-tree-file"
> > > +
> > > +static int test_no_flags(void) {
> > > +    int treefd = -1;
> > > +    int fd = -1;
> > > +    int rc = 1;
> > > +
> > > +    treefd = open_tree(AT_FDCWD, TEST_DIR, 0);
> > > +    if (treefd == -1) {
> > > +        perror("open_tree");
> > > +        goto out;
> > > +    }
> > > +
> > > +    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
> > > +    if (fd < 0) {
> > > +        perror("openat");
> > > +        goto out;
> > > +    }
> > > +
> > > +    rc = 0;
> > > +out:
> > > +    if (treefd != -1) {
> > > +        close(treefd);
> > > +    }
> > > +    if (fd != -1) {
> > > +        close(fd);
> > > +    }
> > > +    return rc;
> > > +}
> > > +
> > > +static int test_relative_dirfd(void) {
> > > +    int basefd = -1;
> > > +    int treefd = -1;
> > > +    int fd = -1;
> > > +    int rc = 1;
> > > +
> > > +    basefd = open(".", O_PATH | O_DIRECTORY);
> > > +    if (basefd < 0) {
> > > +        perror("open");
> > > +        goto out;
> > > +    }
> > > +
> > > +    treefd = open_tree(basefd, TEST_DIR, 0);
> > > +    if (treefd < 0) {
> > > +        perror("open_tree");
> > > +        goto out;
> > > +    }
> > > +
> > > +    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
> > > +    if (fd < 0) {
> > > +        perror("openat");
> > > +        goto out;
> > > +    }
> > > +
> > > +    rc = 0;
> > > +out:
> > > +    if (basefd != -1) {
> > > +        close(basefd);
> > > +    }
> > > +    if (treefd != -1) {
> > > +        close(treefd);
> > > +    }
> > > +    if (fd != -1) {
> > > +        close(fd);
> > > +    }
> > > +    return rc;
> > > +}
> > > +
> > > +static int test_at_empty_path(void) {
> > > +    int treefd = -1;
> > > +    int dirfd = -1;
> > > +    int fd = -1;
> > > +    int rc = 1;
> > > +
> > > +    dirfd = open(TEST_DIR, O_PATH | O_DIRECTORY);
> > > +    if (dirfd < 0) {
> > > +        perror("open");
> > > +        goto out;
> > > +    }
> > > +
> > > +    treefd = open_tree(dirfd, "", AT_EMPTY_PATH);
> > > +    if (treefd == -1) {
> > > +        perror("open_tree");
> > > +        goto out;
> > > +    }
> > > +
> > > +    fd = openat(treefd, TEST_FILE, O_CREAT | O_RDWR, 0666);
> > > +    if (fd < 0) {
> > > +        perror("openat");
> > > +        goto out;
> > > +    }
> > > +
> > > +    rc = 0;
> > > +out:
> > > +    if (dirfd != -1) {
> > > +        close(dirfd);
> > > +    }
> > > +    if (treefd != -1) {
> > > +        close(treefd);
> > > +    }
> > > +    if (fd != -1) {
> > > +        close(fd);
> > > +    }
> > > +    return rc;
> > > +}
> > > +
> > > +static void cleanup(void) {
> > > +    if (unlink(TEST_DIR "/" TEST_FILE) == -1 && errno != ENOENT) {
> > > +        perror("unlink");
> > > +    }
> > > +    if (rmdir(TEST_DIR) == -1 && errno != ENOENT) {
> > > +        perror("rmdir");
> > > +    }
> > > +}
> > > +
> > > +int main(void) {
> > > +    cleanup();
> > > +
> > > +    if (mkdir(TEST_DIR, 0777) == -1) {
> > > +        perror("mkdir");
> > > +        return 1;
> > > +    }
> > > +
> > > +    int rc = test_no_flags() || test_at_empty_path() ||
> > test_relative_dirfd();
> > 
> > This will short-circuit on the first failing test. We should run all
> > test cases and accumulate the pass/fail results.
> > 
> > > +
> > > +    cleanup();
> > 
> > Do we need to run cleanup() between test cases? Or at least cleanup
> > TEST_FILE between test cases?
> > 
> 
> I don't think so. In every test case we always open TEST_DIR with open_tree
> and then openat(TEST_FILE) with O_CREAT.
> So I think removing this file is not necessary.

Ok. I'm happy this isn't needed.

Best regards,

-- 
Paul Barker



^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-10-06  7:27 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-07 11:18 [pseudo] [PATCH v3 0/6] Add open_tree() wrapper frezidok1
2026-09-07 11:18 ` [pseudo] [PATCH v3 1/6] ports/linux/guts: Add open_tree wrapper frezidok1
2026-09-21  9:28   ` Paul Barker
2026-09-21 11:12     ` Dmitry Sakhonchik
2026-10-02 12:15       ` Paul Barker
2026-09-07 11:18 ` [pseudo] [PATCH v3 2/6] test: Add open_tree test frezidok1
2026-09-21  9:09   ` Paul Barker
2026-09-21  9:38     ` Dmitry Sakhonchik
2026-10-02 12:16       ` Paul Barker
2026-09-07 11:18 ` [pseudo] [PATCH v3 3/6] ports/linux/pseudo_wrappers.c: Add syscall support for open_tree() wrapper frezidok1
2026-09-21  9:10   ` Paul Barker
2026-09-07 11:18 ` [pseudo] [PATCH v3 4/6] test: Add open_tree syscall test frezidok1
2026-09-07 11:18 ` [pseudo] [PATCH v3 5/6] test: Add open_tree_attr " frezidok1
2026-09-07 11:18 ` [pseudo] [PATCH v3 6/6] ports/linux/guts: Add open_tree_attr wrapper frezidok1

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.