From: Peter Xu <peterx@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Eric Blake" <eblake@redhat.com>,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Markus Armbruster" <armbru@redhat.com>,
"Stefan Hajnoczi" <stefanha@redhat.com>,
"Dr . David Alan Gilbert" <dgilbert@redhat.com>,
peterx@redhat.com
Subject: [Qemu-devel] [PATCH v9 7/7] monitor: add lock to protect mon_fdsets
Date: Tue, 29 May 2018 13:57:55 +0800 [thread overview]
Message-ID: <20180529055755.12404-8-peterx@redhat.com> (raw)
In-Reply-To: <20180529055755.12404-1-peterx@redhat.com>
Introduce a new global big lock for mon_fdsets. Take it where needed.
The monitor_fdset_get_fd() handling is a bit tricky: now we need to call
qemu_mutex_unlock() which might pollute errno, so we need to make sure
the correct errno be passed up to the callers. To make things simpler,
we let monitor_fdset_get_fd() return the -errno directly when error
happens, then in qemu_open() we move it back into errno.
Signed-off-by: Peter Xu <peterx@redhat.com>
---
monitor.c | 52 +++++++++++++++++++++++++++++++++++++++++----------
stubs/fdset.c | 2 +-
util/osdep.c | 3 ++-
3 files changed, 45 insertions(+), 12 deletions(-)
diff --git a/monitor.c b/monitor.c
index bd9ab5597f..09902a58d5 100644
--- a/monitor.c
+++ b/monitor.c
@@ -272,7 +272,10 @@ static QemuMutex monitor_lock;
static GHashTable *monitor_qapi_event_state;
static QTAILQ_HEAD(mon_list, Monitor) mon_list;
+/* Protects mon_fdsets */
+static QemuMutex mon_fdsets_lock;
static QLIST_HEAD(mon_fdsets, MonFdset) mon_fdsets;
+
static int mon_refcount;
static mon_cmd_t mon_cmds[];
@@ -2317,9 +2320,11 @@ static void monitor_fdsets_cleanup(void)
MonFdset *mon_fdset;
MonFdset *mon_fdset_next;
+ qemu_mutex_lock(&mon_fdsets_lock);
QLIST_FOREACH_SAFE(mon_fdset, &mon_fdsets, next, mon_fdset_next) {
monitor_fdset_cleanup(mon_fdset);
}
+ qemu_mutex_unlock(&mon_fdsets_lock);
}
AddfdInfo *qmp_add_fd(bool has_fdset_id, int64_t fdset_id, bool has_opaque,
@@ -2354,6 +2359,7 @@ void qmp_remove_fd(int64_t fdset_id, bool has_fd, int64_t fd, Error **errp)
MonFdsetFd *mon_fdset_fd;
char fd_str[60];
+ qemu_mutex_lock(&mon_fdsets_lock);
QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
if (mon_fdset->id != fdset_id) {
continue;
@@ -2373,10 +2379,12 @@ void qmp_remove_fd(int64_t fdset_id, bool has_fd, int64_t fd, Error **errp)
goto error;
}
monitor_fdset_cleanup(mon_fdset);
+ qemu_mutex_unlock(&mon_fdsets_lock);
return;
}
error:
+ qemu_mutex_unlock(&mon_fdsets_lock);
if (has_fd) {
snprintf(fd_str, sizeof(fd_str), "fdset-id:%" PRId64 ", fd:%" PRId64,
fdset_id, fd);
@@ -2392,6 +2400,7 @@ FdsetInfoList *qmp_query_fdsets(Error **errp)
MonFdsetFd *mon_fdset_fd;
FdsetInfoList *fdset_list = NULL;
+ qemu_mutex_lock(&mon_fdsets_lock);
QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
FdsetInfoList *fdset_info = g_malloc0(sizeof(*fdset_info));
FdsetFdInfoList *fdsetfd_list = NULL;
@@ -2421,6 +2430,7 @@ FdsetInfoList *qmp_query_fdsets(Error **errp)
fdset_info->next = fdset_list;
fdset_list = fdset_info;
}
+ qemu_mutex_unlock(&mon_fdsets_lock);
return fdset_list;
}
@@ -2433,6 +2443,7 @@ AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id,
MonFdsetFd *mon_fdset_fd;
AddfdInfo *fdinfo;
+ qemu_mutex_lock(&mon_fdsets_lock);
if (has_fdset_id) {
QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
/* Break if match found or match impossible due to ordering by ID */
@@ -2453,6 +2464,7 @@ AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id,
if (fdset_id < 0) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "fdset-id",
"a non-negative value");
+ qemu_mutex_unlock(&mon_fdsets_lock);
return NULL;
}
/* Use specified fdset ID */
@@ -2503,16 +2515,21 @@ AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id,
fdinfo->fdset_id = mon_fdset->id;
fdinfo->fd = mon_fdset_fd->fd;
+ qemu_mutex_unlock(&mon_fdsets_lock);
return fdinfo;
}
int monitor_fdset_get_fd(int64_t fdset_id, int flags)
{
-#ifndef _WIN32
+#ifdef _WIN32
+ return -ENOENT;
+#else
MonFdset *mon_fdset;
MonFdsetFd *mon_fdset_fd;
int mon_fd_flags;
+ int ret;
+ qemu_mutex_lock(&mon_fdsets_lock);
QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
if (mon_fdset->id != fdset_id) {
continue;
@@ -2520,20 +2537,24 @@ int monitor_fdset_get_fd(int64_t fdset_id, int flags)
QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) {
mon_fd_flags = fcntl(mon_fdset_fd->fd, F_GETFL);
if (mon_fd_flags == -1) {
- return -1;
+ ret = -errno;
+ goto out;
}
if ((flags & O_ACCMODE) == (mon_fd_flags & O_ACCMODE)) {
- return mon_fdset_fd->fd;
+ ret = mon_fdset_fd->fd;
+ goto out;
}
}
- errno = EACCES;
- return -1;
+ ret = -EACCES;
+ goto out;
}
-#endif
+ ret = -ENOENT;
- errno = ENOENT;
- return -1;
+out:
+ qemu_mutex_unlock(&mon_fdsets_lock);
+ return ret;
+#endif
}
int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd)
@@ -2541,20 +2562,25 @@ int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd)
MonFdset *mon_fdset;
MonFdsetFd *mon_fdset_fd_dup;
+ qemu_mutex_lock(&mon_fdsets_lock);
QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
if (mon_fdset->id != fdset_id) {
continue;
}
QLIST_FOREACH(mon_fdset_fd_dup, &mon_fdset->dup_fds, next) {
if (mon_fdset_fd_dup->fd == dup_fd) {
- return -1;
+ goto err;
}
}
mon_fdset_fd_dup = g_malloc0(sizeof(*mon_fdset_fd_dup));
mon_fdset_fd_dup->fd = dup_fd;
QLIST_INSERT_HEAD(&mon_fdset->dup_fds, mon_fdset_fd_dup, next);
+ qemu_mutex_unlock(&mon_fdsets_lock);
return 0;
}
+
+err:
+ qemu_mutex_unlock(&mon_fdsets_lock);
return -1;
}
@@ -2563,6 +2589,7 @@ static int monitor_fdset_dup_fd_find_remove(int dup_fd, bool remove)
MonFdset *mon_fdset;
MonFdsetFd *mon_fdset_fd_dup;
+ qemu_mutex_lock(&mon_fdsets_lock);
QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
QLIST_FOREACH(mon_fdset_fd_dup, &mon_fdset->dup_fds, next) {
if (mon_fdset_fd_dup->fd == dup_fd) {
@@ -2571,13 +2598,17 @@ static int monitor_fdset_dup_fd_find_remove(int dup_fd, bool remove)
if (QLIST_EMPTY(&mon_fdset->dup_fds)) {
monitor_fdset_cleanup(mon_fdset);
}
- return -1;
+ goto err;
} else {
+ qemu_mutex_unlock(&mon_fdsets_lock);
return mon_fdset->id;
}
}
}
}
+
+err:
+ qemu_mutex_unlock(&mon_fdsets_lock);
return -1;
}
@@ -4511,6 +4542,7 @@ void monitor_init_globals(void)
monitor_qapi_event_init();
sortcmdlist();
qemu_mutex_init(&monitor_lock);
+ qemu_mutex_init(&mon_fdsets_lock);
monitor_iothread_init();
}
diff --git a/stubs/fdset.c b/stubs/fdset.c
index 6020cf28c8..4f3edf2ea4 100644
--- a/stubs/fdset.c
+++ b/stubs/fdset.c
@@ -14,7 +14,7 @@ int monitor_fdset_dup_fd_find(int dup_fd)
int monitor_fdset_get_fd(int64_t fdset_id, int flags)
{
- return -1;
+ return -ENOENT;
}
void monitor_fdset_dup_fd_remove(int dupfd)
diff --git a/util/osdep.c b/util/osdep.c
index a73de0e1ba..ea51d500b6 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -302,7 +302,8 @@ int qemu_open(const char *name, int flags, ...)
}
fd = monitor_fdset_get_fd(fdset_id, flags);
- if (fd == -1) {
+ if (fd < 0) {
+ errno = -fd;
return -1;
}
--
2.17.0
next prev parent reply other threads:[~2018-05-29 5:58 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-29 5:57 [Qemu-devel] [PATCH v9 0/7] monitor: let Monitor be thread safe Peter Xu
2018-05-29 5:57 ` [Qemu-devel] [PATCH v9 1/7] monitor: rename out_lock to mon_lock Peter Xu
2018-06-07 14:24 ` Markus Armbruster
2018-05-29 5:57 ` [Qemu-devel] [PATCH v9 2/7] monitor: protect mon->fds with mon_lock Peter Xu
2018-05-29 5:57 ` [Qemu-devel] [PATCH v9 3/7] monitor: more comments on lock-free elements Peter Xu
2018-05-30 16:26 ` Stefan Hajnoczi
2018-06-07 14:26 ` Markus Armbruster
2018-05-29 5:57 ` [Qemu-devel] [PATCH v9 4/7] monitor: fix comment for monitor_lock Peter Xu
2018-05-30 16:29 ` Stefan Hajnoczi
2018-06-07 14:27 ` Markus Armbruster
2018-05-29 5:57 ` [Qemu-devel] [PATCH v9 5/7] monitor: remove event_clock_type Peter Xu
2018-05-30 16:35 ` Stefan Hajnoczi
2018-05-31 4:11 ` Peter Xu
2018-05-31 8:23 ` Stefan Hajnoczi
2018-05-31 8:30 ` Peter Xu
2018-06-07 14:32 ` Markus Armbruster
2018-06-08 3:54 ` Peter Xu
2018-05-29 5:57 ` [Qemu-devel] [PATCH v9 6/7] monitor: move init global earlier Peter Xu
2018-05-30 16:37 ` Stefan Hajnoczi
2018-06-07 14:33 ` Markus Armbruster
2018-05-29 5:57 ` Peter Xu [this message]
2018-05-30 16:39 ` [Qemu-devel] [PATCH v9 7/7] monitor: add lock to protect mon_fdsets Stefan Hajnoczi
2018-06-07 14:38 ` Markus Armbruster
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=20180529055755.12404-8-peterx@redhat.com \
--to=peterx@redhat.com \
--cc=armbru@redhat.com \
--cc=dgilbert@redhat.com \
--cc=eblake@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.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 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.