All of lore.kernel.org
 help / color / mirror / Atom feed
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-trivial] [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



WARNING: multiple messages have this Message-ID (diff)
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

  reply	other threads:[~2018-06-08 17:09 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-08 17:09 [Qemu-trivial] [PATCH 0/8] Add a standard authorization framework Daniel P. Berrangé
2018-06-08 17:09 ` [Qemu-devel] " Daniel P. Berrangé
2018-06-08 17:09 ` Daniel P. Berrangé [this message]
2018-06-08 17:09   ` [Qemu-devel] [PATCH 1/8] util: add helper APIs for dealing with inotify Daniel P. Berrangé
2018-06-12 10:05   ` [Qemu-trivial] " Gerd Hoffmann
2018-06-12 10:05     ` [Qemu-devel] " Gerd Hoffmann
2018-06-08 17:09 ` [Qemu-trivial] [PATCH 2/8] hw/usb: switch MTP to use new inotify APIs Daniel P. Berrangé
2018-06-08 17:09   ` [Qemu-devel] " Daniel P. Berrangé
2018-06-12 10:06   ` [Qemu-trivial] " Gerd Hoffmann
2018-06-12 10:06     ` [Qemu-devel] " Gerd Hoffmann
2018-06-08 17:09 ` [Qemu-trivial] [PATCH 3/8] authz: add QAuthZ object as an authorization base class Daniel P. Berrangé
2018-06-08 17:09   ` [Qemu-devel] " Daniel P. Berrangé
2018-06-08 17:09 ` [Qemu-trivial] [PATCH 4/8] authz: add QAuthZSimple object type for trivial auth checks Daniel P. Berrangé
2018-06-08 17:09   ` [Qemu-devel] " Daniel P. Berrangé
2018-06-08 17:09 ` [Qemu-trivial] [PATCH 5/8] authz: add QAuthZList object type for an access control list Daniel P. Berrangé
2018-06-08 17:09   ` [Qemu-devel] " Daniel P. Berrangé
2018-06-08 17:09 ` [Qemu-trivial] [PATCH 6/8] authz: add QAuthZListFile object type for a file " Daniel P. Berrangé
2018-06-08 17:09   ` [Qemu-devel] " Daniel P. Berrangé
2018-06-08 17:09 ` [Qemu-trivial] [PATCH 7/8] authz: add QAuthZPAM object type for authorizing using PAM Daniel P. Berrangé
2018-06-08 17:09   ` [Qemu-devel] " Daniel P. Berrangé
2018-06-08 17:09 ` [Qemu-trivial] [PATCH 8/8] authz: delete existing ACL implementation Daniel P. Berrangé
2018-06-08 17:09   ` [Qemu-devel] " Daniel P. Berrangé
2018-06-08 17:38 ` [Qemu-trivial] [Qemu-devel] [PATCH 0/8] Add a standard authorization framework no-reply
2018-06-08 17:38   ` no-reply
2018-06-08 20:28 ` [Qemu-trivial] " 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 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.