There is an issue in pseudo where if you open a file, rename the file, then call fstat on the open fd, pseudo would thrown an abort. This is because it needs to track the open fd mappings to files and it doesn't update in the case of a rename.
Add code in pseudo to update the fd mappings in the case of a rename call. Also add a test case. Signed-off-by: Richard Purdie <richard.pur...@linuxfoundation.org> --- Makefile.in | 1 + pseudo_client.c | 20 +++++++++++++++++++- test/test-rename-fstat.c | 21 +++++++++++++++++++++ test/test-rename-fstat.sh | 9 +++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 test/test-rename-fstat.c create mode 100755 test/test-rename-fstat.sh diff --git a/Makefile.in b/Makefile.in index d1f77d5..6eff522 100644 --- a/Makefile.in +++ b/Makefile.in @@ -75,6 +75,7 @@ TABLES=table_templates/pseudo_tables.c table_templates/pseudo_tables.h all: $(LIBPSEUDO) $(PSEUDO) $(PSEUDODB) $(PSEUDOLOG) $(PSEUDO_PROFILE) test: all | $(BIN) $(LIB) $(LOCALSTATE) + $(CC) $(CFLAGS) $(CFLAGS_PSEUDO) -o test/test-rename-fstat test/test-rename-fstat.c @./run_tests.sh -v install-lib: $(LIBPSEUDO) diff --git a/pseudo_client.c b/pseudo_client.c index f5cab7e..f846d54 100644 --- a/pseudo_client.c +++ b/pseudo_client.c @@ -943,6 +943,21 @@ pseudo_client_linked_paths(const char *oldpath, const char *newpath) { } } +static void +pseudo_client_rename_path(const char *oldpath, const char *newpath) { + int fd; + for (fd = 3; fd < nfds; ++fd) { + if (fd_paths[fd] && !strcmp(oldpath, fd_paths[fd])) { + pseudo_client_path(fd, newpath); + } + } + for (fd = 0; fd < linked_nfds; ++fd) { + if (linked_fd_paths[fd] && fd_paths[fd] && !strcmp(oldpath, linked_fd_paths[fd])) { + pseudo_client_path_set(fd, newpath, &linked_fd_paths, &linked_nfds); + } + } +} + static void pseudo_client_unlinked_path(const char *path) { int fd; @@ -1939,7 +1954,6 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path case OP_FCHOWN: case OP_FSTAT: case OP_LINK: - case OP_RENAME: case OP_STAT: case OP_CANCEL_UNLINK: case OP_MAY_UNLINK: @@ -1949,6 +1963,10 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path case OP_REMOVE_XATTR: do_request = 1; break; + case OP_RENAME: + pseudo_client_rename_path(path_extra_1, path); + do_request = 1; + break; default: pseudo_diag("error: unknown or unimplemented operator %d (%s)", op, pseudo_op_name(op)); break; diff --git a/test/test-rename-fstat.c b/test/test-rename-fstat.c new file mode 100644 index 0000000..ef1daf7 --- /dev/null +++ b/test/test-rename-fstat.c @@ -0,0 +1,21 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-only + * + * Test we can rename a file whilst holding an open fd which we fstat after renaming + */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +int main() +{ + struct stat buf; + int fd = open("test-rename-fstat1", O_RDONLY); + rename("test-rename-fstat1", "test-rename-fstat1"); + fstat(fd, &buf); + return 0; +} diff --git a/test/test-rename-fstat.sh b/test/test-rename-fstat.sh new file mode 100755 index 0000000..93b3d8a --- /dev/null +++ b/test/test-rename-fstat.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# +# SPDX-License-Identifier: LGPL-2.1-only +# + +rm -f test-rename-fstat1 test-rename-fstat2 +# Will abort if it fails +./test/test-rename-fstat +exit $? -- 2.27.0
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#147410): https://lists.openembedded.org/g/openembedded-core/message/147410 Mute This Topic: https://lists.openembedded.org/mt/80194815/21656 Group Owner: openembedded-core+ow...@lists.openembedded.org Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-