From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, stefanha@gmail.com
Subject: [Qemu-devel] [RFC PATCH 13/13] nbd: add notifier to close exports when the image is closed
Date: Mon, 27 Aug 2012 17:00:26 +0200 [thread overview]
Message-ID: <1346079626-16386-14-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1346079626-16386-1-git-send-email-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
blockdev-nbd.c | 38 ++++++++++++++++++++++++++++++++++++++
qapi/opts-visitor.c | 48 ++++++++++++++++++++----------------------------
2 file modificati, 58 inserzioni(+), 28 rimozioni(-)
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 5a415be..c190caa 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -62,12 +62,39 @@ void qmp_nbd_server_start(IPSocketAddress *addr, Error **errp)
qemu_opts_del(opts);
}
+/* Hook into the BlockDriverState notifiers to close the export when
+ * the file is closed.
+ */
+typedef struct NBDCloseNotifier {
+ Notifier n;
+ NBDExport *exp;
+ QTAILQ_ENTRY(NBDCloseNotifier) next;
+} NBDCloseNotifier;
+
+static QTAILQ_HEAD(, NBDCloseNotifier) close_notifiers =
+ QTAILQ_HEAD_INITIALIZER(close_notifiers);
+
+static void nbd_close_notifier_remove(NBDCloseNotifier *cn)
+{
+ notifier_remove(&cn->n);
+ QTAILQ_REMOVE(&close_notifiers, cn, next);
+ g_free(cn);
+}
+
+static void nbd_close_notifier(Notifier *n, void *data)
+{
+ NBDCloseNotifier *cn = DO_UPCAST(NBDCloseNotifier, n, n);
+
+ nbd_export_close(cn->exp);
+ nbd_close_notifier_remove(cn);
+}
void qmp_nbd_server_add(const char *device, bool has_writable, bool writable,
Error **errp)
{
BlockDriverState *bs;
NBDExport *exp;
+ NBDCloseNotifier *n;
bs = bdrv_find(device);
if (!bs) {
@@ -82,10 +109,21 @@ void qmp_nbd_server_add(const char *device, bool has_writable, bool writable,
exp = nbd_export_new(bs, 0, -1, writable ? 0 : NBD_FLAG_READ_ONLY);
nbd_export_set_name(exp, device);
+
+ n = g_malloc0(sizeof(NBDCloseNotifier));
+ n->n.notify = nbd_close_notifier;
+ n->exp = exp;
+ bdrv_add_close_notifier(bs, &n->n);
+ QTAILQ_INSERT_TAIL(&close_notifiers, n, next);
}
void qmp_nbd_server_stop(Error **errp)
{
+ while (!QTAILQ_EMPTY(&close_notifiers)) {
+ NBDCloseNotifier *cn = QTAILQ_FIRST(&close_notifiers);
+ nbd_close_notifier_remove(cn);
+ }
+
nbd_export_close_all();
qemu_set_fd_handler2(server_fd, NULL, NULL, NULL, NULL);
close(server_fd);
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index a59d306..6893d62 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -20,9 +20,6 @@ struct OptsVisitor
{
Visitor visitor;
- /* Ownership remains with opts_visitor_new()'s caller. */
- const QemuOpts *opts_root;
-
unsigned depth;
/* Non-null iff depth is positive. Each key is a QemuOpt name. Each value
@@ -36,9 +33,9 @@ struct OptsVisitor
GQueue *repeated_opts;
bool repeated_opts_first;
- /* If "opts_root->id" is set, reinstantiate it as a fake QemuOpt for
- * uniformity. Only its "name" and "str" fields are set. "fake_id_opt" does
- * not survive or escape the OptsVisitor object.
+ /* If the "id" is set on the QemuOpts, reinstantiate it as a fake QemuOpt
+ * for uniformity. Only its "name" and "str" fields are set. "fake_id_opt"
+ * does not survive or escape the OptsVisitor object.
*/
QemuOpt *fake_id_opt;
};
@@ -77,29 +74,9 @@ opts_start_struct(Visitor *v, void **obj, const char *kind,
const char *name, size_t size, Error **errp)
{
OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
- const QemuOpt *opt;
*obj = g_malloc0(size > 0 ? size : 1);
- if (ov->depth++ > 0) {
- return;
- }
-
- ov->unprocessed_opts = g_hash_table_new_full(&g_str_hash, &g_str_equal,
- NULL, &destroy_list);
- QTAILQ_FOREACH(opt, &ov->opts_root->head, next) {
- /* ensured by qemu-option.c::opts_do_parse() */
- assert(strcmp(opt->name, "id") != 0);
-
- opts_visitor_insert(ov->unprocessed_opts, opt);
- }
-
- if (ov->opts_root->id != NULL) {
- ov->fake_id_opt = g_malloc0(sizeof *ov->fake_id_opt);
-
- ov->fake_id_opt->name = "id";
- ov->fake_id_opt->str = ov->opts_root->id;
- opts_visitor_insert(ov->unprocessed_opts, ov->fake_id_opt);
- }
+ ov->depth++;
}
@@ -372,6 +349,7 @@ OptsVisitor *
opts_visitor_new(const QemuOpts *opts)
{
OptsVisitor *ov;
+ const QemuOpt *opt;
ov = g_malloc0(sizeof *ov);
@@ -403,8 +381,22 @@ opts_visitor_new(const QemuOpts *opts)
ov->visitor.start_optional = &opts_start_optional;
- ov->opts_root = opts;
+ ov->unprocessed_opts = g_hash_table_new_full(&g_str_hash, &g_str_equal,
+ NULL, &destroy_list);
+ QTAILQ_FOREACH(opt, &opts->head, next) {
+ /* ensured by qemu-option.c::opts_do_parse() */
+ assert(strcmp(opt->name, "id") != 0);
+ opts_visitor_insert(ov->unprocessed_opts, opt);
+ }
+
+ if (opts->id != NULL) {
+ ov->fake_id_opt = g_malloc0(sizeof *ov->fake_id_opt);
+
+ ov->fake_id_opt->name = "id";
+ ov->fake_id_opt->str = opts->id;
+ opts_visitor_insert(ov->unprocessed_opts, ov->fake_id_opt);
+ }
return ov;
}
--
1.7.11.2
next prev parent reply other threads:[~2012-08-27 15:01 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-27 15:00 [Qemu-devel] [RFC PATCH 00/13] Embedded NBD server Paolo Bonzini
2012-08-27 15:00 ` [Qemu-devel] [RFC PATCH 01/13] nbd: add more constants Paolo Bonzini
2012-08-27 15:00 ` [Qemu-devel] [RFC PATCH 02/13] nbd: pass NBDClient to nbd_send_negotiate Paolo Bonzini
2012-08-27 15:00 ` [Qemu-devel] [RFC PATCH 03/13] nbd: do not leak nbd_trip coroutines when a connection is torn down Paolo Bonzini
2012-08-27 15:00 ` [Qemu-devel] [RFC PATCH 04/13] nbd: close all clients on deleting export Paolo Bonzini
2012-08-27 15:00 ` [Qemu-devel] [RFC PATCH 05/13] nbd: register named exports Paolo Bonzini
2012-08-27 15:00 ` [Qemu-devel] [RFC PATCH 06/13] nbd: negotiate with " Paolo Bonzini
2012-08-27 15:00 ` [Qemu-devel] [RFC PATCH 07/13] nbd: do not close BlockDriverState in nbd_export_close Paolo Bonzini
2012-08-27 15:00 ` [Qemu-devel] [RFC PATCH 08/13] qemu-sockets: publish dummy_opts Paolo Bonzini
2012-08-27 15:00 ` [Qemu-devel] [RFC PATCH 09/13] qmp: add NBD server commands Paolo Bonzini
2012-09-18 20:11 ` Luiz Capitulino
2012-09-19 8:16 ` Paolo Bonzini
2012-08-27 15:00 ` [Qemu-devel] [RFC PATCH 10/13] qemu-sockets: make inet_parse public Paolo Bonzini
2012-08-27 15:00 ` [Qemu-devel] [RFC PATCH 11/13] hmp: add NBD server commands Paolo Bonzini
2012-09-18 20:22 ` Luiz Capitulino
2012-09-19 8:00 ` Paolo Bonzini
2012-08-27 15:00 ` [Qemu-devel] [RFC PATCH 12/13] block: add close notifiers Paolo Bonzini
2012-08-27 15:00 ` Paolo Bonzini [this message]
2012-09-07 15:50 ` [Qemu-devel] ping Re: [RFC PATCH 00/13] Embedded NBD server Paolo Bonzini
2012-09-07 16:11 ` Kevin Wolf
2012-09-17 16:43 ` Paolo Bonzini
2012-09-18 8:45 ` Kevin Wolf
2012-09-18 9:09 ` Paolo Bonzini
2012-09-18 9:40 ` Kevin Wolf
2012-09-18 9:48 ` Paolo Bonzini
2012-09-18 9:55 ` Kevin Wolf
2012-09-19 10:16 ` [Qemu-devel] " Daniel P. Berrange
2012-09-19 10:22 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1346079626-16386-14-git-send-email-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=kwolf@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).