From: "Daniel P. Berrangé" <berrange@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Markus Armbruster" <armbru@redhat.com>,
"Andreas Färber" <afaerber@suse.de>,
"Laurent Vivier" <laurent@vivier.eu>,
"Gerd Hoffmann" <kraxel@redhat.com>,
"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
qemu-trivial@nongnu.org,
"Daniel P. Berrangé" <berrange@redhat.com>,
"Eric Blake" <eblake@redhat.com>,
"Michael Tokarev" <mjt@tls.msk.ru>
Subject: [Qemu-devel] [PATCH 1/8] util: add helper APIs for dealing with inotify
Date: Fri, 8 Jun 2018 18:09:26 +0100 [thread overview]
Message-ID: <20180608170933.9137-2-berrange@redhat.com> (raw)
In-Reply-To: <20180608170933.9137-1-berrange@redhat.com>
The inotify userspace API for reading events is quite horrible, so it is
useful to wrap it in a more friendly API to avoid duplicating code
across many users in QEMU.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
MAINTAINERS | 6 ++
include/qemu/inotify.h | 49 +++++++++++++++
util/Makefile.objs | 1 +
util/inotify.c | 138 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 194 insertions(+)
create mode 100644 include/qemu/inotify.h
create mode 100644 util/inotify.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 41cd3736a9..3610479af7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1766,6 +1766,12 @@ F: include/qemu/sockets.h
F: util/qemu-sockets.c
F: qapi/sockets.json
+Inotify
+M: Daniel P. Berrange <berrange@redhat.com>
+S: Odd fixes
+F: util/inotify.c
+F: include/qemu/inotify.h
+
Throttling infrastructure
M: Alberto Garcia <berto@igalia.com>
S: Supported
diff --git a/include/qemu/inotify.h b/include/qemu/inotify.h
new file mode 100644
index 0000000000..d78d04c5bb
--- /dev/null
+++ b/include/qemu/inotify.h
@@ -0,0 +1,49 @@
+/*
+ * QEMU inotify helper
+ *
+ * Copyright (c) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef QEMU_INOTIFY_H
+#define QEMU_INOTIFY_H
+
+#include "qemu-common.h"
+#ifdef CONFIG_INOTIFY1
+#include <sys/inotify.h>
+#endif
+
+
+typedef struct QInotify QInotify;
+
+typedef void (*QInotifyHandler)(int wd,
+ uint32_t mask,
+ const char *name,
+ void *opaque);
+
+QInotify *qemu_inotify_new(QInotifyHandler cb,
+ void *opaque,
+ GDestroyNotify ffcb,
+ Error **errp);
+
+void qemu_inotify_free(QInotify *in);
+
+int qemu_inotify_add_watch(QInotify *in,
+ const char *path,
+ uint32_t mask,
+ Error **errp);
+
+#endif /* QEMU_INOTIFY_H */
diff --git a/util/Makefile.objs b/util/Makefile.objs
index e1c3fed4dc..4c1b44d019 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -48,4 +48,5 @@ util-obj-y += range.o
util-obj-y += stats64.o
util-obj-y += systemd.o
util-obj-y += iova-tree.o
+util-obj-y += inotify.o
util-obj-$(CONFIG_LINUX) += vfio-helpers.o
diff --git a/util/inotify.c b/util/inotify.c
new file mode 100644
index 0000000000..dd9c194bea
--- /dev/null
+++ b/util/inotify.c
@@ -0,0 +1,138 @@
+/*
+ * QEMU inotify helper
+ *
+ * Copyright (c) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/inotify.h"
+#include "qemu/main-loop.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+
+struct QInotify {
+ int fd;
+ QInotifyHandler cb;
+ void *opaque;
+ GDestroyNotify ffcb;
+};
+
+#ifdef CONFIG_INOTIFY1
+static void qemu_inotify_watch(void *arg)
+{
+ QInotify *in = arg;
+ char buf[4096]
+ __attribute__ ((aligned(__alignof__(struct inotify_event))));
+ int used = 0;
+ int len = read(in->fd, buf, sizeof(buf));
+
+ if (len < 0) {
+ if (errno != EAGAIN) {
+ error_report("Failure monitoring inotify FD, disabling events");
+ goto error;
+ }
+
+ /* no more events right now */
+ return;
+ }
+
+ /* Loop over all events in the buffer */
+ while (used < len) {
+ struct inotify_event *ev =
+ (struct inotify_event *)buf + used;
+
+ in->cb(ev->wd, ev->mask, ev->name, in->opaque);
+
+ used += sizeof(struct inotify_event) + ev->len;
+ }
+
+ return;
+
+ error:
+ qemu_set_fd_handler(in->fd, NULL, NULL, NULL);
+ close(in->fd);
+ in->fd = -1;
+}
+#endif
+
+QInotify *qemu_inotify_new(QInotifyHandler cb,
+ void *opaque,
+ GDestroyNotify ffcb,
+ Error **errp)
+{
+#ifdef CONFIG_INOTIFY1
+ QInotify *in = g_new0(QInotify, 1);
+
+ in->fd = inotify_init1(IN_NONBLOCK);
+ if (in->fd == -1) {
+ error_setg_errno(errp, errno,
+ "Unable to initialize inotify");
+ g_free(in);
+ return NULL;
+ }
+ in->cb = cb;
+ in->opaque = opaque;
+ in->ffcb = ffcb;
+
+ qemu_set_fd_handler(in->fd, qemu_inotify_watch, NULL, in);
+
+ return in;
+#else
+ error_setg(errp, "Inotify not available on this platform");
+ return NULL;
+#endif
+
+}
+
+
+void qemu_inotify_free(QInotify *in)
+{
+ if (!in) {
+ return;
+ }
+
+ if (in->ffcb) {
+ in->ffcb(in->opaque);
+ }
+
+ if (in->fd != -1) {
+ qemu_set_fd_handler(in->fd, NULL, NULL, NULL);
+ close(in->fd);
+ g_free(in);
+ }
+}
+
+
+int qemu_inotify_add_watch(QInotify *in,
+ const char *path,
+ uint32_t mask,
+ Error **errp)
+{
+#ifdef CONFIG_INOTIFY1
+ int rv;
+ rv = inotify_add_watch(in->fd, path, mask);
+ if (rv < 0) {
+ error_setg_errno(errp, errno, "Unable to watch '%s'", path);
+ return -1;
+ }
+
+ return rv;
+#else
+ error_setg(errp, "Inotify not available on this platform");
+ return -1;
+#endif
+}
--
2.17.0
next prev parent reply other threads:[~2018-06-08 17:09 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-08 17:09 [Qemu-devel] [PATCH 0/8] Add a standard authorization framework Daniel P. Berrangé
2018-06-08 17:09 ` Daniel P. Berrangé [this message]
2018-06-12 10:05 ` [Qemu-devel] [PATCH 1/8] util: add helper APIs for dealing with inotify Gerd Hoffmann
2018-06-08 17:09 ` [Qemu-devel] [PATCH 2/8] hw/usb: switch MTP to use new inotify APIs Daniel P. Berrangé
2018-06-12 10:06 ` Gerd Hoffmann
2018-06-08 17:09 ` [Qemu-devel] [PATCH 3/8] authz: add QAuthZ object as an authorization base class Daniel P. Berrangé
2018-06-08 17:09 ` [Qemu-devel] [PATCH 4/8] authz: add QAuthZSimple object type for trivial auth checks Daniel P. Berrangé
2018-06-08 17:09 ` [Qemu-devel] [PATCH 5/8] authz: add QAuthZList object type for an access control list Daniel P. Berrangé
2018-06-08 17:09 ` [Qemu-devel] [PATCH 6/8] authz: add QAuthZListFile object type for a file " Daniel P. Berrangé
2018-06-08 17:09 ` [Qemu-devel] [PATCH 7/8] authz: add QAuthZPAM object type for authorizing using PAM Daniel P. Berrangé
2018-06-08 17:09 ` [Qemu-devel] [PATCH 8/8] authz: delete existing ACL implementation Daniel P. Berrangé
2018-06-08 17:38 ` [Qemu-devel] [PATCH 0/8] Add a standard authorization framework no-reply
2018-06-08 20:28 ` no-reply
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=20180608170933.9137-2-berrange@redhat.com \
--to=berrange@redhat.com \
--cc=afaerber@suse.de \
--cc=armbru@redhat.com \
--cc=dgilbert@redhat.com \
--cc=eblake@redhat.com \
--cc=kraxel@redhat.com \
--cc=laurent@vivier.eu \
--cc=mjt@tls.msk.ru \
--cc=qemu-devel@nongnu.org \
--cc=qemu-trivial@nongnu.org \
/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).