* [PULL 0/7] 9p queue 2025-02-06
@ 2025-02-06 16:41 Christian Schoenebeck
2025-02-06 16:41 ` [PULL 6/7] tests/9p: extend use_dir_after_unlink test with Treaddir Christian Schoenebeck
` (7 more replies)
0 siblings, 8 replies; 10+ messages in thread
From: Christian Schoenebeck @ 2025-02-06 16:41 UTC (permalink / raw)
To: qemu-devel, Peter Maydell; +Cc: Greg Kurz, Stefan Hajnoczi
The following changes since commit d922088eb4ba6bc31a99f17b32cf75e59dd306cd:
Merge tag 'ui-pull-request' of https://gitlab.com/marcandre.lureau/qemu into staging (2025-02-03 13:42:02 -0500)
are available in the Git repository at:
https://github.com/cschoenebeck/qemu.git tags/pull-9p-20250206
for you to fetch changes up to bfa7bf02782dbd996201c90f850ca11730041af1:
MAINTAINERS: Mark me as reviewer only for 9pfs (2025-02-06 17:10:46 +0100)
----------------------------------------------------------------
* Greg Kurz steps back as maintainer of 9pfs.
* Make multidevs=remap default option (instead of multidevs=warn)
and update documentation related to this option.
* Improve tracing (i.e. usefulness of log output content).
* Add test cases for accessing a directory after removal.
----------------------------------------------------------------
Christian Schoenebeck (6):
9pfs: improve v9fs_walk() tracing
9pfs: make multidevs=remap default
9pfs: improve v9fs_open() tracing
tests/9p: rename test use_after_unlink -> use_file_after_unlink
tests/9p: add use_dir_after_unlink test
tests/9p: extend use_dir_after_unlink test with Treaddir
Greg Kurz (1):
MAINTAINERS: Mark me as reviewer only for 9pfs
MAINTAINERS | 3 +--
hw/9pfs/9p-local.c | 3 +++
hw/9pfs/9p-util-generic.c | 50 ++++++++++++++++++++++++++++++++++++++++++++
hw/9pfs/9p-util.h | 6 ++++++
hw/9pfs/9p.c | 45 +++++++++++++++++++++++++++++++++------
hw/9pfs/meson.build | 1 +
hw/9pfs/trace-events | 4 ++--
qemu-options.hx | 49 ++++++++++++++++++++++++-------------------
tests/qtest/virtio-9p-test.c | 50 ++++++++++++++++++++++++++++++++++++++++----
9 files changed, 175 insertions(+), 36 deletions(-)
create mode 100644 hw/9pfs/9p-util-generic.c
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PULL 3/7] 9pfs: improve v9fs_open() tracing
2025-02-06 16:41 [PULL 0/7] 9p queue 2025-02-06 Christian Schoenebeck
` (4 preceding siblings ...)
2025-02-06 16:41 ` [PULL 4/7] tests/9p: rename test use_after_unlink -> use_file_after_unlink Christian Schoenebeck
@ 2025-02-06 16:41 ` Christian Schoenebeck
2025-02-06 16:41 ` [PULL 2/7] 9pfs: make multidevs=remap default Christian Schoenebeck
2025-02-06 18:49 ` [PULL 0/7] 9p queue 2025-02-06 Stefan Hajnoczi
7 siblings, 0 replies; 10+ messages in thread
From: Christian Schoenebeck @ 2025-02-06 16:41 UTC (permalink / raw)
To: qemu-devel, Peter Maydell; +Cc: Greg Kurz, Stefan Hajnoczi
Improve tracing of 9p 'Topen' request type by showing open() flags as
human-readable text.
E.g. trace output:
v9fs_open tag 0 id 12 fid 2 mode 100352
would become:
v9fs_open tag=0 id=12 fid=2 mode=100352(RDONLY|NONBLOCK|DIRECTORY|
TMPFILE|NDELAY)
Therefor add a new utility function qemu_open_flags_tostr() that converts
numeric open() flags from host's native O_* flag constants to a string
presentation.
9p2000.L and 9p2000.u protocol variants use different numeric 'mode'
constants for 'Topen' requests. Instead of writing string conversion code
for both protocol variants, use the already existing conversion functions
that convert the mode flags from respective protocol constants to host's
native open() numeric flag constants and pass that result to the new
string conversion function qemu_open_flags_tostr().
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Message-Id: <E1tTgDR-000oRr-9g@kylie.crudebyte.com>
---
hw/9pfs/9p-util-generic.c | 50 +++++++++++++++++++++++++++++++++++++++
hw/9pfs/9p-util.h | 6 +++++
hw/9pfs/9p.c | 9 ++++++-
hw/9pfs/meson.build | 1 +
hw/9pfs/trace-events | 2 +-
5 files changed, 66 insertions(+), 2 deletions(-)
create mode 100644 hw/9pfs/9p-util-generic.c
diff --git a/hw/9pfs/9p-util-generic.c b/hw/9pfs/9p-util-generic.c
new file mode 100644
index 0000000000..4c1e9c887d
--- /dev/null
+++ b/hw/9pfs/9p-util-generic.c
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "9p-util.h"
+#include <glib/gstrfuncs.h>
+
+char *qemu_open_flags_tostr(int flags)
+{
+ int acc = flags & O_ACCMODE;
+ return g_strconcat(
+ (acc == O_WRONLY) ? "WRONLY" : (acc == O_RDONLY) ? "RDONLY" : "RDWR",
+ (flags & O_CREAT) ? "|CREAT" : "",
+ (flags & O_EXCL) ? "|EXCL" : "",
+ (flags & O_NOCTTY) ? "|NOCTTY" : "",
+ (flags & O_TRUNC) ? "|TRUNC" : "",
+ (flags & O_APPEND) ? "|APPEND" : "",
+ (flags & O_NONBLOCK) ? "|NONBLOCK" : "",
+ (flags & O_DSYNC) ? "|DSYNC" : "",
+ #ifdef O_DIRECT
+ (flags & O_DIRECT) ? "|DIRECT" : "",
+ #endif
+ (flags & O_LARGEFILE) ? "|LARGEFILE" : "",
+ (flags & O_DIRECTORY) ? "|DIRECTORY" : "",
+ (flags & O_NOFOLLOW) ? "|NOFOLLOW" : "",
+ #ifdef O_NOATIME
+ (flags & O_NOATIME) ? "|NOATIME" : "",
+ #endif
+ #ifdef O_CLOEXEC
+ (flags & O_CLOEXEC) ? "|CLOEXEC" : "",
+ #endif
+ #ifdef __O_SYNC
+ (flags & __O_SYNC) ? "|SYNC" : "",
+ #else
+ ((flags & O_SYNC) == O_SYNC) ? "|SYNC" : "",
+ #endif
+ #ifdef O_PATH
+ (flags & O_PATH) ? "|PATH" : "",
+ #endif
+ #ifdef __O_TMPFILE
+ (flags & __O_TMPFILE) ? "|TMPFILE" : "",
+ #elif defined(O_TMPFILE)
+ ((flags & O_TMPFILE) == O_TMPFILE) ? "|TMPFILE" : "",
+ #endif
+ /* O_NDELAY is usually just an alias of O_NONBLOCK */
+ #if defined(O_NDELAY) && O_NDELAY != O_NONBLOCK
+ (flags & O_NDELAY) ? "|NDELAY" : "",
+ #endif
+ NULL /* always last (required NULL termination) */
+ );
+}
diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h
index 95ee4da9bd..7bc4ec8e85 100644
--- a/hw/9pfs/9p-util.h
+++ b/hw/9pfs/9p-util.h
@@ -267,4 +267,10 @@ int pthread_fchdir_np(int fd) __attribute__((weak_import));
#endif
int qemu_mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev);
+/*
+ * Returns a newly allocated string presentation of open() flags, intended
+ * for debugging (tracing) purposes only.
+ */
+char *qemu_open_flags_tostr(int flags);
+
#endif
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index 6f24c1abb3..7cad2bce62 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -2008,6 +2008,7 @@ static void coroutine_fn v9fs_open(void *opaque)
V9fsFidState *fidp;
V9fsPDU *pdu = opaque;
V9fsState *s = pdu->s;
+ g_autofree char *trace_oflags = NULL;
if (s->proto_version == V9FS_PROTO_2000L) {
err = pdu_unmarshal(pdu, offset, "dd", &fid, &mode);
@@ -2019,7 +2020,13 @@ static void coroutine_fn v9fs_open(void *opaque)
if (err < 0) {
goto out_nofid;
}
- trace_v9fs_open(pdu->tag, pdu->id, fid, mode);
+ if (trace_event_get_state_backends(TRACE_V9FS_OPEN)) {
+ trace_oflags = qemu_open_flags_tostr(
+ (s->proto_version == V9FS_PROTO_2000L) ?
+ dotl_to_open_flags(mode) : omode_to_uflags(mode)
+ );
+ trace_v9fs_open(pdu->tag, pdu->id, fid, mode, trace_oflags);
+ }
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
diff --git a/hw/9pfs/meson.build b/hw/9pfs/meson.build
index eceffdb81e..d35d4f44ff 100644
--- a/hw/9pfs/meson.build
+++ b/hw/9pfs/meson.build
@@ -3,6 +3,7 @@ fs_ss.add(files(
'9p-local.c',
'9p-posix-acl.c',
'9p-synth.c',
+ '9p-util-generic.c',
'9p-xattr-user.c',
'9p-xattr.c',
'9p.c',
diff --git a/hw/9pfs/trace-events b/hw/9pfs/trace-events
index ed9f4e7209..0e0fc37261 100644
--- a/hw/9pfs/trace-events
+++ b/hw/9pfs/trace-events
@@ -13,7 +13,7 @@ v9fs_getattr(uint16_t tag, uint8_t id, int32_t fid, uint64_t request_mask) "tag
v9fs_getattr_return(uint16_t tag, uint8_t id, uint64_t result_mask, uint32_t mode, uint32_t uid, uint32_t gid) "tag %d id %d getattr={result_mask %"PRId64" mode %u uid %u gid %u}"
v9fs_walk(uint16_t tag, uint8_t id, int32_t fid, int32_t newfid, uint16_t nwnames, const char* wnames) "tag=%d id=%d fid=%d newfid=%d nwnames=%d wnames={%s}"
v9fs_walk_return(uint16_t tag, uint8_t id, uint16_t nwnames, void* qids) "tag %d id %d nwnames %d qids %p"
-v9fs_open(uint16_t tag, uint8_t id, int32_t fid, int32_t mode) "tag %d id %d fid %d mode %d"
+v9fs_open(uint16_t tag, uint8_t id, int32_t fid, int32_t mode, const char* oflags) "tag=%d id=%d fid=%d mode=%d(%s)"
v9fs_open_return(uint16_t tag, uint8_t id, uint8_t type, uint32_t version, uint64_t path, int iounit) "tag %u id %u qid={type %u version %u path %"PRIu64"} iounit %d"
v9fs_lcreate(uint16_t tag, uint8_t id, int32_t dfid, int32_t flags, int32_t mode, uint32_t gid) "tag %d id %d dfid %d flags %d mode %d gid %u"
v9fs_lcreate_return(uint16_t tag, uint8_t id, uint8_t type, uint32_t version, uint64_t path, int32_t iounit) "tag %u id %u qid={type %u version %u path %"PRIu64"} iounit %d"
--
2.30.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PULL 5/7] tests/9p: add use_dir_after_unlink test
2025-02-06 16:41 [PULL 0/7] 9p queue 2025-02-06 Christian Schoenebeck
` (2 preceding siblings ...)
2025-02-06 16:41 ` [PULL 1/7] 9pfs: improve v9fs_walk() tracing Christian Schoenebeck
@ 2025-02-06 16:41 ` Christian Schoenebeck
2025-02-06 16:41 ` [PULL 4/7] tests/9p: rename test use_after_unlink -> use_file_after_unlink Christian Schoenebeck
` (3 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Christian Schoenebeck @ 2025-02-06 16:41 UTC (permalink / raw)
To: qemu-devel, Peter Maydell; +Cc: Greg Kurz, Stefan Hajnoczi
After removing a directory from the filesystem, it should still be
possible to operate on the directory if the directory has been opened
before.
As a first step this new test will verify whether Tgetattr request
works on the unlinked directory.
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Message-Id: <0a9b3419356731e34b1be4a8577d6b416379d085.1736427878.git.qemu_oss@crudebyte.com>
---
tests/qtest/virtio-9p-test.c | 39 ++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c
index 07459c5289..35c42cd0d7 100644
--- a/tests/qtest/virtio-9p-test.c
+++ b/tests/qtest/virtio-9p-test.c
@@ -737,6 +737,43 @@ static void fs_use_file_after_unlink(void *obj, void *data,
g_assert_cmpint(count, ==, write_count);
}
+static void fs_use_dir_after_unlink(void *obj, void *data,
+ QGuestAllocator *t_alloc)
+{
+ QVirtio9P *v9p = obj;
+ v9fs_set_allocator(t_alloc);
+ g_autofree char *real_dir = virtio_9p_test_path("10/doa_dir");
+ struct stat st_dir;
+ struct v9fs_attr attr;
+ uint32_t fid_dir;
+
+ tattach({ .client = v9p });
+
+ /* create a dir "10/doa_dir" and make sure it exists */
+ tmkdir({ .client = v9p, .atPath = "/", .name = "10" });
+ tmkdir({ .client = v9p, .atPath = "10", .name = "doa_dir" });
+ g_assert(stat(real_dir, &st_dir) == 0);
+ g_assert((st_dir.st_mode & S_IFMT) == S_IFDIR);
+
+ /* request a FID for that directory that we can work with next */
+ fid_dir = twalk({
+ .client = v9p, .fid = 0, .path = "10/doa_dir"
+ }).newfid;
+ g_assert(fid_dir != 0);
+
+ /* now first open the dir before ... */
+ tlopen({ .client = v9p, .fid = fid_dir, .flags = O_RDONLY });
+ /* ... removing the dir from file system */
+ tunlinkat({ .client = v9p, .atPath = "10", .name = "doa_dir",
+ .flags = AT_REMOVEDIR });
+
+ /* dir is removed, but we still have it open, so this should succeed */
+ tgetattr({
+ .client = v9p, .fid = fid_dir, .request_mask = P9_GETATTR_BASIC,
+ .rgetattr.attr = &attr
+ });
+}
+
static void cleanup_9p_local_driver(void *data)
{
/* remove previously created test dir when test is completed */
@@ -804,6 +841,8 @@ static void register_virtio_9p_test(void)
&opts);
qos_add_test("local/use_file_after_unlink", "virtio-9p",
fs_use_file_after_unlink, &opts);
+ qos_add_test("local/use_dir_after_unlink", "virtio-9p",
+ fs_use_dir_after_unlink, &opts);
}
libqos_init(register_virtio_9p_test);
--
2.30.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PULL 2/7] 9pfs: make multidevs=remap default
2025-02-06 16:41 [PULL 0/7] 9p queue 2025-02-06 Christian Schoenebeck
` (5 preceding siblings ...)
2025-02-06 16:41 ` [PULL 3/7] 9pfs: improve v9fs_open() tracing Christian Schoenebeck
@ 2025-02-06 16:41 ` Christian Schoenebeck
2025-02-06 18:49 ` [PULL 0/7] 9p queue 2025-02-06 Stefan Hajnoczi
7 siblings, 0 replies; 10+ messages in thread
From: Christian Schoenebeck @ 2025-02-06 16:41 UTC (permalink / raw)
To: qemu-devel, Peter Maydell; +Cc: Greg Kurz, Stefan Hajnoczi
1a6ed33cc5 introduced option multidevs=remap|forbid|warn and made
"warn" the default option.
As it turned out though, e.g. by several reports in conjunction with
following 9p client issue:
https://github.com/torvalds/linux/commit/850925a8133c73c4a2453c360b2c3beb3bab67c9
Many people are just ignoring this warning, or even do not notice the
warning at all. Therefore make multidevs=remap the new default option to
prevent people to run into such kind of severe misbehaviours in the first
place.
From performance PoV the runtime overhead of multidevs=remap is
neglectable with few or even just only one device being shared with the
same 9p export, expected to be constant Theta(1). The inode numbers
emitted to guest also just loose one bit (since 6b6aa8285d) for the 1st
device being shared.
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Message-Id: <09cc84e5561f66b6a8cf49b3532c6c78a6acc806.1734876877.git.qemu_oss@crudebyte.com>
---
hw/9pfs/9p-local.c | 3 +++
qemu-options.hx | 49 +++++++++++++++++++++++++---------------------
2 files changed, 30 insertions(+), 22 deletions(-)
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index 1b1f3b9ec8..928523afcc 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -1538,6 +1538,9 @@ static int local_parse_opts(QemuOpts *opts, FsDriverEntry *fse, Error **errp)
"[remap|forbid|warn]\n");
return -1;
}
+ } else {
+ fse->export_flags &= ~V9FS_FORBID_MULTIDEVS;
+ fse->export_flags |= V9FS_REMAP_INODES;
}
if (!path) {
diff --git a/qemu-options.hx b/qemu-options.hx
index ec0090dfe2..1b26ad53bd 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1951,32 +1951,37 @@ SRST
Specifies the tag name to be used by the guest to mount this
export point.
- ``multidevs=multidevs``
- Specifies how to deal with multiple devices being shared with a
- 9p export. Supported behaviours are either "remap", "forbid" or
- "warn". The latter is the default behaviour on which virtfs 9p
- expects only one device to be shared with the same export, and
- if more than one device is shared and accessed via the same 9p
- export then only a warning message is logged (once) by qemu on
- host side. In order to avoid file ID collisions on guest you
- should either create a separate virtfs export for each device to
- be shared with guests (recommended way) or you might use "remap"
- instead which allows you to share multiple devices with only one
- export instead, which is achieved by remapping the original
- inode numbers from host to guest in a way that would prevent
- such collisions. Remapping inodes in such use cases is required
+ ``multidevs=remap|forbid|warn``
+ Specifies how to deal with multiple devices being shared with
+ the same 9p export in order to avoid file ID collisions on guest.
+ Supported behaviours are either "remap" (default), "forbid" or
+ "warn".
+
+ ``remap`` : assumes the possibility that more than one device is
+ shared with the same 9p export. Therefore inode numbers from host
+ are remapped for guest in a way that would prevent file ID
+ collisions on guest. Remapping inodes in such cases is required
because the original device IDs from host are never passed and
exposed on guest. Instead all files of an export shared with
- virtfs always share the same device id on guest. So two files
+ virtfs always share the same device ID on guest. So two files
with identical inode numbers but from actually different devices
on host would otherwise cause a file ID collision and hence
- potential misbehaviours on guest. "forbid" on the other hand
- assumes like "warn" that only one device is shared by the same
- export, however it will not only log a warning message but also
- deny access to additional devices on guest. Note though that
- "forbid" does currently not block all possible file access
- operations (e.g. readdir() would still return entries from other
- devices).
+ potential severe misbehaviours on guest.
+
+ ``warn`` : virtfs 9p expects only one device to be shared with
+ the same export. If however more than one device is shared and
+ accessed via the same 9p export then only a warning message is
+ logged (once) by qemu on host side. No further action is performed
+ in this case that would prevent file ID collisions on guest. This
+ could thus lead to severe misbehaviours in this case like wrong
+ files being accessed and data corruption on the exported tree.
+
+ ``forbid`` : assumes like "warn" that only one device is shared
+ by the same 9p export, however it will not only log a warning
+ message but also deny access to additional devices on guest. Note
+ though that "forbid" does currently not block all possible file
+ access operations (e.g. readdir() would still return entries from
+ other devices).
ERST
DEF("iscsi", HAS_ARG, QEMU_OPTION_iscsi,
--
2.30.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PULL 4/7] tests/9p: rename test use_after_unlink -> use_file_after_unlink
2025-02-06 16:41 [PULL 0/7] 9p queue 2025-02-06 Christian Schoenebeck
` (3 preceding siblings ...)
2025-02-06 16:41 ` [PULL 5/7] tests/9p: add use_dir_after_unlink test Christian Schoenebeck
@ 2025-02-06 16:41 ` Christian Schoenebeck
2025-02-06 16:41 ` [PULL 3/7] 9pfs: improve v9fs_open() tracing Christian Schoenebeck
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Christian Schoenebeck @ 2025-02-06 16:41 UTC (permalink / raw)
To: qemu-devel, Peter Maydell; +Cc: Greg Kurz, Stefan Hajnoczi
To pave the way for adding new test use_dir_after_unlink with subsequent
patch, i.e. making it clear that the existing test is just about unlinked
files, not unlinked directories.
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Message-Id: <9d2ca46a58b812ad17ca7bb8a84f12252d3e3832.1736427878.git.qemu_oss@crudebyte.com>
---
tests/qtest/virtio-9p-test.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c
index ab3a12c816..07459c5289 100644
--- a/tests/qtest/virtio-9p-test.c
+++ b/tests/qtest/virtio-9p-test.c
@@ -693,8 +693,8 @@ static void fs_unlinkat_hardlink(void *obj, void *data,
g_assert(stat(real_file, &st_real) == 0);
}
-static void fs_use_after_unlink(void *obj, void *data,
- QGuestAllocator *t_alloc)
+static void fs_use_file_after_unlink(void *obj, void *data,
+ QGuestAllocator *t_alloc)
{
QVirtio9P *v9p = obj;
v9fs_set_allocator(t_alloc);
@@ -802,8 +802,8 @@ static void register_virtio_9p_test(void)
qos_add_test("local/hardlink_file", "virtio-9p", fs_hardlink_file, &opts);
qos_add_test("local/unlinkat_hardlink", "virtio-9p", fs_unlinkat_hardlink,
&opts);
- qos_add_test("local/use_after_unlink", "virtio-9p", fs_use_after_unlink,
- &opts);
+ qos_add_test("local/use_file_after_unlink", "virtio-9p",
+ fs_use_file_after_unlink, &opts);
}
libqos_init(register_virtio_9p_test);
--
2.30.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PULL 7/7] MAINTAINERS: Mark me as reviewer only for 9pfs
2025-02-06 16:41 [PULL 0/7] 9p queue 2025-02-06 Christian Schoenebeck
2025-02-06 16:41 ` [PULL 6/7] tests/9p: extend use_dir_after_unlink test with Treaddir Christian Schoenebeck
@ 2025-02-06 16:41 ` Christian Schoenebeck
2025-02-06 16:41 ` [PULL 1/7] 9pfs: improve v9fs_walk() tracing Christian Schoenebeck
` (5 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Christian Schoenebeck @ 2025-02-06 16:41 UTC (permalink / raw)
To: qemu-devel, Peter Maydell; +Cc: Greg Kurz, Stefan Hajnoczi
From: Greg Kurz <groug@kaod.org>
I still review 9pfs changes from time to time but I'm definitely
not able to do actual maintainer work. Drop my tree on the way
as I'll obviously not use it anymore, and it has been left
untouched since May 2020.
Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Message-Id: <20250115100849.259612-1-groug@kaod.org>
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
---
MAINTAINERS | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 0cf37fce7b..c6859cbb0e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2254,8 +2254,8 @@ F: include/system/balloon.h
F: tests/qtest/virtio-balloon-test.c
virtio-9p
-M: Greg Kurz <groug@kaod.org>
M: Christian Schoenebeck <qemu_oss@crudebyte.com>
+R: Greg Kurz <groug@kaod.org>
S: Maintained
W: https://wiki.qemu.org/Documentation/9p
F: hw/9pfs/
@@ -2263,7 +2263,6 @@ X: hw/9pfs/xen-9p*
F: fsdev/
F: tests/qtest/virtio-9p-test.c
F: tests/qtest/libqos/virtio-9p*
-T: git https://gitlab.com/gkurz/qemu.git 9p-next
T: git https://github.com/cschoenebeck/qemu.git 9p.next
virtio-blk
--
2.30.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PULL 6/7] tests/9p: extend use_dir_after_unlink test with Treaddir
2025-02-06 16:41 [PULL 0/7] 9p queue 2025-02-06 Christian Schoenebeck
@ 2025-02-06 16:41 ` Christian Schoenebeck
2025-02-06 16:41 ` [PULL 7/7] MAINTAINERS: Mark me as reviewer only for 9pfs Christian Schoenebeck
` (6 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Christian Schoenebeck @ 2025-02-06 16:41 UTC (permalink / raw)
To: qemu-devel, Peter Maydell; +Cc: Greg Kurz, Stefan Hajnoczi
Sending a Treaddir request on an unlinked directory should also succeed
if the directory was alread opened before unlink. We just check that no
error occurs and that we get some kind of Treaddir result, but completely
ignore the actual Treaddir result content. In fact, there should be no
system as of to date that would allow a removed directory to have any
content (files, links, devices, subdirectories) and POSIX specifies that
a directory must be empty when trying to remove it from the file system.
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Message-Id: <f1b91e3a33a6502be816d88dfb6b719101b69d41.1736427878.git.qemu_oss@crudebyte.com>
---
tests/qtest/virtio-9p-test.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c
index 35c42cd0d7..10243247ab 100644
--- a/tests/qtest/virtio-9p-test.c
+++ b/tests/qtest/virtio-9p-test.c
@@ -772,6 +772,9 @@ static void fs_use_dir_after_unlink(void *obj, void *data,
.client = v9p, .fid = fid_dir, .request_mask = P9_GETATTR_BASIC,
.rgetattr.attr = &attr
});
+ treaddir({
+ .client = v9p, .fid = fid_dir, .offset = 0, .count = P9_MAX_SIZE - 11
+ });
}
static void cleanup_9p_local_driver(void *data)
--
2.30.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PULL 1/7] 9pfs: improve v9fs_walk() tracing
2025-02-06 16:41 [PULL 0/7] 9p queue 2025-02-06 Christian Schoenebeck
2025-02-06 16:41 ` [PULL 6/7] tests/9p: extend use_dir_after_unlink test with Treaddir Christian Schoenebeck
2025-02-06 16:41 ` [PULL 7/7] MAINTAINERS: Mark me as reviewer only for 9pfs Christian Schoenebeck
@ 2025-02-06 16:41 ` Christian Schoenebeck
2025-02-06 16:41 ` [PULL 5/7] tests/9p: add use_dir_after_unlink test Christian Schoenebeck
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Christian Schoenebeck @ 2025-02-06 16:41 UTC (permalink / raw)
To: qemu-devel, Peter Maydell; +Cc: Greg Kurz, Stefan Hajnoczi
'Twalk' is the most important request type in the 9p protocol to look out
for when debugging 9p communication. That's because it is the only part
of the 9p protocol which actually deals with human-readable path names,
whereas all other 9p request types work on numeric file IDs (FIDs) only.
Improve tracing of 'Twalk' requests, e.g. let's say client wanted to walk
to "/home/bob/src", then improve trace output from:
v9fs_walk tag 0 id 110 fid 0 newfid 1 nwnames 3
to:
v9fs_walk tag=0 id=110 fid=0 newfid=1 nwnames=3 wnames={home, bob, src}
To achieve this, add a new helper function trace_v9fs_walk_wnames() which
converts the received V9fsString array of individual path elements into a
comma-separated string presentation for being passed to the tracing system.
As this conversion is somewhat expensive, this conversion function is only
called if tracing of event 'v9fs_walk' is currently enabled.
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <E1tJamT-007Cqk-9E@kylie.crudebyte.com>
---
hw/9pfs/9p.c | 36 +++++++++++++++++++++++++++++++-----
hw/9pfs/trace-events | 2 +-
2 files changed, 32 insertions(+), 6 deletions(-)
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index 578517739a..6f24c1abb3 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -1774,6 +1774,21 @@ static bool same_stat_id(const struct stat *a, const struct stat *b)
return a->st_dev == b->st_dev && a->st_ino == b->st_ino;
}
+/*
+ * Returns a (newly allocated) comma-separated string presentation of the
+ * passed array for logging (tracing) purpose for trace event "v9fs_walk".
+ *
+ * It is caller's responsibility to free the returned string.
+ */
+static char *trace_v9fs_walk_wnames(V9fsString *wnames, size_t nwnames)
+{
+ g_autofree char **arr = g_malloc0_n(nwnames + 1, sizeof(char *));
+ for (size_t i = 0; i < nwnames; ++i) {
+ arr[i] = wnames[i].data;
+ }
+ return g_strjoinv(", ", arr);
+}
+
static void coroutine_fn v9fs_walk(void *opaque)
{
int name_idx, nwalked;
@@ -1787,6 +1802,7 @@ static void coroutine_fn v9fs_walk(void *opaque)
size_t offset = 7;
int32_t fid, newfid;
P9ARRAY_REF(V9fsString) wnames = NULL;
+ g_autofree char *trace_wnames = NULL;
V9fsFidState *fidp;
V9fsFidState *newfidp = NULL;
V9fsPDU *pdu = opaque;
@@ -1800,11 +1816,9 @@ static void coroutine_fn v9fs_walk(void *opaque)
}
offset += err;
- trace_v9fs_walk(pdu->tag, pdu->id, fid, newfid, nwnames);
-
if (nwnames > P9_MAXWELEM) {
err = -EINVAL;
- goto out_nofid;
+ goto out_nofid_nownames;
}
if (nwnames) {
P9ARRAY_NEW(V9fsString, wnames, nwnames);
@@ -1814,15 +1828,23 @@ static void coroutine_fn v9fs_walk(void *opaque)
for (i = 0; i < nwnames; i++) {
err = pdu_unmarshal(pdu, offset, "s", &wnames[i]);
if (err < 0) {
- goto out_nofid;
+ goto out_nofid_nownames;
}
if (name_is_illegal(wnames[i].data)) {
err = -ENOENT;
- goto out_nofid;
+ goto out_nofid_nownames;
}
offset += err;
}
+ if (trace_event_get_state_backends(TRACE_V9FS_WALK)) {
+ trace_wnames = trace_v9fs_walk_wnames(wnames, nwnames);
+ trace_v9fs_walk(pdu->tag, pdu->id, fid, newfid, nwnames,
+ trace_wnames);
+ }
+ } else {
+ trace_v9fs_walk(pdu->tag, pdu->id, fid, newfid, nwnames, "");
}
+
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
err = -ENOENT;
@@ -1957,7 +1979,11 @@ out:
}
v9fs_path_free(&dpath);
v9fs_path_free(&path);
+ goto out_pdu_complete;
+out_nofid_nownames:
+ trace_v9fs_walk(pdu->tag, pdu->id, fid, newfid, nwnames, "<?>");
out_nofid:
+out_pdu_complete:
pdu_complete(pdu, err);
}
diff --git a/hw/9pfs/trace-events b/hw/9pfs/trace-events
index a12e55c165..ed9f4e7209 100644
--- a/hw/9pfs/trace-events
+++ b/hw/9pfs/trace-events
@@ -11,7 +11,7 @@ v9fs_stat(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
v9fs_stat_return(uint16_t tag, uint8_t id, int32_t mode, int32_t atime, int32_t mtime, int64_t length) "tag %d id %d stat={mode %d atime %d mtime %d length %"PRId64"}"
v9fs_getattr(uint16_t tag, uint8_t id, int32_t fid, uint64_t request_mask) "tag %d id %d fid %d request_mask %"PRIu64
v9fs_getattr_return(uint16_t tag, uint8_t id, uint64_t result_mask, uint32_t mode, uint32_t uid, uint32_t gid) "tag %d id %d getattr={result_mask %"PRId64" mode %u uid %u gid %u}"
-v9fs_walk(uint16_t tag, uint8_t id, int32_t fid, int32_t newfid, uint16_t nwnames) "tag %d id %d fid %d newfid %d nwnames %d"
+v9fs_walk(uint16_t tag, uint8_t id, int32_t fid, int32_t newfid, uint16_t nwnames, const char* wnames) "tag=%d id=%d fid=%d newfid=%d nwnames=%d wnames={%s}"
v9fs_walk_return(uint16_t tag, uint8_t id, uint16_t nwnames, void* qids) "tag %d id %d nwnames %d qids %p"
v9fs_open(uint16_t tag, uint8_t id, int32_t fid, int32_t mode) "tag %d id %d fid %d mode %d"
v9fs_open_return(uint16_t tag, uint8_t id, uint8_t type, uint32_t version, uint64_t path, int iounit) "tag %u id %u qid={type %u version %u path %"PRIu64"} iounit %d"
--
2.30.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PULL 0/7] 9p queue 2025-02-06
2025-02-06 16:41 [PULL 0/7] 9p queue 2025-02-06 Christian Schoenebeck
` (6 preceding siblings ...)
2025-02-06 16:41 ` [PULL 2/7] 9pfs: make multidevs=remap default Christian Schoenebeck
@ 2025-02-06 18:49 ` Stefan Hajnoczi
2025-02-06 19:31 ` Christian Schoenebeck
7 siblings, 1 reply; 10+ messages in thread
From: Stefan Hajnoczi @ 2025-02-06 18:49 UTC (permalink / raw)
To: Christian Schoenebeck
Cc: qemu-devel, Peter Maydell, Greg Kurz, Stefan Hajnoczi
On Thu, Feb 6, 2025 at 11:49 AM Christian Schoenebeck
<qemu_oss@crudebyte.com> wrote:
>
> The following changes since commit d922088eb4ba6bc31a99f17b32cf75e59dd306cd:
>
> Merge tag 'ui-pull-request' of https://gitlab.com/marcandre.lureau/qemu into staging (2025-02-03 13:42:02 -0500)
>
> are available in the Git repository at:
>
> https://github.com/cschoenebeck/qemu.git tags/pull-9p-20250206
>
> for you to fetch changes up to bfa7bf02782dbd996201c90f850ca11730041af1:
>
> MAINTAINERS: Mark me as reviewer only for 9pfs (2025-02-06 17:10:46 +0100)
>
> ----------------------------------------------------------------
>
> * Greg Kurz steps back as maintainer of 9pfs.
>
> * Make multidevs=remap default option (instead of multidevs=warn)
> and update documentation related to this option.
>
> * Improve tracing (i.e. usefulness of log output content).
>
> * Add test cases for accessing a directory after removal.
>
> ----------------------------------------------------------------
> Christian Schoenebeck (6):
> 9pfs: improve v9fs_walk() tracing
> 9pfs: make multidevs=remap default
> 9pfs: improve v9fs_open() tracing
> tests/9p: rename test use_after_unlink -> use_file_after_unlink
> tests/9p: add use_dir_after_unlink test
> tests/9p: extend use_dir_after_unlink test with Treaddir
The following test failure occurred in the CI system:
12/65 qemu:qtest+qtest-x86_64 / qtest-x86_64/qos-test ERROR 14.74s
killed by signal 6 SIGABRT
――――――――――――――――――――――――――――――――――――― ✀ ―――――――――――――――――――――――――――――――――――――
stderr:
Received response 7 (RLERROR) instead of 77 (RUNLINKAT)
Rlerror has errno 22 (Invalid argument)
**
ERROR:../tests/qtest/libqos/virtio-9p-client.c:276:v9fs_req_recv:
assertion failed (hdr.id == id): (7 == 77)
(test program exited with status code -6)
https://gitlab.com/qemu-project/qemu/-/jobs/9065429175
Please take a look. Thanks!
Stefan
>
> Greg Kurz (1):
> MAINTAINERS: Mark me as reviewer only for 9pfs
>
> MAINTAINERS | 3 +--
> hw/9pfs/9p-local.c | 3 +++
> hw/9pfs/9p-util-generic.c | 50 ++++++++++++++++++++++++++++++++++++++++++++
> hw/9pfs/9p-util.h | 6 ++++++
> hw/9pfs/9p.c | 45 +++++++++++++++++++++++++++++++++------
> hw/9pfs/meson.build | 1 +
> hw/9pfs/trace-events | 4 ++--
> qemu-options.hx | 49 ++++++++++++++++++++++++-------------------
> tests/qtest/virtio-9p-test.c | 50 ++++++++++++++++++++++++++++++++++++++++----
> 9 files changed, 175 insertions(+), 36 deletions(-)
> create mode 100644 hw/9pfs/9p-util-generic.c
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PULL 0/7] 9p queue 2025-02-06
2025-02-06 18:49 ` [PULL 0/7] 9p queue 2025-02-06 Stefan Hajnoczi
@ 2025-02-06 19:31 ` Christian Schoenebeck
0 siblings, 0 replies; 10+ messages in thread
From: Christian Schoenebeck @ 2025-02-06 19:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Greg Kurz, Stefan Hajnoczi
On Thursday, February 6, 2025 7:49:07 PM CET Stefan Hajnoczi wrote:
> On Thu, Feb 6, 2025 at 11:49 AM Christian Schoenebeck
> <qemu_oss@crudebyte.com> wrote:
> >
> > The following changes since commit d922088eb4ba6bc31a99f17b32cf75e59dd306cd:
> >
> > Merge tag 'ui-pull-request' of https://gitlab.com/marcandre.lureau/qemu into staging (2025-02-03 13:42:02 -0500)
> >
> > are available in the Git repository at:
> >
> > https://github.com/cschoenebeck/qemu.git tags/pull-9p-20250206
> >
> > for you to fetch changes up to bfa7bf02782dbd996201c90f850ca11730041af1:
> >
> > MAINTAINERS: Mark me as reviewer only for 9pfs (2025-02-06 17:10:46 +0100)
> >
> > ----------------------------------------------------------------
> >
> > * Greg Kurz steps back as maintainer of 9pfs.
> >
> > * Make multidevs=remap default option (instead of multidevs=warn)
> > and update documentation related to this option.
> >
> > * Improve tracing (i.e. usefulness of log output content).
> >
> > * Add test cases for accessing a directory after removal.
> >
> > ----------------------------------------------------------------
> > Christian Schoenebeck (6):
> > 9pfs: improve v9fs_walk() tracing
> > 9pfs: make multidevs=remap default
> > 9pfs: improve v9fs_open() tracing
> > tests/9p: rename test use_after_unlink -> use_file_after_unlink
> > tests/9p: add use_dir_after_unlink test
> > tests/9p: extend use_dir_after_unlink test with Treaddir
>
> The following test failure occurred in the CI system:
>
> 12/65 qemu:qtest+qtest-x86_64 / qtest-x86_64/qos-test ERROR 14.74s
> killed by signal 6 SIGABRT
> ――――――――――――――――――――――――――――――――――――― ✀ ―――――――――――――――――――――――――――――――――――――
> stderr:
> Received response 7 (RLERROR) instead of 77 (RUNLINKAT)
> Rlerror has errno 22 (Invalid argument)
> **
> ERROR:../tests/qtest/libqos/virtio-9p-client.c:276:v9fs_req_recv:
> assertion failed (hdr.id == id): (7 == 77)
> (test program exited with status code -6)
>
> https://gitlab.com/qemu-project/qemu/-/jobs/9065429175
>
> Please take a look. Thanks!
>
> Stefan
Hmm, in that test a directory is deleted while still having a directory stream
open (via opendir() call) on it. And that directory removal fails when running
in the Gitlab cloud.
So I guess that means that this is file system dependant behaviour whether or
not it is accepted to delete a directory while still having a dir stream open.
I'll just drop this directory test then.
/Christian
> >
> > Greg Kurz (1):
> > MAINTAINERS: Mark me as reviewer only for 9pfs
> >
> > MAINTAINERS | 3 +--
> > hw/9pfs/9p-local.c | 3 +++
> > hw/9pfs/9p-util-generic.c | 50 ++++++++++++++++++++++++++++++++++++++++++++
> > hw/9pfs/9p-util.h | 6 ++++++
> > hw/9pfs/9p.c | 45 +++++++++++++++++++++++++++++++++------
> > hw/9pfs/meson.build | 1 +
> > hw/9pfs/trace-events | 4 ++--
> > qemu-options.hx | 49 ++++++++++++++++++++++++-------------------
> > tests/qtest/virtio-9p-test.c | 50 ++++++++++++++++++++++++++++++++++++++++----
> > 9 files changed, 175 insertions(+), 36 deletions(-)
> > create mode 100644 hw/9pfs/9p-util-generic.c
> >
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-02-06 19:32 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-06 16:41 [PULL 0/7] 9p queue 2025-02-06 Christian Schoenebeck
2025-02-06 16:41 ` [PULL 6/7] tests/9p: extend use_dir_after_unlink test with Treaddir Christian Schoenebeck
2025-02-06 16:41 ` [PULL 7/7] MAINTAINERS: Mark me as reviewer only for 9pfs Christian Schoenebeck
2025-02-06 16:41 ` [PULL 1/7] 9pfs: improve v9fs_walk() tracing Christian Schoenebeck
2025-02-06 16:41 ` [PULL 5/7] tests/9p: add use_dir_after_unlink test Christian Schoenebeck
2025-02-06 16:41 ` [PULL 4/7] tests/9p: rename test use_after_unlink -> use_file_after_unlink Christian Schoenebeck
2025-02-06 16:41 ` [PULL 3/7] 9pfs: improve v9fs_open() tracing Christian Schoenebeck
2025-02-06 16:41 ` [PULL 2/7] 9pfs: make multidevs=remap default Christian Schoenebeck
2025-02-06 18:49 ` [PULL 0/7] 9p queue 2025-02-06 Stefan Hajnoczi
2025-02-06 19:31 ` Christian Schoenebeck
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).