[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 08/12] virtio-9p: add reset handler
From: |
Greg Kurz |
Subject: |
[Qemu-devel] [PULL 08/12] virtio-9p: add reset handler |
Date: |
Mon, 17 Oct 2016 17:05:50 +0200 |
Virtio devices should implement the VirtIODevice->reset() function to
perform necessary cleanup actions and to bring the device to a quiescent
state.
In the case of the virtio-9p device, this means:
- emptying the list of active PDUs (i.e. draining all in-flight I/O)
- freeing all fids (i.e. close open file descriptors and free memory)
That's what this patch does.
The reset handler first waits for all active PDUs to complete. Since
completion happens in the QEMU global aio context, we just have to
loop around aio_poll() until the active list is empty.
The freeing part involves some actions to be performed on the backend,
like closing file descriptors or flushing extended attributes to the
underlying filesystem. The virtfs_reset() function already does the
job: it calls free_fid() for all open fids not involved in an ongoing
I/O operation. We are sure this is the case since we have drained
the PDU active list.
The current code implements all backend accesses with coroutines, but we
want to stay synchronous on the reset path. We can either change the
current code to be able to run when not in coroutine context, or create
a coroutine context and wait for virtfs_reset() to complete. This patch
goes for the latter because it results in simpler code.
Note that we also need to create a dummy PDU because it is also an API
to pass the FsContext pointer to all backend callbacks.
Signed-off-by: Greg Kurz <address@hidden>
Reviewed-by: Michael S. Tsirkin <address@hidden>
Reviewed-by: Stefan Hajnoczi <address@hidden>
---
hw/9pfs/9p.c | 30 ++++++++++++++++++++++++++++++
hw/9pfs/9p.h | 1 +
hw/9pfs/virtio-9p-device.c | 8 ++++++++
3 files changed, 39 insertions(+)
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index f0dc2ce589cd..26aa7d564815 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -3522,6 +3522,36 @@ void v9fs_device_unrealize_common(V9fsState *s, Error
**errp)
g_free(s->tag);
}
+typedef struct VirtfsCoResetData {
+ V9fsPDU pdu;
+ bool done;
+} VirtfsCoResetData;
+
+static void coroutine_fn virtfs_co_reset(void *opaque)
+{
+ VirtfsCoResetData *data = opaque;
+
+ virtfs_reset(&data->pdu);
+ data->done = true;
+}
+
+void v9fs_reset(V9fsState *s)
+{
+ VirtfsCoResetData data = { .pdu = { .s = s }, .done = false };
+ Coroutine *co;
+
+ while (!QLIST_EMPTY(&s->active_list)) {
+ aio_poll(qemu_get_aio_context(), true);
+ }
+
+ co = qemu_coroutine_create(virtfs_co_reset, &data);
+ qemu_coroutine_enter(co);
+
+ while (!data.done) {
+ aio_poll(qemu_get_aio_context(), true);
+ }
+}
+
static void __attribute__((__constructor__)) v9fs_set_fd_limit(void)
{
struct rlimit rlim;
diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
index c4df66d1c4ea..2523a445f81f 100644
--- a/hw/9pfs/9p.h
+++ b/hw/9pfs/9p.h
@@ -339,5 +339,6 @@ ssize_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const
char *fmt, ...);
V9fsPDU *pdu_alloc(V9fsState *s);
void pdu_free(V9fsPDU *pdu);
void pdu_submit(V9fsPDU *pdu);
+void v9fs_reset(V9fsState *s);
#endif
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index e98dd0c4c0af..1782e4a2277f 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -141,6 +141,13 @@ static void virtio_9p_device_unrealize(DeviceState *dev,
Error **errp)
v9fs_device_unrealize_common(s, errp);
}
+static void virtio_9p_reset(VirtIODevice *vdev)
+{
+ V9fsVirtioState *v = (V9fsVirtioState *)vdev;
+
+ v9fs_reset(&v->state);
+}
+
ssize_t virtio_pdu_vmarshal(V9fsPDU *pdu, size_t offset,
const char *fmt, va_list ap)
{
@@ -207,6 +214,7 @@ static void virtio_9p_class_init(ObjectClass *klass, void
*data)
vdc->unrealize = virtio_9p_device_unrealize;
vdc->get_features = virtio_9p_get_features;
vdc->get_config = virtio_9p_get_config;
+ vdc->reset = virtio_9p_reset;
}
static const TypeInfo virtio_device_info = {
--
2.5.5
- [Qemu-devel] [PULL 00/12] 9p patches for 2.8 20161017, Greg Kurz, 2016/10/17
- [Qemu-devel] [PULL 02/12] 9pfs: fix potential host memory leak in v9fs_read, Greg Kurz, 2016/10/17
- [Qemu-devel] [PULL 01/12] 9pfs: allocate space for guest originated empty strings, Greg Kurz, 2016/10/17
- [Qemu-devel] [PULL 06/12] 9pfs: drop useless check in pdu_free(), Greg Kurz, 2016/10/17
- [Qemu-devel] [PULL 05/12] 9pfs: use coroutine_fn annotation in hw/9pfs/9p.[ch], Greg Kurz, 2016/10/17
- [Qemu-devel] [PULL 04/12] 9pfs: use coroutine_fn annotation in hw/9pfs/co*.[ch], Greg Kurz, 2016/10/17
- [Qemu-devel] [PULL 03/12] 9pfs: fsdev: drop useless extern annotation for functions, Greg Kurz, 2016/10/17
- [Qemu-devel] [PULL 08/12] virtio-9p: add reset handler,
Greg Kurz <=
- [Qemu-devel] [PULL 07/12] 9pfs: only free completed request if not flushed, Greg Kurz, 2016/10/17
- [Qemu-devel] [PULL 11/12] 9pfs: fix memory leak in v9fs_link, Greg Kurz, 2016/10/17
- [Qemu-devel] [PULL 10/12] 9pfs: fix memory leak in v9fs_xattrcreate, Greg Kurz, 2016/10/17
- [Qemu-devel] [PULL 09/12] 9pfs: fix information leak in xattr read, Greg Kurz, 2016/10/17
- [Qemu-devel] [PULL 12/12] 9pfs: fix memory leak in v9fs_write, Greg Kurz, 2016/10/17
- Re: [Qemu-devel] [PULL 00/12] 9p patches for 2.8 20161017, Peter Maydell, 2016/10/17