All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs
@ 2023-11-10 16:07 Juergen Gross
  2023-11-10 16:07 ` [PATCH v2 01/29] xen/public: add some more 9pfs xenstore paths Juergen Gross
                   ` (28 more replies)
  0 siblings, 29 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Wei Liu, Anthony PERARD, Julien Grall, Samuel Thibault

This series is adding 9pfs support to Xenstore-stubdom, enabling it
to do logging to a dom0 directory.

This is a prerequisite for the final goal to add live update support
to Xenstore-stubdom, as it enables the stubdom to store its state in
a dom0 file.

The 9pfs backend is a new daemon written from scratch. Using a
dedicated 9pfs daemon has several advantages:

- it is using much less resources than a full blown qemu process
- it can serve multiple guests (the idea is to use it for other
  infrastructure domains, like qemu-stubdom or driver domains, too)
- it is designed to support several security enhancements, like
  limiting the number of files for a guest, or limiting the allocated
  file system space
- it doesn't support file links (neither hard nor soft links) or
  referencing parent directories via "..", minimizing the risk that
  a guest can "escape" from its home directory

Note that for now the daemon only contains the minimal needed
functionality to do logging from Xenstore-stubdom. I didn't want to
add all the 9pfs commands and security add-ons in the beginning, in
order to avoid needless efforts in case the idea of the daemon is
being rejected.

Note that the series can only be committed after the related Mini-OS
series [1] has gone in.

[1]: https://lists.xen.org/archives/html/xen-devel/2023-11/threads.html#00639

Changes in V2:
- support of multiple rings per device
- xenlogd->xen-9pfsd rename
- addressed review comments
- fixed some bugs

Juergen Gross (29):
  xen/public: add some more 9pfs xenstore paths
  tools: add a new xen logging daemon
  tools/xenlogd: connect to frontend
  tools/xenlogd: add transport layer
  tools/xenlogd: add 9pfs response generation support
  tools/xenlogd: add 9pfs version request support
  tools/xenlogd: add 9pfs attach request support
  tools/xenlogd: add 9pfs walk request support
  tools/xenlogd: add 9pfs open request support
  tools/xenlogd: add 9pfs clunk request support
  tools/xenlogd: add 9pfs create request support
  tools/xenlogd: add 9pfs stat request support
  tools/xenlogd: add 9pfs write request support
  tools/xenlogd: add 9pfs read request support
  tools/libs/light: add backend type for 9pfs PV devices
  tools/xl: support new 9pfs backend xen-9pfsd
  tools/helpers: allocate xenstore event channel for xenstore stubdom
  tools/xenstored: rename xenbus_evtchn()
  stubdom: extend xenstore stubdom configs
  tools: add 9pfs device to xenstore-stubdom
  tools/xenstored: add early_init() function
  tools/xenstored: get own domid in stubdom case
  tools/xenstored: rework ring page (un)map functions
  tools/xenstored: split domain_init()
  tools/xenstored: map stubdom interface
  tools/xenstored: mount 9pfs device in stubdom
  tools/xenstored: add helpers for filename handling
  tools/xenstored: support complete log capabilities in stubdom
  tools/xenstored: have a single do_control_memreport()

 docs/man/xl.cfg.5.pod.in                  |   36 +-
 stubdom/xenstore-minios.cfg               |    2 +-
 stubdom/xenstorepvh-minios.cfg            |    2 +-
 tools/Makefile                            |    1 +
 tools/helpers/init-xenstore-domain.c      |    9 +
 tools/hotplug/Linux/launch-xenstore.in    |    1 +
 tools/include/libxl.h                     |   17 +
 tools/include/xen-tools/common-macros.h   |    4 +
 tools/libs/light/libxl_9pfs.c             |  174 ++-
 tools/libs/light/libxl_create.c           |    4 +-
 tools/libs/light/libxl_dm.c               |    2 +-
 tools/libs/light/libxl_types.idl          |   11 +
 tools/libs/light/libxl_types_internal.idl |    1 +
 tools/xen-9pfsd/.gitignore                |    1 +
 tools/xen-9pfsd/Makefile                  |   38 +
 tools/xen-9pfsd/io.c                      | 1462 +++++++++++++++++++++
 tools/xen-9pfsd/xen-9pfsd.c               |  770 +++++++++++
 tools/xen-9pfsd/xen-9pfsd.h               |   98 ++
 tools/xenstored/control.c                 |   29 +-
 tools/xenstored/core.c                    |   20 +-
 tools/xenstored/core.h                    |   13 +-
 tools/xenstored/domain.c                  |   72 +-
 tools/xenstored/domain.h                  |    2 +
 tools/xenstored/lu_daemon.c               |    4 +-
 tools/xenstored/minios.c                  |   54 +-
 tools/xenstored/posix.c                   |   18 +-
 tools/xl/xl_parse.c                       |   36 +
 xen/include/public/io/9pfs.h              |   34 +
 28 files changed, 2847 insertions(+), 68 deletions(-)
 create mode 100644 tools/xen-9pfsd/.gitignore
 create mode 100644 tools/xen-9pfsd/Makefile
 create mode 100644 tools/xen-9pfsd/io.c
 create mode 100644 tools/xen-9pfsd/xen-9pfsd.c
 create mode 100644 tools/xen-9pfsd/xen-9pfsd.h

-- 
2.35.3



^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v2 01/29] xen/public: add some more 9pfs xenstore paths
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-13 17:14   ` Jason Andryuk
  2023-11-10 16:07 ` [PATCH v2 02/29] tools: add a new xen logging daemon Juergen Gross
                   ` (27 subsequent siblings)
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross

Add some optional additional backend paths for 9pfs PV devices. Those
paths will be supported by the new xenlogd 9pfs backend.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
 xen/include/public/io/9pfs.h | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/xen/include/public/io/9pfs.h b/xen/include/public/io/9pfs.h
index 9ad2773082..ac4bf0434b 100644
--- a/xen/include/public/io/9pfs.h
+++ b/xen/include/public/io/9pfs.h
@@ -71,6 +71,40 @@
  *                 created on the guest (no user ownership squash or remap)
  *         Only "none" is supported in this version of the protocol.
  *
+ *    max-files
+ *         Values:        <uint32_t>
+ *
+ *         The maximum number of files (including directories) allowed for
+ *         this device. Backend support of this node is optional. If the node
+ *         is not present or the value is zero the number of files is not
+ *         limited.
+ *
+ *    max-open-files
+ *         Values:        <uint32_t>
+ *
+ *         The maximum number of files the guest is allowed to have opened
+ *         concurrently. Multiple concurrent opens of the same file are counted
+ *         individually. Backend support of this node is optional. If the node
+ *         is not present or the value is zero a backend specific default is
+ *         applied.
+ *
+ *    max-space
+ *         Values:        <uint32_t>
+ *
+ *         The maximum file space in MiBs the guest is allowed to use for this
+ *         device. Backend support of this node is optional. If the node is
+ *         not present or the value is zero the space is not limited.
+ *
+ *    auto-delete
+ *         Values:        <bool>
+ *
+ *         When set to "1" the backend will delete the file with the oldest
+ *         modification date below <path> in case the allowed maximum file
+ *         space (see <max-space>) or file number (see <max-files>) is being
+ *         exceeded due to guest activity (creation or extension of files).
+ *         Files currently opened by the guest won't be deleted. Backend
+ *         support of this node is optional.
+ *
  ******************************************************************************
  *                            Frontend XenBus Nodes
  ******************************************************************************
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 02/29] tools: add a new xen logging daemon
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
  2023-11-10 16:07 ` [PATCH v2 01/29] xen/public: add some more 9pfs xenstore paths Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-10 16:13   ` Andrew Cooper
  2023-11-13 17:36   ` Jason Andryuk
  2023-11-10 16:07 ` [PATCH v2 03/29] tools/xenlogd: connect to frontend Juergen Gross
                   ` (26 subsequent siblings)
  28 siblings, 2 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Anthony PERARD

Add "xen-9pfsd", a new logging daemon meant to support infrastructure
domains (e.g. xenstore-stubdom) to access files in dom0.

For now only add the code needed for starting the daemon and
registering it with Xenstore via a new "libxl/xen-9pfs/state" node by
writing the "running" state to it.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- rename from xenlogd to xen-9pfsd (Andrew Cooper)
- use a backend domain local Xenstore node (Jason Andryuk)
- use "volatile" for stop_me (Andrew Cooper)
---
 tools/Makefile              |   1 +
 tools/xen-9pfsd/.gitignore  |   1 +
 tools/xen-9pfsd/Makefile    |  38 ++++++++++
 tools/xen-9pfsd/xen-9pfsd.c | 145 ++++++++++++++++++++++++++++++++++++
 4 files changed, 185 insertions(+)
 create mode 100644 tools/xen-9pfsd/.gitignore
 create mode 100644 tools/xen-9pfsd/Makefile
 create mode 100644 tools/xen-9pfsd/xen-9pfsd.c

diff --git a/tools/Makefile b/tools/Makefile
index 3a510663a0..f8faa3a902 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -32,6 +32,7 @@ SUBDIRS-y += xenpmd
 SUBDIRS-$(CONFIG_GOLANG) += golang
 SUBDIRS-y += xl
 SUBDIRS-y += helpers
+SUBDIRS-y += xen-9pfsd
 SUBDIRS-$(CONFIG_X86) += xenpaging
 SUBDIRS-$(CONFIG_X86) += debugger
 SUBDIRS-$(CONFIG_TESTS) += tests
diff --git a/tools/xen-9pfsd/.gitignore b/tools/xen-9pfsd/.gitignore
new file mode 100644
index 0000000000..d0c2d223ef
--- /dev/null
+++ b/tools/xen-9pfsd/.gitignore
@@ -0,0 +1 @@
+/xen-9pfsd
diff --git a/tools/xen-9pfsd/Makefile b/tools/xen-9pfsd/Makefile
new file mode 100644
index 0000000000..4e35202f08
--- /dev/null
+++ b/tools/xen-9pfsd/Makefile
@@ -0,0 +1,38 @@
+#
+# tools/xen-9pfsd/Makefile
+#
+
+XEN_ROOT = $(CURDIR)/../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+CFLAGS += $(PTHREAD_CFLAGS)
+LDFLAGS += $(PTHREAD_LDFLAGS)
+
+TARGETS := xen-9pfsd
+
+XEN-9PFSD_OBJS = xen-9pfsd.o
+$(XEN-9PFSD_OBJS): CFLAGS += $(CFLAGS_libxenstore)
+$(XEN-9PFSD_OBJS): CFLAGS += $(CFLAGS_libxenevtchn)
+$(XEN-9PFSD_OBJS): CFLAGS += $(CFLAGS_libxengnttab)
+xen-9pfsd: LDLIBS += $(call xenlibs-ldlibs,store evtchn gnttab)
+
+.PHONY: all
+all: $(TARGETS)
+
+xen-9pfsd: $(XEN-9PFSD_OBJS)
+	$(CC) $(LDFLAGS) -o $@ $(XEN-9PFSD_OBJS) $(LDLIBS) $(APPEND_LDFLAGS)
+
+.PHONY: install
+install: all
+	$(INSTALL_DIR) $(DESTDIR)$(LIBEXEC_BIN)
+	for i in $(TARGETS); do $(INSTALL_PROG) $$i $(DESTDIR)$(LIBEXEC_BIN); done
+
+.PHONY: uninstall
+uninstall:
+	for i in $(TARGETS); do rm -f $(DESTDIR)$(LIBEXEC_BIN)/$$i; done
+
+.PHONY: clean
+clean:
+	$(RM) *.o $(TARGETS) $(DEPS_RM)
+
+distclean: clean
diff --git a/tools/xen-9pfsd/xen-9pfsd.c b/tools/xen-9pfsd/xen-9pfsd.c
new file mode 100644
index 0000000000..c365b35fe5
--- /dev/null
+++ b/tools/xen-9pfsd/xen-9pfsd.c
@@ -0,0 +1,145 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * xen-9pfsd - Xen 9pfs daemon
+ *
+ * Copyright (C) 2023 Juergen Gross <jgross@suse.com>
+ *
+ * Daemon to enable guests to access a directory of the dom0 file system.
+ * Access is made via the 9pfs protocol (xen-9pfsd acts as a PV 9pfs backend).
+ *
+ * Usage: xen-9pfsd
+ *
+ * xen-9pfsd does NOT support writing any links (neither soft links nor hard
+ * links), and it is accepting only canonicalized file paths in order to
+ * avoid the possibility to "escape" from the guest specific directory.
+ *
+ * The backend device string is "xen_9pfs", the tag used for mounting the
+ * 9pfs device is "Xen".
+ *
+ * As an additional security measure the maximum file space used by the guest
+ * can be limited by the backend Xenstore node "max-size" specifying the size
+ * in MBytes. This size includes the size of the root directory of the guest.
+ */
+
+#include <err.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <xenevtchn.h>
+#include <xengnttab.h>
+#include <xenstore.h>
+
+static volatile bool stop_me;
+static bool daemon_running;
+static struct xs_handle *xs;
+static xengnttab_handle *xg;
+static xenevtchn_handle *xe;
+
+static void handle_stop(int sig)
+{
+    stop_me = true;
+}
+
+static void close_all(void)
+{
+    if ( daemon_running )
+        xs_rm(xs, XBT_NULL, "libxl/xen-9pfs");
+    if ( xe )
+        xenevtchn_close(xe);
+    if ( xg )
+        xengnttab_close(xg);
+    if ( xs )
+        xs_close(xs);
+    closelog();
+}
+
+static void do_err(const char *msg)
+{
+    syslog(LOG_ALERT, "%s, errno = %d", msg, errno);
+    close_all();
+    exit(1);
+}
+
+static void xen_connect(void)
+{
+    xs_transaction_t t;
+    char *val;
+    unsigned int len;
+
+    xs = xs_open(0);
+    if ( xs == NULL )
+        do_err("xs_open() failed");
+
+    xg = xengnttab_open(NULL, 0);
+    if ( xg == NULL )
+        do_err("xengnttab_open() failed");
+
+    xe = xenevtchn_open(NULL, 0);
+    if ( xe == NULL )
+        do_err("xenevtchn_open() failed");
+
+    while ( true )
+    {
+        t = xs_transaction_start(xs);
+        if ( t == XBT_NULL )
+            do_err("xs_transaction_start() failed");
+
+        val = xs_read(xs, t, "libxl/xen-9pfs/state", &len);
+        if ( val )
+        {
+            free(val);
+            xs_transaction_end(xs, t, true);
+            do_err("daemon already running");
+        }
+
+        if ( !xs_write(xs, t, "libxl/xen-9pfs/state", "running",
+                       strlen("running")) )
+        {
+            xs_transaction_end(xs, t, true);
+            do_err("xs_write() failed writing state");
+        }
+
+        if ( xs_transaction_end(xs, t, false) )
+            break;
+        if ( errno != EAGAIN )
+            do_err("xs_transaction_end() failed");
+    }
+
+    daemon_running = true;
+}
+
+int main(int argc, char *argv[])
+{
+    struct sigaction act = { .sa_handler = handle_stop, };
+    int syslog_mask = LOG_MASK(LOG_WARNING) | LOG_MASK(LOG_ERR) |
+                      LOG_MASK(LOG_CRIT) | LOG_MASK(LOG_ALERT) |
+                      LOG_MASK(LOG_EMERG);
+
+    umask(027);
+    if ( getenv("XEN_9PFSD_VERBOSE") )
+        syslog_mask |= LOG_MASK(LOG_NOTICE) | LOG_MASK(LOG_INFO);
+    openlog("xen-9pfsd", LOG_CONS, LOG_DAEMON);
+    setlogmask(syslog_mask);
+
+    sigemptyset(&act.sa_mask);
+    sigaction(SIGHUP, &act, NULL);
+
+    xen_connect();
+
+    while ( !stop_me )
+    {
+        sleep(60);
+    }
+
+    close_all();
+
+    return 0;
+}
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 03/29] tools/xenlogd: connect to frontend
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
  2023-11-10 16:07 ` [PATCH v2 01/29] xen/public: add some more 9pfs xenstore paths Juergen Gross
  2023-11-10 16:07 ` [PATCH v2 02/29] tools: add a new xen logging daemon Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-20 15:49   ` Jason Andryuk
  2023-11-10 16:07 ` [PATCH v2 04/29] tools/xenlogd: add transport layer Juergen Gross
                   ` (25 subsequent siblings)
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Anthony PERARD

Add the code for connecting to frontends to xenlogd.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- support multiple rings per device (Jason Andryuk)
- don't set .revents initially (Jason Andryuk)
- call poll() with infinite timeout (Jason Andryuk)
- take mutex before calling pthread_cond_signal()
---
 tools/xen-9pfsd/Makefile    |   2 +-
 tools/xen-9pfsd/io.c        |  45 +++
 tools/xen-9pfsd/xen-9pfsd.c | 625 +++++++++++++++++++++++++++++++++++-
 tools/xen-9pfsd/xen-9pfsd.h |  60 ++++
 4 files changed, 728 insertions(+), 4 deletions(-)
 create mode 100644 tools/xen-9pfsd/io.c
 create mode 100644 tools/xen-9pfsd/xen-9pfsd.h

diff --git a/tools/xen-9pfsd/Makefile b/tools/xen-9pfsd/Makefile
index 4e35202f08..2023b19c62 100644
--- a/tools/xen-9pfsd/Makefile
+++ b/tools/xen-9pfsd/Makefile
@@ -10,7 +10,7 @@ LDFLAGS += $(PTHREAD_LDFLAGS)
 
 TARGETS := xen-9pfsd
 
-XEN-9PFSD_OBJS = xen-9pfsd.o
+XEN-9PFSD_OBJS = xen-9pfsd.o io.o
 $(XEN-9PFSD_OBJS): CFLAGS += $(CFLAGS_libxenstore)
 $(XEN-9PFSD_OBJS): CFLAGS += $(CFLAGS_libxenevtchn)
 $(XEN-9PFSD_OBJS): CFLAGS += $(CFLAGS_libxengnttab)
diff --git a/tools/xen-9pfsd/io.c b/tools/xen-9pfsd/io.c
new file mode 100644
index 0000000000..e1e37970f4
--- /dev/null
+++ b/tools/xen-9pfsd/io.c
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * xen-9pfsd - Xen 9pfs daemon
+ *
+ * Copyright (C) 2023 Juergen Gross <jgross@suse.com>
+ *
+ * I/O thread handling.
+ */
+
+#include <stdbool.h>
+#include <string.h>
+#include <syslog.h>
+
+#include "xen-9pfsd.h"
+
+static bool io_work_pending(struct ring *ring)
+{
+    if ( ring->stop_thread )
+        return true;
+    return false;
+}
+
+void *io_thread(void *arg)
+{
+    struct ring *ring = arg;
+
+    while ( !ring->stop_thread )
+    {
+        pthread_mutex_lock(&ring->mutex);
+        if ( !io_work_pending(ring) )
+        {
+            if ( xenevtchn_unmask(xe, ring->evtchn) < 0 )
+                syslog(LOG_WARNING, "xenevtchn_unmask() failed");
+            pthread_cond_wait(&ring->cond, &ring->mutex);
+        }
+        pthread_mutex_unlock(&ring->mutex);
+
+        /* TODO: I/O handling. */
+    }
+
+    ring->thread_active = false;
+
+    return NULL;
+}
diff --git a/tools/xen-9pfsd/xen-9pfsd.c b/tools/xen-9pfsd/xen-9pfsd.c
index c365b35fe5..cc5734402d 100644
--- a/tools/xen-9pfsd/xen-9pfsd.c
+++ b/tools/xen-9pfsd/xen-9pfsd.c
@@ -24,34 +24,604 @@
 
 #include <err.h>
 #include <errno.h>
+#include <poll.h>
+#include <pthread.h>
 #include <signal.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <syslog.h>
+#include <sys/mman.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
-#include <xenevtchn.h>
 #include <xengnttab.h>
 #include <xenstore.h>
 
+#include "xen-9pfsd.h"
+
+/*
+ * List of currently known devices.
+ * The list itself is modified only in the main thread. When a device is being
+ * removed its memory needs to be freed after the I/O thread (if existing)
+ * has stopped.
+ */
+static XEN_TAILQ_HEAD(devhead, device) devs = XEN_TAILQ_HEAD_INITIALIZER(devs);
+
+struct path {
+    char path[100];
+};
+
 static volatile bool stop_me;
 static bool daemon_running;
 static struct xs_handle *xs;
 static xengnttab_handle *xg;
-static xenevtchn_handle *xe;
+static unsigned int now;
+
+xenevtchn_handle *xe;
 
 static void handle_stop(int sig)
 {
     stop_me = true;
 }
 
+static int check_host_path(device *device)
+{
+    struct stat statbuf;
+    char *path, *p;
+    int ret = 1;
+
+    if ( !device->host_path )
+        return 1;
+
+    if ( device->host_path[0] != '/' )
+        return 1;
+
+    path = strdup(device->host_path);
+    if ( !path )
+    {
+        syslog(LOG_CRIT, "memory allocation failure!");
+        return 1;
+    }
+
+    for ( p = path; p; )
+    {
+        p = strchr(p + 1, '/');
+        if ( p )
+            *p = 0;
+        if ( !stat(path, &statbuf) )
+        {
+            if ( !(statbuf.st_mode & S_IFDIR) )
+                break;
+            if ( !p )
+            {
+                ret = 0;
+                break;
+            }
+            *p = '/';
+            continue;
+        }
+        if ( mkdir(path, 0777) )
+            break;
+        if ( p )
+            *p = '/';
+    }
+
+    free(path);
+    return ret;
+}
+
+static void construct_frontend_path(device *device, const char *node,
+                                    struct path *p)
+{
+    snprintf(p->path, sizeof(p->path), "/local/domain/%u/device/9pfs/%u/%s",
+             device->domid, device->devid, node);
+}
+
+static void construct_backend_path(device *device, const char *node,
+                                   struct path *p)
+{
+    snprintf(p->path, sizeof(p->path), "backend/xen_9pfs/%u/%u/%s",
+             device->domid, device->devid, node);
+}
+
+static char *read_backend_node(device *device, const char *node)
+{
+    struct path p;
+    char *val;
+    unsigned int len;
+
+    construct_backend_path(device, node, &p);
+    val = xs_read(xs, XBT_NULL, p.path, &len);
+
+    return val;
+}
+
+static unsigned int uint_from_string(char *string, unsigned int def)
+{
+    unsigned long val;
+    char *end;
+
+    if ( !string )
+        return def;
+
+    val = strtoul(string, &end, 10);
+    if ( *end || val > UINT_MAX )
+        val = def;
+    free(string);
+
+    return val;
+}
+
+static unsigned int read_backend_node_uint(device *device, const char *node,
+                                           unsigned int def)
+{
+    return uint_from_string(read_backend_node(device, node), def);
+}
+
+static unsigned int read_frontend_node_uint(device *device, const char *node,
+                                            unsigned int def)
+{
+    struct path p;
+    unsigned int len;
+
+    construct_frontend_path(device, node, &p);
+
+    return uint_from_string(xs_read(xs, XBT_NULL, p.path, &len), def);
+}
+
+static int write_backend_node(device *device, const char *node, const char *val)
+{
+    struct path p;
+    struct xs_permissions perms[2] = {
+        { .id = 0, .perms = XS_PERM_NONE },
+        { .id = device->domid, .perms = XS_PERM_READ }
+    };
+
+    construct_backend_path(device, node, &p);
+    if ( !xs_write(xs, XBT_NULL, p.path, val, strlen(val)) )
+    {
+        syslog(LOG_ERR, "error writing bacḱend node \"%s\" for device %u/%u",
+               node, device->domid, device->devid);
+        return 1;
+    }
+
+    if ( !xs_set_permissions(xs, XBT_NULL, p.path, perms, 2) )
+    {
+        syslog(LOG_ERR, "error setting permissions for \"%s\"", p.path);
+        return 1;
+    }
+
+    return 0;
+}
+
+static int write_backend_node_uint(device *device, const char *node,
+                                   unsigned int val)
+{
+    char str[12];
+
+    snprintf(str, sizeof(str), "%u", val);
+
+    return write_backend_node(device, node, str);
+}
+
+static int write_backend_state(device *device, enum xenbus_state state)
+{
+    struct path p;
+    char val[2];
+
+    snprintf(val, sizeof(val), "%u", state);
+    construct_backend_path(device, "state", &p);
+    if ( !xs_write(xs, XBT_NULL, p.path, val, 1) )
+    {
+        syslog(LOG_ERR, "error writing backend state %u for device %u/%u",
+               state, device->domid, device->devid);
+        return 1;
+    }
+
+    device->backend_state = state;
+
+    return 0;
+}
+
+static device *find_device(unsigned int domid, unsigned int devid)
+{
+    device *device;
+
+    XEN_TAILQ_FOREACH( device, &devs, list )
+    {
+        if ( domid == device->domid && devid == device->devid )
+            return device;
+    }
+
+    return NULL;
+}
+
+static void free_device(device *device)
+{
+    char token[20];
+    struct path p;
+
+    construct_frontend_path(device, "state", &p);
+    snprintf(token, sizeof(token), "%u/%u", device->domid, device->devid);
+    xs_unwatch(xs, p.path, token);
+
+    free(device->host_path);
+    free(device);
+}
+
+static device *new_device(unsigned int domid, unsigned int devid)
+{
+    device *device;
+    char token[20];
+    struct path p;
+    char *val;
+
+    device = calloc(1, sizeof(*device));
+    if ( !device )
+    {
+        syslog(LOG_CRIT, "Got no memory for new device %u/%u", domid, devid);
+        return NULL;
+    }
+
+    device->domid = domid;
+    device->devid = devid;
+
+    construct_frontend_path(device, "state", &p);
+    snprintf(token, sizeof(token), "%u/%u", domid, devid);
+    if ( !xs_watch(xs, p.path, token) )
+    {
+        syslog(LOG_ERR, "Setting up watch for device %u/%u failed",
+               domid, devid);
+        free(device);
+        return NULL;
+    }
+
+    val = read_backend_node(device, "security_model");
+    if ( !val || strcmp(val, "none") )
+    {
+        syslog(LOG_ERR, "Security model \"%s\" for device %u/%u invalid.",
+               val, domid, devid);
+        free(val);
+        goto err;
+    }
+    free(val);
+
+    device->max_space = read_backend_node_uint(device, "max-space", 0);
+    device->max_files = read_backend_node_uint(device, "max-files", 0);
+    device->max_open_files =
+        read_backend_node_uint(device, "max-open-files", 0)
+        ?: MAX_OPEN_FILES_DEFAULT;
+    device->auto_delete = read_backend_node_uint(device, "auto-delete", 0);
+
+    device->host_path = read_backend_node(device, "path");
+    if ( check_host_path(device) )
+    {
+        syslog(LOG_ERR, "Host path \"%s\" for device %u/%u invalid.",
+               device->host_path, domid, devid);
+        goto err;
+    }
+
+    if ( write_backend_node(device, "versions", "1") )
+        goto err;
+    if ( write_backend_node_uint(device, "max-rings", MAX_RINGS) )
+        goto err;
+    if ( write_backend_node_uint(device, "max-ring-page-order",
+                                 MAX_RING_ORDER) )
+        goto err;
+
+    if ( write_backend_state(device, XenbusStateInitWait) )
+        goto err;
+
+    XEN_TAILQ_INSERT_TAIL(&devs, device, list);
+    syslog(LOG_INFO, "New device %u/%u added", domid, devid);
+
+    return device;
+
+ err:
+    free_device(device);
+    return NULL;
+}
+
+static void disconnect_ring(struct ring *ring)
+{
+    if ( !ring )
+        return;
+
+    if ( ring->thread_active )
+    {
+        ring->stop_thread = true;
+        pthread_cond_signal(&ring->cond);
+        pthread_join(ring->thread, NULL);
+        ring->stop_thread = false;
+    }
+
+    if ( ring->data.in )
+    {
+        xengnttab_unmap(xg, ring->data.in, 1 << ring->ring_order);
+        ring->data.in = NULL;
+    }
+    if ( ring->intf )
+    {
+        xengnttab_unmap(xg, ring->intf, 1 );
+        ring->intf = NULL;
+    }
+
+    if ( ring->evtchn )
+    {
+        xenevtchn_unbind(xe, ring->evtchn);
+        ring->evtchn = 0;
+    }
+
+    pthread_mutex_destroy(&ring->mutex);
+    pthread_cond_destroy(&ring->cond);
+}
+
+static void disconnect_guest(device *device)
+{
+    unsigned int ring_idx;
+
+    for ( ring_idx = 0; ring_idx < device->num_rings; ring_idx++ )
+    {
+        disconnect_ring(device->ring[ring_idx]);
+        free(device->ring[ring_idx]);
+        device->ring[ring_idx] = NULL;
+    }
+
+    device->num_rings = 0;
+}
+
+static void close_device(device *device, enum xenbus_state state)
+{
+    disconnect_guest(device);
+    write_backend_state(device, state);
+}
+
+static void connect_err(device *device, const char *msg)
+{
+    syslog(LOG_WARNING, "%s", msg);
+    close_device(device, XenbusStateClosed);
+}
+
+static void connect_device(device *device)
+{
+    unsigned int val;
+    unsigned int ring_idx;
+    char node[20];
+    struct ring *ring;
+    xenevtchn_port_or_error_t evtchn;
+
+    val = read_frontend_node_uint(device, "version", 0);
+    if ( val != 1 )
+        return connect_err(device, "frontend specifies illegal version");
+    device->num_rings = read_frontend_node_uint(device, "num-rings", 0);
+    if ( device->num_rings < 1 || device->num_rings > MAX_RINGS )
+        return connect_err(device, "frontend specifies illegal ring number");
+
+    for ( ring_idx = 0; ring_idx < device->num_rings; ring_idx++ )
+    {
+        ring = calloc(1, sizeof(*ring));
+        if ( !ring )
+            return connect_err(device, "could not allocate ring memory");
+        device->ring[ring_idx] = ring;
+        ring->device = device;
+        pthread_cond_init(&ring->cond, NULL);
+        pthread_mutex_init(&ring->mutex, NULL);
+
+
+        snprintf(node, sizeof(node), "event-channel-%u", ring_idx);
+        val = read_frontend_node_uint(device, node, 0);
+        if ( val == 0 )
+            return connect_err(device, "frontend specifies illegal evtchn");
+        evtchn = xenevtchn_bind_interdomain(xe, device->domid, val);
+        if ( evtchn < 0 )
+            return connect_err(device, "could not bind to event channel");
+        ring->evtchn = evtchn;
+
+        snprintf(node, sizeof(node), "ring-ref%u", ring_idx);
+        val = read_frontend_node_uint(device, node, 0);
+        if ( val == 0 )
+            return connect_err(device,
+                               "frontend specifies illegal grant for ring");
+        ring->intf = xengnttab_map_grant_ref(xg, device->domid, val,
+                                             PROT_READ | PROT_WRITE);
+        if ( !ring->intf )
+            return connect_err(device, "could not map interface page");
+        ring->ring_order = ring->intf->ring_order;
+        if ( ring->ring_order > MAX_RING_ORDER || ring->ring_order < 1 )
+            return connect_err(device, "frontend specifies illegal ring order");
+        ring->ring_size = XEN_FLEX_RING_SIZE(ring->ring_order);
+        ring->data.in = xengnttab_map_domain_grant_refs(xg,
+                                                        1 << ring->ring_order,
+                                                        device->domid,
+                                                        ring->intf->ref,
+                                                        PROT_READ | PROT_WRITE);
+        if ( !ring->data.in )
+            return connect_err(device, "could not map ring pages");
+        ring->data.out = ring->data.in + ring->ring_size;
+
+        if ( pthread_create(&ring->thread, NULL, io_thread, ring) )
+            return connect_err(device, "could not start I/O thread");
+        ring->thread_active = true;
+    }
+
+    write_backend_state(device, XenbusStateConnected);
+}
+
+static void remove_device(device *device)
+{
+    XEN_TAILQ_REMOVE(&devs, device, list);
+
+    disconnect_guest(device);
+    free_device(device);
+}
+
+static void remove_all_devices(void)
+{
+    device *device, *tmp;
+
+    XEN_TAILQ_FOREACH_SAFE( device, &devs, list, tmp )
+        remove_device(device);
+}
+
+static void frontend_changed(device *device)
+{
+    struct path p;
+    char *state, *end;
+    unsigned int len;
+    unsigned long new_state;
+
+    construct_frontend_path(device, "state", &p);
+    state = xs_read(xs, XBT_NULL, p.path, &len);
+    if ( !state )
+    {
+        close_device(device, XenbusStateClosed);
+        return;
+    }
+
+    new_state = strtoul(state, &end, 10);
+    if ( *end || new_state > XenbusStateReconfigured )
+    {
+        syslog(LOG_WARNING, "unknown state \"%s\" seen for device %u/%u", state,
+               device->domid, device->devid);
+        new_state = XenbusStateUnknown;
+    }
+    free(state);
+
+    if ( new_state == device->frontend_state )
+        return;
+
+    switch ( new_state )
+    {
+    case XenbusStateInitialising:
+        break;
+
+    case XenbusStateInitialised:
+        connect_device(device);
+        break;
+
+    case XenbusStateConnected:
+        break;
+
+    case XenbusStateClosing:
+        close_device(device, XenbusStateClosing);
+        break;
+
+    case XenbusStateClosed:
+        close_device(device, XenbusStateClosed);
+        break;
+
+    default:
+        syslog(LOG_WARNING, "not handled frontend state %lu for device %u/%u",
+               new_state, device->domid, device->devid);
+        break;
+    }
+
+    device->frontend_state = new_state;
+}
+
+static void check_device(unsigned int domid, unsigned int devid)
+{
+    device *device;
+
+    device = find_device(domid, devid);
+    if ( !device )
+    {
+        device = new_device(domid, devid);
+        if ( !device )
+            return;
+    }
+
+    device->last_seen = now;
+}
+
+static void scan_backend(void)
+{
+    char **doms;
+    unsigned int n_doms, dom;
+    char **devices;
+    unsigned int n_devs, dev;
+    char dom_path[24];
+    unsigned long domid, devid;
+    char *end;
+    device *device, *tmp;
+
+    now++;
+
+    doms = xs_directory(xs, XBT_NULL, "backend/xen_9pfs", &n_doms);
+    if ( doms == NULL )
+        return;
+
+    for ( dom = 0; dom < n_doms; dom++ )
+    {
+        errno = 0;
+        domid = strtoul(doms[dom], &end, 10);
+        if ( errno || *end || domid >= DOMID_FIRST_RESERVED )
+            continue;
+
+        snprintf(dom_path, sizeof(dom_path), "backend/xen_9pfs/%lu", domid);
+        devices = xs_directory(xs, XBT_NULL, dom_path, &n_devs);
+
+        for ( dev = 0; dev < n_devs; dev++ )
+        {
+            errno = 0;
+            devid = strtoul(devices[dev], &end, 10);
+            if ( errno || *end || devid > UINT_MAX )
+                continue;
+
+            check_device(domid, devid);
+        }
+
+        free(devices);
+    }
+
+    free(doms);
+
+    XEN_TAILQ_FOREACH_SAFE( device, &devs, list, tmp )
+    {
+        if ( device->last_seen != now )
+            remove_device(device);
+    }
+}
+
+static void handle_watch(char *path, char *token)
+{
+    unsigned int domid, devid;
+    device *device;
+
+    if ( !strcmp(token, "main") )
+    {
+        scan_backend();
+        return;
+    }
+
+    if ( sscanf(token, "%u/%u", &domid, &devid) != 2 )
+    {
+        syslog(LOG_WARNING, "unknown watch event %s %s", path, token);
+        return;
+    }
+
+    device = find_device(domid, devid);
+    if ( !device )
+    {
+        syslog(LOG_WARNING, "watch event for unknown device %u/%u",
+               domid, devid);
+        return;
+    }
+
+    frontend_changed(device);
+}
+
 static void close_all(void)
 {
     if ( daemon_running )
+    {
         xs_rm(xs, XBT_NULL, "libxl/xen-9pfs");
+        xs_unwatch(xs, "backend/xen_9pfs", "main");
+
+        remove_all_devices();
+    }
     if ( xe )
         xenevtchn_close(xe);
     if ( xg )
@@ -68,6 +638,33 @@ static void do_err(const char *msg)
     exit(1);
 }
 
+static void handle_event(void)
+{
+    xenevtchn_port_or_error_t evtchn;
+    device *device;
+    struct ring *ring;
+    unsigned int ring_idx;
+
+    evtchn = xenevtchn_pending(xe);
+    if ( evtchn < 0 )
+        do_err("xenevtchn_pending() failed");
+
+    XEN_TAILQ_FOREACH( device, &devs, list )
+    {
+        for ( ring_idx = 0; ring_idx < device->num_rings; ring_idx++ )
+        {
+            ring = device->ring[ring_idx];
+            if ( ring && ring->evtchn == evtchn )
+            {
+                pthread_mutex_lock(&ring->mutex);
+                pthread_cond_signal(&ring->cond);
+                pthread_mutex_unlock(&ring->mutex);
+                return;
+            }
+        }
+    }
+}
+
 static void xen_connect(void)
 {
     xs_transaction_t t;
@@ -122,6 +719,11 @@ int main(int argc, char *argv[])
     int syslog_mask = LOG_MASK(LOG_WARNING) | LOG_MASK(LOG_ERR) |
                       LOG_MASK(LOG_CRIT) | LOG_MASK(LOG_ALERT) |
                       LOG_MASK(LOG_EMERG);
+    char **watch;
+    struct pollfd p[2] = {
+        { .events = POLLIN },
+        { .events = POLLIN }
+    };
 
     umask(027);
     if ( getenv("XEN_9PFSD_VERBOSE") )
@@ -134,9 +736,26 @@ int main(int argc, char *argv[])
 
     xen_connect();
 
+    if ( !xs_watch(xs, "backend/xen_9pfs", "main") )
+        do_err("xs_watch() in main thread failed");
+    p[0].fd = xs_fileno(xs);
+    p[1].fd = xenevtchn_fd(xe);
+
+    scan_backend();
+
     while ( !stop_me )
     {
-        sleep(60);
+        while ( (p[0].revents & POLLIN) &&
+                (watch = xs_check_watch(xs)) != NULL )
+        {
+            handle_watch(watch[XS_WATCH_PATH], watch[XS_WATCH_TOKEN]);
+            free(watch);
+        }
+
+        if ( p[1].revents & POLLIN )
+            handle_event();
+
+        poll(p, 2, -1);
     }
 
     close_all();
diff --git a/tools/xen-9pfsd/xen-9pfsd.h b/tools/xen-9pfsd/xen-9pfsd.h
new file mode 100644
index 0000000000..432f321d0d
--- /dev/null
+++ b/tools/xen-9pfsd/xen-9pfsd.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef XEN_9PFSD_H
+#define XEN_9PFSD_H
+
+#include <pthread.h>
+#include <stdbool.h>
+#include <xenevtchn.h>
+#include <xen_list.h>
+#include <xen/xen.h>
+#include <xen/io/xenbus.h>
+#include <xen/io/9pfs.h>
+
+#define MAX_RINGS                4
+#define MAX_RING_ORDER           9
+#define MAX_OPEN_FILES_DEFAULT   5
+
+typedef struct device device;
+
+struct ring {
+    device *device;
+    pthread_t thread;
+    bool thread_active;
+    bool stop_thread;
+    pthread_cond_t cond;
+    pthread_mutex_t mutex;
+
+    evtchn_port_t evtchn;
+    struct xen_9pfs_data_intf *intf;
+    unsigned int ring_order;
+    RING_IDX ring_size;
+    struct xen_9pfs_data data;
+};
+
+struct device {
+    /* Admin data. */
+    XEN_TAILQ_ENTRY(device) list;
+    unsigned int last_seen;    /* Set in scan_backend(). */
+    unsigned int domid;
+    unsigned int devid;
+
+    /* Tool side configuration data. */
+    char *host_path;
+    unsigned int max_space;
+    unsigned int max_files;
+    unsigned int max_open_files;
+    bool auto_delete;
+
+    /* Connection data. */
+    enum xenbus_state backend_state;
+    enum xenbus_state frontend_state;
+    unsigned int num_rings;
+    struct ring *ring[MAX_RINGS];
+};
+
+extern xenevtchn_handle *xe;
+
+void *io_thread(void *arg);
+
+#endif /* XEN_9PFSD_H */
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 04/29] tools/xenlogd: add transport layer
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (2 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 03/29] tools/xenlogd: connect to frontend Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-20 16:12   ` Jason Andryuk
  2023-11-10 16:07 ` [PATCH v2 05/29] tools/xenlogd: add 9pfs response generation support Juergen Gross
                   ` (24 subsequent siblings)
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Anthony PERARD

Add the transport layer of 9pfs. This is basically the infrastructure
to receive requests from the frontend and to send the related answers
via the rings.

In order to avoid unaligned accesses e.g. on Arm, add the definition of
__packed to the common-macros.h header.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- rename put_request_bytes() (Jason Andryuk)
- rename get_request_bytes() and put_response_bytes() len parameter
  (Jason Andryuk)
- don't unmask event channel if error indicator is set (Jason Andryuk)
---
 tools/include/xen-tools/common-macros.h |   4 +
 tools/xen-9pfsd/io.c                    | 143 +++++++++++++++++++++++-
 tools/xen-9pfsd/xen-9pfsd.h             |  16 +++
 3 files changed, 160 insertions(+), 3 deletions(-)

diff --git a/tools/include/xen-tools/common-macros.h b/tools/include/xen-tools/common-macros.h
index e5ed603904..c3fd7d2a30 100644
--- a/tools/include/xen-tools/common-macros.h
+++ b/tools/include/xen-tools/common-macros.h
@@ -79,6 +79,10 @@
 #define __must_check __attribute__((__warn_unused_result__))
 #endif
 
+#ifndef __packed
+#define __packed __attribute__((__packed__))
+#endif
+
 #define container_of(ptr, type, member) ({              \
     typeof(((type *)0)->member) *mptr__ = (ptr);        \
     (type *)((char *)mptr__ - offsetof(type, member));  \
diff --git a/tools/xen-9pfsd/io.c b/tools/xen-9pfsd/io.c
index e1e37970f4..d9aa081bea 100644
--- a/tools/xen-9pfsd/io.c
+++ b/tools/xen-9pfsd/io.c
@@ -6,39 +6,176 @@
  * Copyright (C) 2023 Juergen Gross <jgross@suse.com>
  *
  * I/O thread handling.
+ *
+ * Only handle one request at a time, pushing out the complete response
+ * before looking for the next request.
  */
 
 #include <stdbool.h>
+#include <stdlib.h>
 #include <string.h>
 #include <syslog.h>
+#include <xenctrl.h>           /* For cpu barriers. */
+#include <xen-tools/common-macros.h>
 
 #include "xen-9pfsd.h"
 
+/*
+ * Note that the ring names "in" and "out" are from the frontend's
+ * perspective, so the "in" ring will be used for responses to the frontend,
+ * while the "out" ring is used for requests from the frontend to the
+ * backend.
+ */
+static unsigned int ring_in_free(struct ring *ring)
+{
+    unsigned int queued;
+
+    queued = xen_9pfs_queued(ring->prod_pvt_in, ring->intf->in_cons,
+                             ring->ring_size);
+    xen_rmb();
+
+    return ring->ring_size - queued;
+}
+
+static unsigned int ring_out_data(struct ring *ring)
+{
+    unsigned int queued;
+
+    queued = xen_9pfs_queued(ring->intf->out_prod, ring->cons_pvt_out,
+                             ring->ring_size);
+    xen_rmb();
+
+    return queued;
+}
+
+static unsigned int get_request_bytes(struct ring *ring, unsigned int off,
+                                      unsigned int total_len)
+{
+    unsigned int size;
+    unsigned int out_data = ring_out_data(ring);
+    RING_IDX prod, cons;
+
+    size = min(total_len - off, out_data);
+    prod = xen_9pfs_mask(ring->intf->out_prod, ring->ring_size);
+    cons = xen_9pfs_mask(ring->cons_pvt_out, ring->ring_size);
+    xen_9pfs_read_packet(ring->buffer + off, ring->data.out, size,
+                         prod, &cons, ring->ring_size);
+
+    xen_rmb();           /* Read data out before setting visible consumer. */
+    ring->cons_pvt_out += size;
+    ring->intf->out_cons = ring->cons_pvt_out;
+
+    /* Signal that more space is available now. */
+    xenevtchn_notify(xe, ring->evtchn);
+
+    return size;
+}
+
+static unsigned int put_response_bytes(struct ring *ring, unsigned int off,
+                                       unsigned int total_len)
+{
+    unsigned int size;
+    unsigned int in_data = ring_in_free(ring);
+    RING_IDX prod, cons;
+
+    size = min(total_len - off, in_data);
+    prod = xen_9pfs_mask(ring->prod_pvt_in, ring->ring_size);
+    cons = xen_9pfs_mask(ring->intf->in_cons, ring->ring_size);
+    xen_9pfs_write_packet(ring->data.in, ring->buffer + off, size,
+                          &prod, cons, ring->ring_size);
+
+    xen_wmb();           /* Write data out before setting visible producer. */
+    ring->prod_pvt_in += size;
+    ring->intf->in_prod = ring->prod_pvt_in;
+
+    return size;
+}
+
 static bool io_work_pending(struct ring *ring)
 {
     if ( ring->stop_thread )
         return true;
-    return false;
+    if ( ring->error )
+        return false;
+    return ring->handle_response ? ring_in_free(ring) : ring_out_data(ring);
 }
 
 void *io_thread(void *arg)
 {
     struct ring *ring = arg;
+    unsigned int count = 0;
+    struct p9_header hdr;
+    bool in_hdr = true;
+
+    ring->max_size = ring->ring_size;
+    ring->buffer = malloc(ring->max_size);
+    if ( !ring->buffer )
+    {
+        syslog(LOG_CRIT, "memory allocation failure!");
+        return NULL;
+    }
 
     while ( !ring->stop_thread )
     {
         pthread_mutex_lock(&ring->mutex);
         if ( !io_work_pending(ring) )
         {
-            if ( xenevtchn_unmask(xe, ring->evtchn) < 0 )
+            if ( !ring->error && xenevtchn_unmask(xe, ring->evtchn) < 0 )
                 syslog(LOG_WARNING, "xenevtchn_unmask() failed");
             pthread_cond_wait(&ring->cond, &ring->mutex);
         }
         pthread_mutex_unlock(&ring->mutex);
 
-        /* TODO: I/O handling. */
+        if ( ring->stop_thread || ring->error )
+            continue;
+
+        if ( !ring->handle_response )
+        {
+            if ( in_hdr )
+            {
+                count += get_request_bytes(ring, count, sizeof(hdr));
+                if ( count != sizeof(hdr) )
+                    continue;
+                hdr = *(struct p9_header *)ring->buffer;
+                if ( hdr.size > ring->max_size || hdr.size < sizeof(hdr) )
+                {
+                    syslog(LOG_ERR, "%u.%u specified illegal request length %u",
+                           ring->device->domid, ring->device->devid, hdr.size);
+                    ring->error = true;
+                    continue;
+                }
+                in_hdr = false;
+            }
+
+            count += get_request_bytes(ring, count, hdr.size);
+            if ( count < hdr.size )
+                continue;
+
+            /* TODO: handle request (will rewrite hdr.size). */
+
+            ring->handle_response = true;
+            hdr.size = ((struct p9_header *)ring->buffer)->size;
+            count = 0;
+        }
+
+        if ( ring->handle_response )
+        {
+            count += put_response_bytes(ring, count, hdr.size);
+
+            if ( count == hdr.size )
+            {
+                /* Signal presence of response. */
+                xenevtchn_notify(xe, ring->evtchn);
+
+                ring->handle_response = false;
+                in_hdr = true;
+                count = 0;
+            }
+        }
     }
 
+    free(ring->buffer);
+
     ring->thread_active = false;
 
     return NULL;
diff --git a/tools/xen-9pfsd/xen-9pfsd.h b/tools/xen-9pfsd/xen-9pfsd.h
index 432f321d0d..7d6921f164 100644
--- a/tools/xen-9pfsd/xen-9pfsd.h
+++ b/tools/xen-9pfsd/xen-9pfsd.h
@@ -15,6 +15,12 @@
 #define MAX_RING_ORDER           9
 #define MAX_OPEN_FILES_DEFAULT   5
 
+struct p9_header {
+    uint32_t size;
+    uint8_t cmd;
+    uint16_t tag;
+} __attribute__((packed));
+
 typedef struct device device;
 
 struct ring {
@@ -29,7 +35,17 @@ struct ring {
     struct xen_9pfs_data_intf *intf;
     unsigned int ring_order;
     RING_IDX ring_size;
+
+    /* Transport layer data. */
     struct xen_9pfs_data data;
+    RING_IDX prod_pvt_in;
+    RING_IDX cons_pvt_out;
+
+    /* Request and response handling. */
+    uint32_t max_size;
+    bool error;             /* Protocol error - stop processing. */
+    bool handle_response;   /* Main loop now handling response. */
+    void *buffer;           /* Request/response buffer. */
 };
 
 struct device {
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 05/29] tools/xenlogd: add 9pfs response generation support
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (3 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 04/29] tools/xenlogd: add transport layer Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-20 16:57   ` Jason Andryuk
  2023-12-01 19:30   ` Jason Andryuk
  2023-11-10 16:07 ` [PATCH v2 06/29] tools/xenlogd: add 9pfs version request support Juergen Gross
                   ` (23 subsequent siblings)
  28 siblings, 2 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Anthony PERARD

Add support for generation a 9pfs protocol response via a format based
approach.

Strings are stored in a per device string buffer and they are
referenced via their offset in this buffer. This allows to avoid
having to dynamically allocate memory for each single string.

As a first user of the response handling add a generic p9_error()
function which will be used to return any error to the client.

Add all format parsing variants in order to avoid additional code churn
later when adding the users of those variants. Prepare a special case
for the "read" case already (format character 'D'): in order to avoid
adding another buffer for read data support doing the read I/O directly
into the response buffer.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- check parameter size limits (Jason Andryuk)
---
 tools/xen-9pfsd/io.c        | 199 +++++++++++++++++++++++++++++++++++-
 tools/xen-9pfsd/xen-9pfsd.h |   3 +
 2 files changed, 201 insertions(+), 1 deletion(-)

diff --git a/tools/xen-9pfsd/io.c b/tools/xen-9pfsd/io.c
index d9aa081bea..a64199c9de 100644
--- a/tools/xen-9pfsd/io.c
+++ b/tools/xen-9pfsd/io.c
@@ -11,6 +11,7 @@
  * before looking for the next request.
  */
 
+#include <errno.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
@@ -20,6 +21,16 @@
 
 #include "xen-9pfsd.h"
 
+/* P9 protocol commands (response is either cmd+1 or P9_CMD_ERROR). */
+#define P9_CMD_ERROR      107
+
+struct p9_qid {
+    uint8_t type;
+#define QID_TYPE_DIR      0x80
+    uint32_t version;
+    uint64_t path;
+};
+
 /*
  * Note that the ring names "in" and "out" are from the frontend's
  * perspective, so the "in" ring will be used for responses to the frontend,
@@ -100,6 +111,182 @@ static bool io_work_pending(struct ring *ring)
     return ring->handle_response ? ring_in_free(ring) : ring_out_data(ring);
 }
 
+static void fmt_err(const char *fmt)
+{
+    syslog(LOG_CRIT, "illegal format %s passed to fill_buffer()", fmt);
+    exit(1);
+}
+
+/*
+ * Fill buffer with response data.
+ * fmt is a sequence of format characters. Supported characters are:
+ * a: an array (2 bytes number of elements + the following format as elements)
+ *    The number of elements is passed in the first unsigned int parameter, the
+ *    next parameter is a pointer to an array of elements as denoted by the next
+ *    format character.
+ * b: 2 byte unsigned integer
+ *    The parameter is a pointer to a uint16_t value
+ * D: Data blob (4 byte length + <length> bytes)
+ *    2 parameters are consumed, first an unsigned int for the length, then a
+ *    pointer to the first uint8_t value.
+ *    No array support.
+ * L: 8 byte unsigned integer
+ *    The parameter is a pointer to a uint64_t value
+ * Q: Qid (struct p9_qid)
+ * S: String (2 byte length + <length> characters)
+ *    The length is obtained via strlen() of the parameter, being a pointer
+ *    to the first character of the string
+ * U: 4 byte unsigned integer
+ *    The parameter is a pointer to a uint32_t value
+ */
+static void fill_buffer(struct ring *ring, uint8_t cmd, uint16_t tag,
+                        const char *fmt, ...)
+{
+    struct p9_header *hdr = ring->buffer;
+    void *data = hdr + 1;
+    const char *f;
+    const void *par;
+    const char *str_val;
+    const struct p9_qid *qid;
+    unsigned int len;
+    va_list ap;
+    unsigned int array_sz = 0;
+    unsigned int elem_sz = 0;
+
+    hdr->cmd = cmd;
+    hdr->tag = tag;
+
+    va_start(ap, fmt);
+
+    for ( f = fmt; *f; f++ )
+    {
+        if ( !array_sz )
+            par = va_arg(ap, const void *);
+        else
+        {
+            par += elem_sz;
+            array_sz--;
+        }
+
+        switch ( *f )
+        {
+        case 'a':
+            f++;
+            if ( !*f || array_sz )
+                fmt_err(fmt);
+            array_sz = *(const unsigned int *)par;
+            if ( array_sz > 0xffff )
+            {
+                syslog(LOG_CRIT, "array size %u in fill_buffer()", array_sz);
+                exit(1);
+            }
+            *(__packed uint16_t *)data = array_sz;
+            data += sizeof(uint16_t);
+            par = va_arg(ap, const void *);
+            elem_sz = 0;
+            break;
+
+        case 'u':
+            *(__packed uint16_t *)data = *(const uint16_t *)par;
+            elem_sz = sizeof(uint16_t);
+            data += sizeof(uint16_t);
+            break;
+
+        case 'D':
+            if ( array_sz )
+                fmt_err(fmt);
+            len = *(const unsigned int *)par;
+            *(__packed uint32_t *)data = len;
+            data += sizeof(uint32_t);
+            par = va_arg(ap, const void *);
+            if ( data != par )
+                memcpy(data, par, len);
+            data += len;
+            break;
+
+        case 'L':
+            *(__packed uint64_t *)data = *(const uint64_t *)par;
+            elem_sz = sizeof(uint64_t);
+            data += sizeof(uint64_t);
+            break;
+
+        case 'Q':
+            qid = par;
+            elem_sz = sizeof(*qid);
+            *(uint8_t *)data = qid->type;
+            data += sizeof(uint8_t);
+            *(__packed uint32_t *)data = qid->version;
+            data += sizeof(uint32_t);
+            *(__packed uint64_t *)data = qid->path;
+            data += sizeof(uint64_t);
+            break;
+
+        case 'S':
+            str_val = par;
+            elem_sz = sizeof(str_val);
+            len = strlen(str_val);
+            if ( len > 0xffff )
+            {
+                syslog(LOG_CRIT, "string length %u in fill_buffer()", len);
+                exit(1);
+            }
+            *(__packed uint16_t *)data = len;
+            data += sizeof(uint16_t);
+            memcpy(data, str_val, len);
+            data += len;
+            break;
+
+        case 'U':
+            *(__packed uint32_t *)data = *(const uint32_t *)par;
+            elem_sz = sizeof(uint32_t);
+            data += sizeof(uint32_t);
+            break;
+
+        default:
+            fmt_err(fmt);
+        }
+
+        if ( array_sz )
+            f--;
+    }
+
+    hdr->size = data - ring->buffer;
+}
+
+static unsigned int add_string(struct ring *ring, const char *str,
+                               unsigned int len)
+{
+    char *tmp;
+    unsigned int ret;
+
+    if ( ring->str_used + len + 1 > ring->str_size )
+    {
+        tmp = realloc(ring->str, ring->str_used + len + 1);
+        if ( !tmp )
+            return ~0;
+        ring->str = tmp;
+        ring->str_size = ring->str_used + len + 1;
+    }
+
+    ret = ring->str_used;
+    memcpy(ring->str + ret, str, len);
+    ring->str_used += len;
+    ring->str[ring->str_used++] = 0;
+
+    return ret;
+}
+
+static void p9_error(struct ring *ring, uint16_t tag, uint32_t err)
+{
+    unsigned int erroff;
+
+    strerror_r(err, ring->buffer, ring->ring_size);
+    erroff = add_string(ring, ring->buffer, strlen(ring->buffer));
+    fill_buffer(ring, P9_CMD_ERROR, tag, "SU",
+                erroff != ~0 ? ring->str + erroff : "cannot allocate memory",
+                &err);
+}
+
 void *io_thread(void *arg)
 {
     struct ring *ring = arg;
@@ -151,7 +338,16 @@ void *io_thread(void *arg)
             if ( count < hdr.size )
                 continue;
 
-            /* TODO: handle request (will rewrite hdr.size). */
+            ring->str_used = 0;
+
+            switch ( hdr.cmd )
+            {
+            default:
+                syslog(LOG_DEBUG, "%u.%u sent unhandled command %u\n",
+                       ring->device->domid, ring->device->devid, hdr.cmd);
+                p9_error(ring, hdr.tag, EOPNOTSUPP);
+                break;
+            }
 
             ring->handle_response = true;
             hdr.size = ((struct p9_header *)ring->buffer)->size;
@@ -174,6 +370,7 @@ void *io_thread(void *arg)
         }
     }
 
+    free(ring->str);
     free(ring->buffer);
 
     ring->thread_active = false;
diff --git a/tools/xen-9pfsd/xen-9pfsd.h b/tools/xen-9pfsd/xen-9pfsd.h
index 7d6921f164..5ff87ca5bd 100644
--- a/tools/xen-9pfsd/xen-9pfsd.h
+++ b/tools/xen-9pfsd/xen-9pfsd.h
@@ -46,6 +46,9 @@ struct ring {
     bool error;             /* Protocol error - stop processing. */
     bool handle_response;   /* Main loop now handling response. */
     void *buffer;           /* Request/response buffer. */
+    char *str;              /* String work space. */
+    unsigned int str_size;  /* Size of *str. */
+    unsigned int str_used;  /* Currently used size of *str. */
 };
 
 struct device {
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 06/29] tools/xenlogd: add 9pfs version request support
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (4 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 05/29] tools/xenlogd: add 9pfs response generation support Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-10 16:07 ` [PATCH v2 07/29] tools/xenlogd: add 9pfs attach " Juergen Gross
                   ` (22 subsequent siblings)
  28 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Anthony PERARD, Jason Andryuk

Add the version request of the 9pfs protocol. For the version use the
"9P2000.u" variant, as it is supported by Mini-OS and Linux.

For the request parsing add all format items needed even in future in
order to avoid code churn for those additions later.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
---
 tools/xen-9pfsd/io.c | 201 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 201 insertions(+)

diff --git a/tools/xen-9pfsd/io.c b/tools/xen-9pfsd/io.c
index a64199c9de..18f81319b4 100644
--- a/tools/xen-9pfsd/io.c
+++ b/tools/xen-9pfsd/io.c
@@ -22,8 +22,12 @@
 #include "xen-9pfsd.h"
 
 /* P9 protocol commands (response is either cmd+1 or P9_CMD_ERROR). */
+#define P9_CMD_VERSION    100
 #define P9_CMD_ERROR      107
 
+#define P9_MIN_MSIZE      2048
+#define P9_VERSION        "9P2000.u"
+
 struct p9_qid {
     uint8_t type;
 #define QID_TYPE_DIR      0x80
@@ -276,6 +280,169 @@ static unsigned int add_string(struct ring *ring, const char *str,
     return ret;
 }
 
+static bool chk_data(struct ring *ring, void *data, unsigned int len)
+{
+    struct p9_header *hdr = ring->buffer;
+
+    if ( data + len <= ring->buffer + hdr->size )
+        return true;
+
+    errno = E2BIG;
+
+    return false;
+}
+
+static bool fill_data_elem(void **par, void **array, unsigned int *array_sz,
+                           unsigned int elem_sz, void *data)
+{
+    if ( *array_sz && !*array )
+    {
+        *array = calloc(*array_sz, elem_sz);
+        if ( !*array )
+            return false;
+        *par = *array;
+    }
+
+    memcpy(*par, data, elem_sz);
+
+    if ( *array_sz )
+    {
+        *par += elem_sz;
+        *array_sz -= 1;
+    }
+
+    return true;
+}
+
+/*
+ * Fill variables with request data.
+ * fmt is a sequence of format characters. Supported characters are:
+ * a: an array (2 bytes number of elements + the following format as elements)
+ *    The number of elements is stored in the first unsigned int parameter, the
+ *    next parameter is a pointer to an array of elements as denoted by the next
+ *    format character. The array is allocated dynamically.
+ * b: 1 byte unsigned integer
+ *    The value is stored in the next parameter with type uint8_t.
+ * D: Data blob (4 byte length + <length> bytes)
+ *    2 parameters are consumed, first an unsigned int for the length, then a
+ *    pointer to the first uint8_t value.
+ *    No array support.
+ * L: 8 byte unsigned integer
+ *    The value is stored in the next parameter with type uint64_t.
+ * S: String (2 byte length + <length> characters)
+ *    The 0-terminated string is stored in device->str + off, off is stored in
+ *    the next parameter with type unsigned int.
+ * U: 4 byte unsigned integer
+ *    The value is stored in the next parameter with type uint32_t.
+ *
+ * Return value: number of filled variables, errno will be set in case of
+ *   error.
+ */
+static int fill_data(struct ring *ring, const char *fmt, ...)
+{
+    struct p9_header *hdr = ring->buffer;
+    void *data = hdr + 1;
+    void *par;
+    unsigned int pars = 0;
+    const char *f;
+    va_list ap;
+    unsigned int len;
+    unsigned int str_off;
+    unsigned int array_sz = 0;
+    void **array = NULL;
+
+    va_start(ap, fmt);
+
+    for ( f = fmt; *f; f++ )
+    {
+        if ( !array_sz )
+            par = va_arg(ap, void *);
+
+        switch ( *f )
+        {
+        case 'a':
+            f++;
+            if ( !*f || array_sz )
+                fmt_err(fmt);
+            if ( !chk_data(ring, data, sizeof(uint16_t)) )
+                return pars;
+            array_sz = *(__packed uint16_t *)data;
+            data += sizeof(uint16_t);
+            *(unsigned int *)par = array_sz;
+            array = va_arg(ap, void **);
+            *array = NULL;
+            break;
+
+        case 'b':
+            if ( !chk_data(ring, data, sizeof(uint8_t)) )
+                return pars;
+            if ( !fill_data_elem(&par, array, &array_sz, sizeof(uint8_t),
+                                 data) )
+                return pars;
+            data += sizeof(uint8_t);
+            break;
+
+        case 'D':
+            if ( array_sz )
+                fmt_err(fmt);
+            if ( !chk_data(ring, data, sizeof(uint32_t)) )
+                return pars;
+            len = *(__packed uint32_t *)data;
+            data += sizeof(uint32_t);
+            *(unsigned int *)par = len;
+            par = va_arg(ap, void *);
+            if ( !chk_data(ring, data, len) )
+                return pars;
+            memcpy(par, data, len);
+            data += len;
+            break;
+
+        case 'L':
+            if ( !chk_data(ring, data, sizeof(uint64_t)) )
+                return pars;
+            if ( !fill_data_elem(&par, array, &array_sz, sizeof(uint64_t),
+                                 data) )
+                return pars;
+            data += sizeof(uint64_t);
+            break;
+
+        case 'S':
+            if ( !chk_data(ring, data, sizeof(uint16_t)) )
+                return pars;
+            len = *(__packed uint16_t *)data;
+            data += sizeof(uint16_t);
+            if ( !chk_data(ring, data, len) )
+                return pars;
+            str_off = add_string(ring, data, len);
+            if ( str_off == ~0 )
+                return pars;
+            if ( !fill_data_elem(&par, array, &array_sz, sizeof(unsigned int),
+                                 &str_off) )
+                return pars;
+            data += len;
+            break;
+
+        case 'U':
+            if ( !chk_data(ring, data, sizeof(uint32_t)) )
+                return pars;
+            if ( !fill_data_elem(&par, array, &array_sz, sizeof(uint32_t),
+                                 data) )
+                return pars;
+            data += sizeof(uint32_t);
+            break;
+
+        default:
+            fmt_err(fmt);
+        }
+
+        if ( array_sz )
+            f--;
+        pars++;
+    }
+
+    return pars;
+}
+
 static void p9_error(struct ring *ring, uint16_t tag, uint32_t err)
 {
     unsigned int erroff;
@@ -287,6 +454,36 @@ static void p9_error(struct ring *ring, uint16_t tag, uint32_t err)
                 &err);
 }
 
+static void p9_version(struct ring *ring, struct p9_header *hdr)
+{
+    uint32_t max_size;
+    unsigned int off;
+    char *version;
+    int ret;
+
+    ret = fill_data(ring, "US", &max_size, &off);
+    if ( ret != 2 )
+    {
+        p9_error(ring, hdr->tag, errno);
+        return;
+    }
+
+    if ( max_size < P9_MIN_MSIZE )
+    {
+        p9_error(ring, hdr->tag, EMSGSIZE);
+        return;
+    }
+
+    if ( max_size < ring->max_size )
+        ring->max_size = max_size;
+
+    version = ring->str + off;
+    if ( strcmp(version, P9_VERSION) )
+        version = "unknown";
+
+    fill_buffer(ring, hdr->cmd + 1, hdr->tag, "US", &ring->max_size, version);
+}
+
 void *io_thread(void *arg)
 {
     struct ring *ring = arg;
@@ -342,6 +539,10 @@ void *io_thread(void *arg)
 
             switch ( hdr.cmd )
             {
+            case P9_CMD_VERSION:
+                p9_version(ring, &hdr);
+                break;
+
             default:
                 syslog(LOG_DEBUG, "%u.%u sent unhandled command %u\n",
                        ring->device->domid, ring->device->devid, hdr.cmd);
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 07/29] tools/xenlogd: add 9pfs attach request support
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (5 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 06/29] tools/xenlogd: add 9pfs version request support Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-20 20:35   ` Jason Andryuk
  2023-11-10 16:07 ` [PATCH v2 08/29] tools/xenlogd: add 9pfs walk " Juergen Gross
                   ` (21 subsequent siblings)
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Anthony PERARD

Add the attach request of the 9pfs protocol. This introduces the "fid"
scheme of the 9pfs protocol.

As this will be needed later, use a dedicated memory allocation
function in alloc_fid() and prepare a fid reference count.

For filling the qid data take the approach from the qemu 9pfs backend
implementation.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- make fill_qid() parameter stbuf const (Jason Andryuk)
- free fids after disconnecting guest (Jason Andryuk)
---
 tools/xen-9pfsd/io.c        | 155 ++++++++++++++++++++++++++++++++++++
 tools/xen-9pfsd/xen-9pfsd.c |   6 ++
 tools/xen-9pfsd/xen-9pfsd.h |  14 ++++
 3 files changed, 175 insertions(+)

diff --git a/tools/xen-9pfsd/io.c b/tools/xen-9pfsd/io.c
index 18f81319b4..03e45d5f8b 100644
--- a/tools/xen-9pfsd/io.c
+++ b/tools/xen-9pfsd/io.c
@@ -16,6 +16,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <syslog.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <xenctrl.h>           /* For cpu barriers. */
 #include <xen-tools/common-macros.h>
 
@@ -23,6 +25,7 @@
 
 /* P9 protocol commands (response is either cmd+1 or P9_CMD_ERROR). */
 #define P9_CMD_VERSION    100
+#define P9_CMD_ATTACH     104
 #define P9_CMD_ERROR      107
 
 #define P9_MIN_MSIZE      2048
@@ -443,6 +446,118 @@ static int fill_data(struct ring *ring, const char *fmt, ...)
     return pars;
 }
 
+static struct p9_fid *find_fid(device *device, unsigned int fid)
+{
+    struct p9_fid *fidp;
+
+    XEN_TAILQ_FOREACH(fidp, &device->fids, list)
+    {
+        if ( fidp->fid == fid )
+            return fidp;
+    }
+
+    return NULL;
+}
+
+static struct p9_fid *alloc_fid_mem(device *device, unsigned int fid,
+                                    const char *path)
+{
+    struct p9_fid *fidp;
+    size_t pathlen;
+
+    pathlen = strlen(device->host_path) + strlen(path) + 1;
+    fidp = calloc(sizeof(*fidp) + pathlen, 1);
+    if ( !fidp )
+        return NULL;
+
+    fidp->fid = fid;
+    snprintf(fidp->path, pathlen, "%s%s", device->host_path, path);
+
+    return fidp;
+}
+
+static struct p9_fid *alloc_fid(device *device, unsigned int fid,
+                                const char *path)
+{
+    struct p9_fid *fidp = NULL;
+
+    pthread_mutex_lock(&device->fid_mutex);
+
+    if ( find_fid(device, fid) )
+    {
+        errno = EBADFD;
+        goto out;
+    }
+
+    if ( device->n_fids >= device->max_open_files )
+    {
+        errno = EMFILE;
+        goto out;
+    }
+
+    fidp = alloc_fid_mem(device, fid, path);
+    if ( !fidp )
+        goto out;
+
+    fidp->ref = 1;
+    XEN_TAILQ_INSERT_HEAD(&device->fids, fidp, list);
+    device->n_fids++;
+
+ out:
+    pthread_mutex_unlock(&device->fid_mutex);
+
+    return fidp;
+}
+
+static void free_fid(device *device, struct p9_fid *fidp)
+{
+    if ( !fidp )
+        return;
+
+    pthread_mutex_lock(&device->fid_mutex);
+
+    fidp->ref--;
+    if ( !fidp->ref )
+    {
+        device->n_fids--;
+        XEN_TAILQ_REMOVE(&device->fids, fidp, list);
+        free(fidp);
+    }
+
+    pthread_mutex_unlock(&device->fid_mutex);
+}
+
+void free_fids(device *device)
+{
+    struct p9_fid *fidp;
+
+    while ( (fidp = XEN_TAILQ_FIRST(&device->fids)) != NULL )
+    {
+        XEN_TAILQ_REMOVE(&device->fids, fidp, list);
+        free(fidp);
+    }
+}
+
+static int fill_qid(const char *path, struct p9_qid *qid,
+                    const struct stat *stbuf)
+{
+    struct stat st;
+
+    if ( !stbuf )
+    {
+        if ( stat(path, &st) )
+            return errno;
+
+        stbuf = &st;
+    }
+
+    qid->type = S_ISDIR(stbuf->st_mode) ? QID_TYPE_DIR : 0;
+    qid->version = stbuf->st_mtime ^ (stbuf->st_size << 8);
+    qid->path = stbuf->st_ino;
+
+    return 0;
+}
+
 static void p9_error(struct ring *ring, uint16_t tag, uint32_t err)
 {
     unsigned int erroff;
@@ -484,6 +599,42 @@ static void p9_version(struct ring *ring, struct p9_header *hdr)
     fill_buffer(ring, hdr->cmd + 1, hdr->tag, "US", &ring->max_size, version);
 }
 
+static void p9_attach(struct ring *ring, struct p9_header *hdr)
+{
+    device *device = ring->device;
+    uint32_t fid;
+    uint32_t dummy_u32;
+    unsigned int dummy_uint;
+    struct p9_qid qid;
+    int ret;
+
+    ret = fill_data(ring, "UUSSU", &fid, &dummy_u32, &dummy_uint, &dummy_uint,
+                    &dummy_u32);
+    if ( ret != 5 )
+    {
+        p9_error(ring, hdr->tag, errno);
+        return;
+    }
+
+    device->root_fid = alloc_fid(device, fid, "");
+    if ( !device->root_fid )
+    {
+        p9_error(ring, hdr->tag, errno);
+        return;
+    }
+
+    ret = fill_qid(device->host_path, &qid, NULL);
+    if ( ret )
+    {
+        free_fid(device, device->root_fid);
+        device->root_fid = NULL;
+        p9_error(ring, hdr->tag, ret);
+        return;
+    }
+
+    fill_buffer(ring, hdr->cmd + 1, hdr->tag, "Q", &qid);
+}
+
 void *io_thread(void *arg)
 {
     struct ring *ring = arg;
@@ -543,6 +694,10 @@ void *io_thread(void *arg)
                 p9_version(ring, &hdr);
                 break;
 
+            case P9_CMD_ATTACH:
+                p9_attach(ring, &hdr);
+                break;
+
             default:
                 syslog(LOG_DEBUG, "%u.%u sent unhandled command %u\n",
                        ring->device->domid, ring->device->devid, hdr.cmd);
diff --git a/tools/xen-9pfsd/xen-9pfsd.c b/tools/xen-9pfsd/xen-9pfsd.c
index cc5734402d..534c0cefa5 100644
--- a/tools/xen-9pfsd/xen-9pfsd.c
+++ b/tools/xen-9pfsd/xen-9pfsd.c
@@ -278,6 +278,9 @@ static device *new_device(unsigned int domid, unsigned int devid)
         return NULL;
     }
 
+    pthread_mutex_init(&device->fid_mutex, NULL);
+    XEN_TAILQ_INIT(&device->fids);
+
     val = read_backend_node(device, "security_model");
     if ( !val || strcmp(val, "none") )
     {
@@ -370,6 +373,8 @@ static void disconnect_guest(device *device)
     }
 
     device->num_rings = 0;
+
+    free_fids(device);
 }
 
 static void close_device(device *device, enum xenbus_state state)
@@ -454,6 +459,7 @@ static void remove_device(device *device)
     XEN_TAILQ_REMOVE(&devs, device, list);
 
     disconnect_guest(device);
+    pthread_mutex_destroy(&device->fid_mutex);
     free_device(device);
 }
 
diff --git a/tools/xen-9pfsd/xen-9pfsd.h b/tools/xen-9pfsd/xen-9pfsd.h
index 5ff87ca5bd..e511acdb76 100644
--- a/tools/xen-9pfsd/xen-9pfsd.h
+++ b/tools/xen-9pfsd/xen-9pfsd.h
@@ -21,6 +21,13 @@ struct p9_header {
     uint16_t tag;
 } __attribute__((packed));
 
+struct p9_fid {
+    XEN_TAILQ_ENTRY(struct p9_fid) list;
+    unsigned int fid;
+    unsigned int ref;
+    char path[];
+};
+
 typedef struct device device;
 
 struct ring {
@@ -70,10 +77,17 @@ struct device {
     enum xenbus_state frontend_state;
     unsigned int num_rings;
     struct ring *ring[MAX_RINGS];
+
+    /* File system handling. */
+    pthread_mutex_t fid_mutex;
+    XEN_TAILQ_HEAD(fidhead, struct p9_fid) fids;
+    struct p9_fid *root_fid;
+    unsigned int n_fids;
 };
 
 extern xenevtchn_handle *xe;
 
 void *io_thread(void *arg);
+void free_fids(device *device);
 
 #endif /* XEN_9PFSD_H */
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 08/29] tools/xenlogd: add 9pfs walk request support
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (6 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 07/29] tools/xenlogd: add 9pfs attach " Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-28 15:04   ` Jason Andryuk
  2023-11-10 16:07 ` [PATCH v2 09/29] tools/xenlogd: add 9pfs open " Juergen Gross
                   ` (20 subsequent siblings)
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Anthony PERARD

Add the walk request of the 9pfs protocol.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- don't allow walking across symbolic links
---
 tools/xen-9pfsd/io.c        | 172 ++++++++++++++++++++++++++++++++++++
 tools/xen-9pfsd/xen-9pfsd.h |   1 +
 2 files changed, 173 insertions(+)

diff --git a/tools/xen-9pfsd/io.c b/tools/xen-9pfsd/io.c
index 03e45d5f8b..62c64474e6 100644
--- a/tools/xen-9pfsd/io.c
+++ b/tools/xen-9pfsd/io.c
@@ -27,9 +27,11 @@
 #define P9_CMD_VERSION    100
 #define P9_CMD_ATTACH     104
 #define P9_CMD_ERROR      107
+#define P9_CMD_WALK       110
 
 #define P9_MIN_MSIZE      2048
 #define P9_VERSION        "9P2000.u"
+#define P9_WALK_MAXELEM   16
 
 struct p9_qid {
     uint8_t type;
@@ -459,6 +461,21 @@ static struct p9_fid *find_fid(device *device, unsigned int fid)
     return NULL;
 }
 
+static struct p9_fid *get_fid_ref(device *device, unsigned int fid)
+{
+    struct p9_fid *fidp;
+
+    pthread_mutex_lock(&device->fid_mutex);
+
+    fidp = find_fid(device, fid);
+    if ( fidp )
+        fidp->ref++;
+
+    pthread_mutex_unlock(&device->fid_mutex);
+
+    return fidp;
+}
+
 static struct p9_fid *alloc_fid_mem(device *device, unsigned int fid,
                                     const char *path)
 {
@@ -551,6 +568,10 @@ static int fill_qid(const char *path, struct p9_qid *qid,
         stbuf = &st;
     }
 
+    /* Don't allow symbolic links. */
+    if ( S_ISLNK(stbuf->st_mode) )
+        return EMLINK;
+
     qid->type = S_ISDIR(stbuf->st_mode) ? QID_TYPE_DIR : 0;
     qid->version = stbuf->st_mtime ^ (stbuf->st_size << 8);
     qid->path = stbuf->st_ino;
@@ -558,6 +579,20 @@ static int fill_qid(const char *path, struct p9_qid *qid,
     return 0;
 }
 
+static bool name_ok(const char *str)
+{
+    if ( !*str )
+        return false;
+
+    if ( strchr(str, '/' ) )
+        return false;
+
+    if ( !strcmp(str, "..") || !strcmp(str, ".") )
+        return false;
+
+    return true;
+}
+
 static void p9_error(struct ring *ring, uint16_t tag, uint32_t err)
 {
     unsigned int erroff;
@@ -635,6 +670,139 @@ static void p9_attach(struct ring *ring, struct p9_header *hdr)
     fill_buffer(ring, hdr->cmd + 1, hdr->tag, "Q", &qid);
 }
 
+static void p9_walk(struct ring *ring, struct p9_header *hdr)
+{
+    device *device = ring->device;
+    uint32_t fid;
+    uint32_t newfid;
+    struct p9_fid *fidp = NULL;
+    struct p9_qid *qids = NULL;
+    unsigned int n_names = 0;
+    unsigned int *names = NULL;
+    unsigned int walked = 0;
+    unsigned int i;
+    char *path = NULL;
+    unsigned int path_len;
+    int ret;
+
+    ret = fill_data(ring, "UUaS", &fid, &newfid, &n_names, &names);
+    if ( n_names > P9_WALK_MAXELEM )
+    {
+        p9_error(ring, hdr->tag, EINVAL);
+        goto out;
+    }
+    if ( ret != 3 + n_names )
+    {
+        p9_error(ring, hdr->tag, errno);
+        goto out;
+    }
+
+    fidp = get_fid_ref(device, fid);
+    if ( !fidp )
+    {
+        p9_error(ring, hdr->tag, ENOENT);
+        goto out;
+    }
+    if ( fidp->opened )
+    {
+        p9_error(ring, hdr->tag, EINVAL);
+        goto out;
+    }
+
+    path_len = strlen(fidp->path) + 1;
+    for ( i = 0; i < n_names; i++ )
+    {
+        if ( !name_ok(ring->str + names[i]) )
+        {
+            p9_error(ring, hdr->tag, ENOENT);
+            goto out;
+        }
+        path_len += strlen(ring->str + names[i]) + 1;
+    }
+    path = calloc(path_len + 1, 1);
+    if ( !path )
+    {
+        p9_error(ring, hdr->tag, ENOMEM);
+        goto out;
+    }
+    strcpy(path, fidp->path);
+
+    if ( n_names )
+    {
+        qids = calloc(n_names, sizeof(*qids));
+        if ( !qids )
+        {
+            p9_error(ring, hdr->tag, ENOMEM);
+            goto out;
+        }
+        for ( i = 0; i < n_names; i++ )
+        {
+            strcat(path, "/");
+            strcat(path, ring->str + names[i]);
+            ret = fill_qid(path, qids + i, NULL);
+            if ( ret )
+            {
+                if ( !walked )
+                {
+                    p9_error(ring, hdr->tag, errno);
+                    goto out;
+                }
+                break;
+            }
+            walked++;
+        }
+    }
+
+    if ( walked == n_names )
+    {
+        const char *rel_path = path + strlen(device->host_path);
+        bool ok = false;
+
+        if ( fid == newfid )
+        {
+            struct p9_fid *new_fidp;
+
+            pthread_mutex_lock(&device->fid_mutex);
+
+            if ( fidp->ref != 2 )
+            {
+                errno = EBUSY;
+            }
+            else
+            {
+                new_fidp = alloc_fid_mem(device, fid, rel_path);
+                if ( new_fidp )
+                {
+                    new_fidp->ref = 2;
+                    XEN_TAILQ_REMOVE(&device->fids, fidp, list);
+                    XEN_TAILQ_INSERT_HEAD(&device->fids, new_fidp, list);
+                    free(fidp);
+                    fidp = new_fidp;
+                    ok = true;
+                }
+            }
+
+            pthread_mutex_unlock(&device->fid_mutex);
+        }
+        else
+            ok = alloc_fid(device, newfid, rel_path);
+
+        if ( !ok )
+        {
+            p9_error(ring, hdr->tag, errno);
+            goto out;
+        }
+    }
+
+    fill_buffer(ring, hdr->cmd + 1, hdr->tag, "aQ", &walked, qids);
+
+ out:
+    free_fid(device, fidp);
+    free(qids);
+    free(path);
+    free(names);
+}
+
 void *io_thread(void *arg)
 {
     struct ring *ring = arg;
@@ -698,6 +866,10 @@ void *io_thread(void *arg)
                 p9_attach(ring, &hdr);
                 break;
 
+            case P9_CMD_WALK:
+                p9_walk(ring, &hdr);
+                break;
+
             default:
                 syslog(LOG_DEBUG, "%u.%u sent unhandled command %u\n",
                        ring->device->domid, ring->device->devid, hdr.cmd);
diff --git a/tools/xen-9pfsd/xen-9pfsd.h b/tools/xen-9pfsd/xen-9pfsd.h
index e511acdb76..75eaac9f7b 100644
--- a/tools/xen-9pfsd/xen-9pfsd.h
+++ b/tools/xen-9pfsd/xen-9pfsd.h
@@ -25,6 +25,7 @@ struct p9_fid {
     XEN_TAILQ_ENTRY(struct p9_fid) list;
     unsigned int fid;
     unsigned int ref;
+    bool opened;
     char path[];
 };
 
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 09/29] tools/xenlogd: add 9pfs open request support
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (7 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 08/29] tools/xenlogd: add 9pfs walk " Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-28 15:49   ` Jason Andryuk
  2023-11-10 16:07 ` [PATCH v2 10/29] tools/xenlogd: add 9pfs clunk " Juergen Gross
                   ` (19 subsequent siblings)
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Anthony PERARD

Add the open request of the 9pfs protocol.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- don't allow to open symbolic link
---
 tools/xen-9pfsd/io.c        | 144 ++++++++++++++++++++++++++++++++++++
 tools/xen-9pfsd/xen-9pfsd.h |   4 +
 2 files changed, 148 insertions(+)

diff --git a/tools/xen-9pfsd/io.c b/tools/xen-9pfsd/io.c
index 62c64474e6..bb9c78a1f5 100644
--- a/tools/xen-9pfsd/io.c
+++ b/tools/xen-9pfsd/io.c
@@ -18,6 +18,8 @@
 #include <syslog.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <dirent.h>
+#include <fcntl.h>
 #include <xenctrl.h>           /* For cpu barriers. */
 #include <xen-tools/common-macros.h>
 
@@ -28,6 +30,15 @@
 #define P9_CMD_ATTACH     104
 #define P9_CMD_ERROR      107
 #define P9_CMD_WALK       110
+#define P9_CMD_OPEN       112
+
+/* P9 protocol open flags. */
+#define P9_OREAD            0   /* read */
+#define P9_OWRITE           1   /* write */
+#define P9_ORDWR            2   /* read and write */
+#define P9_OMODEMASK     0x03
+#define P9_OTRUNC        0x10   /* or'ed in, truncate file first */
+#define P9_OREMOVE       0x40   /* or'ed in, remove file after clunk */
 
 #define P9_MIN_MSIZE      2048
 #define P9_VERSION        "9P2000.u"
@@ -803,6 +814,135 @@ static void p9_walk(struct ring *ring, struct p9_header *hdr)
     free(names);
 }
 
+static int open_flags_from_mode(uint8_t mode)
+{
+    int flags;
+
+    switch ( mode & P9_OMODEMASK )
+    {
+    case P9_OREAD:
+        flags = O_RDONLY;
+        break;
+
+    case P9_OWRITE:
+        flags = O_WRONLY;
+        break;
+
+    case P9_ORDWR:
+        flags = O_RDWR;
+        break;
+
+    default:
+        return -1;
+    }
+
+    if ( mode & P9_OTRUNC )
+        flags |= O_TRUNC;
+
+    return flags;
+}
+
+static unsigned int get_iounit(struct ring *ring, struct stat *st)
+{
+    return (ring->max_size - st->st_blksize) & ~(st->st_blksize - 1);
+}
+
+static void p9_open(struct ring *ring, struct p9_header *hdr)
+{
+    device *device = ring->device;
+    uint32_t fid;
+    uint8_t mode;
+    struct p9_fid *fidp;
+    struct stat st;
+    struct p9_qid qid;
+    uint32_t iounit;
+    int flags;
+    int ret;
+
+    ret = fill_data(ring, "Ub", &fid, &mode);
+    if ( ret != 2 )
+    {
+        p9_error(ring, hdr->tag, EINVAL);
+        return;
+    }
+    if ( mode & ~(P9_OMODEMASK | P9_OTRUNC | P9_OREMOVE) )
+    {
+        p9_error(ring, hdr->tag, EINVAL);
+        return;
+    }
+
+    fidp = get_fid_ref(device, fid);
+    if ( !fidp )
+    {
+        p9_error(ring, hdr->tag, ENOENT);
+        return;
+    }
+    if ( fidp->opened )
+    {
+        free_fid(device, fidp);
+        p9_error(ring, hdr->tag, EINVAL);
+        return;
+    }
+
+    if ( stat(fidp->path, &st) < 0 )
+    {
+        free_fid(device, fidp);
+        p9_error(ring, hdr->tag, ENOENT);
+        return;
+    }
+
+    if ( S_ISLNK(st.st_mode) )
+    {
+        free_fid(device, fidp);
+        p9_error(ring, hdr->tag, EMLINK);
+        return;
+    }
+
+    fidp->isdir = S_ISDIR(st.st_mode);
+    fidp->mode = mode;
+    if ( fidp->isdir )
+    {
+        if ( mode != P9_OREAD )
+        {
+            free_fid(device, fidp);
+            p9_error(ring, hdr->tag, EINVAL);
+            return;
+        }
+        fidp->data = opendir(fidp->path);
+        if ( !fidp->data )
+        {
+            free_fid(device, fidp);
+            p9_error(ring, hdr->tag, errno);
+            return;
+        }
+        fidp->fd = dirfd(fidp->data);
+    }
+    else
+    {
+        flags = open_flags_from_mode(mode);
+        if ( flags < 0 )
+        {
+            free_fid(device, fidp);
+            p9_error(ring, hdr->tag, EINVAL);
+            return;
+        }
+
+        fidp->fd = open(fidp->path, flags);
+        if ( fidp->fd < 0 )
+        {
+            free_fid(device, fidp);
+            p9_error(ring, hdr->tag, errno);
+            return;
+        }
+    }
+
+    fill_qid(fidp->path, &qid, &st);
+    iounit = get_iounit(ring, &st);
+    fidp->opened = true;
+
+    fill_buffer(ring, hdr->cmd + 1, hdr->tag, "QU", &qid, &iounit);
+}
+
 void *io_thread(void *arg)
 {
     struct ring *ring = arg;
@@ -870,6 +1010,10 @@ void *io_thread(void *arg)
                 p9_walk(ring, &hdr);
                 break;
 
+            case P9_CMD_OPEN:
+                p9_open(ring, &hdr);
+                break;
+
             default:
                 syslog(LOG_DEBUG, "%u.%u sent unhandled command %u\n",
                        ring->device->domid, ring->device->devid, hdr.cmd);
diff --git a/tools/xen-9pfsd/xen-9pfsd.h b/tools/xen-9pfsd/xen-9pfsd.h
index 75eaac9f7b..1ca3093f1a 100644
--- a/tools/xen-9pfsd/xen-9pfsd.h
+++ b/tools/xen-9pfsd/xen-9pfsd.h
@@ -25,7 +25,11 @@ struct p9_fid {
     XEN_TAILQ_ENTRY(struct p9_fid) list;
     unsigned int fid;
     unsigned int ref;
+    int fd;
+    uint8_t mode;
     bool opened;
+    bool isdir;
+    void *data;    /* File type specific. */
     char path[];
 };
 
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 10/29] tools/xenlogd: add 9pfs clunk request support
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (8 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 09/29] tools/xenlogd: add 9pfs open " Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-28 20:15   ` Jason Andryuk
  2023-11-10 16:07 ` [PATCH v2 11/29] tools/xenlogd: add 9pfs create " Juergen Gross
                   ` (18 subsequent siblings)
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Anthony PERARD

Add the clunk request of the 9pfs protocol.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
 tools/xen-9pfsd/io.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/tools/xen-9pfsd/io.c b/tools/xen-9pfsd/io.c
index bb9c78a1f5..c182ef0483 100644
--- a/tools/xen-9pfsd/io.c
+++ b/tools/xen-9pfsd/io.c
@@ -31,6 +31,7 @@
 #define P9_CMD_ERROR      107
 #define P9_CMD_WALK       110
 #define P9_CMD_OPEN       112
+#define P9_CMD_CLUNK      120
 
 /* P9 protocol open flags. */
 #define P9_OREAD            0   /* read */
@@ -943,6 +944,43 @@ static void p9_open(struct ring *ring, struct p9_header *hdr)
     fill_buffer(ring, hdr->cmd + 1, hdr->tag, "QU", &qid, &iounit);
 }
 
+static void p9_clunk(struct ring *ring, struct p9_header *hdr)
+{
+    device *device = ring->device;
+    uint32_t fid;
+    struct p9_fid *fidp;
+    int ret;
+
+    ret = fill_data(ring, "U", &fid);
+    if ( ret != 1 )
+    {
+        p9_error(ring, hdr->tag, EINVAL);
+        return;
+    }
+
+    fidp = get_fid_ref(device, fid);
+    if ( !fidp )
+    {
+        p9_error(ring, hdr->tag, ENOENT);
+        return;
+    }
+
+    if ( fidp->opened )
+    {
+        fidp->opened = false;
+        free_fid(device, fidp);
+        close(fidp->fd);
+        if ( fidp->mode & P9_OREMOVE )
+            unlink(fidp->path);
+    }
+
+    /* 2 calls of free_fid(): one for our reference, and one to free it. */
+    free_fid(device, fidp);
+    free_fid(device, fidp);
+
+    fill_buffer(ring, hdr->cmd + 1, hdr->tag, "");
+}
+
 void *io_thread(void *arg)
 {
     struct ring *ring = arg;
@@ -1014,6 +1052,10 @@ void *io_thread(void *arg)
                 p9_open(ring, &hdr);
                 break;
 
+            case P9_CMD_CLUNK:
+                p9_clunk(ring, &hdr);
+                break;
+
             default:
                 syslog(LOG_DEBUG, "%u.%u sent unhandled command %u\n",
                        ring->device->domid, ring->device->devid, hdr.cmd);
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 11/29] tools/xenlogd: add 9pfs create request support
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (9 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 10/29] tools/xenlogd: add 9pfs clunk " Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-28 20:22   ` Jason Andryuk
  2023-11-10 16:07 ` [PATCH v2 12/29] tools/xenlogd: add 9pfs stat " Juergen Gross
                   ` (17 subsequent siblings)
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Anthony PERARD

Add the create request of the 9pfs protocol.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- set permissions correctly (Jason Andryuk)
---
 tools/xen-9pfsd/io.c | 159 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 159 insertions(+)

diff --git a/tools/xen-9pfsd/io.c b/tools/xen-9pfsd/io.c
index c182ef0483..a605f51dc6 100644
--- a/tools/xen-9pfsd/io.c
+++ b/tools/xen-9pfsd/io.c
@@ -31,6 +31,7 @@
 #define P9_CMD_ERROR      107
 #define P9_CMD_WALK       110
 #define P9_CMD_OPEN       112
+#define P9_CMD_CREATE     114
 #define P9_CMD_CLUNK      120
 
 /* P9 protocol open flags. */
@@ -41,6 +42,12 @@
 #define P9_OTRUNC        0x10   /* or'ed in, truncate file first */
 #define P9_OREMOVE       0x40   /* or'ed in, remove file after clunk */
 
+/* P9 protocol create permission masks. */
+#define P9_CREATE_PERM_DIR        0x80000000
+#define P9_CREATE_PERM_NOTSUPP    0x03b00000   /* link, symlink, ... */
+#define P9_CREATE_PERM_DIR_MASK   0777
+#define P9_CREATE_PERM_FILE_MASK  0666
+
 #define P9_MIN_MSIZE      2048
 #define P9_VERSION        "9P2000.u"
 #define P9_WALK_MAXELEM   16
@@ -944,6 +951,154 @@ static void p9_open(struct ring *ring, struct p9_header *hdr)
     fill_buffer(ring, hdr->cmd + 1, hdr->tag, "QU", &qid, &iounit);
 }
 
+static void p9_create(struct ring *ring, struct p9_header *hdr)
+{
+    device *device = ring->device;
+    uint32_t fid;
+    unsigned int name_off;
+    uint32_t perm;
+    uint8_t mode;
+    unsigned int ext_off;
+    struct p9_fid *fidp;
+    struct p9_fid *new_fidp;
+    char *path;
+    struct stat st;
+    struct p9_qid qid;
+    uint32_t iounit;
+    int flags;
+    int ret;
+
+    ret = fill_data(ring, "USUbS", &fid, &name_off, &perm, &mode, &ext_off);
+    if ( ret != 5 )
+    {
+        p9_error(ring, hdr->tag, EINVAL);
+        return;
+    }
+
+    if ( !name_ok(ring->str + name_off) )
+    {
+        p9_error(ring, hdr->tag, ENOENT);
+        return;
+    }
+
+    if ( perm & P9_CREATE_PERM_NOTSUPP )
+    {
+        p9_error(ring, hdr->tag, EINVAL);
+        return;
+    }
+
+    fidp = get_fid_ref(device, fid);
+    if ( !fidp || fidp->opened )
+    {
+        free_fid(device, fidp);
+        p9_error(ring, hdr->tag, EINVAL);
+        return;
+    }
+    if ( stat(fidp->path, &st) < 0 )
+    {
+        free_fid(device, fidp);
+        p9_error(ring, hdr->tag, errno);
+        return;
+    }
+
+    path = malloc(strlen(fidp->path) + strlen(ring->str + name_off) + 2 -
+                  strlen(device->host_path));
+    if ( !path )
+    {
+        free_fid(device, fidp);
+        p9_error(ring, hdr->tag, ENOMEM);
+        return;
+    }
+    sprintf(path, "%s/%s", fidp->path + strlen(device->host_path),
+            ring->str + name_off);
+    new_fidp = alloc_fid_mem(device, fid, path);
+    free(path);
+    if ( !new_fidp )
+    {
+        free_fid(device, fidp);
+        p9_error(ring, hdr->tag, ENOMEM);
+        return;
+    }
+
+    pthread_mutex_lock(&device->fid_mutex);
+
+    new_fidp->ref = fidp->ref;
+
+    if ( perm & P9_CREATE_PERM_DIR )
+    {
+        perm &= P9_CREATE_PERM_DIR_MASK & st.st_mode;
+        if ( mode != P9_OREAD )
+        {
+            p9_error(ring, hdr->tag, EINVAL);
+            free(new_fidp);
+            goto err;
+        }
+        if ( mkdir(new_fidp->path, perm) < 0 )
+        {
+            p9_error(ring, hdr->tag, errno);
+            free(new_fidp);
+            goto err;
+        }
+
+        XEN_TAILQ_REMOVE(&device->fids, fidp, list);
+        XEN_TAILQ_INSERT_HEAD(&device->fids, new_fidp, list);
+        free(fidp);
+        fidp = new_fidp;
+
+        fidp->data = opendir(fidp->path);
+        if ( !fidp->data )
+        {
+            p9_error(ring, hdr->tag, errno);
+            goto err;
+        }
+        fidp->fd = dirfd(fidp->data);
+    }
+    else
+    {
+        flags = open_flags_from_mode(mode);
+        if ( flags < 0 )
+        {
+            p9_error(ring, hdr->tag, EINVAL);
+            free(new_fidp);
+            goto err;
+        }
+        flags |= perm & P9_CREATE_PERM_FILE_MASK & st.st_mode;
+
+        XEN_TAILQ_REMOVE(&device->fids, fidp, list);
+        XEN_TAILQ_INSERT_HEAD(&device->fids, new_fidp, list);
+        free(fidp);
+        fidp = new_fidp;
+
+        fidp->fd = creat(fidp->path, flags);
+        if ( fidp->fd < 0 )
+        {
+            p9_error(ring, hdr->tag, errno);
+            goto err;
+        }
+    }
+
+    if ( stat(fidp->path, &st) < 0 )
+    {
+        p9_error(ring, hdr->tag, errno);
+        goto err;
+    }
+    fill_qid(fidp->path, &qid, &st);
+    iounit = get_iounit(ring, &st);
+    fidp->opened = true;
+    fidp->mode = mode;
+
+    pthread_mutex_unlock(&device->fid_mutex);
+
+    fill_buffer(ring, hdr->cmd + 1, hdr->tag, "QU", &qid, &iounit);
+
+    return;
+
+ err:
+    pthread_mutex_unlock(&device->fid_mutex);
+
+    free_fid(device, fidp);
+}
+
 static void p9_clunk(struct ring *ring, struct p9_header *hdr)
 {
     device *device = ring->device;
@@ -1052,6 +1207,10 @@ void *io_thread(void *arg)
                 p9_open(ring, &hdr);
                 break;
 
+            case P9_CMD_CREATE:
+                p9_create(ring, &hdr);
+                break;
+
             case P9_CMD_CLUNK:
                 p9_clunk(ring, &hdr);
                 break;
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 12/29] tools/xenlogd: add 9pfs stat request support
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (10 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 11/29] tools/xenlogd: add 9pfs create " Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-10 16:07 ` [PATCH v2 13/29] tools/xenlogd: add 9pfs write " Juergen Gross
                   ` (16 subsequent siblings)
  28 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Anthony PERARD, Jason Andryuk

Add the stat request of the 9pfs protocol.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
---
 tools/xen-9pfsd/io.c | 92 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/tools/xen-9pfsd/io.c b/tools/xen-9pfsd/io.c
index a605f51dc6..e5abd25857 100644
--- a/tools/xen-9pfsd/io.c
+++ b/tools/xen-9pfsd/io.c
@@ -33,6 +33,7 @@
 #define P9_CMD_OPEN       112
 #define P9_CMD_CREATE     114
 #define P9_CMD_CLUNK      120
+#define P9_CMD_STAT       124
 
 /* P9 protocol open flags. */
 #define P9_OREAD            0   /* read */
@@ -59,6 +60,25 @@ struct p9_qid {
     uint64_t path;
 };
 
+struct p9_stat {
+    uint16_t size;
+    uint16_t type;
+    uint32_t dev;
+    struct p9_qid qid;
+    uint32_t mode;
+    uint32_t atime;
+    uint32_t mtime;
+    uint64_t length;
+    const char *name;
+    const char *uid;
+    const char *gid;
+    const char *muid;
+    const char *extension;
+    uint32_t n_uid;
+    uint32_t n_gid;
+    uint32_t n_muid;
+};
+
 /*
  * Note that the ring names "in" and "out" are from the frontend's
  * perspective, so the "in" ring will be used for responses to the frontend,
@@ -1136,6 +1156,74 @@ static void p9_clunk(struct ring *ring, struct p9_header *hdr)
     fill_buffer(ring, hdr->cmd + 1, hdr->tag, "");
 }
 
+static void fill_p9_stat(struct p9_stat *p9s, struct stat *st, const char *name)
+{
+    memset(p9s, 0, sizeof(*p9s));
+    fill_qid(NULL, &p9s->qid, st);
+    p9s->mode = st->st_mode & 0777;
+    if ( S_ISDIR(st->st_mode) )
+        p9s->mode |= P9_CREATE_PERM_DIR;
+    p9s->atime = st->st_atime;
+    p9s->mtime = st->st_mtime;
+    p9s->length = st->st_size;
+    p9s->name = name;
+    p9s->uid = "";
+    p9s->gid = "";
+    p9s->muid = "";
+    p9s->extension = "";
+    p9s->n_uid = 0;
+    p9s->n_gid = 0;
+    p9s->n_muid = 0;
+
+    /*
+     * Size of individual fields without the size field, including 5 2-byte
+     * string length fields.
+     */
+    p9s->size = 71 + strlen(p9s->name);
+}
+
+static void p9_stat(struct ring *ring, struct p9_header *hdr)
+{
+    device *device = ring->device;
+    uint32_t fid;
+    struct p9_fid *fidp;
+    struct p9_stat p9s;
+    struct stat st;
+    uint16_t total_length;
+    int ret;
+
+    ret = fill_data(ring, "U", &fid);
+    if ( ret != 1 )
+    {
+        p9_error(ring, hdr->tag, EINVAL);
+        return;
+    }
+
+    fidp = get_fid_ref(device, fid);
+    if ( !fidp )
+    {
+        p9_error(ring, hdr->tag, ENOENT);
+        return;
+    }
+
+    if ( stat(fidp->path, &st) < 0 )
+    {
+        p9_error(ring, hdr->tag, errno);
+        goto out;
+    }
+    fill_p9_stat(&p9s, &st, strrchr(fidp->path, '/') + 1);
+
+    total_length = p9s.size + sizeof(p9s.size);
+    fill_buffer(ring, hdr->cmd + 1, hdr->tag, "uuuUQUUULSSSSSUUU",
+                &total_length, &p9s.size, &p9s.type, &p9s.dev, &p9s.qid,
+                &p9s.mode, &p9s.atime, &p9s.mtime, &p9s.length, p9s.name,
+                p9s.uid, p9s.gid, p9s.muid, p9s.extension, &p9s.n_uid,
+                &p9s.n_gid, &p9s.n_muid);
+
+ out:
+    free_fid(device, fidp);
+}
+
 void *io_thread(void *arg)
 {
     struct ring *ring = arg;
@@ -1215,6 +1303,10 @@ void *io_thread(void *arg)
                 p9_clunk(ring, &hdr);
                 break;
 
+            case P9_CMD_STAT:
+                p9_stat(ring, &hdr);
+                break;
+
             default:
                 syslog(LOG_DEBUG, "%u.%u sent unhandled command %u\n",
                        ring->device->domid, ring->device->devid, hdr.cmd);
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 13/29] tools/xenlogd: add 9pfs write request support
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (11 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 12/29] tools/xenlogd: add 9pfs stat " Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-10 16:07 ` [PATCH v2 14/29] tools/xenlogd: add 9pfs read " Juergen Gross
                   ` (15 subsequent siblings)
  28 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Anthony PERARD, Jason Andryuk

Add the write request of the 9pfs protocol.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
---
 tools/xen-9pfsd/io.c | 54 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/tools/xen-9pfsd/io.c b/tools/xen-9pfsd/io.c
index e5abd25857..f8d981c2a6 100644
--- a/tools/xen-9pfsd/io.c
+++ b/tools/xen-9pfsd/io.c
@@ -32,6 +32,7 @@
 #define P9_CMD_WALK       110
 #define P9_CMD_OPEN       112
 #define P9_CMD_CREATE     114
+#define P9_CMD_WRITE      118
 #define P9_CMD_CLUNK      120
 #define P9_CMD_STAT       124
 
@@ -1119,6 +1120,55 @@ static void p9_create(struct ring *ring, struct p9_header *hdr)
     free_fid(device, fidp);
 }
 
+static void p9_write(struct ring *ring, struct p9_header *hdr)
+{
+    device *device = ring->device;
+    uint32_t fid;
+    uint64_t off;
+    unsigned int len;
+    uint32_t written;
+    void *buf;
+    struct p9_fid *fidp;
+    int ret;
+
+    ret = fill_data(ring, "ULD", &fid, &off, &len, ring->buffer);
+    if ( ret != 3 )
+    {
+        p9_error(ring, hdr->tag, EINVAL);
+        return;
+    }
+
+    fidp = get_fid_ref(device, fid);
+    if ( !fidp || !fidp->opened || fidp->isdir )
+    {
+        p9_error(ring, hdr->tag, EBADF);
+        goto out;
+    }
+
+    buf = ring->buffer;
+
+    while ( len != 0 )
+    {
+        ret = pwrite(fidp->fd, buf, len, off);
+        if ( ret < 0 )
+            break;
+        len -= ret;
+        buf += ret;
+        off += ret;
+    }
+
+    written = buf - ring->buffer;
+    if ( written == 0 )
+    {
+        p9_error(ring, hdr->tag, errno);
+        goto out;
+    }
+    fill_buffer(ring, hdr->cmd + 1, hdr->tag, "U", &written);
+
+ out:
+    free_fid(device, fidp);
+}
+
 static void p9_clunk(struct ring *ring, struct p9_header *hdr)
 {
     device *device = ring->device;
@@ -1299,6 +1349,10 @@ void *io_thread(void *arg)
                 p9_create(ring, &hdr);
                 break;
 
+            case P9_CMD_WRITE:
+                p9_write(ring, &hdr);
+                break;
+
             case P9_CMD_CLUNK:
                 p9_clunk(ring, &hdr);
                 break;
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 14/29] tools/xenlogd: add 9pfs read request support
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (12 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 13/29] tools/xenlogd: add 9pfs write " Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-10 16:07 ` [PATCH v2 15/29] tools/libs/light: add backend type for 9pfs PV devices Juergen Gross
                   ` (14 subsequent siblings)
  28 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Anthony PERARD, Jason Andryuk

Add the read request of the 9pfs protocol.

For now support only reading plain files (no directories).

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
---
V2:
- make error check more readable (Jason Andryuk)
---
 tools/xen-9pfsd/io.c | 64 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/tools/xen-9pfsd/io.c b/tools/xen-9pfsd/io.c
index f8d981c2a6..1edea2e24a 100644
--- a/tools/xen-9pfsd/io.c
+++ b/tools/xen-9pfsd/io.c
@@ -32,6 +32,7 @@
 #define P9_CMD_WALK       110
 #define P9_CMD_OPEN       112
 #define P9_CMD_CREATE     114
+#define P9_CMD_READ       116
 #define P9_CMD_WRITE      118
 #define P9_CMD_CLUNK      120
 #define P9_CMD_STAT       124
@@ -1120,6 +1121,65 @@ static void p9_create(struct ring *ring, struct p9_header *hdr)
     free_fid(device, fidp);
 }
 
+static void p9_read(struct ring *ring, struct p9_header *hdr)
+{
+    device *device = ring->device;
+    uint32_t fid;
+    uint64_t off;
+    unsigned int len;
+    uint32_t count;
+    void *buf;
+    struct p9_fid *fidp;
+    int ret;
+
+    ret = fill_data(ring, "ULU", &fid, &off, &count);
+    if ( ret != 3 )
+    {
+        p9_error(ring, hdr->tag, EINVAL);
+        return;
+    }
+
+    fidp = get_fid_ref(device, fid);
+    if ( !fidp || !fidp->opened )
+    {
+        p9_error(ring, hdr->tag, EBADF);
+        goto out;
+    }
+
+    if ( fidp->isdir )
+    {
+        p9_error(ring, hdr->tag, EOPNOTSUPP);
+        goto out;
+    }
+    else
+    {
+        len = count;
+        buf = ring->buffer + sizeof(*hdr) + sizeof(uint32_t);
+
+        while ( len != 0 )
+        {
+            ret = pread(fidp->fd, buf, len, off);
+            if ( ret <= 0 )
+                break;
+            len -= ret;
+            buf += ret;
+            off += ret;
+        }
+        if ( ret < 0 && len == count )
+        {
+            p9_error(ring, hdr->tag, errno);
+            goto out;
+        }
+
+        buf = ring->buffer + sizeof(*hdr) + sizeof(uint32_t);
+        len = count - len;
+        fill_buffer(ring, hdr->cmd + 1, hdr->tag, "D", &len, buf);
+    }
+
+ out:
+    free_fid(device, fidp);
+}
+
 static void p9_write(struct ring *ring, struct p9_header *hdr)
 {
     device *device = ring->device;
@@ -1349,6 +1409,10 @@ void *io_thread(void *arg)
                 p9_create(ring, &hdr);
                 break;
 
+            case P9_CMD_READ:
+                p9_read(ring, &hdr);
+                break;
+
             case P9_CMD_WRITE:
                 p9_write(ring, &hdr);
                 break;
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 15/29] tools/libs/light: add backend type for 9pfs PV devices
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (13 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 14/29] tools/xenlogd: add 9pfs read " Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-12-06 13:17   ` Jason Andryuk
  2023-11-10 16:07 ` [PATCH v2 16/29] tools/xl: support new 9pfs backend xen-9pfsd Juergen Gross
                   ` (13 subsequent siblings)
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Anthony PERARD, Jason Andryuk

Make the backend type of 9pfs PV devices configurable. The default is
"qemu" with the related Xenstore backend-side directory being "9pfs".

Add another type "xen-9pfsd" with the related Xenstore backend-side
directory "xen_9pfs".

As additional security features it is possible to specify:
- "max-space" for limiting the maximum space consumed on the filesystem
  in MBs
- "max-files" for limiting the maximum number of files in the
  filesystem
- "max-open-files" for limiting the maximum number of concurrent open
  files

For convenience "auto-delete" is available to let the backend delete the
oldest file of the guest in case otherwise "max-space" or "max-files"
would be violated.

The xen-9pfsd daemon will be started by libxenlight automatically when
the first "xen_9pfs" device is being created.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
---
 tools/libs/light/libxl_9pfs.c             | 145 +++++++++++++++++++++-
 tools/libs/light/libxl_create.c           |   4 +-
 tools/libs/light/libxl_dm.c               |   2 +-
 tools/libs/light/libxl_types.idl          |  11 ++
 tools/libs/light/libxl_types_internal.idl |   1 +
 5 files changed, 156 insertions(+), 7 deletions(-)

diff --git a/tools/libs/light/libxl_9pfs.c b/tools/libs/light/libxl_9pfs.c
index 5ab0d3aa21..87e9dda8e7 100644
--- a/tools/libs/light/libxl_9pfs.c
+++ b/tools/libs/light/libxl_9pfs.c
@@ -33,20 +33,159 @@ static int libxl__set_xenstore_p9(libxl__gc *gc, uint32_t domid,
 
     flexarray_append_pair(front, "tag", p9->tag);
 
+    if (p9->type == LIBXL_P9_TYPE_XEN_9PFSD) {
+        flexarray_append_pair(back, "max-space",
+                              GCSPRINTF("%u", p9->max_space));
+        flexarray_append_pair(back, "max-files",
+                              GCSPRINTF("%u", p9->max_files));
+        flexarray_append_pair(back, "max-open-files",
+                              GCSPRINTF("%u", p9->max_open_files));
+        flexarray_append_pair(back, "auto-delete",
+                              p9->auto_delete ? "1" : "0");
+    }
+
+    return 0;
+}
+
+static int libxl__device_from_p9(libxl__gc *gc, uint32_t domid,
+                                 libxl_device_p9 *type, libxl__device *device)
+{
+    device->backend_devid   = type->devid;
+    device->backend_domid   = type->backend_domid;
+    device->backend_kind    = type->type == LIBXL_P9_TYPE_QEMU
+                              ? LIBXL__DEVICE_KIND_9PFS
+                              : LIBXL__DEVICE_KIND_XEN_9PFS;
+    device->devid           = type->devid;
+    device->domid           = domid;
+    device->kind            = LIBXL__DEVICE_KIND_9PFS;
+
     return 0;
 }
 
-#define libxl__add_p9s NULL
+static int libxl_device_p9_dm_needed(void *e, unsigned domid)
+{
+    libxl_device_p9 *elem = e;
+
+    return elem->type == LIBXL_P9_TYPE_QEMU && elem->backend_domid == domid;
+}
+
+typedef struct libxl__aop9_state libxl__aop9_state;
+
+struct libxl__aop9_state {
+    libxl__spawn_state spawn;
+    libxl__ao_device *aodev;
+    libxl_device_p9 *p9;
+    uint32_t domid;
+    void (*callback)(libxl__egc *, libxl__aop9_state *, int);
+};
+
+static void xen9pfsd_spawn_outcome(libxl__egc *egc, libxl__aop9_state *aop9,
+                                   int rc)
+{
+    aop9->aodev->rc = rc;
+    if (rc)
+        aop9->aodev->callback(egc, aop9->aodev);
+    else
+        libxl__device_add_async(egc, aop9->domid, &libxl__p9_devtype,
+                                aop9->p9, aop9->aodev);
+}
+
+static void xen9pfsd_confirm(libxl__egc *egc, libxl__spawn_state *spawn,
+                             const char *xsdata)
+{
+    STATE_AO_GC(spawn->ao);
+
+    if (!xsdata)
+        return;
+
+    if (strcmp(xsdata, "running"))
+        return;
+
+    libxl__spawn_initiate_detach(gc, spawn);
+}
+
+static void xen9pfsd_failed(libxl__egc *egc, libxl__spawn_state *spawn, int rc)
+{
+    libxl__aop9_state *aop9 = CONTAINER_OF(spawn, *aop9, spawn);
+
+    xen9pfsd_spawn_outcome(egc, aop9, rc);
+}
+
+static void xen9pfsd_detached(libxl__egc *egc, libxl__spawn_state *spawn)
+{
+    libxl__aop9_state *aop9 = CONTAINER_OF(spawn, *aop9, spawn);
+
+    xen9pfsd_spawn_outcome(egc, aop9, 0);
+}
+
+static int xen9pfsd_spawn(libxl__egc *egc, uint32_t domid, libxl_device_p9 *p9,
+                         libxl__ao_device *aodev)
+{
+    STATE_AO_GC(aodev->ao);
+    struct libxl__aop9_state *aop9;
+    int rc;
+    char *args[] = { "xen-9pfsd", NULL };
+    char *path = GCSPRINTF("/local/domain/%u/libxl/xen-9pfs",
+                           p9->backend_domid);
+
+    if (p9->type != LIBXL_P9_TYPE_XEN_9PFSD ||
+        libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/state", path)))
+        return 0;
+
+    GCNEW(aop9);
+    aop9->aodev = aodev;
+    aop9->p9 = p9;
+    aop9->domid = domid;
+    aop9->callback = xen9pfsd_spawn_outcome;
+
+    aop9->spawn.ao = aodev->ao;
+    aop9->spawn.what = "xen-9pfs daemon";
+    aop9->spawn.xspath = GCSPRINTF("%s/state", path);
+    aop9->spawn.timeout_ms = LIBXL_DEVICE_MODEL_START_TIMEOUT * 1000;
+    aop9->spawn.pidpath = GCSPRINTF("%s/pid", path);
+    aop9->spawn.midproc_cb = libxl__spawn_record_pid;
+    aop9->spawn.confirm_cb = xen9pfsd_confirm;
+    aop9->spawn.failure_cb = xen9pfsd_failed;
+    aop9->spawn.detached_cb = xen9pfsd_detached;
+    rc = libxl__spawn_spawn(egc, &aop9->spawn);
+    if (rc < 0)
+        return rc;
+    if (!rc) {
+        setsid();
+        libxl__exec(gc, -1, -1, -1, LIBEXEC_BIN "/xen-9pfsd", args, NULL);
+    }
+
+    return 1;
+}
+
+static void libxl__device_p9_add(libxl__egc *egc, uint32_t domid,
+                                 libxl_device_p9 *p9,
+                                 libxl__ao_device *aodev)
+{
+    int rc;
+
+    rc = xen9pfsd_spawn(egc, domid, p9, aodev);
+    if (rc == 1)
+        return;
+
+    if (rc == 0)
+        libxl__device_add_async(egc, domid, &libxl__p9_devtype, p9, aodev);
+
+    aodev->rc = rc;
+    if (rc)
+        aodev->callback(egc, aodev);
+}
+
 #define libxl_device_p9_list NULL
 #define libxl_device_p9_compare NULL
 
 static LIBXL_DEFINE_UPDATE_DEVID(p9)
-static LIBXL_DEFINE_DEVICE_FROM_TYPE(p9)
+static LIBXL_DEFINE_DEVICES_ADD(p9)
 
 LIBXL_DEFINE_DEVICE_REMOVE(p9)
 
 DEFINE_DEVICE_TYPE_STRUCT(p9, 9PFS, p9s,
-    .skip_attach = 1,
     .set_xenstore_config = (device_set_xenstore_config_fn_t)
                            libxl__set_xenstore_p9,
+    .dm_needed = libxl_device_p9_dm_needed,
 );
diff --git a/tools/libs/light/libxl_create.c b/tools/libs/light/libxl_create.c
index ce1d431103..b19e9379b6 100644
--- a/tools/libs/light/libxl_create.c
+++ b/tools/libs/light/libxl_create.c
@@ -1760,9 +1760,6 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev,
         libxl__device_console_dispose(&console);
     }
 
-    for (i = 0; i < d_config->num_p9s; i++)
-        libxl__device_add(gc, domid, &libxl__p9_devtype, &d_config->p9s[i]);
-
     for (i = 0; i < d_config->num_pvcallsifs; i++)
         libxl__device_add(gc, domid, &libxl__pvcallsif_devtype,
                           &d_config->pvcallsifs[i]);
@@ -1899,6 +1896,7 @@ const libxl__device_type *device_type_tbl[] = {
     &libxl__vdispl_devtype,
     &libxl__vsnd_devtype,
     &libxl__virtio_devtype,
+    &libxl__p9_devtype,
     NULL
 };
 
diff --git a/tools/libs/light/libxl_dm.c b/tools/libs/light/libxl_dm.c
index 14b593110f..2aaaeb5aa7 100644
--- a/tools/libs/light/libxl_dm.c
+++ b/tools/libs/light/libxl_dm.c
@@ -3761,7 +3761,7 @@ int libxl__need_xenpv_qemu(libxl__gc *gc, libxl_domain_config *d_config)
         goto out;
     }
 
-    if (d_config->num_vfbs > 0 || d_config->num_p9s > 0) {
+    if (d_config->num_vfbs > 0) {
         ret = 1;
         goto out;
     }
diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
index 7d8bd5d216..82565c4c10 100644
--- a/tools/libs/light/libxl_types.idl
+++ b/tools/libs/light/libxl_types.idl
@@ -150,6 +150,12 @@ libxl_nic_type = Enumeration("nic_type", [
     (2, "VIF"),
     ])
 
+libxl_p9_type = Enumeration("p9_type", [
+    (0, "unknown"),
+    (1, "qemu"),
+    (2, "xen_9pfsd"),
+    ])
+
 libxl_action_on_shutdown = Enumeration("action_on_shutdown", [
     (1, "DESTROY"),
 
@@ -942,6 +948,11 @@ libxl_device_p9 = Struct("device_p9", [
     ("path",             string),
     ("security_model",   string),
     ("devid",            libxl_devid),
+    ("type",             libxl_p9_type),
+    ("max_space",        integer),
+    ("max_files",        integer),
+    ("max_open_files",   integer),
+    ("auto_delete",      bool),
 ])
 
 libxl_device_pvcallsif = Struct("device_pvcallsif", [
diff --git a/tools/libs/light/libxl_types_internal.idl b/tools/libs/light/libxl_types_internal.idl
index e24288f1a5..39da71cef5 100644
--- a/tools/libs/light/libxl_types_internal.idl
+++ b/tools/libs/light/libxl_types_internal.idl
@@ -34,6 +34,7 @@ libxl__device_kind = Enumeration("device_kind", [
     (16, "VINPUT"),
     (17, "VIRTIO_DISK"),
     (18, "VIRTIO"),
+    (19, "XEN_9PFS"),
     ])
 
 libxl__console_backend = Enumeration("console_backend", [
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 16/29] tools/xl: support new 9pfs backend xen-9pfsd
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (14 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 15/29] tools/libs/light: add backend type for 9pfs PV devices Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-28 20:25   ` Jason Andryuk
  2023-11-10 16:07 ` [PATCH v2 17/29] tools/helpers: allocate xenstore event channel for xenstore stubdom Juergen Gross
                   ` (12 subsequent siblings)
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Anthony PERARD

Add support for the new 9pfs backend "xen-9pfsd". For this backend type
the tag defaults to "Xen" and the host side path to
"/var/log/xen/guests/<dom-name>".

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- test max_files and max_open_files, too (Jason Andryuk)
---
 docs/man/xl.cfg.5.pod.in | 36 ++++++++++++++++++++++++++++++++++--
 tools/xl/xl_parse.c      | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in
index 2e234b450e..80011adbf3 100644
--- a/docs/man/xl.cfg.5.pod.in
+++ b/docs/man/xl.cfg.5.pod.in
@@ -772,10 +772,16 @@ settings, from the following list:
 
 =over 4
 
+=item B<type=TYPE>
+
+The backendtype for the PV device. Supported values are B<qemu> and
+B<xen-9pfsd>.  The default is B<qemu>.
+
 =item B<tag=STRING>
 
 9pfs tag to identify the filesystem share. The tag is needed on the
-guest side to mount it.
+guest side to mount it. For the backendtype of B<xen-9pfsd> the tag defaults to
+"Xen".
 
 =item B<security_model="none">
 
@@ -785,12 +791,38 @@ squash or remap).
 
 =item B<path=STRING>
 
-Filesystem path on the backend to export.
+Filesystem path on the backend to export. For the backendtype of B<xen-9pfsd>
+the path defaults to "@XEN_LOG_DIR@/guests/<guest-name>".
 
 =item B<backend=domain-id>
 
 Specify the backend domain name or id, defaults to dom0.
 
+=item B<max-files=NUMBER>
+
+Specify the maximum number of files below B<path>. A value of 0 (which
+is the default) doesn't limit the number of files. Only valid for
+B<type=xen-9pfsd>.
+
+=item B<max-open-files=NUMBER>
+
+Specify the maximum number of concurrently opened files below B<path>.
+Multiple opens of the same file are counted individually. Only valid for
+B<type=xen-9pfsd>, which has a default of B<max-open-files=5>.
+
+=item B<max-space=NUMBER>
+
+Specify the maximum used disk space in MiB below B<path>. A value of 0 (which
+is the default) doesn't limit the usable disk space. Only valid for
+B<type=xen-9pfsd>.
+
+=item B<auto-delete=BOOLEAN>
+
+When set the backend will delete the oldest file which is currently not
+opened by the guest in case the disk space limit set via B<max-space> or the
+file limit set via B<max-files> is being reached. Only valid for
+B<type=xen-9pfsd>.
+
 =back
 
 =item B<pvcalls=[ "backend=domain-id", ... ]>
diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index ed983200c3..3ded557ebc 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -2232,6 +2232,20 @@ void parse_config_data(const char *config_source,
                     replace_string(&p9->tag, value);
                 } else if (!strcmp(key, "backend")) {
                     replace_string(&p9->backend_domname, value);
+                } else if (!strcmp(key, "type")) {
+                    if (libxl_p9_type_from_string(value, &p9->type)) {
+                        fprintf(stderr, "failed to parse 9pfs type: %s\n",
+                                value);
+                        exit(1);
+                    }
+                } else if (!strcmp(key, "max-files")) {
+                    p9->max_files = parse_ulong(value);
+                } else if (!strcmp(key, "max-open-files")) {
+                    p9->max_open_files = parse_ulong(value);
+                } else if (!strcmp(key, "max-space")) {
+                    p9->max_space = parse_ulong(value);
+                } else if (!strcmp(key, "auto-delete")) {
+                    p9->auto_delete = strtoul(value, NULL, 0);
                 } else {
                     fprintf(stderr, "Unknown 9pfs parameter '%s'\n", key);
                     exit(1);
@@ -2242,6 +2256,28 @@ void parse_config_data(const char *config_source,
 
             libxl_string_list_dispose(&pairs);
 
+            if (p9->type == LIBXL_P9_TYPE_UNKNOWN) {
+                p9->type = LIBXL_P9_TYPE_QEMU;
+            }
+            if (p9->type == LIBXL_P9_TYPE_QEMU &&
+                (p9->max_files || p9->max_open_files || p9->max_space ||
+                 p9->auto_delete)) {
+                fprintf(stderr, "Illegal 9pfs parameter combination\n");
+                exit(1);
+            }
+            if (p9->type == LIBXL_P9_TYPE_XEN_9PFSD) {
+                if (!p9->tag) {
+                    replace_string(&p9->tag, "Xen");
+                }
+                if (!p9->path) {
+                    char *path;
+
+                    xasprintf(&path, XEN_LOG_DIR "/guests/%s", c_info->name);
+                    replace_string(&p9->path, path);
+                    free(path);
+                }
+            }
+
             if (!p9->path || !p9->security_model || !p9->tag) {
                 fprintf(stderr, "9pfs spec missing required field!\n");
                 exit(1);
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 17/29] tools/helpers: allocate xenstore event channel for xenstore stubdom
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (15 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 16/29] tools/xl: support new 9pfs backend xen-9pfsd Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-10 16:07 ` [PATCH v2 18/29] tools/xenstored: rename xenbus_evtchn() Juergen Gross
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Wei Liu, Julien Grall, Anthony PERARD, Jason Andryuk

In order to prepare support of PV frontends in xenstore-stubdom, add
allocation of a Xenstore event channel to init-xenstore-domain.c.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
---
 tools/helpers/init-xenstore-domain.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/tools/helpers/init-xenstore-domain.c b/tools/helpers/init-xenstore-domain.c
index b2d5df8ba5..140ed610ae 100644
--- a/tools/helpers/init-xenstore-domain.c
+++ b/tools/helpers/init-xenstore-domain.c
@@ -248,6 +248,13 @@ static int build(xc_interface *xch)
     dom->cmdline = xc_dom_strdup(dom, cmdline);
     dom->xenstore_domid = domid;
     dom->console_evtchn = console_evtchn;
+    rv = xc_evtchn_alloc_unbound(xch, domid, domid);
+    if ( rv < 0 )
+    {
+        fprintf(stderr, "xc_evtchn_alloc_unbound failed\n");
+        goto err;
+    }
+    dom->xenstore_evtchn = rv;
 
     rv = xc_dom_mem_init(dom, memory);
     if ( rv )
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 18/29] tools/xenstored: rename xenbus_evtchn()
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (16 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 17/29] tools/helpers: allocate xenstore event channel for xenstore stubdom Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-28 20:26   ` Jason Andryuk
  2023-11-10 16:07 ` [PATCH v2 19/29] stubdom: extend xenstore stubdom configs Juergen Gross
                   ` (10 subsequent siblings)
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Wei Liu, Julien Grall, Anthony PERARD, Julien Grall

Rename the xenbus_evtchn() function to get_xenbus_evtchn() in order to
avoid two externally visible symbols with the same name when Xenstore-
stubdom is being built with a Mini-OS with CONFIG_XENBUS set.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstored/core.h   | 2 +-
 tools/xenstored/domain.c | 2 +-
 tools/xenstored/minios.c | 2 +-
 tools/xenstored/posix.c  | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
index ad87199042..480b0f5f7b 100644
--- a/tools/xenstored/core.h
+++ b/tools/xenstored/core.h
@@ -383,7 +383,7 @@ static inline bool domain_is_unprivileged(const struct connection *conn)
 }
 
 /* Return the event channel used by xenbus. */
-evtchn_port_t xenbus_evtchn(void);
+evtchn_port_t get_xenbus_evtchn(void);
 
 /* Write out the pidfile */
 void write_pidfile(const char *pidfile);
diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index 409b53acf9..6ef136e01f 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -1208,7 +1208,7 @@ void dom0_init(void)
 	evtchn_port_t port;
 	struct domain *dom0;
 
-	port = xenbus_evtchn();
+	port = get_xenbus_evtchn();
 	if (port == -1)
 		barf_perror("Failed to initialize dom0 port");
 
diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
index b5c3a205e6..0779efbf91 100644
--- a/tools/xenstored/minios.c
+++ b/tools/xenstored/minios.c
@@ -38,7 +38,7 @@ void init_pipe(int reopen_log_pipe[2])
 	reopen_log_pipe[1] = -1;
 }
 
-evtchn_port_t xenbus_evtchn(void)
+evtchn_port_t get_xenbus_evtchn(void)
 {
 	return dom0_event;
 }
diff --git a/tools/xenstored/posix.c b/tools/xenstored/posix.c
index 6ac45fdb45..7e03dd982d 100644
--- a/tools/xenstored/posix.c
+++ b/tools/xenstored/posix.c
@@ -111,7 +111,7 @@ void unmap_xenbus(void *interface)
 	munmap(interface, getpagesize());
 }
 
-evtchn_port_t xenbus_evtchn(void)
+evtchn_port_t get_xenbus_evtchn(void)
 {
 	int fd;
 	int rc;
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 19/29] stubdom: extend xenstore stubdom configs
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (17 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 18/29] tools/xenstored: rename xenbus_evtchn() Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-10 16:07 ` [PATCH v2 20/29] tools: add 9pfs device to xenstore-stubdom Juergen Gross
                   ` (9 subsequent siblings)
  28 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Samuel Thibault, Jason Andryuk

Extend the config files of the Xenstore stubdoms to include XENBUS
and 9PFRONT items in order to support file based logging.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
---
 stubdom/xenstore-minios.cfg    | 2 +-
 stubdom/xenstorepvh-minios.cfg | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/stubdom/xenstore-minios.cfg b/stubdom/xenstore-minios.cfg
index a41704bb6b..239da519b9 100644
--- a/stubdom/xenstore-minios.cfg
+++ b/stubdom/xenstore-minios.cfg
@@ -3,7 +3,7 @@ CONFIG_NETFRONT=n
 CONFIG_FBFRONT=n
 CONFIG_KBDFRONT=n
 CONFIG_CONSFRONT=n
-CONFIG_XENBUS=n
 CONFIG_LWIP=n
+CONFIG_9PFRONT=y
 CONFIG_BALLOON=y
 XEN_INTERFACE_VERSION=__XEN_LATEST_INTERFACE_VERSION__
diff --git a/stubdom/xenstorepvh-minios.cfg b/stubdom/xenstorepvh-minios.cfg
index 6af51f5753..752b90d7d3 100644
--- a/stubdom/xenstorepvh-minios.cfg
+++ b/stubdom/xenstorepvh-minios.cfg
@@ -4,7 +4,7 @@ CONFIG_NETFRONT=n
 CONFIG_FBFRONT=n
 CONFIG_KBDFRONT=n
 CONFIG_CONSFRONT=n
-CONFIG_XENBUS=n
 CONFIG_LWIP=n
+CONFIG_9PFRONT=y
 CONFIG_BALLOON=y
 XEN_INTERFACE_VERSION=__XEN_LATEST_INTERFACE_VERSION__
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 20/29] tools: add 9pfs device to xenstore-stubdom
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (18 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 19/29] stubdom: extend xenstore stubdom configs Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-10 16:07 ` [PATCH v2 21/29] tools/xenstored: add early_init() function Juergen Gross
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Wei Liu, Julien Grall, Anthony PERARD, Jason Andryuk

Add a 9pfs device to Xenstore stubdom in order to allow it to do e.g.
logging into a dom0 file.

Use the following parameters for the new device:

- tag = "xen"
- type = "xen-9pfsd"
- path = "/var/lib/xen/xenstore"
- security-model = "none"

For now don't limit allowed file space or number of files.

Add a new libxl function for adding it similar to the function for
adding the console device.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
---
V2:
- add security_model parameter to new libxl function (Jason Andryuk)
---
 tools/helpers/init-xenstore-domain.c |  2 ++
 tools/include/libxl.h                | 17 ++++++++++++++++
 tools/libs/light/libxl_9pfs.c        | 29 ++++++++++++++++++++++++++++
 3 files changed, 48 insertions(+)

diff --git a/tools/helpers/init-xenstore-domain.c b/tools/helpers/init-xenstore-domain.c
index 140ed610ae..591cb3766d 100644
--- a/tools/helpers/init-xenstore-domain.c
+++ b/tools/helpers/init-xenstore-domain.c
@@ -543,6 +543,8 @@ int main(int argc, char** argv)
     }
     libxl_console_add_xenstore(ctx, domid, 0, console_evtchn, console_gfn,
                                NULL);
+    libxl_p9_add_xenstore(ctx, domid, 0, LIBXL_P9_TYPE_XEN_9PFSD, "xen",
+                          XEN_LIB_DIR"/xenstore", "none", 0, 0, 0, 0, NULL);
     libxl_ctx_free(ctx);
 
     fd = creat(XEN_RUN_DIR "/xenstored.pid", 0666);
diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 907aa0a330..00693264f7 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -583,6 +583,13 @@
  * libxl_console_add_xenstore() in libxl.
  */
 #define LIBXL_HAVE_CONSOLE_ADD_XENSTORE 1
+
+/*
+ * LIBXL_HAVE_P9_ADD_XENSTORE indicates presence of the function
+ * libxl_p9_add_xenstore() in libxl.
+ */
+#define LIBXL_HAVE_P9_ADD_XENSTORE 1
+
 /*
  * libxl ABI compatibility
  *
@@ -2060,6 +2067,16 @@ int libxl_console_add_xenstore(libxl_ctx *ctx, uint32_t domid, uint32_t backend,
                                const libxl_asyncop_how *ao_how)
                                LIBXL_EXTERNAL_CALLERS_ONLY;
 
+/* libxl_p9_add_xenstore writes the Xenstore entries for a domain's
+ * primary 9pfs device based on domid, backend type and device parameters.
+ */
+int libxl_p9_add_xenstore(libxl_ctx *ctx, uint32_t domid, uint32_t backend,
+                          libxl_p9_type type, char *tag, char *path,
+                          char *security_model, unsigned int max_space,
+                          unsigned int max_files, unsigned int max_open_files,
+                          bool auto_delete, const libxl_asyncop_how *ao_how)
+                          LIBXL_EXTERNAL_CALLERS_ONLY;
+
 /* May be called with info_r == NULL to check for domain's existence.
  * Returns ERROR_DOMAIN_NOTFOUND if domain does not exist (used to return
  * ERROR_INVAL for this scenario). */
diff --git a/tools/libs/light/libxl_9pfs.c b/tools/libs/light/libxl_9pfs.c
index 87e9dda8e7..43702e3d9f 100644
--- a/tools/libs/light/libxl_9pfs.c
+++ b/tools/libs/light/libxl_9pfs.c
@@ -176,6 +176,35 @@ static void libxl__device_p9_add(libxl__egc *egc, uint32_t domid,
         aodev->callback(egc, aodev);
 }
 
+int libxl_p9_add_xenstore(libxl_ctx *ctx, uint32_t domid, uint32_t backend,
+                          libxl_p9_type type, char *tag, char *path,
+                          char *security_model, unsigned int max_space,
+                          unsigned int max_files, unsigned int max_open_files,
+                          bool auto_delete, const libxl_asyncop_how *ao_how)
+{
+    AO_CREATE(ctx, domid, ao_how);
+    libxl__ao_device *aodev;
+    libxl_device_p9 p9 = { .backend_domid = backend,
+                           .tag = tag,
+                           .path = path,
+                           .security_model = security_model,
+                           .type = type,
+                           .max_space = max_space,
+                           .max_files = max_files,
+                           .max_open_files = max_open_files,
+                           .auto_delete = auto_delete,
+                         };
+
+    GCNEW(aodev);
+    libxl__prepare_ao_device(ao, aodev);
+    aodev->action = LIBXL__DEVICE_ACTION_ADD;
+    aodev->callback = device_addrm_aocomplete;
+
+    libxl__device_p9_add(egc, domid, &p9, aodev);
+
+    return AO_INPROGRESS;
+}
+
 #define libxl_device_p9_list NULL
 #define libxl_device_p9_compare NULL
 
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 21/29] tools/xenstored: add early_init() function
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (19 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 20/29] tools: add 9pfs device to xenstore-stubdom Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-10 17:31   ` Julien Grall
  2023-11-10 16:07 ` [PATCH v2 22/29] tools/xenstored: get own domid in stubdom case Juergen Gross
                   ` (7 subsequent siblings)
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Wei Liu, Julien Grall, Anthony PERARD, Jason Andryuk

Some xenstored initialization needs to be done in the daemon case only,
so split it out into a new early_init() function being a stub in the
stubdom case.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
---
V2:
- rename function
- move patch earlier in the series
---
 tools/xenstored/core.c   |  6 +-----
 tools/xenstored/core.h   |  3 +++
 tools/xenstored/minios.c |  3 +++
 tools/xenstored/posix.c  | 11 +++++++++++
 4 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
index edd07711db..0c14823fb0 100644
--- a/tools/xenstored/core.c
+++ b/tools/xenstored/core.c
@@ -2933,11 +2933,7 @@ int main(int argc, char *argv[])
 	if (optind != argc)
 		barf("%s: No arguments desired", argv[0]);
 
-	reopen_log();
-
-	/* Make sure xenstored directory exists. */
-	/* Errors ignored here, will be reported when we open files */
-	mkdir(xenstore_daemon_rundir(), 0755);
+	early_init();
 
 	if (dofork) {
 		openlog("xenstored", 0, LOG_DAEMON);
diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
index 480b0f5f7b..d0ac587f8f 100644
--- a/tools/xenstored/core.h
+++ b/tools/xenstored/core.h
@@ -35,6 +35,8 @@
 #include "list.h"
 #include "hashtable.h"
 
+#define XENSTORE_LIB_DIR	XEN_LIB_DIR "/xenstore"
+
 #ifndef O_CLOEXEC
 #define O_CLOEXEC 0
 /* O_CLOEXEC support is needed for Live Update in the daemon case. */
@@ -384,6 +386,7 @@ static inline bool domain_is_unprivileged(const struct connection *conn)
 
 /* Return the event channel used by xenbus. */
 evtchn_port_t get_xenbus_evtchn(void);
+void early_init(void);
 
 /* Write out the pidfile */
 void write_pidfile(const char *pidfile);
diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
index 0779efbf91..0cdec3ae51 100644
--- a/tools/xenstored/minios.c
+++ b/tools/xenstored/minios.c
@@ -54,3 +54,6 @@ void unmap_xenbus(void *interface)
 	xengnttab_unmap(*xgt_handle, interface, 1);
 }
 
+void early_init(void)
+{
+}
diff --git a/tools/xenstored/posix.c b/tools/xenstored/posix.c
index 7e03dd982d..fcb7791bd7 100644
--- a/tools/xenstored/posix.c
+++ b/tools/xenstored/posix.c
@@ -22,6 +22,7 @@
 #include <fcntl.h>
 #include <stdlib.h>
 #include <sys/mman.h>
+#include <xen-tools/xenstore-common.h>
 
 #include "utils.h"
 #include "core.h"
@@ -157,3 +158,13 @@ void *xenbus_map(void)
 
 	return addr;
 }
+
+void early_init(void)
+{
+	reopen_log();
+
+	/* Make sure xenstored directories exist. */
+	/* Errors ignored here, will be reported when we open files */
+	mkdir(xenstore_daemon_rundir(), 0755);
+	mkdir(XENSTORE_LIB_DIR, 0755);
+}
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 22/29] tools/xenstored: get own domid in stubdom case
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (20 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 21/29] tools/xenstored: add early_init() function Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-10 17:36   ` Julien Grall
  2023-11-13 21:59   ` Julien Grall
  2023-11-10 16:07 ` [PATCH v2 23/29] tools/xenstored: rework ring page (un)map functions Juergen Gross
                   ` (6 subsequent siblings)
  28 siblings, 2 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Julien Grall, Anthony PERARD

Obtain the own domid from the Xenstore special grant entry when running
as stubdom.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- replacement of V1 patch (ANdrew Cooper)
---
 tools/xenstored/core.c   | 1 +
 tools/xenstored/core.h   | 1 +
 tools/xenstored/minios.c | 5 +++++
 3 files changed, 7 insertions(+)

diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
index 0c14823fb0..8e271e31f9 100644
--- a/tools/xenstored/core.c
+++ b/tools/xenstored/core.c
@@ -2738,6 +2738,7 @@ static struct option options[] = {
 int dom0_domid = 0;
 int dom0_event = 0;
 int priv_domid = 0;
+int stub_domid = -1;
 
 static unsigned int get_optval_uint(const char *arg)
 {
diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
index d0ac587f8f..3c28007d11 100644
--- a/tools/xenstored/core.h
+++ b/tools/xenstored/core.h
@@ -361,6 +361,7 @@ do {						\
 extern int dom0_domid;
 extern int dom0_event;
 extern int priv_domid;
+extern int stub_domid;
 extern bool keep_orphans;
 
 extern unsigned int timeout_watch_event_msec;
diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
index 0cdec3ae51..202d70387a 100644
--- a/tools/xenstored/minios.c
+++ b/tools/xenstored/minios.c
@@ -19,6 +19,8 @@
 #include <sys/mman.h>
 #include "core.h"
 #include <xen/grant_table.h>
+#include <mini-os/events.h>
+#include <mini-os/gnttab.h>
 
 void write_pidfile(const char *pidfile)
 {
@@ -56,4 +58,7 @@ void unmap_xenbus(void *interface)
 
 void early_init(void)
 {
+	stub_domid = evtchn_get_domid();
+	if (stub_domid == DOMID_INVALID)
+		barf("could not get own domid");
 }
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 23/29] tools/xenstored: rework ring page (un)map functions
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (21 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 22/29] tools/xenstored: get own domid in stubdom case Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-10 17:51   ` Julien Grall
  2023-11-10 16:07 ` [PATCH v2 24/29] tools/xenstored: split domain_init() Juergen Gross
                   ` (5 subsequent siblings)
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Wei Liu, Julien Grall, Anthony PERARD, Jason Andryuk

When [un]mapping the ring page of a Xenstore client, different actions
are required for "normal" guests and dom0. Today this distinction is
made at call site.

Move this distinction into [un]map_interface() instead, avoiding code
duplication and preparing special handling for [un]mapping the stub
domain's ring page.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
---
 tools/xenstored/domain.c | 31 +++++++++++++------------------
 1 file changed, 13 insertions(+), 18 deletions(-)

diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index 6ef136e01f..58b0942043 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -497,14 +497,20 @@ static const struct interface_funcs domain_funcs = {
 
 static void *map_interface(domid_t domid)
 {
+	if (domid == xenbus_master_domid())
+		return xenbus_map();
+
 	return xengnttab_map_grant_ref(*xgt_handle, domid,
 				       GNTTAB_RESERVED_XENSTORE,
 				       PROT_READ|PROT_WRITE);
 }
 
-static void unmap_interface(void *interface)
+static void unmap_interface(domid_t domid, void *interface)
 {
-	xengnttab_unmap(*xgt_handle, interface, 1);
+	if (domid == xenbus_master_domid())
+		unmap_xenbus(interface);
+	else
+		xengnttab_unmap(*xgt_handle, interface, 1);
 }
 
 static int domain_tree_remove_sub(const void *ctx, struct connection *conn,
@@ -594,14 +600,8 @@ static int destroy_domain(void *_domain)
 			eprintf("> Unbinding port %i failed!\n", domain->port);
 	}
 
-	if (domain->interface) {
-		/* Domain 0 was mapped by dom0_init, so it must be unmapped
-		   using munmap() and not the grant unmap call. */
-		if (domain->domid == dom0_domid)
-			unmap_xenbus(domain->interface);
-		else
-			unmap_interface(domain->interface);
-	}
+	if (domain->interface)
+		unmap_interface(domain->domid, domain->interface);
 
 	fire_special_watches("@releaseDomain");
 
@@ -966,18 +966,13 @@ static struct domain *introduce_domain(const void *ctx,
 		return NULL;
 
 	if (!domain->introduced) {
-		interface = is_master_domain ? xenbus_map()
-					     : map_interface(domid);
+		interface = map_interface(domid);
 		if (!interface && !restore)
 			return NULL;
 		if (new_domain(domain, port, restore)) {
 			rc = errno;
-			if (interface) {
-				if (is_master_domain)
-					unmap_xenbus(interface);
-				else
-					unmap_interface(interface);
-			}
+			if (interface)
+				unmap_interface(domid, interface);
 			errno = rc;
 			return NULL;
 		}
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 24/29] tools/xenstored: split domain_init()
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (22 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 23/29] tools/xenstored: rework ring page (un)map functions Juergen Gross
@ 2023-11-10 16:07 ` Juergen Gross
  2023-11-10 18:05   ` Julien Grall
  2023-11-10 16:08 ` [PATCH v2 25/29] tools/xenstored: map stubdom interface Juergen Gross
                   ` (4 subsequent siblings)
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Julien Grall, Anthony PERARD

Today domain_init() is called either just before calling dom0_init()
in case no live update is being performed, or it is called after
reading the global state from read_state_global(), as the event
channel fd is needed.

Split up domain_init() into a preparation part which can be called
unconditionally, and in a part setting up the event channel handle.

Note that there is no chance that chk_domain_generation() can be
called now before xc_handle has been setup, so there is no need for
the related special case anymore.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
 tools/xenstored/core.c   |  2 ++
 tools/xenstored/domain.c | 12 ++++++------
 tools/xenstored/domain.h |  1 +
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
index 8e271e31f9..b9ec50b34c 100644
--- a/tools/xenstored/core.c
+++ b/tools/xenstored/core.c
@@ -2960,6 +2960,8 @@ int main(int argc, char *argv[])
 
 	init_pipe(reopen_log_pipe);
 
+	domain_static_init();
+
 	/* Listen to hypervisor. */
 	if (!no_domain_init && !live_update) {
 		domain_init(-1);
diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index 58b0942043..fa17f68618 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -1224,10 +1224,8 @@ static int domeq_fn(const void *key1, const void *key2)
 	return *(const unsigned int *)key1 == *(const unsigned int *)key2;
 }
 
-void domain_init(int evtfd)
+void domain_static_init(void)
 {
-	int rc;
-
 	/* Start with a random rather low domain count for the hashtable. */
 	domhash = create_hashtable(NULL, "domains", domhash_fn, domeq_fn, 0);
 	if (!domhash)
@@ -1258,6 +1256,11 @@ void domain_init(int evtfd)
 	xengnttab_set_max_grants(*xgt_handle, DOMID_FIRST_RESERVED);
 
 	talloc_set_destructor(xgt_handle, close_xgt_handle);
+}
+
+void domain_init(int evtfd)
+{
+	int rc;
 
 	if (evtfd < 0)
 		xce_handle = xenevtchn_open(NULL, XENEVTCHN_NO_CLOEXEC);
@@ -1291,9 +1294,6 @@ static bool chk_domain_generation(unsigned int domid, uint64_t gen)
 {
 	struct domain *d;
 
-	if (!xc_handle && domid == dom0_domid)
-		return true;
-
 	d = find_domain_struct(domid);
 
 	return d && d->generation <= gen;
diff --git a/tools/xenstored/domain.h b/tools/xenstored/domain.h
index 7625dca8cd..6c00540311 100644
--- a/tools/xenstored/domain.h
+++ b/tools/xenstored/domain.h
@@ -82,6 +82,7 @@ int do_get_domain_path(const void *ctx, struct connection *conn,
 int do_reset_watches(const void *ctx, struct connection *conn,
 		     struct buffered_data *in);
 
+void domain_static_init(void);
 void domain_init(int evtfd);
 void dom0_init(void);
 void domain_deinit(void);
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 25/29] tools/xenstored: map stubdom interface
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (23 preceding siblings ...)
  2023-11-10 16:07 ` [PATCH v2 24/29] tools/xenstored: split domain_init() Juergen Gross
@ 2023-11-10 16:08 ` Juergen Gross
  2023-11-13 22:04   ` Julien Grall
  2023-11-10 16:08 ` [PATCH v2 26/29] tools/xenstored: mount 9pfs device in stubdom Juergen Gross
                   ` (3 subsequent siblings)
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:08 UTC (permalink / raw)
  To: xen-devel; +Cc: Juergen Gross, Wei Liu, Julien Grall, Anthony PERARD

When running as stubdom, map the stubdom's Xenstore ring page in order
to support using the 9pfs frontend.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
 tools/xenstored/core.c   |  2 ++
 tools/xenstored/domain.c | 27 ++++++++++++++++++++++++++-
 tools/xenstored/domain.h |  1 +
 3 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
index b9ec50b34c..4a9d874f17 100644
--- a/tools/xenstored/core.c
+++ b/tools/xenstored/core.c
@@ -2991,6 +2991,8 @@ int main(int argc, char *argv[])
 		lu_read_state();
 #endif
 
+	stubdom_init();
+
 	check_store();
 
 	/* Get ready to listen to the tools. */
diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index fa17f68618..162b87b460 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -37,6 +37,10 @@
 #include <xenctrl.h>
 #include <xen/grant_table.h>
 
+#ifdef __MINIOS__
+#include <mini-os/xenbus.h>
+#endif
+
 static xc_interface **xc_handle;
 xengnttab_handle **xgt_handle;
 static evtchn_port_t virq_port;
@@ -500,6 +504,11 @@ static void *map_interface(domid_t domid)
 	if (domid == xenbus_master_domid())
 		return xenbus_map();
 
+#ifdef __MINIOS__
+	if (domid == stub_domid)
+		return xenstore_buf;
+#endif
+
 	return xengnttab_map_grant_ref(*xgt_handle, domid,
 				       GNTTAB_RESERVED_XENSTORE,
 				       PROT_READ|PROT_WRITE);
@@ -509,7 +518,7 @@ static void unmap_interface(domid_t domid, void *interface)
 {
 	if (domid == xenbus_master_domid())
 		unmap_xenbus(interface);
-	else
+	else if (domid != stub_domid)
 		xengnttab_unmap(*xgt_handle, interface, 1);
 }
 
@@ -1214,6 +1223,22 @@ void dom0_init(void)
 	xenevtchn_notify(xce_handle, dom0->port);
 }
 
+void stubdom_init(void)
+{
+#ifdef __MINIOS__
+	struct domain *stubdom;
+
+	if (stub_domid < 0)
+		return;
+
+	stubdom = introduce_domain(NULL, stub_domid, xenbus_evtchn, false);
+	if (!stubdom)
+		barf_perror("Failed to initialize stubdom");
+
+	xenevtchn_notify(xce_handle, stubdom->port);
+#endif
+}
+
 static unsigned int domhash_fn(const void *k)
 {
 	return *(const unsigned int *)k;
diff --git a/tools/xenstored/domain.h b/tools/xenstored/domain.h
index 6c00540311..49c60c56bf 100644
--- a/tools/xenstored/domain.h
+++ b/tools/xenstored/domain.h
@@ -85,6 +85,7 @@ int do_reset_watches(const void *ctx, struct connection *conn,
 void domain_static_init(void);
 void domain_init(int evtfd);
 void dom0_init(void);
+void stubdom_init(void);
 void domain_deinit(void);
 void ignore_connection(struct connection *conn, unsigned int err);
 
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 26/29] tools/xenstored: mount 9pfs device in stubdom
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (24 preceding siblings ...)
  2023-11-10 16:08 ` [PATCH v2 25/29] tools/xenstored: map stubdom interface Juergen Gross
@ 2023-11-10 16:08 ` Juergen Gross
  2023-11-13 22:09   ` Julien Grall
  2023-11-10 16:08 ` [PATCH v2 27/29] tools/xenstored: add helpers for filename handling Juergen Gross
                   ` (2 subsequent siblings)
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:08 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Wei Liu, Julien Grall, Anthony PERARD, Jason Andryuk

Mount the 9pfs device in stubdom enabling it to use files.

This has to happen in a worker thread in order to allow the main thread
handling the required Xenstore accesses in parallel.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
---
 tools/xenstored/core.h   |  4 ++++
 tools/xenstored/domain.c |  2 ++
 tools/xenstored/minios.c | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 42 insertions(+)

diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
index 3c28007d11..a0d3592961 100644
--- a/tools/xenstored/core.h
+++ b/tools/xenstored/core.h
@@ -389,6 +389,10 @@ static inline bool domain_is_unprivileged(const struct connection *conn)
 evtchn_port_t get_xenbus_evtchn(void);
 void early_init(void);
 
+#ifdef __MINIOS__
+void mount_9pfs(void);
+#endif
+
 /* Write out the pidfile */
 void write_pidfile(const char *pidfile);
 
diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index 162b87b460..4263c1360f 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -1236,6 +1236,8 @@ void stubdom_init(void)
 		barf_perror("Failed to initialize stubdom");
 
 	xenevtchn_notify(xce_handle, stubdom->port);
+
+	mount_9pfs();
 #endif
 }
 
diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
index 202d70387a..fddbede869 100644
--- a/tools/xenstored/minios.c
+++ b/tools/xenstored/minios.c
@@ -19,8 +19,16 @@
 #include <sys/mman.h>
 #include "core.h"
 #include <xen/grant_table.h>
+#include <mini-os/9pfront.h>
 #include <mini-os/events.h>
 #include <mini-os/gnttab.h>
+#include <mini-os/sched.h>
+#include <mini-os/xenbus.h>
+#include <mini-os/xmalloc.h>
+
+#define P9_STATE_PATH	"device/9pfs/0/state"
+
+static void *p9_device;
 
 void write_pidfile(const char *pidfile)
 {
@@ -62,3 +70,31 @@ void early_init(void)
 	if (stub_domid == DOMID_INVALID)
 		barf("could not get own domid");
 }
+
+static void mount_thread(void *p)
+{
+	xenbus_event_queue events = NULL;
+	char *err;
+	char *dummy;
+
+	free(xenbus_watch_path_token(XBT_NIL, P9_STATE_PATH, "9pfs", &events));
+
+	for (;;) {
+		xenbus_wait_for_watch(&events);
+		err = xenbus_read(XBT_NIL, P9_STATE_PATH, &dummy);
+		if (!err)
+			break;
+		free(err);
+	}
+
+	free(dummy);
+
+	free(xenbus_unwatch_path_token(XBT_NIL, P9_STATE_PATH, "9pfs"));
+
+	p9_device = init_9pfront(0, XENSTORE_LIB_DIR);
+}
+
+void mount_9pfs(void)
+{
+	create_thread("mount-9pfs", mount_thread, NULL);
+}
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 27/29] tools/xenstored: add helpers for filename handling
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (25 preceding siblings ...)
  2023-11-10 16:08 ` [PATCH v2 26/29] tools/xenstored: mount 9pfs device in stubdom Juergen Gross
@ 2023-11-10 16:08 ` Juergen Gross
  2023-11-13 22:25   ` Julien Grall
  2023-11-10 16:08 ` [PATCH v2 28/29] tools/xenstored: support complete log capabilities in stubdom Juergen Gross
  2023-11-10 16:08 ` [PATCH v2 29/29] tools/xenstored: have a single do_control_memreport() Juergen Gross
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:08 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Wei Liu, Julien Grall, Anthony PERARD, Jason Andryuk

Add some helpers for handling filenames which might need different
implementations between stubdom and daemon environments:

- expansion of relative filenames (those are not really defined today,
  just expand them to be relative to /var/lib/xen/xenstore)
- expansion of xenstore_daemon_rundir() (used e.g. for saving the state
  file in case of live update - needs to be unchanged in the daemon
  case, but should result in /var/lib/xen/xenstore for stubdom)

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
---
 tools/xenstored/core.c      | 9 ++++++++-
 tools/xenstored/core.h      | 3 +++
 tools/xenstored/lu_daemon.c | 4 ++--
 tools/xenstored/minios.c    | 5 +++++
 tools/xenstored/posix.c     | 5 +++++
 5 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
index 4a9d874f17..77befd24c9 100644
--- a/tools/xenstored/core.c
+++ b/tools/xenstored/core.c
@@ -158,6 +158,13 @@ void trace_destroy(const void *data, const char *type)
 		trace("obj: DESTROY %s %p\n", type, data);
 }
 
+char *absolute_filename(const void *ctx, const char *filename)
+{
+	if (filename[0] != '/')
+		return talloc_asprintf(ctx, XENSTORE_LIB_DIR "/%s", filename);
+	return talloc_strdup(ctx, filename);
+}
+
 /**
  * Signal handler for SIGHUP, which requests that the trace log is reopened
  * (in the main loop).  A single byte is written to reopen_log_pipe, to awaken
@@ -2983,7 +2990,7 @@ int main(int argc, char *argv[])
 
 	signal(SIGHUP, trigger_reopen_log);
 	if (tracefile)
-		tracefile = talloc_strdup(NULL, tracefile);
+		tracefile = absolute_filename(NULL, tracefile);
 
 #ifndef NO_LIVE_UPDATE
 	/* Read state in case of live update. */
diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
index a0d3592961..51e1dddb22 100644
--- a/tools/xenstored/core.h
+++ b/tools/xenstored/core.h
@@ -393,6 +393,9 @@ void early_init(void);
 void mount_9pfs(void);
 #endif
 
+const char *xenstore_rundir(void);
+char *absolute_filename(const void *ctx, const char *filename);
+
 /* Write out the pidfile */
 void write_pidfile(const char *pidfile);
 
diff --git a/tools/xenstored/lu_daemon.c b/tools/xenstored/lu_daemon.c
index 71bcabadd3..6351111ab0 100644
--- a/tools/xenstored/lu_daemon.c
+++ b/tools/xenstored/lu_daemon.c
@@ -24,7 +24,7 @@ void lu_get_dump_state(struct lu_dump_state *state)
 	state->size = 0;
 
 	state->filename = talloc_asprintf(NULL, "%s/state_dump",
-					  xenstore_daemon_rundir());
+					  xenstore_rundir());
 	if (!state->filename)
 		barf("Allocation failure");
 
@@ -65,7 +65,7 @@ FILE *lu_dump_open(const void *ctx)
 	int fd;
 
 	filename = talloc_asprintf(ctx, "%s/state_dump",
-				   xenstore_daemon_rundir());
+				   xenstore_rundir());
 	if (!filename)
 		return NULL;
 
diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
index fddbede869..cfc2377857 100644
--- a/tools/xenstored/minios.c
+++ b/tools/xenstored/minios.c
@@ -98,3 +98,8 @@ void mount_9pfs(void)
 {
 	create_thread("mount-9pfs", mount_thread, NULL);
 }
+
+const char *xenstore_rundir(void)
+{
+	return XENSTORE_LIB_DIR;
+}
diff --git a/tools/xenstored/posix.c b/tools/xenstored/posix.c
index fcb7791bd7..76f5c9ab84 100644
--- a/tools/xenstored/posix.c
+++ b/tools/xenstored/posix.c
@@ -168,3 +168,8 @@ void early_init(void)
 	mkdir(xenstore_daemon_rundir(), 0755);
 	mkdir(XENSTORE_LIB_DIR, 0755);
 }
+
+const char *xenstore_rundir(void)
+{
+	return xenstore_daemon_rundir();
+}
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 28/29] tools/xenstored: support complete log capabilities in stubdom
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (26 preceding siblings ...)
  2023-11-10 16:08 ` [PATCH v2 27/29] tools/xenstored: add helpers for filename handling Juergen Gross
@ 2023-11-10 16:08 ` Juergen Gross
  2023-11-13 22:40   ` Julien Grall
  2023-11-10 16:08 ` [PATCH v2 29/29] tools/xenstored: have a single do_control_memreport() Juergen Gross
  28 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:08 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Wei Liu, Anthony PERARD, Julien Grall, Jason Andryuk

With 9pfs being fully available in Xenstore-stubdom now, there is no
reason to not fully support all logging capabilities in stubdom.

Open the logfile on stubdom only after the 9pfs file system has been
mounted.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
---
 tools/hotplug/Linux/launch-xenstore.in |  1 +
 tools/xenstored/control.c              | 30 +++++++++++++-------------
 tools/xenstored/minios.c               |  3 +++
 3 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/tools/hotplug/Linux/launch-xenstore.in b/tools/hotplug/Linux/launch-xenstore.in
index e854ca1eb8..da4eeca7c5 100644
--- a/tools/hotplug/Linux/launch-xenstore.in
+++ b/tools/hotplug/Linux/launch-xenstore.in
@@ -98,6 +98,7 @@ test -f @CONFIG_DIR@/@CONFIG_LEAF_DIR@/xencommons && . @CONFIG_DIR@/@CONFIG_LEAF
 	[ -z "$XENSTORE_DOMAIN_SIZE" ] && XENSTORE_DOMAIN_SIZE=8
 	XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS --memory $XENSTORE_DOMAIN_SIZE"
 	[ -z "$XENSTORE_MAX_DOMAIN_SIZE" ] || XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS --maxmem $XENSTORE_MAX_DOMAIN_SIZE"
+	[ -z "$XENSTORED_TRACE" ] || XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS -T xenstored-trace.log"
 
 	echo -n Starting $XENSTORE_DOMAIN_KERNEL...
 	${LIBEXEC_BIN}/init-xenstore-domain $XENSTORE_DOMAIN_ARGS || exit 1
diff --git a/tools/xenstored/control.c b/tools/xenstored/control.c
index b2f64d674f..dae23a5ac0 100644
--- a/tools/xenstored/control.c
+++ b/tools/xenstored/control.c
@@ -201,19 +201,6 @@ static int do_control_quota_s(const void *ctx, struct connection *conn,
 	return EINVAL;
 }
 
-#ifdef __MINIOS__
-static int do_control_memreport(const void *ctx, struct connection *conn,
-				const char **vec, int num)
-{
-	if (num)
-		return EINVAL;
-
-	talloc_report_full(NULL, stdout);
-
-	send_ack(conn, XS_CONTROL);
-	return 0;
-}
-#else
 static int do_control_logfile(const void *ctx, struct connection *conn,
 			      const char **vec, int num)
 {
@@ -222,13 +209,26 @@ static int do_control_logfile(const void *ctx, struct connection *conn,
 
 	close_log();
 	talloc_free(tracefile);
-	tracefile = talloc_strdup(NULL, vec[0]);
+	tracefile = absolute_filename(NULL, vec[0]);
 	reopen_log();
 
 	send_ack(conn, XS_CONTROL);
 	return 0;
 }
 
+#ifdef __MINIOS__
+static int do_control_memreport(const void *ctx, struct connection *conn,
+				const char **vec, int num)
+{
+	if (num)
+		return EINVAL;
+
+	talloc_report_full(NULL, stdout);
+
+	send_ack(conn, XS_CONTROL);
+	return 0;
+}
+#else
 static int do_control_memreport(const void *ctx, struct connection *conn,
 				const char **vec, int num)
 {
@@ -309,10 +309,10 @@ static struct cmd_s cmds[] = {
 		"[-c <cmdline>] [-F] [-t <timeout>] <file>\n"
 		"    Default timeout is 60 seconds.", 5 },
 #endif
+	{ "logfile", do_control_logfile, "<file>" },
 #ifdef __MINIOS__
 	{ "memreport", do_control_memreport, "" },
 #else
-	{ "logfile", do_control_logfile, "<file>" },
 	{ "memreport", do_control_memreport, "[<file>]" },
 #endif
 	{ "print", do_control_print, "<string>" },
diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
index cfc2377857..9e78b96d07 100644
--- a/tools/xenstored/minios.c
+++ b/tools/xenstored/minios.c
@@ -92,6 +92,9 @@ static void mount_thread(void *p)
 	free(xenbus_unwatch_path_token(XBT_NIL, P9_STATE_PATH, "9pfs"));
 
 	p9_device = init_9pfront(0, XENSTORE_LIB_DIR);
+
+	/* Start logging if selected. */
+	reopen_log();
 }
 
 void mount_9pfs(void)
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 29/29] tools/xenstored: have a single do_control_memreport()
  2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
                   ` (27 preceding siblings ...)
  2023-11-10 16:08 ` [PATCH v2 28/29] tools/xenstored: support complete log capabilities in stubdom Juergen Gross
@ 2023-11-10 16:08 ` Juergen Gross
  28 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:08 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Wei Liu, Julien Grall, Anthony PERARD, Jason Andryuk

With 9pfs now available in Xenstore-stubdom, there is no reason to
have distinct do_control_memreport() variants for the daemon and the
stubdom implementations.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
---
 tools/xenstored/control.c | 27 +++++++--------------------
 1 file changed, 7 insertions(+), 20 deletions(-)

diff --git a/tools/xenstored/control.c b/tools/xenstored/control.c
index dae23a5ac0..7db2c4703b 100644
--- a/tools/xenstored/control.c
+++ b/tools/xenstored/control.c
@@ -216,23 +216,11 @@ static int do_control_logfile(const void *ctx, struct connection *conn,
 	return 0;
 }
 
-#ifdef __MINIOS__
-static int do_control_memreport(const void *ctx, struct connection *conn,
-				const char **vec, int num)
-{
-	if (num)
-		return EINVAL;
-
-	talloc_report_full(NULL, stdout);
-
-	send_ack(conn, XS_CONTROL);
-	return 0;
-}
-#else
 static int do_control_memreport(const void *ctx, struct connection *conn,
 				const char **vec, int num)
 {
 	FILE *fp;
+	char *filename;
 	int fd;
 
 	if (num > 1)
@@ -255,8 +243,12 @@ static int do_control_memreport(const void *ctx, struct connection *conn,
 			if (!fp)
 				close(fd);
 		}
-	} else
-		fp = fopen(vec[0], "a");
+	} else {
+		filename = absolute_filename(ctx, vec[0]);
+		if (!filename)
+			return ENOMEM;
+		fp = fopen(filename, "a");
+	}
 
 	if (!fp)
 		return EBADF;
@@ -267,7 +259,6 @@ static int do_control_memreport(const void *ctx, struct connection *conn,
 	send_ack(conn, XS_CONTROL);
 	return 0;
 }
-#endif
 
 static int do_control_print(const void *ctx, struct connection *conn,
 			    const char **vec, int num)
@@ -310,11 +301,7 @@ static struct cmd_s cmds[] = {
 		"    Default timeout is 60 seconds.", 5 },
 #endif
 	{ "logfile", do_control_logfile, "<file>" },
-#ifdef __MINIOS__
-	{ "memreport", do_control_memreport, "" },
-#else
 	{ "memreport", do_control_memreport, "[<file>]" },
-#endif
 	{ "print", do_control_print, "<string>" },
 	{ "quota", do_control_quota,
 		"[set <name> <val>|<domid>|max [-r]]" },
-- 
2.35.3



^ permalink raw reply related	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 02/29] tools: add a new xen logging daemon
  2023-11-10 16:07 ` [PATCH v2 02/29] tools: add a new xen logging daemon Juergen Gross
@ 2023-11-10 16:13   ` Andrew Cooper
  2023-11-10 16:14     ` Juergen Gross
  2023-11-13 17:36   ` Jason Andryuk
  1 sibling, 1 reply; 86+ messages in thread
From: Andrew Cooper @ 2023-11-10 16:13 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD

Subject wants a log->9pfsd adjustment too

On 10/11/2023 4:07 pm, Juergen Gross wrote:
> diff --git a/tools/xen-9pfsd/xen-9pfsd.c b/tools/xen-9pfsd/xen-9pfsd.c
> new file mode 100644
> index 0000000000..c365b35fe5
> --- /dev/null
> +++ b/tools/xen-9pfsd/xen-9pfsd.c
> @@ -0,0 +1,145 @@
> +/* SPDX-License-Identifier: GPL-2.0 */

Sorry I didn't notice this before.  This is a deprecated SDPX tag now,
and the preferred form is with an explicit -only or -or-later suffix.

I presume you mean -only in this case?

(Happy to fix both up on commit if there are no other issues.)

~Andrew


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 02/29] tools: add a new xen logging daemon
  2023-11-10 16:13   ` Andrew Cooper
@ 2023-11-10 16:14     ` Juergen Gross
  0 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-10 16:14 UTC (permalink / raw)
  To: Andrew Cooper, xen-devel; +Cc: Wei Liu, Anthony PERARD


[-- Attachment #1.1.1: Type: text/plain, Size: 696 bytes --]

On 10.11.23 17:13, Andrew Cooper wrote:
> Subject wants a log->9pfsd adjustment too
> 
> On 10/11/2023 4:07 pm, Juergen Gross wrote:
>> diff --git a/tools/xen-9pfsd/xen-9pfsd.c b/tools/xen-9pfsd/xen-9pfsd.c
>> new file mode 100644
>> index 0000000000..c365b35fe5
>> --- /dev/null
>> +++ b/tools/xen-9pfsd/xen-9pfsd.c
>> @@ -0,0 +1,145 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
> 
> Sorry I didn't notice this before.  This is a deprecated SDPX tag now,
> and the preferred form is with an explicit -only or -or-later suffix.
> 
> I presume you mean -only in this case?

Yes.

> 
> (Happy to fix both up on commit if there are no other issues.)

Thanks,


Juergen


[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 21/29] tools/xenstored: add early_init() function
  2023-11-10 16:07 ` [PATCH v2 21/29] tools/xenstored: add early_init() function Juergen Gross
@ 2023-11-10 17:31   ` Julien Grall
  2023-11-13 10:27     ` Juergen Gross
  0 siblings, 1 reply; 86+ messages in thread
From: Julien Grall @ 2023-11-10 17:31 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk

Hi Juergen,

On 10/11/2023 16:07, Juergen Gross wrote:
> Some xenstored initialization needs to be done in the daemon case only,
> so split it out into a new early_init() function being a stub in the
> stubdom case.

It is not entirely clear to me how you decided the split. For example...

> 
> Signed-off-by: Juergen Gross <jgross@suse.com>
> Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
> ---
> V2:
> - rename function
> - move patch earlier in the series
> ---
>   tools/xenstored/core.c   |  6 +-----
>   tools/xenstored/core.h   |  3 +++
>   tools/xenstored/minios.c |  3 +++
>   tools/xenstored/posix.c  | 11 +++++++++++
>   4 files changed, 18 insertions(+), 5 deletions(-)
> 
> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
> index edd07711db..0c14823fb0 100644
> --- a/tools/xenstored/core.c
> +++ b/tools/xenstored/core.c
> @@ -2933,11 +2933,7 @@ int main(int argc, char *argv[])
>   	if (optind != argc)
>   		barf("%s: No arguments desired", argv[0]);
>   
> -	reopen_log();
> -
> -	/* Make sure xenstored directory exists. */
> -	/* Errors ignored here, will be reported when we open files */
> -	mkdir(xenstore_daemon_rundir(), 0755);
> +	early_init();
>   
>   	if (dofork) {
>   		openlog("xenstored", 0, LOG_DAEMON);

For stubdom we would not fork, so I would expect the call to openlog() 
not necessary. Same for the init_pipe() below.

> diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
> index 480b0f5f7b..d0ac587f8f 100644
> --- a/tools/xenstored/core.h
> +++ b/tools/xenstored/core.h
> @@ -35,6 +35,8 @@
>   #include "list.h"
>   #include "hashtable.h"
>   
> +#define XENSTORE_LIB_DIR	XEN_LIB_DIR "/xenstore"
> +
>   #ifndef O_CLOEXEC
>   #define O_CLOEXEC 0
>   /* O_CLOEXEC support is needed for Live Update in the daemon case. */
> @@ -384,6 +386,7 @@ static inline bool domain_is_unprivileged(const struct connection *conn)
>   
>   /* Return the event channel used by xenbus. */
>   evtchn_port_t get_xenbus_evtchn(void);
> +void early_init(void);
>   
>   /* Write out the pidfile */
>   void write_pidfile(const char *pidfile);
> diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
> index 0779efbf91..0cdec3ae51 100644
> --- a/tools/xenstored/minios.c
> +++ b/tools/xenstored/minios.c
> @@ -54,3 +54,6 @@ void unmap_xenbus(void *interface)
>   	xengnttab_unmap(*xgt_handle, interface, 1);
>   }
>   
> +void early_init(void)
> +{
> +}
> diff --git a/tools/xenstored/posix.c b/tools/xenstored/posix.c
> index 7e03dd982d..fcb7791bd7 100644
> --- a/tools/xenstored/posix.c
> +++ b/tools/xenstored/posix.c
> @@ -22,6 +22,7 @@
>   #include <fcntl.h>
>   #include <stdlib.h>
>   #include <sys/mman.h>
> +#include <xen-tools/xenstore-common.h>
>   
>   #include "utils.h"
>   #include "core.h"
> @@ -157,3 +158,13 @@ void *xenbus_map(void)
>   
>   	return addr;
>   }
> +
> +void early_init(void)
> +{
> +	reopen_log();
> +
> +	/* Make sure xenstored directories exist. */
> +	/* Errors ignored here, will be reported when we open files */
> +	mkdir(xenstore_daemon_rundir(), 0755);
> +	mkdir(XENSTORE_LIB_DIR, 0755);

The addition of the second mkdir() doesn't seem to be explained in the 
commit message.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 22/29] tools/xenstored: get own domid in stubdom case
  2023-11-10 16:07 ` [PATCH v2 22/29] tools/xenstored: get own domid in stubdom case Juergen Gross
@ 2023-11-10 17:36   ` Julien Grall
  2023-11-13  9:03     ` Juergen Gross
  2023-11-13 21:59   ` Julien Grall
  1 sibling, 1 reply; 86+ messages in thread
From: Julien Grall @ 2023-11-10 17:36 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD

Hi Juergen,

On 10/11/2023 16:07, Juergen Gross wrote:
> Obtain the own domid from the Xenstore special grant entry when running
> as stubdom.
The commit message says we would use the grant entry but ...

> 
> Signed-off-by: Juergen Gross <jgross@suse.com>
> ---
> V2:
> - replacement of V1 patch (ANdrew Cooper)
> ---
>   tools/xenstored/core.c   | 1 +
>   tools/xenstored/core.h   | 1 +
>   tools/xenstored/minios.c | 5 +++++
>   3 files changed, 7 insertions(+)
> 
> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
> index 0c14823fb0..8e271e31f9 100644
> --- a/tools/xenstored/core.c
> +++ b/tools/xenstored/core.c
> @@ -2738,6 +2738,7 @@ static struct option options[] = {
>   int dom0_domid = 0;
>   int dom0_event = 0;
>   int priv_domid = 0;
> +int stub_domid = -1;
>   
>   static unsigned int get_optval_uint(const char *arg)
>   {
> diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
> index d0ac587f8f..3c28007d11 100644
> --- a/tools/xenstored/core.h
> +++ b/tools/xenstored/core.h
> @@ -361,6 +361,7 @@ do {						\
>   extern int dom0_domid;
>   extern int dom0_event;
>   extern int priv_domid;
> +extern int stub_domid;
>   extern bool keep_orphans;
>   
>   extern unsigned int timeout_watch_event_msec;
> diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
> index 0cdec3ae51..202d70387a 100644
> --- a/tools/xenstored/minios.c
> +++ b/tools/xenstored/minios.c
> @@ -19,6 +19,8 @@
>   #include <sys/mman.h>
>   #include "core.h"
>   #include <xen/grant_table.h>
> +#include <mini-os/events.h>
> +#include <mini-os/gnttab.h>
>   
>   void write_pidfile(const char *pidfile)
>   {
> @@ -56,4 +58,7 @@ void unmap_xenbus(void *interface)
>   
>   void early_init(void)
>   {
> +	stub_domid = evtchn_get_domid();

... the function is called evtchn_*. So the commit message doesn't seem 
to match the code.

Also, you seem to include mini-os/gnttab.h when you don't add any 
function that seems to be related.

Lastly, shouldn't this helper be called get_domain_id() (or similar) 
because the domid is not specific to the event channel subsystem?

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 23/29] tools/xenstored: rework ring page (un)map functions
  2023-11-10 16:07 ` [PATCH v2 23/29] tools/xenstored: rework ring page (un)map functions Juergen Gross
@ 2023-11-10 17:51   ` Julien Grall
  0 siblings, 0 replies; 86+ messages in thread
From: Julien Grall @ 2023-11-10 17:51 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk

Hi Juergen,

On 10/11/2023 16:07, Juergen Gross wrote:
> When [un]mapping the ring page of a Xenstore client, different actions
> are required for "normal" guests and dom0. Today this distinction is
> made at call site.
> 
> Move this distinction into [un]map_interface() instead, avoiding code
> duplication and preparing special handling for [un]mapping the stub
> domain's ring page.
> 
> Signed-off-by: Juergen Gross <jgross@suse.com>
> Reviewed-by: Jason Andryuk <jandryuk@gmail.com>

Reviewed-by: Julien Grall <jgrall@amazon.com>

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 24/29] tools/xenstored: split domain_init()
  2023-11-10 16:07 ` [PATCH v2 24/29] tools/xenstored: split domain_init() Juergen Gross
@ 2023-11-10 18:05   ` Julien Grall
  2023-11-13  8:58     ` Juergen Gross
  0 siblings, 1 reply; 86+ messages in thread
From: Julien Grall @ 2023-11-10 18:05 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD

Hi Juergen,

On 10/11/2023 16:07, Juergen Gross wrote:
> Today domain_init() is called either just before calling dom0_init()
> in case no live update is being performed, or it is called after
> reading the global state from read_state_global(), as the event
> channel fd is needed.
> 
> Split up domain_init() into a preparation part which can be called
> unconditionally, and in a part setting up the event channel handle.

Looking at the code, domain_init() may not be called if -D is passed to 
Xen. With your change, part of it would not be called unconditionally.

So does -D actually make sense? Did it actually work before your change? 
Should it be removed?

> 
> Note that there is no chance that chk_domain_generation() can be
> called now before xc_handle has been setup, so there is no need for
> the related special case anymore.
> 
> Signed-off-by: Juergen Gross <jgross@suse.com>
> ---
>   tools/xenstored/core.c   |  2 ++
>   tools/xenstored/domain.c | 12 ++++++------
>   tools/xenstored/domain.h |  1 +
>   3 files changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
> index 8e271e31f9..b9ec50b34c 100644
> --- a/tools/xenstored/core.c
> +++ b/tools/xenstored/core.c
> @@ -2960,6 +2960,8 @@ int main(int argc, char *argv[])
>   
>   	init_pipe(reopen_log_pipe);
>   
> +	domain_static_init();

NIT: I find 'static' a bit confusing. How about using 'early' instead to 
match 'early_init()'?

> +
>   	/* Listen to hypervisor. */
>   	if (!no_domain_init && !live_update) {
>   		domain_init(-1);
> diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
> index 58b0942043..fa17f68618 100644
> --- a/tools/xenstored/domain.c
> +++ b/tools/xenstored/domain.c
> @@ -1224,10 +1224,8 @@ static int domeq_fn(const void *key1, const void *key2)
>   	return *(const unsigned int *)key1 == *(const unsigned int *)key2;
>   }
>   
> -void domain_init(int evtfd)
> +void domain_static_init(void)
>   {
> -	int rc;
> -
>   	/* Start with a random rather low domain count for the hashtable. */
>   	domhash = create_hashtable(NULL, "domains", domhash_fn, domeq_fn, 0);
>   	if (!domhash)
> @@ -1258,6 +1256,11 @@ void domain_init(int evtfd)
>   	xengnttab_set_max_grants(*xgt_handle, DOMID_FIRST_RESERVED);
>   
>   	talloc_set_destructor(xgt_handle, close_xgt_handle);
> +}
> +
> +void domain_init(int evtfd)
> +{
> +	int rc;
>   
>   	if (evtfd < 0)
>   		xce_handle = xenevtchn_open(NULL, XENEVTCHN_NO_CLOEXEC);
> @@ -1291,9 +1294,6 @@ static bool chk_domain_generation(unsigned int domid, uint64_t gen)
>   {
>   	struct domain *d;
>   
> -	if (!xc_handle && domid == dom0_domid)
> -		return true;
> -
>   	d = find_domain_struct(domid);
>   
>   	return d && d->generation <= gen;
> diff --git a/tools/xenstored/domain.h b/tools/xenstored/domain.h
> index 7625dca8cd..6c00540311 100644
> --- a/tools/xenstored/domain.h
> +++ b/tools/xenstored/domain.h
> @@ -82,6 +82,7 @@ int do_get_domain_path(const void *ctx, struct connection *conn,
>   int do_reset_watches(const void *ctx, struct connection *conn,
>   		     struct buffered_data *in);
>   
> +void domain_static_init(void);
>   void domain_init(int evtfd);
>   void dom0_init(void);
>   void domain_deinit(void);

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 24/29] tools/xenstored: split domain_init()
  2023-11-10 18:05   ` Julien Grall
@ 2023-11-13  8:58     ` Juergen Gross
  2023-11-13 11:37       ` Juergen Gross
  0 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-13  8:58 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: Wei Liu, Anthony PERARD


[-- Attachment #1.1.1: Type: text/plain, Size: 1761 bytes --]

On 10.11.23 19:05, Julien Grall wrote:
> Hi Juergen,
> 
> On 10/11/2023 16:07, Juergen Gross wrote:
>> Today domain_init() is called either just before calling dom0_init()
>> in case no live update is being performed, or it is called after
>> reading the global state from read_state_global(), as the event
>> channel fd is needed.
>>
>> Split up domain_init() into a preparation part which can be called
>> unconditionally, and in a part setting up the event channel handle.
> 
> Looking at the code, domain_init() may not be called if -D is passed to Xen. 
> With your change, part of it would not be called unconditionally.
> 
> So does -D actually make sense? Did it actually work before your change? Should 
> it be removed?

Good point.

I think it should be removed. I don't think it can work at all.

> 
>>
>> Note that there is no chance that chk_domain_generation() can be
>> called now before xc_handle has been setup, so there is no need for
>> the related special case anymore.
>>
>> Signed-off-by: Juergen Gross <jgross@suse.com>
>> ---
>>   tools/xenstored/core.c   |  2 ++
>>   tools/xenstored/domain.c | 12 ++++++------
>>   tools/xenstored/domain.h |  1 +
>>   3 files changed, 9 insertions(+), 6 deletions(-)
>>
>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>> index 8e271e31f9..b9ec50b34c 100644
>> --- a/tools/xenstored/core.c
>> +++ b/tools/xenstored/core.c
>> @@ -2960,6 +2960,8 @@ int main(int argc, char *argv[])
>>       init_pipe(reopen_log_pipe);
>> +    domain_static_init();
> 
> NIT: I find 'static' a bit confusing. How about using 'early' instead to match 
> 'early_init()'?

Yes, good idea. I wasn't very happy with the name either.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 22/29] tools/xenstored: get own domid in stubdom case
  2023-11-10 17:36   ` Julien Grall
@ 2023-11-13  9:03     ` Juergen Gross
  0 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-13  9:03 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: Wei Liu, Anthony PERARD


[-- Attachment #1.1.1: Type: text/plain, Size: 2398 bytes --]

On 10.11.23 18:36, Julien Grall wrote:
> Hi Juergen,
> 
> On 10/11/2023 16:07, Juergen Gross wrote:
>> Obtain the own domid from the Xenstore special grant entry when running
>> as stubdom.
> The commit message says we would use the grant entry but ...

Sorry, now fixed.

> 
>>
>> Signed-off-by: Juergen Gross <jgross@suse.com>
>> ---
>> V2:
>> - replacement of V1 patch (ANdrew Cooper)
>> ---
>>   tools/xenstored/core.c   | 1 +
>>   tools/xenstored/core.h   | 1 +
>>   tools/xenstored/minios.c | 5 +++++
>>   3 files changed, 7 insertions(+)
>>
>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>> index 0c14823fb0..8e271e31f9 100644
>> --- a/tools/xenstored/core.c
>> +++ b/tools/xenstored/core.c
>> @@ -2738,6 +2738,7 @@ static struct option options[] = {
>>   int dom0_domid = 0;
>>   int dom0_event = 0;
>>   int priv_domid = 0;
>> +int stub_domid = -1;
>>   static unsigned int get_optval_uint(const char *arg)
>>   {
>> diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
>> index d0ac587f8f..3c28007d11 100644
>> --- a/tools/xenstored/core.h
>> +++ b/tools/xenstored/core.h
>> @@ -361,6 +361,7 @@ do {                        \
>>   extern int dom0_domid;
>>   extern int dom0_event;
>>   extern int priv_domid;
>> +extern int stub_domid;
>>   extern bool keep_orphans;
>>   extern unsigned int timeout_watch_event_msec;
>> diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
>> index 0cdec3ae51..202d70387a 100644
>> --- a/tools/xenstored/minios.c
>> +++ b/tools/xenstored/minios.c
>> @@ -19,6 +19,8 @@
>>   #include <sys/mman.h>
>>   #include "core.h"
>>   #include <xen/grant_table.h>
>> +#include <mini-os/events.h>
>> +#include <mini-os/gnttab.h>
>>   void write_pidfile(const char *pidfile)
>>   {
>> @@ -56,4 +58,7 @@ void unmap_xenbus(void *interface)
>>   void early_init(void)
>>   {
>> +    stub_domid = evtchn_get_domid();
> 
> ... the function is called evtchn_*. So the commit message doesn't seem to match 
> the code.
> 
> Also, you seem to include mini-os/gnttab.h when you don't add any function that 
> seems to be related.
> 
> Lastly, shouldn't this helper be called get_domain_id() (or similar) because the 
> domid is not specific to the event channel subsystem?

I've named it get_domid() now.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 21/29] tools/xenstored: add early_init() function
  2023-11-10 17:31   ` Julien Grall
@ 2023-11-13 10:27     ` Juergen Gross
  0 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-13 10:27 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk


[-- Attachment #1.1.1: Type: text/plain, Size: 3843 bytes --]

On 10.11.23 18:31, Julien Grall wrote:
> Hi Juergen,
> 
> On 10/11/2023 16:07, Juergen Gross wrote:
>> Some xenstored initialization needs to be done in the daemon case only,
>> so split it out into a new early_init() function being a stub in the
>> stubdom case.
> 
> It is not entirely clear to me how you decided the split. For example...
> 
>>
>> Signed-off-by: Juergen Gross <jgross@suse.com>
>> Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
>> ---
>> V2:
>> - rename function
>> - move patch earlier in the series
>> ---
>>   tools/xenstored/core.c   |  6 +-----
>>   tools/xenstored/core.h   |  3 +++
>>   tools/xenstored/minios.c |  3 +++
>>   tools/xenstored/posix.c  | 11 +++++++++++
>>   4 files changed, 18 insertions(+), 5 deletions(-)
>>
>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>> index edd07711db..0c14823fb0 100644
>> --- a/tools/xenstored/core.c
>> +++ b/tools/xenstored/core.c
>> @@ -2933,11 +2933,7 @@ int main(int argc, char *argv[])
>>       if (optind != argc)
>>           barf("%s: No arguments desired", argv[0]);
>> -    reopen_log();
>> -
>> -    /* Make sure xenstored directory exists. */
>> -    /* Errors ignored here, will be reported when we open files */
>> -    mkdir(xenstore_daemon_rundir(), 0755);
>> +    early_init();
>>       if (dofork) {
>>           openlog("xenstored", 0, LOG_DAEMON);
> 
> For stubdom we would not fork, so I would expect the call to openlog() not 
> necessary. Same for the init_pipe() below.

The main goal was to move the "mkdir(xenstore_daemon_rundir(), 0755);" out of
the way for stubdom.

I'll make this more clear in the commit message, ...

> 
>> diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
>> index 480b0f5f7b..d0ac587f8f 100644
>> --- a/tools/xenstored/core.h
>> +++ b/tools/xenstored/core.h
>> @@ -35,6 +35,8 @@
>>   #include "list.h"
>>   #include "hashtable.h"
>> +#define XENSTORE_LIB_DIR    XEN_LIB_DIR "/xenstore"
>> +
>>   #ifndef O_CLOEXEC
>>   #define O_CLOEXEC 0
>>   /* O_CLOEXEC support is needed for Live Update in the daemon case. */
>> @@ -384,6 +386,7 @@ static inline bool domain_is_unprivileged(const struct 
>> connection *conn)
>>   /* Return the event channel used by xenbus. */
>>   evtchn_port_t get_xenbus_evtchn(void);
>> +void early_init(void);
>>   /* Write out the pidfile */
>>   void write_pidfile(const char *pidfile);
>> diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
>> index 0779efbf91..0cdec3ae51 100644
>> --- a/tools/xenstored/minios.c
>> +++ b/tools/xenstored/minios.c
>> @@ -54,3 +54,6 @@ void unmap_xenbus(void *interface)
>>       xengnttab_unmap(*xgt_handle, interface, 1);
>>   }
>> +void early_init(void)
>> +{
>> +}
>> diff --git a/tools/xenstored/posix.c b/tools/xenstored/posix.c
>> index 7e03dd982d..fcb7791bd7 100644
>> --- a/tools/xenstored/posix.c
>> +++ b/tools/xenstored/posix.c
>> @@ -22,6 +22,7 @@
>>   #include <fcntl.h>
>>   #include <stdlib.h>
>>   #include <sys/mman.h>
>> +#include <xen-tools/xenstore-common.h>
>>   #include "utils.h"
>>   #include "core.h"
>> @@ -157,3 +158,13 @@ void *xenbus_map(void)
>>       return addr;
>>   }
>> +
>> +void early_init(void)
>> +{
>> +    reopen_log();
>> +
>> +    /* Make sure xenstored directories exist. */
>> +    /* Errors ignored here, will be reported when we open files */
>> +    mkdir(xenstore_daemon_rundir(), 0755);
>> +    mkdir(XENSTORE_LIB_DIR, 0755);
> 
> The addition of the second mkdir() doesn't seem to be explained in the commit 
> message.

... moving this change into context.

I'll look into moving more non-stubdom function calls into early_init() in
posix.c.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 24/29] tools/xenstored: split domain_init()
  2023-11-13  8:58     ` Juergen Gross
@ 2023-11-13 11:37       ` Juergen Gross
  0 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-13 11:37 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: Wei Liu, Anthony PERARD


[-- Attachment #1.1.1: Type: text/plain, Size: 1312 bytes --]

On 13.11.23 09:58, Juergen Gross wrote:
> On 10.11.23 19:05, Julien Grall wrote:
>> Hi Juergen,
>>
>> On 10/11/2023 16:07, Juergen Gross wrote:
>>> Today domain_init() is called either just before calling dom0_init()
>>> in case no live update is being performed, or it is called after
>>> reading the global state from read_state_global(), as the event
>>> channel fd is needed.
>>>
>>> Split up domain_init() into a preparation part which can be called
>>> unconditionally, and in a part setting up the event channel handle.
>>
>> Looking at the code, domain_init() may not be called if -D is passed to Xen. 
>> With your change, part of it would not be called unconditionally.
>>
>> So does -D actually make sense? Did it actually work before your change? 
>> Should it be removed?
> 
> Good point.
> 
> I think it should be removed. I don't think it can work at all.

I even think the "-N" and "-P" should be removed, too.

"-N" isn't really _that_ helpful when doing tests. Attaching gdb to the
running xenstored daemon is by far superior. And if you are testing any
changes in the init code you can easily patch xenstored not to daemonize.

"-P" has no real purpose at all. Why would we want to show the PID, if we
can just look into the pidfile?

Thoughts?


Juergen


[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 01/29] xen/public: add some more 9pfs xenstore paths
  2023-11-10 16:07 ` [PATCH v2 01/29] xen/public: add some more 9pfs xenstore paths Juergen Gross
@ 2023-11-13 17:14   ` Jason Andryuk
  0 siblings, 0 replies; 86+ messages in thread
From: Jason Andryuk @ 2023-11-13 17:14 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel

On Fri, Nov 10, 2023 at 1:18 PM Juergen Gross <jgross@suse.com> wrote:
>
> Add some optional additional backend paths for 9pfs PV devices. Those
> paths will be supported by the new xenlogd 9pfs backend.

xen-9pfsd

>
> Signed-off-by: Juergen Gross <jgross@suse.com>

Reviewed-by: Jason Andryuk <jandryuk@gmail.com>


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 02/29] tools: add a new xen logging daemon
  2023-11-10 16:07 ` [PATCH v2 02/29] tools: add a new xen logging daemon Juergen Gross
  2023-11-10 16:13   ` Andrew Cooper
@ 2023-11-13 17:36   ` Jason Andryuk
  2023-11-14  6:21     ` Juergen Gross
  1 sibling, 1 reply; 86+ messages in thread
From: Jason Andryuk @ 2023-11-13 17:36 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel, Wei Liu, Anthony PERARD

On Fri, Nov 10, 2023 at 11:08 AM Juergen Gross <jgross@suse.com> wrote:
>
> Add "xen-9pfsd", a new logging daemon meant to support infrastructure
> domains (e.g. xenstore-stubdom) to access files in dom0.
>
> For now only add the code needed for starting the daemon and
> registering it with Xenstore via a new "libxl/xen-9pfs/state" node by
> writing the "running" state to it.
>
> Signed-off-by: Juergen Gross <jgross@suse.com>
> ---

> --- /dev/null
> +++ b/tools/xen-9pfsd/xen-9pfsd.c
> @@ -0,0 +1,145 @@

> + * The backend device string is "xen_9pfs", the tag used for mounting the
> + * 9pfs device is "Xen".

'_' is much less common in xenstore node names than '-'.  Is there a
particular reason you chose '_'?  I generally prefer '-', but IIRC the
libxl idl can't handle '-'.  Did you hit that?

Reviewed-by: Jason Andryuk <jandryuk@gmail.com>


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 22/29] tools/xenstored: get own domid in stubdom case
  2023-11-10 16:07 ` [PATCH v2 22/29] tools/xenstored: get own domid in stubdom case Juergen Gross
  2023-11-10 17:36   ` Julien Grall
@ 2023-11-13 21:59   ` Julien Grall
  2023-11-14  6:21     ` Juergen Gross
  1 sibling, 1 reply; 86+ messages in thread
From: Julien Grall @ 2023-11-13 21:59 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD

Hi Juergen,

On 10/11/2023 16:07, Juergen Gross wrote:
> Obtain the own domid from the Xenstore special grant entry when running
> as stubdom.
> 
> Signed-off-by: Juergen Gross <jgross@suse.com>
> ---
> V2:
> - replacement of V1 patch (ANdrew Cooper)
> ---
>   tools/xenstored/core.c   | 1 +
>   tools/xenstored/core.h   | 1 +
>   tools/xenstored/minios.c | 5 +++++
>   3 files changed, 7 insertions(+)
> 
> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
> index 0c14823fb0..8e271e31f9 100644
> --- a/tools/xenstored/core.c
> +++ b/tools/xenstored/core.c
> @@ -2738,6 +2738,7 @@ static struct option options[] = {
>   int dom0_domid = 0;
>   int dom0_event = 0;
>   int priv_domid = 0;
> +int stub_domid = -1;

After looking at partch #25, I feel that it would make more sense if 
stub_domid is a domid_t and initialized to DOMID_INVALID.

At least this makes clearer that initial value is not supported to be a 
valid domid.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 25/29] tools/xenstored: map stubdom interface
  2023-11-10 16:08 ` [PATCH v2 25/29] tools/xenstored: map stubdom interface Juergen Gross
@ 2023-11-13 22:04   ` Julien Grall
  2023-11-14  6:33     ` Juergen Gross
  0 siblings, 1 reply; 86+ messages in thread
From: Julien Grall @ 2023-11-13 22:04 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD

Hi Juergen,

On 10/11/2023 16:08, Juergen Gross wrote:
> When running as stubdom, map the stubdom's Xenstore ring page in order
> to support using the 9pfs frontend.
> 
> Signed-off-by: Juergen Gross <jgross@suse.com>
> ---
>   tools/xenstored/core.c   |  2 ++
>   tools/xenstored/domain.c | 27 ++++++++++++++++++++++++++-
>   tools/xenstored/domain.h |  1 +
>   3 files changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
> index b9ec50b34c..4a9d874f17 100644
> --- a/tools/xenstored/core.c
> +++ b/tools/xenstored/core.c
> @@ -2991,6 +2991,8 @@ int main(int argc, char *argv[])
>   		lu_read_state();
>   #endif
>   
> +	stubdom_init();
> +
>   	check_store();
>   
>   	/* Get ready to listen to the tools. */
> diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
> index fa17f68618..162b87b460 100644
> --- a/tools/xenstored/domain.c
> +++ b/tools/xenstored/domain.c
> @@ -37,6 +37,10 @@
>   #include <xenctrl.h>
>   #include <xen/grant_table.h>
>   
> +#ifdef __MINIOS__
> +#include <mini-os/xenbus.h>
> +#endif
> +
>   static xc_interface **xc_handle;
>   xengnttab_handle **xgt_handle;
>   static evtchn_port_t virq_port;
> @@ -500,6 +504,11 @@ static void *map_interface(domid_t domid)
>   	if (domid == xenbus_master_domid())
>   		return xenbus_map();
>   
> +#ifdef __MINIOS__
> +	if (domid == stub_domid)
> +		return xenstore_buf;
> +#endif
> +
>   	return xengnttab_map_grant_ref(*xgt_handle, domid,
>   				       GNTTAB_RESERVED_XENSTORE,
>   				       PROT_READ|PROT_WRITE);
> @@ -509,7 +518,7 @@ static void unmap_interface(domid_t domid, void *interface)
>   {
>   	if (domid == xenbus_master_domid())
>   		unmap_xenbus(interface);
> -	else
> +	else if (domid != stub_domid)
>   		xengnttab_unmap(*xgt_handle, interface, 1);
>   }
>   
> @@ -1214,6 +1223,22 @@ void dom0_init(void)
>   	xenevtchn_notify(xce_handle, dom0->port);
>   }
>   
> +void stubdom_init(void)
> +{
> +#ifdef __MINIOS__
> +	struct domain *stubdom;
> +
> +	if (stub_domid < 0)
> +		return;
> +
> +	stubdom = introduce_domain(NULL, stub_domid, xenbus_evtchn, false);
> +	if (!stubdom)
> +		barf_perror("Failed to initialize stubdom");
> +
> +	xenevtchn_notify(xce_handle, stubdom->port);

If I compare to introduce_domain(), it is not entirely clear to me why 
the notification is done unconditionally here. Can you clarify?

> +#endif
> +}
> +
>   static unsigned int domhash_fn(const void *k)
>   {
>   	return *(const unsigned int *)k;
> diff --git a/tools/xenstored/domain.h b/tools/xenstored/domain.h
> index 6c00540311..49c60c56bf 100644
> --- a/tools/xenstored/domain.h
> +++ b/tools/xenstored/domain.h
> @@ -85,6 +85,7 @@ int do_reset_watches(const void *ctx, struct connection *conn,
>   void domain_static_init(void);
>   void domain_init(int evtfd);
>   void dom0_init(void);
> +void stubdom_init(void);
>   void domain_deinit(void);
>   void ignore_connection(struct connection *conn, unsigned int err);
>   

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 26/29] tools/xenstored: mount 9pfs device in stubdom
  2023-11-10 16:08 ` [PATCH v2 26/29] tools/xenstored: mount 9pfs device in stubdom Juergen Gross
@ 2023-11-13 22:09   ` Julien Grall
  2023-11-14  6:40     ` Juergen Gross
  0 siblings, 1 reply; 86+ messages in thread
From: Julien Grall @ 2023-11-13 22:09 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk

Hi Juergen,

On 10/11/2023 16:08, Juergen Gross wrote:
> diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
> index 162b87b460..4263c1360f 100644
> --- a/tools/xenstored/domain.c
> +++ b/tools/xenstored/domain.c
> @@ -1236,6 +1236,8 @@ void stubdom_init(void)
>   		barf_perror("Failed to initialize stubdom");
>   
>   	xenevtchn_notify(xce_handle, stubdom->port);
> +
> +	mount_9pfs();
>   #endif
>   }
>   
> diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
> index 202d70387a..fddbede869 100644
> --- a/tools/xenstored/minios.c
> +++ b/tools/xenstored/minios.c
> @@ -19,8 +19,16 @@
>   #include <sys/mman.h>
>   #include "core.h"
>   #include <xen/grant_table.h>
> +#include <mini-os/9pfront.h>
>   #include <mini-os/events.h>
>   #include <mini-os/gnttab.h>
> +#include <mini-os/sched.h>
> +#include <mini-os/xenbus.h>
> +#include <mini-os/xmalloc.h>
> +
> +#define P9_STATE_PATH	"device/9pfs/0/state"
> +
> +static void *p9_device;
>   
>   void write_pidfile(const char *pidfile)
>   {
> @@ -62,3 +70,31 @@ void early_init(void)
>   	if (stub_domid == DOMID_INVALID)
>   		barf("could not get own domid");
>   }
> +
> +static void mount_thread(void *p)
> +{
> +	xenbus_event_queue events = NULL;
> +	char *err;
> +	char *dummy;
> +
> +	free(xenbus_watch_path_token(XBT_NIL, P9_STATE_PATH, "9pfs", &events));

AFAICT, xenbus_watch_path_token() can fail. I agree this is unlikely, 
but if it fails, then it would be useful to get some logs. Otherwise...

> +
> +	for (;;) {

... this loop would be infinite.

> +		xenbus_wait_for_watch(&events);
> +		err = xenbus_read(XBT_NIL, P9_STATE_PATH, &dummy);

Can you explain why don't care about the value of the node?

> +		if (!err)
> +			break;
> +		free(err);
> +	}
> +
> +	free(dummy);
> +
> +	free(xenbus_unwatch_path_token(XBT_NIL, P9_STATE_PATH, "9pfs"));

xenbus_unwatch_path_token() could technically fails. It would be helpful 
to print a message.

> +
> +	p9_device = init_9pfront(0, XENSTORE_LIB_DIR);
> +}
> +
> +void mount_9pfs(void)
> +{
> +	create_thread("mount-9pfs", mount_thread, NULL);
> +}

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 27/29] tools/xenstored: add helpers for filename handling
  2023-11-10 16:08 ` [PATCH v2 27/29] tools/xenstored: add helpers for filename handling Juergen Gross
@ 2023-11-13 22:25   ` Julien Grall
  2023-11-14  6:45     ` Juergen Gross
  0 siblings, 1 reply; 86+ messages in thread
From: Julien Grall @ 2023-11-13 22:25 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk

Hi Juergen,

On 10/11/2023 16:08, Juergen Gross wrote:
> Add some helpers for handling filenames which might need different
> implementations between stubdom and daemon environments:
> 
> - expansion of relative filenames (those are not really defined today,
>    just expand them to be relative to /var/lib/xen/xenstore)
> - expansion of xenstore_daemon_rundir() (used e.g. for saving the state
>    file in case of live update - needs to be unchanged in the daemon
>    case, but should result in /var/lib/xen/xenstore for stubdom)
> 
> Signed-off-by: Juergen Gross <jgross@suse.com>
> Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
> ---
>   tools/xenstored/core.c      | 9 ++++++++-
>   tools/xenstored/core.h      | 3 +++
>   tools/xenstored/lu_daemon.c | 4 ++--
>   tools/xenstored/minios.c    | 5 +++++
>   tools/xenstored/posix.c     | 5 +++++
>   5 files changed, 23 insertions(+), 3 deletions(-)
> 
> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
> index 4a9d874f17..77befd24c9 100644
> --- a/tools/xenstored/core.c
> +++ b/tools/xenstored/core.c
> @@ -158,6 +158,13 @@ void trace_destroy(const void *data, const char *type)
>   		trace("obj: DESTROY %s %p\n", type, data);
>   }
>   
> +char *absolute_filename(const void *ctx, const char *filename)

Can the return be const?

> +{
> +	if (filename[0] != '/')
> +		return talloc_asprintf(ctx, XENSTORE_LIB_DIR "/%s", filename);

Looking at the rest of patch, you will be using xenstore_rundir(). I 
wonder whether it would not be better to switch to xenstore_rundir() so...

> +	return talloc_strdup(ctx, filename);
> +}
> +
>   /**
>    * Signal handler for SIGHUP, which requests that the trace log is reopened
>    * (in the main loop).  A single byte is written to reopen_log_pipe, to awaken
> @@ -2983,7 +2990,7 @@ int main(int argc, char *argv[])
>   
>   	signal(SIGHUP, trigger_reopen_log);
>   	if (tracefile)
> -		tracefile = talloc_strdup(NULL, tracefile);
> +		tracefile = absolute_filename(NULL, tracefile);
>   
>   #ifndef NO_LIVE_UPDATE
>   	/* Read state in case of live update. */
> diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
> index a0d3592961..51e1dddb22 100644
> --- a/tools/xenstored/core.h
> +++ b/tools/xenstored/core.h
> @@ -393,6 +393,9 @@ void early_init(void);
>   void mount_9pfs(void);
>   #endif
>   
> +const char *xenstore_rundir(void);
> +char *absolute_filename(const void *ctx, const char *filename);
> +
>   /* Write out the pidfile */
>   void write_pidfile(const char *pidfile);
>   
> diff --git a/tools/xenstored/lu_daemon.c b/tools/xenstored/lu_daemon.c
> index 71bcabadd3..6351111ab0 100644
> --- a/tools/xenstored/lu_daemon.c
> +++ b/tools/xenstored/lu_daemon.c
> @@ -24,7 +24,7 @@ void lu_get_dump_state(struct lu_dump_state *state)
>   	state->size = 0;
>   
>   	state->filename = talloc_asprintf(NULL, "%s/state_dump",
> -					  xenstore_daemon_rundir());
> +					  xenstore_rundir());

... call and ...

>   	if (!state->filename)
>   		barf("Allocation failure");
>   
> @@ -65,7 +65,7 @@ FILE *lu_dump_open(const void *ctx)
>   	int fd;
>   
>   	filename = talloc_asprintf(ctx, "%s/state_dump",
> -				   xenstore_daemon_rundir());
> +				   xenstore_rundir());

... this one could be replaced with absolute_filename().

>   	if (!filename)
>   		return NULL;
>   
> diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
> index fddbede869..cfc2377857 100644
> --- a/tools/xenstored/minios.c
> +++ b/tools/xenstored/minios.c
> @@ -98,3 +98,8 @@ void mount_9pfs(void)
>   {
>   	create_thread("mount-9pfs", mount_thread, NULL);
>   }
> +
> +const char *xenstore_rundir(void)
> +{
> +	return XENSTORE_LIB_DIR;
> +}
> diff --git a/tools/xenstored/posix.c b/tools/xenstored/posix.c
> index fcb7791bd7..76f5c9ab84 100644
> --- a/tools/xenstored/posix.c
> +++ b/tools/xenstored/posix.c
> @@ -168,3 +168,8 @@ void early_init(void)
>   	mkdir(xenstore_daemon_rundir(), 0755);
>   	mkdir(XENSTORE_LIB_DIR, 0755);
>   }
> +
> +const char *xenstore_rundir(void)
> +{
> +	return xenstore_daemon_rundir();
> +}

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 28/29] tools/xenstored: support complete log capabilities in stubdom
  2023-11-10 16:08 ` [PATCH v2 28/29] tools/xenstored: support complete log capabilities in stubdom Juergen Gross
@ 2023-11-13 22:40   ` Julien Grall
  2023-11-14  6:45     ` Juergen Gross
  0 siblings, 1 reply; 86+ messages in thread
From: Julien Grall @ 2023-11-13 22:40 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk

Hi Juergen,

On 10/11/2023 16:08, Juergen Gross wrote:
> With 9pfs being fully available in Xenstore-stubdom now, there is no
> reason to not fully support all logging capabilities in stubdom.
> 
> Open the logfile on stubdom only after the 9pfs file system has been
> mounted.
> 
> Signed-off-by: Juergen Gross <jgross@suse.com>
> Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
> ---
>   tools/hotplug/Linux/launch-xenstore.in |  1 +
>   tools/xenstored/control.c              | 30 +++++++++++++-------------
>   tools/xenstored/minios.c               |  3 +++
>   3 files changed, 19 insertions(+), 15 deletions(-)
> 
> diff --git a/tools/hotplug/Linux/launch-xenstore.in b/tools/hotplug/Linux/launch-xenstore.in
> index e854ca1eb8..da4eeca7c5 100644
> --- a/tools/hotplug/Linux/launch-xenstore.in
> +++ b/tools/hotplug/Linux/launch-xenstore.in
> @@ -98,6 +98,7 @@ test -f @CONFIG_DIR@/@CONFIG_LEAF_DIR@/xencommons && . @CONFIG_DIR@/@CONFIG_LEAF
>   	[ -z "$XENSTORE_DOMAIN_SIZE" ] && XENSTORE_DOMAIN_SIZE=8
>   	XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS --memory $XENSTORE_DOMAIN_SIZE"
>   	[ -z "$XENSTORE_MAX_DOMAIN_SIZE" ] || XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS --maxmem $XENSTORE_MAX_DOMAIN_SIZE"
> +	[ -z "$XENSTORED_TRACE" ] || XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS -T xenstored-trace.log"

I am probably missing something, but any reason to not use 
@XEN_LOG_DIR@/xenstored-trace.log as we do for xenstored?

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 02/29] tools: add a new xen logging daemon
  2023-11-13 17:36   ` Jason Andryuk
@ 2023-11-14  6:21     ` Juergen Gross
  0 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-14  6:21 UTC (permalink / raw)
  To: Jason Andryuk; +Cc: xen-devel, Wei Liu, Anthony PERARD


[-- Attachment #1.1.1: Type: text/plain, Size: 984 bytes --]

On 13.11.23 18:36, Jason Andryuk wrote:
> On Fri, Nov 10, 2023 at 11:08 AM Juergen Gross <jgross@suse.com> wrote:
>>
>> Add "xen-9pfsd", a new logging daemon meant to support infrastructure
>> domains (e.g. xenstore-stubdom) to access files in dom0.
>>
>> For now only add the code needed for starting the daemon and
>> registering it with Xenstore via a new "libxl/xen-9pfs/state" node by
>> writing the "running" state to it.
>>
>> Signed-off-by: Juergen Gross <jgross@suse.com>
>> ---
> 
>> --- /dev/null
>> +++ b/tools/xen-9pfsd/xen-9pfsd.c
>> @@ -0,0 +1,145 @@
> 
>> + * The backend device string is "xen_9pfs", the tag used for mounting the
>> + * 9pfs device is "Xen".
> 
> '_' is much less common in xenstore node names than '-'.  Is there a
> particular reason you chose '_'?  I generally prefer '-', but IIRC the
> libxl idl can't handle '-'.  Did you hit that?

Yes.

> 
> Reviewed-by: Jason Andryuk <jandryuk@gmail.com>

Thanks,

Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 22/29] tools/xenstored: get own domid in stubdom case
  2023-11-13 21:59   ` Julien Grall
@ 2023-11-14  6:21     ` Juergen Gross
  0 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-14  6:21 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: Wei Liu, Anthony PERARD


[-- Attachment #1.1.1: Type: text/plain, Size: 1098 bytes --]

On 13.11.23 22:59, Julien Grall wrote:
> Hi Juergen,
> 
> On 10/11/2023 16:07, Juergen Gross wrote:
>> Obtain the own domid from the Xenstore special grant entry when running
>> as stubdom.
>>
>> Signed-off-by: Juergen Gross <jgross@suse.com>
>> ---
>> V2:
>> - replacement of V1 patch (ANdrew Cooper)
>> ---
>>   tools/xenstored/core.c   | 1 +
>>   tools/xenstored/core.h   | 1 +
>>   tools/xenstored/minios.c | 5 +++++
>>   3 files changed, 7 insertions(+)
>>
>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>> index 0c14823fb0..8e271e31f9 100644
>> --- a/tools/xenstored/core.c
>> +++ b/tools/xenstored/core.c
>> @@ -2738,6 +2738,7 @@ static struct option options[] = {
>>   int dom0_domid = 0;
>>   int dom0_event = 0;
>>   int priv_domid = 0;
>> +int stub_domid = -1;
> 
> After looking at partch #25, I feel that it would make more sense if stub_domid 
> is a domid_t and initialized to DOMID_INVALID.
> 
> At least this makes clearer that initial value is not supported to be a valid 
> domid.

Yes, you are right.


Juergen


[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 25/29] tools/xenstored: map stubdom interface
  2023-11-13 22:04   ` Julien Grall
@ 2023-11-14  6:33     ` Juergen Gross
  2023-11-14  8:56       ` Julien Grall
  0 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-14  6:33 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: Wei Liu, Anthony PERARD


[-- Attachment #1.1.1: Type: text/plain, Size: 2981 bytes --]

On 13.11.23 23:04, Julien Grall wrote:
> Hi Juergen,
> 
> On 10/11/2023 16:08, Juergen Gross wrote:
>> When running as stubdom, map the stubdom's Xenstore ring page in order
>> to support using the 9pfs frontend.
>>
>> Signed-off-by: Juergen Gross <jgross@suse.com>
>> ---
>>   tools/xenstored/core.c   |  2 ++
>>   tools/xenstored/domain.c | 27 ++++++++++++++++++++++++++-
>>   tools/xenstored/domain.h |  1 +
>>   3 files changed, 29 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>> index b9ec50b34c..4a9d874f17 100644
>> --- a/tools/xenstored/core.c
>> +++ b/tools/xenstored/core.c
>> @@ -2991,6 +2991,8 @@ int main(int argc, char *argv[])
>>           lu_read_state();
>>   #endif
>> +    stubdom_init();
>> +
>>       check_store();
>>       /* Get ready to listen to the tools. */
>> diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
>> index fa17f68618..162b87b460 100644
>> --- a/tools/xenstored/domain.c
>> +++ b/tools/xenstored/domain.c
>> @@ -37,6 +37,10 @@
>>   #include <xenctrl.h>
>>   #include <xen/grant_table.h>
>> +#ifdef __MINIOS__
>> +#include <mini-os/xenbus.h>
>> +#endif
>> +
>>   static xc_interface **xc_handle;
>>   xengnttab_handle **xgt_handle;
>>   static evtchn_port_t virq_port;
>> @@ -500,6 +504,11 @@ static void *map_interface(domid_t domid)
>>       if (domid == xenbus_master_domid())
>>           return xenbus_map();
>> +#ifdef __MINIOS__
>> +    if (domid == stub_domid)
>> +        return xenstore_buf;
>> +#endif
>> +
>>       return xengnttab_map_grant_ref(*xgt_handle, domid,
>>                          GNTTAB_RESERVED_XENSTORE,
>>                          PROT_READ|PROT_WRITE);
>> @@ -509,7 +518,7 @@ static void unmap_interface(domid_t domid, void *interface)
>>   {
>>       if (domid == xenbus_master_domid())
>>           unmap_xenbus(interface);
>> -    else
>> +    else if (domid != stub_domid)
>>           xengnttab_unmap(*xgt_handle, interface, 1);
>>   }
>> @@ -1214,6 +1223,22 @@ void dom0_init(void)
>>       xenevtchn_notify(xce_handle, dom0->port);
>>   }
>> +void stubdom_init(void)
>> +{
>> +#ifdef __MINIOS__
>> +    struct domain *stubdom;
>> +
>> +    if (stub_domid < 0)
>> +        return;
>> +
>> +    stubdom = introduce_domain(NULL, stub_domid, xenbus_evtchn, false);
>> +    if (!stubdom)
>> +        barf_perror("Failed to initialize stubdom");
>> +
>> +    xenevtchn_notify(xce_handle, stubdom->port);
> 
> If I compare to introduce_domain(), it is not entirely clear to me why the 
> notification is done unconditionally here. Can you clarify?

There is no reason to do it conditionally, as we can be sure the event channel
is existing and the ring page is accessible.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 26/29] tools/xenstored: mount 9pfs device in stubdom
  2023-11-13 22:09   ` Julien Grall
@ 2023-11-14  6:40     ` Juergen Gross
  2023-11-14  9:00       ` Julien Grall
  0 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-14  6:40 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk


[-- Attachment #1.1.1: Type: text/plain, Size: 2546 bytes --]

On 13.11.23 23:09, Julien Grall wrote:
> Hi Juergen,
> 
> On 10/11/2023 16:08, Juergen Gross wrote:
>> diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
>> index 162b87b460..4263c1360f 100644
>> --- a/tools/xenstored/domain.c
>> +++ b/tools/xenstored/domain.c
>> @@ -1236,6 +1236,8 @@ void stubdom_init(void)
>>           barf_perror("Failed to initialize stubdom");
>>       xenevtchn_notify(xce_handle, stubdom->port);
>> +
>> +    mount_9pfs();
>>   #endif
>>   }
>> diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
>> index 202d70387a..fddbede869 100644
>> --- a/tools/xenstored/minios.c
>> +++ b/tools/xenstored/minios.c
>> @@ -19,8 +19,16 @@
>>   #include <sys/mman.h>
>>   #include "core.h"
>>   #include <xen/grant_table.h>
>> +#include <mini-os/9pfront.h>
>>   #include <mini-os/events.h>
>>   #include <mini-os/gnttab.h>
>> +#include <mini-os/sched.h>
>> +#include <mini-os/xenbus.h>
>> +#include <mini-os/xmalloc.h>
>> +
>> +#define P9_STATE_PATH    "device/9pfs/0/state"
>> +
>> +static void *p9_device;
>>   void write_pidfile(const char *pidfile)
>>   {
>> @@ -62,3 +70,31 @@ void early_init(void)
>>       if (stub_domid == DOMID_INVALID)
>>           barf("could not get own domid");
>>   }
>> +
>> +static void mount_thread(void *p)
>> +{
>> +    xenbus_event_queue events = NULL;
>> +    char *err;
>> +    char *dummy;
>> +
>> +    free(xenbus_watch_path_token(XBT_NIL, P9_STATE_PATH, "9pfs", &events));
> 
> AFAICT, xenbus_watch_path_token() can fail. I agree this is unlikely, but if it 
> fails, then it would be useful to get some logs. Otherwise...
> 
>> +
>> +    for (;;) {
> 
> ... this loop would be infinite.

Okay, will add logging.

> 
>> +        xenbus_wait_for_watch(&events);
>> +        err = xenbus_read(XBT_NIL, P9_STATE_PATH, &dummy);
> 
> Can you explain why don't care about the value of the node?

I only care about the presence of the "state" node. All real state changes
will be handled in init_9pfront().

> 
>> +        if (!err)
>> +            break;
>> +        free(err);
>> +    }
>> +
>> +    free(dummy);
>> +
>> +    free(xenbus_unwatch_path_token(XBT_NIL, P9_STATE_PATH, "9pfs"));
> 
> xenbus_unwatch_path_token() could technically fails. It would be helpful to 
> print a message.

I can add that, but do we really care? This is a common pattern in Mini-OS.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 27/29] tools/xenstored: add helpers for filename handling
  2023-11-13 22:25   ` Julien Grall
@ 2023-11-14  6:45     ` Juergen Gross
  2023-11-14  9:10       ` Julien Grall
  0 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-14  6:45 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk


[-- Attachment #1.1.1: Type: text/plain, Size: 4026 bytes --]

On 13.11.23 23:25, Julien Grall wrote:
> Hi Juergen,
> 
> On 10/11/2023 16:08, Juergen Gross wrote:
>> Add some helpers for handling filenames which might need different
>> implementations between stubdom and daemon environments:
>>
>> - expansion of relative filenames (those are not really defined today,
>>    just expand them to be relative to /var/lib/xen/xenstore)
>> - expansion of xenstore_daemon_rundir() (used e.g. for saving the state
>>    file in case of live update - needs to be unchanged in the daemon
>>    case, but should result in /var/lib/xen/xenstore for stubdom)
>>
>> Signed-off-by: Juergen Gross <jgross@suse.com>
>> Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
>> ---
>>   tools/xenstored/core.c      | 9 ++++++++-
>>   tools/xenstored/core.h      | 3 +++
>>   tools/xenstored/lu_daemon.c | 4 ++--
>>   tools/xenstored/minios.c    | 5 +++++
>>   tools/xenstored/posix.c     | 5 +++++
>>   5 files changed, 23 insertions(+), 3 deletions(-)
>>
>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>> index 4a9d874f17..77befd24c9 100644
>> --- a/tools/xenstored/core.c
>> +++ b/tools/xenstored/core.c
>> @@ -158,6 +158,13 @@ void trace_destroy(const void *data, const char *type)
>>           trace("obj: DESTROY %s %p\n", type, data);
>>   }
>> +char *absolute_filename(const void *ctx, const char *filename)
> 
> Can the return be const?

I'll have a look.

> 
>> +{
>> +    if (filename[0] != '/')
>> +        return talloc_asprintf(ctx, XENSTORE_LIB_DIR "/%s", filename);
> 
> Looking at the rest of patch, you will be using xenstore_rundir(). I wonder 
> whether it would not be better to switch to xenstore_rundir() so...
> 
>> +    return talloc_strdup(ctx, filename);
>> +}
>> +
>>   /**
>>    * Signal handler for SIGHUP, which requests that the trace log is reopened
>>    * (in the main loop).  A single byte is written to reopen_log_pipe, to awaken
>> @@ -2983,7 +2990,7 @@ int main(int argc, char *argv[])
>>       signal(SIGHUP, trigger_reopen_log);
>>       if (tracefile)
>> -        tracefile = talloc_strdup(NULL, tracefile);
>> +        tracefile = absolute_filename(NULL, tracefile);
>>   #ifndef NO_LIVE_UPDATE
>>       /* Read state in case of live update. */
>> diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
>> index a0d3592961..51e1dddb22 100644
>> --- a/tools/xenstored/core.h
>> +++ b/tools/xenstored/core.h
>> @@ -393,6 +393,9 @@ void early_init(void);
>>   void mount_9pfs(void);
>>   #endif
>> +const char *xenstore_rundir(void);
>> +char *absolute_filename(const void *ctx, const char *filename);
>> +
>>   /* Write out the pidfile */
>>   void write_pidfile(const char *pidfile);
>> diff --git a/tools/xenstored/lu_daemon.c b/tools/xenstored/lu_daemon.c
>> index 71bcabadd3..6351111ab0 100644
>> --- a/tools/xenstored/lu_daemon.c
>> +++ b/tools/xenstored/lu_daemon.c
>> @@ -24,7 +24,7 @@ void lu_get_dump_state(struct lu_dump_state *state)
>>       state->size = 0;
>>       state->filename = talloc_asprintf(NULL, "%s/state_dump",
>> -                      xenstore_daemon_rundir());
>> +                      xenstore_rundir());
> 
> ... call and ...
> 
>>       if (!state->filename)
>>           barf("Allocation failure");
>> @@ -65,7 +65,7 @@ FILE *lu_dump_open(const void *ctx)
>>       int fd;
>>       filename = talloc_asprintf(ctx, "%s/state_dump",
>> -                   xenstore_daemon_rundir());
>> +                   xenstore_rundir());
> 
> ... this one could be replaced with absolute_filename().

No, I don't think this is a good idea.

I don't want the daemon to store trace files specified as relative files
to be stored in /var/run/xen, while I want all files of the stubdom to be
stored under /var/lib/xen.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 28/29] tools/xenstored: support complete log capabilities in stubdom
  2023-11-13 22:40   ` Julien Grall
@ 2023-11-14  6:45     ` Juergen Gross
  2023-11-14  9:05       ` Julien Grall
  0 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-14  6:45 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk


[-- Attachment #1.1.1: Type: text/plain, Size: 1678 bytes --]

On 13.11.23 23:40, Julien Grall wrote:
> Hi Juergen,
> 
> On 10/11/2023 16:08, Juergen Gross wrote:
>> With 9pfs being fully available in Xenstore-stubdom now, there is no
>> reason to not fully support all logging capabilities in stubdom.
>>
>> Open the logfile on stubdom only after the 9pfs file system has been
>> mounted.
>>
>> Signed-off-by: Juergen Gross <jgross@suse.com>
>> Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
>> ---
>>   tools/hotplug/Linux/launch-xenstore.in |  1 +
>>   tools/xenstored/control.c              | 30 +++++++++++++-------------
>>   tools/xenstored/minios.c               |  3 +++
>>   3 files changed, 19 insertions(+), 15 deletions(-)
>>
>> diff --git a/tools/hotplug/Linux/launch-xenstore.in 
>> b/tools/hotplug/Linux/launch-xenstore.in
>> index e854ca1eb8..da4eeca7c5 100644
>> --- a/tools/hotplug/Linux/launch-xenstore.in
>> +++ b/tools/hotplug/Linux/launch-xenstore.in
>> @@ -98,6 +98,7 @@ test -f @CONFIG_DIR@/@CONFIG_LEAF_DIR@/xencommons && . 
>> @CONFIG_DIR@/@CONFIG_LEAF
>>       [ -z "$XENSTORE_DOMAIN_SIZE" ] && XENSTORE_DOMAIN_SIZE=8
>>       XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS --memory $XENSTORE_DOMAIN_SIZE"
>>       [ -z "$XENSTORE_MAX_DOMAIN_SIZE" ] || 
>> XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS --maxmem $XENSTORE_MAX_DOMAIN_SIZE"
>> +    [ -z "$XENSTORED_TRACE" ] || XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS 
>> -T xenstored-trace.log"
> 
> I am probably missing something, but any reason to not use 
> @XEN_LOG_DIR@/xenstored-trace.log as we do for xenstored?

Yes. Stubdom has no access to XEN_LOG_DIR.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 25/29] tools/xenstored: map stubdom interface
  2023-11-14  6:33     ` Juergen Gross
@ 2023-11-14  8:56       ` Julien Grall
  2023-11-14  9:12         ` Juergen Gross
  0 siblings, 1 reply; 86+ messages in thread
From: Julien Grall @ 2023-11-14  8:56 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD

Hi,

On 14/11/2023 06:33, Juergen Gross wrote:
> On 13.11.23 23:04, Julien Grall wrote:
>> Hi Juergen,
>>
>> On 10/11/2023 16:08, Juergen Gross wrote:
>>> When running as stubdom, map the stubdom's Xenstore ring page in order
>>> to support using the 9pfs frontend.
>>>
>>> Signed-off-by: Juergen Gross <jgross@suse.com>
>>> ---
>>>   tools/xenstored/core.c   |  2 ++
>>>   tools/xenstored/domain.c | 27 ++++++++++++++++++++++++++-
>>>   tools/xenstored/domain.h |  1 +
>>>   3 files changed, 29 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>>> index b9ec50b34c..4a9d874f17 100644
>>> --- a/tools/xenstored/core.c
>>> +++ b/tools/xenstored/core.c
>>> @@ -2991,6 +2991,8 @@ int main(int argc, char *argv[])
>>>           lu_read_state();
>>>   #endif
>>> +    stubdom_init();
>>> +
>>>       check_store();
>>>       /* Get ready to listen to the tools. */
>>> diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
>>> index fa17f68618..162b87b460 100644
>>> --- a/tools/xenstored/domain.c
>>> +++ b/tools/xenstored/domain.c
>>> @@ -37,6 +37,10 @@
>>>   #include <xenctrl.h>
>>>   #include <xen/grant_table.h>
>>> +#ifdef __MINIOS__
>>> +#include <mini-os/xenbus.h>
>>> +#endif
>>> +
>>>   static xc_interface **xc_handle;
>>>   xengnttab_handle **xgt_handle;
>>>   static evtchn_port_t virq_port;
>>> @@ -500,6 +504,11 @@ static void *map_interface(domid_t domid)
>>>       if (domid == xenbus_master_domid())
>>>           return xenbus_map();
>>> +#ifdef __MINIOS__
>>> +    if (domid == stub_domid)
>>> +        return xenstore_buf;
>>> +#endif
>>> +
>>>       return xengnttab_map_grant_ref(*xgt_handle, domid,
>>>                          GNTTAB_RESERVED_XENSTORE,
>>>                          PROT_READ|PROT_WRITE);
>>> @@ -509,7 +518,7 @@ static void unmap_interface(domid_t domid, void 
>>> *interface)
>>>   {
>>>       if (domid == xenbus_master_domid())
>>>           unmap_xenbus(interface);
>>> -    else
>>> +    else if (domid != stub_domid)
>>>           xengnttab_unmap(*xgt_handle, interface, 1);
>>>   }
>>> @@ -1214,6 +1223,22 @@ void dom0_init(void)
>>>       xenevtchn_notify(xce_handle, dom0->port);
>>>   }
>>> +void stubdom_init(void)
>>> +{
>>> +#ifdef __MINIOS__
>>> +    struct domain *stubdom;
>>> +
>>> +    if (stub_domid < 0)
>>> +        return;
>>> +
>>> +    stubdom = introduce_domain(NULL, stub_domid, xenbus_evtchn, false);
>>> +    if (!stubdom)
>>> +        barf_perror("Failed to initialize stubdom");
>>> +
>>> +    xenevtchn_notify(xce_handle, stubdom->port);
>>
>> If I compare to introduce_domain(), it is not entirely clear to me why 
>> the notification is done unconditionally here. Can you clarify?
> 
> There is no reason to do it conditionally, as we can be sure the event 
> channel
> is existing and the ring page is accessible.

Hmmm... But there is a second part in the condition:

domain->interface->connection == XENSTORE_RECONNECT

Why isn't it necessary here? What I am looking for particularly is some 
in-code comment (or at least in the commit message) because this is not 
100% clear why we are diverging.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 26/29] tools/xenstored: mount 9pfs device in stubdom
  2023-11-14  6:40     ` Juergen Gross
@ 2023-11-14  9:00       ` Julien Grall
  2023-11-14  9:13         ` Juergen Gross
  0 siblings, 1 reply; 86+ messages in thread
From: Julien Grall @ 2023-11-14  9:00 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk

Hi Juergen,

On 14/11/2023 06:40, Juergen Gross wrote:
> On 13.11.23 23:09, Julien Grall wrote:
>> Hi Juergen,
>>
>> On 10/11/2023 16:08, Juergen Gross wrote:
>>> diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
>>> index 162b87b460..4263c1360f 100644
>>> --- a/tools/xenstored/domain.c
>>> +++ b/tools/xenstored/domain.c
>>> @@ -1236,6 +1236,8 @@ void stubdom_init(void)
>>>           barf_perror("Failed to initialize stubdom");
>>>       xenevtchn_notify(xce_handle, stubdom->port);
>>> +
>>> +    mount_9pfs();
>>>   #endif
>>>   }
>>> diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
>>> index 202d70387a..fddbede869 100644
>>> --- a/tools/xenstored/minios.c
>>> +++ b/tools/xenstored/minios.c
>>> @@ -19,8 +19,16 @@
>>>   #include <sys/mman.h>
>>>   #include "core.h"
>>>   #include <xen/grant_table.h>
>>> +#include <mini-os/9pfront.h>
>>>   #include <mini-os/events.h>
>>>   #include <mini-os/gnttab.h>
>>> +#include <mini-os/sched.h>
>>> +#include <mini-os/xenbus.h>
>>> +#include <mini-os/xmalloc.h>
>>> +
>>> +#define P9_STATE_PATH    "device/9pfs/0/state"
>>> +
>>> +static void *p9_device;
>>>   void write_pidfile(const char *pidfile)
>>>   {
>>> @@ -62,3 +70,31 @@ void early_init(void)
>>>       if (stub_domid == DOMID_INVALID)
>>>           barf("could not get own domid");
>>>   }
>>> +
>>> +static void mount_thread(void *p)
>>> +{
>>> +    xenbus_event_queue events = NULL;
>>> +    char *err;
>>> +    char *dummy;
>>> +
>>> +    free(xenbus_watch_path_token(XBT_NIL, P9_STATE_PATH, "9pfs", 
>>> &events));
>>
>> AFAICT, xenbus_watch_path_token() can fail. I agree this is unlikely, 
>> but if it fails, then it would be useful to get some logs. Otherwise...
>>
>>> +
>>> +    for (;;) {
>>
>> ... this loop would be infinite.
> 
> Okay, will add logging.
> 
>>
>>> +        xenbus_wait_for_watch(&events);
>>> +        err = xenbus_read(XBT_NIL, P9_STATE_PATH, &dummy);
>>
>> Can you explain why don't care about the value of the node?
> 
> I only care about the presence of the "state" node. All real state changes
> will be handled in init_9pfront().

Ok. Can this be documented in the code?

> 
>>
>>> +        if (!err)
>>> +            break;
>>> +        free(err);
>>> +    }
>>> +
>>> +    free(dummy);
>>> +
>>> +    free(xenbus_unwatch_path_token(XBT_NIL, P9_STATE_PATH, "9pfs"));
>>
>> xenbus_unwatch_path_token() could technically fails. It would be 
>> helpful to print a message.
> 
> I can add that, but do we really care? 

Well... Such approach is ok until the day all the watches are exhausted. 
At this point, the developper who hit the bug will likely wish there 
were some debugging.

> This is a common pattern in Mini-OS.

You are not selling Mini-OS :). Really all the callers should check 
error return and print errors. Let's not spread that mistake in Xenstored.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 28/29] tools/xenstored: support complete log capabilities in stubdom
  2023-11-14  6:45     ` Juergen Gross
@ 2023-11-14  9:05       ` Julien Grall
  2023-11-14  9:20         ` Juergen Gross
  0 siblings, 1 reply; 86+ messages in thread
From: Julien Grall @ 2023-11-14  9:05 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk

Hi,

On 14/11/2023 06:45, Juergen Gross wrote:
> On 13.11.23 23:40, Julien Grall wrote:
>> Hi Juergen,
>>
>> On 10/11/2023 16:08, Juergen Gross wrote:
>>> With 9pfs being fully available in Xenstore-stubdom now, there is no
>>> reason to not fully support all logging capabilities in stubdom.
>>>
>>> Open the logfile on stubdom only after the 9pfs file system has been
>>> mounted.
>>>
>>> Signed-off-by: Juergen Gross <jgross@suse.com>
>>> Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
>>> ---
>>>   tools/hotplug/Linux/launch-xenstore.in |  1 +
>>>   tools/xenstored/control.c              | 30 +++++++++++++-------------
>>>   tools/xenstored/minios.c               |  3 +++
>>>   3 files changed, 19 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/tools/hotplug/Linux/launch-xenstore.in 
>>> b/tools/hotplug/Linux/launch-xenstore.in
>>> index e854ca1eb8..da4eeca7c5 100644
>>> --- a/tools/hotplug/Linux/launch-xenstore.in
>>> +++ b/tools/hotplug/Linux/launch-xenstore.in
>>> @@ -98,6 +98,7 @@ test -f @CONFIG_DIR@/@CONFIG_LEAF_DIR@/xencommons 
>>> && . @CONFIG_DIR@/@CONFIG_LEAF
>>>       [ -z "$XENSTORE_DOMAIN_SIZE" ] && XENSTORE_DOMAIN_SIZE=8
>>>       XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS --memory 
>>> $XENSTORE_DOMAIN_SIZE"
>>>       [ -z "$XENSTORE_MAX_DOMAIN_SIZE" ] || 
>>> XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS --maxmem 
>>> $XENSTORE_MAX_DOMAIN_SIZE"
>>> +    [ -z "$XENSTORED_TRACE" ] || 
>>> XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS -T xenstored-trace.log"
>>
>> I am probably missing something, but any reason to not use 
>> @XEN_LOG_DIR@/xenstored-trace.log as we do for xenstored?
> 
> Yes. Stubdom has no access to XEN_LOG_DIR.

Ok. This restriction is not that obvious... The documentation in 
sysconfig.xencommons.in implies that it will be written in XEN_LOG_DIR:

## Type: string
## Default: ""
#
# Additional commandline arguments to start xenstored,
# like "--trace-file @XEN_LOG_DIR@/xenstored-trace.log"
# See "@sbindir@/xenstored --help" for possible options.
# Only evaluated if XENSTORETYPE is "daemon".
XENSTORED_ARGS=

Also, we are saying this is only supported when Xenstored is daemonized. 
So I think there are some documentation update necessary in this patch.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 27/29] tools/xenstored: add helpers for filename handling
  2023-11-14  6:45     ` Juergen Gross
@ 2023-11-14  9:10       ` Julien Grall
  2023-11-14  9:26         ` Juergen Gross
  0 siblings, 1 reply; 86+ messages in thread
From: Julien Grall @ 2023-11-14  9:10 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk

Hi Juergen,

On 14/11/2023 06:45, Juergen Gross wrote:
> On 13.11.23 23:25, Julien Grall wrote:
>> Hi Juergen,
>>
>> On 10/11/2023 16:08, Juergen Gross wrote:
>>> Add some helpers for handling filenames which might need different
>>> implementations between stubdom and daemon environments:
>>>
>>> - expansion of relative filenames (those are not really defined today,
>>>    just expand them to be relative to /var/lib/xen/xenstore)
>>> - expansion of xenstore_daemon_rundir() (used e.g. for saving the state
>>>    file in case of live update - needs to be unchanged in the daemon
>>>    case, but should result in /var/lib/xen/xenstore for stubdom)
>>>
>>> Signed-off-by: Juergen Gross <jgross@suse.com>
>>> Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
>>> ---
>>>   tools/xenstored/core.c      | 9 ++++++++-
>>>   tools/xenstored/core.h      | 3 +++
>>>   tools/xenstored/lu_daemon.c | 4 ++--
>>>   tools/xenstored/minios.c    | 5 +++++
>>>   tools/xenstored/posix.c     | 5 +++++
>>>   5 files changed, 23 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>>> index 4a9d874f17..77befd24c9 100644
>>> --- a/tools/xenstored/core.c
>>> +++ b/tools/xenstored/core.c
>>> @@ -158,6 +158,13 @@ void trace_destroy(const void *data, const char 
>>> *type)
>>>           trace("obj: DESTROY %s %p\n", type, data);
>>>   }
>>> +char *absolute_filename(const void *ctx, const char *filename)
>>
>> Can the return be const?
> 
> I'll have a look.
> 
>>
>>> +{
>>> +    if (filename[0] != '/')
>>> +        return talloc_asprintf(ctx, XENSTORE_LIB_DIR "/%s", filename);
>>
>> Looking at the rest of patch, you will be using xenstore_rundir(). I 
>> wonder whether it would not be better to switch to xenstore_rundir() 
>> so...
>>
>>> +    return talloc_strdup(ctx, filename);
>>> +}
>>> +
>>>   /**
>>>    * Signal handler for SIGHUP, which requests that the trace log is 
>>> reopened
>>>    * (in the main loop).  A single byte is written to 
>>> reopen_log_pipe, to awaken
>>> @@ -2983,7 +2990,7 @@ int main(int argc, char *argv[])
>>>       signal(SIGHUP, trigger_reopen_log);
>>>       if (tracefile)
>>> -        tracefile = talloc_strdup(NULL, tracefile);
>>> +        tracefile = absolute_filename(NULL, tracefile);
>>>   #ifndef NO_LIVE_UPDATE
>>>       /* Read state in case of live update. */
>>> diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
>>> index a0d3592961..51e1dddb22 100644
>>> --- a/tools/xenstored/core.h
>>> +++ b/tools/xenstored/core.h
>>> @@ -393,6 +393,9 @@ void early_init(void);
>>>   void mount_9pfs(void);
>>>   #endif
>>> +const char *xenstore_rundir(void);
>>> +char *absolute_filename(const void *ctx, const char *filename);
>>> +
>>>   /* Write out the pidfile */
>>>   void write_pidfile(const char *pidfile);
>>> diff --git a/tools/xenstored/lu_daemon.c b/tools/xenstored/lu_daemon.c
>>> index 71bcabadd3..6351111ab0 100644
>>> --- a/tools/xenstored/lu_daemon.c
>>> +++ b/tools/xenstored/lu_daemon.c
>>> @@ -24,7 +24,7 @@ void lu_get_dump_state(struct lu_dump_state *state)
>>>       state->size = 0;
>>>       state->filename = talloc_asprintf(NULL, "%s/state_dump",
>>> -                      xenstore_daemon_rundir());
>>> +                      xenstore_rundir());
>>
>> ... call and ...
>>
>>>       if (!state->filename)
>>>           barf("Allocation failure");
>>> @@ -65,7 +65,7 @@ FILE *lu_dump_open(const void *ctx)
>>>       int fd;
>>>       filename = talloc_asprintf(ctx, "%s/state_dump",
>>> -                   xenstore_daemon_rundir());
>>> +                   xenstore_rundir());
>>
>> ... this one could be replaced with absolute_filename().
> 
> No, I don't think this is a good idea.
> 
> I don't want the daemon to store trace files specified as relative files
> to be stored in /var/run/xen, while I want all files of the stubdom to be
> stored under /var/lib/xen.

Why? This is a bit odd to have a different behavior between stubdom and 
daemon. It would be much easier for the user if they knew all the files 
would be at the same place regardless the version used.

Also, regarding the background of my question. You are introducing a 
function call absolute_filename(). From the name, there is nothing 
indicating that this should only be used for trace files. If this is 
only indented for tracefile, then I think this should be renamed to 
something like absolute_tracefile(...).

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 25/29] tools/xenstored: map stubdom interface
  2023-11-14  8:56       ` Julien Grall
@ 2023-11-14  9:12         ` Juergen Gross
  2023-11-14 20:48           ` Julien Grall
  0 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-14  9:12 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: Wei Liu, Anthony PERARD


[-- Attachment #1.1.1: Type: text/plain, Size: 4257 bytes --]

On 14.11.23 09:56, Julien Grall wrote:
> Hi,
> 
> On 14/11/2023 06:33, Juergen Gross wrote:
>> On 13.11.23 23:04, Julien Grall wrote:
>>> Hi Juergen,
>>>
>>> On 10/11/2023 16:08, Juergen Gross wrote:
>>>> When running as stubdom, map the stubdom's Xenstore ring page in order
>>>> to support using the 9pfs frontend.
>>>>
>>>> Signed-off-by: Juergen Gross <jgross@suse.com>
>>>> ---
>>>>   tools/xenstored/core.c   |  2 ++
>>>>   tools/xenstored/domain.c | 27 ++++++++++++++++++++++++++-
>>>>   tools/xenstored/domain.h |  1 +
>>>>   3 files changed, 29 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>>>> index b9ec50b34c..4a9d874f17 100644
>>>> --- a/tools/xenstored/core.c
>>>> +++ b/tools/xenstored/core.c
>>>> @@ -2991,6 +2991,8 @@ int main(int argc, char *argv[])
>>>>           lu_read_state();
>>>>   #endif
>>>> +    stubdom_init();
>>>> +
>>>>       check_store();
>>>>       /* Get ready to listen to the tools. */
>>>> diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
>>>> index fa17f68618..162b87b460 100644
>>>> --- a/tools/xenstored/domain.c
>>>> +++ b/tools/xenstored/domain.c
>>>> @@ -37,6 +37,10 @@
>>>>   #include <xenctrl.h>
>>>>   #include <xen/grant_table.h>
>>>> +#ifdef __MINIOS__
>>>> +#include <mini-os/xenbus.h>
>>>> +#endif
>>>> +
>>>>   static xc_interface **xc_handle;
>>>>   xengnttab_handle **xgt_handle;
>>>>   static evtchn_port_t virq_port;
>>>> @@ -500,6 +504,11 @@ static void *map_interface(domid_t domid)
>>>>       if (domid == xenbus_master_domid())
>>>>           return xenbus_map();
>>>> +#ifdef __MINIOS__
>>>> +    if (domid == stub_domid)
>>>> +        return xenstore_buf;
>>>> +#endif
>>>> +
>>>>       return xengnttab_map_grant_ref(*xgt_handle, domid,
>>>>                          GNTTAB_RESERVED_XENSTORE,
>>>>                          PROT_READ|PROT_WRITE);
>>>> @@ -509,7 +518,7 @@ static void unmap_interface(domid_t domid, void *interface)
>>>>   {
>>>>       if (domid == xenbus_master_domid())
>>>>           unmap_xenbus(interface);
>>>> -    else
>>>> +    else if (domid != stub_domid)
>>>>           xengnttab_unmap(*xgt_handle, interface, 1);
>>>>   }
>>>> @@ -1214,6 +1223,22 @@ void dom0_init(void)
>>>>       xenevtchn_notify(xce_handle, dom0->port);
>>>>   }
>>>> +void stubdom_init(void)
>>>> +{
>>>> +#ifdef __MINIOS__
>>>> +    struct domain *stubdom;
>>>> +
>>>> +    if (stub_domid < 0)
>>>> +        return;
>>>> +
>>>> +    stubdom = introduce_domain(NULL, stub_domid, xenbus_evtchn, false);
>>>> +    if (!stubdom)
>>>> +        barf_perror("Failed to initialize stubdom");
>>>> +
>>>> +    xenevtchn_notify(xce_handle, stubdom->port);
>>>
>>> If I compare to introduce_domain(), it is not entirely clear to me why the 
>>> notification is done unconditionally here. Can you clarify?
>>
>> There is no reason to do it conditionally, as we can be sure the event channel
>> is existing and the ring page is accessible.
> 
> Hmmm... But there is a second part in the condition:
> 
> domain->interface->connection == XENSTORE_RECONNECT
> 
> Why isn't it necessary here? What I am looking for particularly is some in-code 
> comment (or at least in the commit message) because this is not 100% clear why 
> we are diverging.

The test of XENSTORE_RECONNECT is done for domUs started before or together with
dom0 in order to give them a signal that they can start to use Xenstore.

Here we are initializing our own connection, so there is no need to test whether
the other end is waiting for us. We know there is no possible problem sending
the event, so we can just do it. The main instruction guarded by the test of
XENSTORE_RECONNECT is the setting of XENSTORE_CONNECTED, which then needs the
event to be sent to signal that change in the connection state.

In the end we are _not_ diverging. You should just compare the code to the more
comparable dom0_init() code. There the event is being sent unconditionally, too.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 26/29] tools/xenstored: mount 9pfs device in stubdom
  2023-11-14  9:00       ` Julien Grall
@ 2023-11-14  9:13         ` Juergen Gross
  0 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-14  9:13 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk


[-- Attachment #1.1.1: Type: text/plain, Size: 3229 bytes --]

On 14.11.23 10:00, Julien Grall wrote:
> Hi Juergen,
> 
> On 14/11/2023 06:40, Juergen Gross wrote:
>> On 13.11.23 23:09, Julien Grall wrote:
>>> Hi Juergen,
>>>
>>> On 10/11/2023 16:08, Juergen Gross wrote:
>>>> diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
>>>> index 162b87b460..4263c1360f 100644
>>>> --- a/tools/xenstored/domain.c
>>>> +++ b/tools/xenstored/domain.c
>>>> @@ -1236,6 +1236,8 @@ void stubdom_init(void)
>>>>           barf_perror("Failed to initialize stubdom");
>>>>       xenevtchn_notify(xce_handle, stubdom->port);
>>>> +
>>>> +    mount_9pfs();
>>>>   #endif
>>>>   }
>>>> diff --git a/tools/xenstored/minios.c b/tools/xenstored/minios.c
>>>> index 202d70387a..fddbede869 100644
>>>> --- a/tools/xenstored/minios.c
>>>> +++ b/tools/xenstored/minios.c
>>>> @@ -19,8 +19,16 @@
>>>>   #include <sys/mman.h>
>>>>   #include "core.h"
>>>>   #include <xen/grant_table.h>
>>>> +#include <mini-os/9pfront.h>
>>>>   #include <mini-os/events.h>
>>>>   #include <mini-os/gnttab.h>
>>>> +#include <mini-os/sched.h>
>>>> +#include <mini-os/xenbus.h>
>>>> +#include <mini-os/xmalloc.h>
>>>> +
>>>> +#define P9_STATE_PATH    "device/9pfs/0/state"
>>>> +
>>>> +static void *p9_device;
>>>>   void write_pidfile(const char *pidfile)
>>>>   {
>>>> @@ -62,3 +70,31 @@ void early_init(void)
>>>>       if (stub_domid == DOMID_INVALID)
>>>>           barf("could not get own domid");
>>>>   }
>>>> +
>>>> +static void mount_thread(void *p)
>>>> +{
>>>> +    xenbus_event_queue events = NULL;
>>>> +    char *err;
>>>> +    char *dummy;
>>>> +
>>>> +    free(xenbus_watch_path_token(XBT_NIL, P9_STATE_PATH, "9pfs", &events));
>>>
>>> AFAICT, xenbus_watch_path_token() can fail. I agree this is unlikely, but if 
>>> it fails, then it would be useful to get some logs. Otherwise...
>>>
>>>> +
>>>> +    for (;;) {
>>>
>>> ... this loop would be infinite.
>>
>> Okay, will add logging.
>>
>>>
>>>> +        xenbus_wait_for_watch(&events);
>>>> +        err = xenbus_read(XBT_NIL, P9_STATE_PATH, &dummy);
>>>
>>> Can you explain why don't care about the value of the node?
>>
>> I only care about the presence of the "state" node. All real state changes
>> will be handled in init_9pfront().
> 
> Ok. Can this be documented in the code?

Fine with me.

> 
>>
>>>
>>>> +        if (!err)
>>>> +            break;
>>>> +        free(err);
>>>> +    }
>>>> +
>>>> +    free(dummy);
>>>> +
>>>> +    free(xenbus_unwatch_path_token(XBT_NIL, P9_STATE_PATH, "9pfs"));
>>>
>>> xenbus_unwatch_path_token() could technically fails. It would be helpful to 
>>> print a message.
>>
>> I can add that, but do we really care? 
> 
> Well... Such approach is ok until the day all the watches are exhausted. At this 
> point, the developper who hit the bug will likely wish there were some debugging.
> 
>> This is a common pattern in Mini-OS.
> 
> You are not selling Mini-OS :). Really all the callers should check error return 
> and print errors. Let's not spread that mistake in Xenstored.

Okay. :-)


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 28/29] tools/xenstored: support complete log capabilities in stubdom
  2023-11-14  9:05       ` Julien Grall
@ 2023-11-14  9:20         ` Juergen Gross
  2023-11-14 20:57           ` Julien Grall
  0 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-14  9:20 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk


[-- Attachment #1.1.1: Type: text/plain, Size: 2795 bytes --]

On 14.11.23 10:05, Julien Grall wrote:
> Hi,
> 
> On 14/11/2023 06:45, Juergen Gross wrote:
>> On 13.11.23 23:40, Julien Grall wrote:
>>> Hi Juergen,
>>>
>>> On 10/11/2023 16:08, Juergen Gross wrote:
>>>> With 9pfs being fully available in Xenstore-stubdom now, there is no
>>>> reason to not fully support all logging capabilities in stubdom.
>>>>
>>>> Open the logfile on stubdom only after the 9pfs file system has been
>>>> mounted.
>>>>
>>>> Signed-off-by: Juergen Gross <jgross@suse.com>
>>>> Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
>>>> ---
>>>>   tools/hotplug/Linux/launch-xenstore.in |  1 +
>>>>   tools/xenstored/control.c              | 30 +++++++++++++-------------
>>>>   tools/xenstored/minios.c               |  3 +++
>>>>   3 files changed, 19 insertions(+), 15 deletions(-)
>>>>
>>>> diff --git a/tools/hotplug/Linux/launch-xenstore.in 
>>>> b/tools/hotplug/Linux/launch-xenstore.in
>>>> index e854ca1eb8..da4eeca7c5 100644
>>>> --- a/tools/hotplug/Linux/launch-xenstore.in
>>>> +++ b/tools/hotplug/Linux/launch-xenstore.in
>>>> @@ -98,6 +98,7 @@ test -f @CONFIG_DIR@/@CONFIG_LEAF_DIR@/xencommons && . 
>>>> @CONFIG_DIR@/@CONFIG_LEAF
>>>>       [ -z "$XENSTORE_DOMAIN_SIZE" ] && XENSTORE_DOMAIN_SIZE=8
>>>>       XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS --memory 
>>>> $XENSTORE_DOMAIN_SIZE"
>>>>       [ -z "$XENSTORE_MAX_DOMAIN_SIZE" ] || 
>>>> XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS --maxmem $XENSTORE_MAX_DOMAIN_SIZE"
>>>> +    [ -z "$XENSTORED_TRACE" ] || 
>>>> XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS -T xenstored-trace.log"
>>>
>>> I am probably missing something, but any reason to not use 
>>> @XEN_LOG_DIR@/xenstored-trace.log as we do for xenstored?
>>
>> Yes. Stubdom has no access to XEN_LOG_DIR.
> 
> Ok. This restriction is not that obvious... The documentation in 
> sysconfig.xencommons.in implies that it will be written in XEN_LOG_DIR:
> 
> ## Type: string
> ## Default: ""
> #
> # Additional commandline arguments to start xenstored,
> # like "--trace-file @XEN_LOG_DIR@/xenstored-trace.log"
> # See "@sbindir@/xenstored --help" for possible options.
> # Only evaluated if XENSTORETYPE is "daemon".
> XENSTORED_ARGS=
> 
> Also, we are saying this is only supported when Xenstored is daemonized. So I 
> think there are some documentation update necessary in this patch.

This is for the daemon. And the documentation example here is using an
absolute filename, so this is very clear where the trace file will be written.

For stubdom a related parameter "XENSTORE_DOMAIN_ARGS" is available. I can add
a sentence to the explanation of that parameter describing setting of a
possible trace file specification.


Juergen


[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 27/29] tools/xenstored: add helpers for filename handling
  2023-11-14  9:10       ` Julien Grall
@ 2023-11-14  9:26         ` Juergen Gross
  2023-11-14 20:53           ` Julien Grall
  0 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-14  9:26 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk


[-- Attachment #1.1.1: Type: text/plain, Size: 5416 bytes --]

On 14.11.23 10:10, Julien Grall wrote:
> Hi Juergen,
> 
> On 14/11/2023 06:45, Juergen Gross wrote:
>> On 13.11.23 23:25, Julien Grall wrote:
>>> Hi Juergen,
>>>
>>> On 10/11/2023 16:08, Juergen Gross wrote:
>>>> Add some helpers for handling filenames which might need different
>>>> implementations between stubdom and daemon environments:
>>>>
>>>> - expansion of relative filenames (those are not really defined today,
>>>>    just expand them to be relative to /var/lib/xen/xenstore)
>>>> - expansion of xenstore_daemon_rundir() (used e.g. for saving the state
>>>>    file in case of live update - needs to be unchanged in the daemon
>>>>    case, but should result in /var/lib/xen/xenstore for stubdom)
>>>>
>>>> Signed-off-by: Juergen Gross <jgross@suse.com>
>>>> Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
>>>> ---
>>>>   tools/xenstored/core.c      | 9 ++++++++-
>>>>   tools/xenstored/core.h      | 3 +++
>>>>   tools/xenstored/lu_daemon.c | 4 ++--
>>>>   tools/xenstored/minios.c    | 5 +++++
>>>>   tools/xenstored/posix.c     | 5 +++++
>>>>   5 files changed, 23 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>>>> index 4a9d874f17..77befd24c9 100644
>>>> --- a/tools/xenstored/core.c
>>>> +++ b/tools/xenstored/core.c
>>>> @@ -158,6 +158,13 @@ void trace_destroy(const void *data, const char *type)
>>>>           trace("obj: DESTROY %s %p\n", type, data);
>>>>   }
>>>> +char *absolute_filename(const void *ctx, const char *filename)
>>>
>>> Can the return be const?
>>
>> I'll have a look.
>>
>>>
>>>> +{
>>>> +    if (filename[0] != '/')
>>>> +        return talloc_asprintf(ctx, XENSTORE_LIB_DIR "/%s", filename);
>>>
>>> Looking at the rest of patch, you will be using xenstore_rundir(). I wonder 
>>> whether it would not be better to switch to xenstore_rundir() so...
>>>
>>>> +    return talloc_strdup(ctx, filename);
>>>> +}
>>>> +
>>>>   /**
>>>>    * Signal handler for SIGHUP, which requests that the trace log is reopened
>>>>    * (in the main loop).  A single byte is written to reopen_log_pipe, to 
>>>> awaken
>>>> @@ -2983,7 +2990,7 @@ int main(int argc, char *argv[])
>>>>       signal(SIGHUP, trigger_reopen_log);
>>>>       if (tracefile)
>>>> -        tracefile = talloc_strdup(NULL, tracefile);
>>>> +        tracefile = absolute_filename(NULL, tracefile);
>>>>   #ifndef NO_LIVE_UPDATE
>>>>       /* Read state in case of live update. */
>>>> diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
>>>> index a0d3592961..51e1dddb22 100644
>>>> --- a/tools/xenstored/core.h
>>>> +++ b/tools/xenstored/core.h
>>>> @@ -393,6 +393,9 @@ void early_init(void);
>>>>   void mount_9pfs(void);
>>>>   #endif
>>>> +const char *xenstore_rundir(void);
>>>> +char *absolute_filename(const void *ctx, const char *filename);
>>>> +
>>>>   /* Write out the pidfile */
>>>>   void write_pidfile(const char *pidfile);
>>>> diff --git a/tools/xenstored/lu_daemon.c b/tools/xenstored/lu_daemon.c
>>>> index 71bcabadd3..6351111ab0 100644
>>>> --- a/tools/xenstored/lu_daemon.c
>>>> +++ b/tools/xenstored/lu_daemon.c
>>>> @@ -24,7 +24,7 @@ void lu_get_dump_state(struct lu_dump_state *state)
>>>>       state->size = 0;
>>>>       state->filename = talloc_asprintf(NULL, "%s/state_dump",
>>>> -                      xenstore_daemon_rundir());
>>>> +                      xenstore_rundir());
>>>
>>> ... call and ...
>>>
>>>>       if (!state->filename)
>>>>           barf("Allocation failure");
>>>> @@ -65,7 +65,7 @@ FILE *lu_dump_open(const void *ctx)
>>>>       int fd;
>>>>       filename = talloc_asprintf(ctx, "%s/state_dump",
>>>> -                   xenstore_daemon_rundir());
>>>> +                   xenstore_rundir());
>>>
>>> ... this one could be replaced with absolute_filename().
>>
>> No, I don't think this is a good idea.
>>
>> I don't want the daemon to store trace files specified as relative files
>> to be stored in /var/run/xen, while I want all files of the stubdom to be
>> stored under /var/lib/xen.
> 
> Why? This is a bit odd to have a different behavior between stubdom and daemon. 
> It would be much easier for the user if they knew all the files would be at the 
> same place regardless the version used.

The main difference is that stubdom has access to only _one_ directory in dom0.
I /could/ give it access to "/", but do we really want that?

We can't get rid of the /var/run/xen access in xenstored, as it is used for
live update, so the old and the new xenstored need to agree on the location of
the state file. And we can't drop the possibility of specifying absolute paths
for e.g. trace files, as those might be in use by users already.

> Also, regarding the background of my question. You are introducing a function 
> call absolute_filename(). From the name, there is nothing indicating that this 
> should only be used for trace files. If this is only indented for tracefile, 
> then I think this should be renamed to something like absolute_tracefile(...).

After the last patch of this series "xenstore-control memreport <file>" will use
it, too.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 25/29] tools/xenstored: map stubdom interface
  2023-11-14  9:12         ` Juergen Gross
@ 2023-11-14 20:48           ` Julien Grall
  2023-11-15  6:07             ` Juergen Gross
  0 siblings, 1 reply; 86+ messages in thread
From: Julien Grall @ 2023-11-14 20:48 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD

Hi,

On 14/11/2023 09:12, Juergen Gross wrote:
> On 14.11.23 09:56, Julien Grall wrote:
>> Hi,
>>
>> On 14/11/2023 06:33, Juergen Gross wrote:
>>> On 13.11.23 23:04, Julien Grall wrote:
>>>> Hi Juergen,
>>>>
>>>> On 10/11/2023 16:08, Juergen Gross wrote:
>>>>> When running as stubdom, map the stubdom's Xenstore ring page in order
>>>>> to support using the 9pfs frontend.
>>>>>
>>>>> Signed-off-by: Juergen Gross <jgross@suse.com>
>>>>> ---
>>>>>   tools/xenstored/core.c   |  2 ++
>>>>>   tools/xenstored/domain.c | 27 ++++++++++++++++++++++++++-
>>>>>   tools/xenstored/domain.h |  1 +
>>>>>   3 files changed, 29 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>>>>> index b9ec50b34c..4a9d874f17 100644
>>>>> --- a/tools/xenstored/core.c
>>>>> +++ b/tools/xenstored/core.c
>>>>> @@ -2991,6 +2991,8 @@ int main(int argc, char *argv[])
>>>>>           lu_read_state();
>>>>>   #endif
>>>>> +    stubdom_init();
>>>>> +
>>>>>       check_store();
>>>>>       /* Get ready to listen to the tools. */
>>>>> diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
>>>>> index fa17f68618..162b87b460 100644
>>>>> --- a/tools/xenstored/domain.c
>>>>> +++ b/tools/xenstored/domain.c
>>>>> @@ -37,6 +37,10 @@
>>>>>   #include <xenctrl.h>
>>>>>   #include <xen/grant_table.h>
>>>>> +#ifdef __MINIOS__
>>>>> +#include <mini-os/xenbus.h>
>>>>> +#endif
>>>>> +
>>>>>   static xc_interface **xc_handle;
>>>>>   xengnttab_handle **xgt_handle;
>>>>>   static evtchn_port_t virq_port;
>>>>> @@ -500,6 +504,11 @@ static void *map_interface(domid_t domid)
>>>>>       if (domid == xenbus_master_domid())
>>>>>           return xenbus_map();
>>>>> +#ifdef __MINIOS__
>>>>> +    if (domid == stub_domid)
>>>>> +        return xenstore_buf;
>>>>> +#endif
>>>>> +
>>>>>       return xengnttab_map_grant_ref(*xgt_handle, domid,
>>>>>                          GNTTAB_RESERVED_XENSTORE,
>>>>>                          PROT_READ|PROT_WRITE);
>>>>> @@ -509,7 +518,7 @@ static void unmap_interface(domid_t domid, void 
>>>>> *interface)
>>>>>   {
>>>>>       if (domid == xenbus_master_domid())
>>>>>           unmap_xenbus(interface);
>>>>> -    else
>>>>> +    else if (domid != stub_domid)
>>>>>           xengnttab_unmap(*xgt_handle, interface, 1);
>>>>>   }
>>>>> @@ -1214,6 +1223,22 @@ void dom0_init(void)
>>>>>       xenevtchn_notify(xce_handle, dom0->port);
>>>>>   }
>>>>> +void stubdom_init(void)
>>>>> +{
>>>>> +#ifdef __MINIOS__
>>>>> +    struct domain *stubdom;
>>>>> +
>>>>> +    if (stub_domid < 0)
>>>>> +        return;
>>>>> +
>>>>> +    stubdom = introduce_domain(NULL, stub_domid, xenbus_evtchn, 
>>>>> false);
>>>>> +    if (!stubdom)
>>>>> +        barf_perror("Failed to initialize stubdom");
>>>>> +
>>>>> +    xenevtchn_notify(xce_handle, stubdom->port);
>>>>
>>>> If I compare to introduce_domain(), it is not entirely clear to me 
>>>> why the notification is done unconditionally here. Can you clarify?
>>>
>>> There is no reason to do it conditionally, as we can be sure the 
>>> event channel
>>> is existing and the ring page is accessible.
>>
>> Hmmm... But there is a second part in the condition:
>>
>> domain->interface->connection == XENSTORE_RECONNECT
>>
>> Why isn't it necessary here? What I am looking for particularly is 
>> some in-code comment (or at least in the commit message) because this 
>> is not 100% clear why we are diverging.
> 
> The test of XENSTORE_RECONNECT is done for domUs started before or 
> together with
> dom0 in order to give them a signal that they can start to use Xenstore.
> 
> Here we are initializing our own connection, so there is no need to test 
> whether
> the other end is waiting for us. We know there is no possible problem 
> sending
> the event, so we can just do it. The main instruction guarded by the 
> test of
> XENSTORE_RECONNECT is the setting of XENSTORE_CONNECTED, which then 
> needs the
> event to be sent to signal that change in the connection state.
> 
> In the end we are _not_ diverging. You should just compare the code to 
> the more
> comparable dom0_init() code. There the event is being sent 
> unconditionally, too.

Ok. Can this be documented somewhere?

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 27/29] tools/xenstored: add helpers for filename handling
  2023-11-14  9:26         ` Juergen Gross
@ 2023-11-14 20:53           ` Julien Grall
  2023-11-15  6:14             ` Juergen Gross
  0 siblings, 1 reply; 86+ messages in thread
From: Julien Grall @ 2023-11-14 20:53 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk

Hi Juergen,

On 14/11/2023 09:26, Juergen Gross wrote:
> On 14.11.23 10:10, Julien Grall wrote:
>> Hi Juergen,
>>
>> On 14/11/2023 06:45, Juergen Gross wrote:
>>> On 13.11.23 23:25, Julien Grall wrote:
>>>> Hi Juergen,
>>>>
>>>> On 10/11/2023 16:08, Juergen Gross wrote:
>>>>> Add some helpers for handling filenames which might need different
>>>>> implementations between stubdom and daemon environments:
>>>>>
>>>>> - expansion of relative filenames (those are not really defined today,
>>>>>    just expand them to be relative to /var/lib/xen/xenstore)
>>>>> - expansion of xenstore_daemon_rundir() (used e.g. for saving the 
>>>>> state
>>>>>    file in case of live update - needs to be unchanged in the daemon
>>>>>    case, but should result in /var/lib/xen/xenstore for stubdom)
>>>>>
>>>>> Signed-off-by: Juergen Gross <jgross@suse.com>
>>>>> Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
>>>>> ---
>>>>>   tools/xenstored/core.c      | 9 ++++++++-
>>>>>   tools/xenstored/core.h      | 3 +++
>>>>>   tools/xenstored/lu_daemon.c | 4 ++--
>>>>>   tools/xenstored/minios.c    | 5 +++++
>>>>>   tools/xenstored/posix.c     | 5 +++++
>>>>>   5 files changed, 23 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>>>>> index 4a9d874f17..77befd24c9 100644
>>>>> --- a/tools/xenstored/core.c
>>>>> +++ b/tools/xenstored/core.c
>>>>> @@ -158,6 +158,13 @@ void trace_destroy(const void *data, const 
>>>>> char *type)
>>>>>           trace("obj: DESTROY %s %p\n", type, data);
>>>>>   }
>>>>> +char *absolute_filename(const void *ctx, const char *filename)
>>>>
>>>> Can the return be const?
>>>
>>> I'll have a look.
>>>
>>>>
>>>>> +{
>>>>> +    if (filename[0] != '/')
>>>>> +        return talloc_asprintf(ctx, XENSTORE_LIB_DIR "/%s", 
>>>>> filename);
>>>>
>>>> Looking at the rest of patch, you will be using xenstore_rundir(). I 
>>>> wonder whether it would not be better to switch to xenstore_rundir() 
>>>> so...
>>>>
>>>>> +    return talloc_strdup(ctx, filename);
>>>>> +}
>>>>> +
>>>>>   /**
>>>>>    * Signal handler for SIGHUP, which requests that the trace log 
>>>>> is reopened
>>>>>    * (in the main loop).  A single byte is written to 
>>>>> reopen_log_pipe, to awaken
>>>>> @@ -2983,7 +2990,7 @@ int main(int argc, char *argv[])
>>>>>       signal(SIGHUP, trigger_reopen_log);
>>>>>       if (tracefile)
>>>>> -        tracefile = talloc_strdup(NULL, tracefile);
>>>>> +        tracefile = absolute_filename(NULL, tracefile);
>>>>>   #ifndef NO_LIVE_UPDATE
>>>>>       /* Read state in case of live update. */
>>>>> diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
>>>>> index a0d3592961..51e1dddb22 100644
>>>>> --- a/tools/xenstored/core.h
>>>>> +++ b/tools/xenstored/core.h
>>>>> @@ -393,6 +393,9 @@ void early_init(void);
>>>>>   void mount_9pfs(void);
>>>>>   #endif
>>>>> +const char *xenstore_rundir(void);
>>>>> +char *absolute_filename(const void *ctx, const char *filename);
>>>>> +
>>>>>   /* Write out the pidfile */
>>>>>   void write_pidfile(const char *pidfile);
>>>>> diff --git a/tools/xenstored/lu_daemon.c b/tools/xenstored/lu_daemon.c
>>>>> index 71bcabadd3..6351111ab0 100644
>>>>> --- a/tools/xenstored/lu_daemon.c
>>>>> +++ b/tools/xenstored/lu_daemon.c
>>>>> @@ -24,7 +24,7 @@ void lu_get_dump_state(struct lu_dump_state *state)
>>>>>       state->size = 0;
>>>>>       state->filename = talloc_asprintf(NULL, "%s/state_dump",
>>>>> -                      xenstore_daemon_rundir());
>>>>> +                      xenstore_rundir());
>>>>
>>>> ... call and ...
>>>>
>>>>>       if (!state->filename)
>>>>>           barf("Allocation failure");
>>>>> @@ -65,7 +65,7 @@ FILE *lu_dump_open(const void *ctx)
>>>>>       int fd;
>>>>>       filename = talloc_asprintf(ctx, "%s/state_dump",
>>>>> -                   xenstore_daemon_rundir());
>>>>> +                   xenstore_rundir());
>>>>
>>>> ... this one could be replaced with absolute_filename().
>>>
>>> No, I don't think this is a good idea.
>>>
>>> I don't want the daemon to store trace files specified as relative files
>>> to be stored in /var/run/xen, while I want all files of the stubdom 
>>> to be
>>> stored under /var/lib/xen.
>>
>> Why? This is a bit odd to have a different behavior between stubdom 
>> and daemon. It would be much easier for the user if they knew all the 
>> files would be at the same place regardless the version used.
> 
> The main difference is that stubdom has access to only _one_ directory 
> in dom0.

Would you be able to explain why we can only give access to a single 
directory? Is this because of the 9pfs protocol?

> I /could/ give it access to "/", but do we really want that?

I don't think we want to give access to "/".

> 
> We can't get rid of the /var/run/xen access in xenstored, as it is used for
> live update, so the old and the new xenstored need to agree on the 
> location of
> the state file.

Well, Xenstored Live-Update is technically a tech preview feature. So we 
*could* break it and allow the state file to be specified on the command 
line.

Anyway, I am ok if you want them to have the live-update state in a 
separate however...


> And we can't drop the possibility of specifying absolute 
> paths
> for e.g. trace files, as those might be in use by users already.
> 
>> Also, regarding the background of my question. You are introducing a 
>> function call absolute_filename(). From the name, there is nothing 
>> indicating that this should only be used for trace files. If this is 
>> only indented for tracefile, then I think this should be renamed to 
>> something like absolute_tracefile(...).
> 
> After the last patch of this series "xenstore-control memreport <file>" 
> will use
> it, too.

... this doesn't change my point here. The function name doesn't *tell* 
me why it can't be used for live-update files.

If this can't be clarified in the name, then it should be clarified in a 
comment. Maybe one top of the Live-Update code.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 28/29] tools/xenstored: support complete log capabilities in stubdom
  2023-11-14  9:20         ` Juergen Gross
@ 2023-11-14 20:57           ` Julien Grall
  2023-11-15  6:17             ` Juergen Gross
  0 siblings, 1 reply; 86+ messages in thread
From: Julien Grall @ 2023-11-14 20:57 UTC (permalink / raw)
  To: Juergen Gross, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk

Hi Juergen,

On 14/11/2023 09:20, Juergen Gross wrote:
> On 14.11.23 10:05, Julien Grall wrote:
>> Hi,
>>
>> On 14/11/2023 06:45, Juergen Gross wrote:
>>> On 13.11.23 23:40, Julien Grall wrote:
>>>> Hi Juergen,
>>>>
>>>> On 10/11/2023 16:08, Juergen Gross wrote:
>>>>> With 9pfs being fully available in Xenstore-stubdom now, there is no
>>>>> reason to not fully support all logging capabilities in stubdom.
>>>>>
>>>>> Open the logfile on stubdom only after the 9pfs file system has been
>>>>> mounted.
>>>>>
>>>>> Signed-off-by: Juergen Gross <jgross@suse.com>
>>>>> Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
>>>>> ---
>>>>>   tools/hotplug/Linux/launch-xenstore.in |  1 +
>>>>>   tools/xenstored/control.c              | 30 
>>>>> +++++++++++++-------------
>>>>>   tools/xenstored/minios.c               |  3 +++
>>>>>   3 files changed, 19 insertions(+), 15 deletions(-)
>>>>>
>>>>> diff --git a/tools/hotplug/Linux/launch-xenstore.in 
>>>>> b/tools/hotplug/Linux/launch-xenstore.in
>>>>> index e854ca1eb8..da4eeca7c5 100644
>>>>> --- a/tools/hotplug/Linux/launch-xenstore.in
>>>>> +++ b/tools/hotplug/Linux/launch-xenstore.in
>>>>> @@ -98,6 +98,7 @@ test -f @CONFIG_DIR@/@CONFIG_LEAF_DIR@/xencommons 
>>>>> && . @CONFIG_DIR@/@CONFIG_LEAF
>>>>>       [ -z "$XENSTORE_DOMAIN_SIZE" ] && XENSTORE_DOMAIN_SIZE=8
>>>>>       XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS --memory 
>>>>> $XENSTORE_DOMAIN_SIZE"
>>>>>       [ -z "$XENSTORE_MAX_DOMAIN_SIZE" ] || 
>>>>> XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS --maxmem 
>>>>> $XENSTORE_MAX_DOMAIN_SIZE"
>>>>> +    [ -z "$XENSTORED_TRACE" ] || 
>>>>> XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS -T xenstored-trace.log"
>>>>
>>>> I am probably missing something, but any reason to not use 
>>>> @XEN_LOG_DIR@/xenstored-trace.log as we do for xenstored?
>>>
>>> Yes. Stubdom has no access to XEN_LOG_DIR.
>>
>> Ok. This restriction is not that obvious... The documentation in 
>> sysconfig.xencommons.in implies that it will be written in XEN_LOG_DIR:
>>
>> ## Type: string
>> ## Default: ""
>> #
>> # Additional commandline arguments to start xenstored,
>> # like "--trace-file @XEN_LOG_DIR@/xenstored-trace.log"
>> # See "@sbindir@/xenstored --help" for possible options.
>> # Only evaluated if XENSTORETYPE is "daemon".
>> XENSTORED_ARGS=
>>
>> Also, we are saying this is only supported when Xenstored is 
>> daemonized. So I think there are some documentation update necessary 
>> in this patch.
> 
> This is for the daemon. And the documentation example here is using an
> absolute filename, so this is very clear where the trace file will be 
> written.

Ah yes. Sorry I got confused.

> 
> For stubdom a related parameter "XENSTORE_DOMAIN_ARGS" is available. I 
> can add
> a sentence to the explanation of that parameter describing setting of a
> possible trace file specification.

Do you mean in the following comment:

## Type: string
## Default: Not defined, tracing off
#
# Log xenstored messages
# Only evaluated if XENSTORETYPE is "daemon".
#XENSTORED_TRACE=[yes|on|1]

I think here we need to remove the "Only...".

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 25/29] tools/xenstored: map stubdom interface
  2023-11-14 20:48           ` Julien Grall
@ 2023-11-15  6:07             ` Juergen Gross
  0 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-15  6:07 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: Wei Liu, Anthony PERARD


[-- Attachment #1.1.1: Type: text/plain, Size: 4668 bytes --]

On 14.11.23 21:48, Julien Grall wrote:
> Hi,
> 
> On 14/11/2023 09:12, Juergen Gross wrote:
>> On 14.11.23 09:56, Julien Grall wrote:
>>> Hi,
>>>
>>> On 14/11/2023 06:33, Juergen Gross wrote:
>>>> On 13.11.23 23:04, Julien Grall wrote:
>>>>> Hi Juergen,
>>>>>
>>>>> On 10/11/2023 16:08, Juergen Gross wrote:
>>>>>> When running as stubdom, map the stubdom's Xenstore ring page in order
>>>>>> to support using the 9pfs frontend.
>>>>>>
>>>>>> Signed-off-by: Juergen Gross <jgross@suse.com>
>>>>>> ---
>>>>>>   tools/xenstored/core.c   |  2 ++
>>>>>>   tools/xenstored/domain.c | 27 ++++++++++++++++++++++++++-
>>>>>>   tools/xenstored/domain.h |  1 +
>>>>>>   3 files changed, 29 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>>>>>> index b9ec50b34c..4a9d874f17 100644
>>>>>> --- a/tools/xenstored/core.c
>>>>>> +++ b/tools/xenstored/core.c
>>>>>> @@ -2991,6 +2991,8 @@ int main(int argc, char *argv[])
>>>>>>           lu_read_state();
>>>>>>   #endif
>>>>>> +    stubdom_init();
>>>>>> +
>>>>>>       check_store();
>>>>>>       /* Get ready to listen to the tools. */
>>>>>> diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
>>>>>> index fa17f68618..162b87b460 100644
>>>>>> --- a/tools/xenstored/domain.c
>>>>>> +++ b/tools/xenstored/domain.c
>>>>>> @@ -37,6 +37,10 @@
>>>>>>   #include <xenctrl.h>
>>>>>>   #include <xen/grant_table.h>
>>>>>> +#ifdef __MINIOS__
>>>>>> +#include <mini-os/xenbus.h>
>>>>>> +#endif
>>>>>> +
>>>>>>   static xc_interface **xc_handle;
>>>>>>   xengnttab_handle **xgt_handle;
>>>>>>   static evtchn_port_t virq_port;
>>>>>> @@ -500,6 +504,11 @@ static void *map_interface(domid_t domid)
>>>>>>       if (domid == xenbus_master_domid())
>>>>>>           return xenbus_map();
>>>>>> +#ifdef __MINIOS__
>>>>>> +    if (domid == stub_domid)
>>>>>> +        return xenstore_buf;
>>>>>> +#endif
>>>>>> +
>>>>>>       return xengnttab_map_grant_ref(*xgt_handle, domid,
>>>>>>                          GNTTAB_RESERVED_XENSTORE,
>>>>>>                          PROT_READ|PROT_WRITE);
>>>>>> @@ -509,7 +518,7 @@ static void unmap_interface(domid_t domid, void 
>>>>>> *interface)
>>>>>>   {
>>>>>>       if (domid == xenbus_master_domid())
>>>>>>           unmap_xenbus(interface);
>>>>>> -    else
>>>>>> +    else if (domid != stub_domid)
>>>>>>           xengnttab_unmap(*xgt_handle, interface, 1);
>>>>>>   }
>>>>>> @@ -1214,6 +1223,22 @@ void dom0_init(void)
>>>>>>       xenevtchn_notify(xce_handle, dom0->port);
>>>>>>   }
>>>>>> +void stubdom_init(void)
>>>>>> +{
>>>>>> +#ifdef __MINIOS__
>>>>>> +    struct domain *stubdom;
>>>>>> +
>>>>>> +    if (stub_domid < 0)
>>>>>> +        return;
>>>>>> +
>>>>>> +    stubdom = introduce_domain(NULL, stub_domid, xenbus_evtchn, false);
>>>>>> +    if (!stubdom)
>>>>>> +        barf_perror("Failed to initialize stubdom");
>>>>>> +
>>>>>> +    xenevtchn_notify(xce_handle, stubdom->port);
>>>>>
>>>>> If I compare to introduce_domain(), it is not entirely clear to me why the 
>>>>> notification is done unconditionally here. Can you clarify?
>>>>
>>>> There is no reason to do it conditionally, as we can be sure the event channel
>>>> is existing and the ring page is accessible.
>>>
>>> Hmmm... But there is a second part in the condition:
>>>
>>> domain->interface->connection == XENSTORE_RECONNECT
>>>
>>> Why isn't it necessary here? What I am looking for particularly is some 
>>> in-code comment (or at least in the commit message) because this is not 100% 
>>> clear why we are diverging.
>>
>> The test of XENSTORE_RECONNECT is done for domUs started before or together with
>> dom0 in order to give them a signal that they can start to use Xenstore.
>>
>> Here we are initializing our own connection, so there is no need to test whether
>> the other end is waiting for us. We know there is no possible problem sending
>> the event, so we can just do it. The main instruction guarded by the test of
>> XENSTORE_RECONNECT is the setting of XENSTORE_CONNECTED, which then needs the
>> event to be sent to signal that change in the connection state.
>>
>> In the end we are _not_ diverging. You should just compare the code to the more
>> comparable dom0_init() code. There the event is being sent unconditionally, too.
> 
> Ok. Can this be documented somewhere?

I'll add something to the commit message.


Juergen


[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 27/29] tools/xenstored: add helpers for filename handling
  2023-11-14 20:53           ` Julien Grall
@ 2023-11-15  6:14             ` Juergen Gross
  2023-11-28 20:42               ` Jason Andryuk
  0 siblings, 1 reply; 86+ messages in thread
From: Juergen Gross @ 2023-11-15  6:14 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk


[-- Attachment #1.1.1: Type: text/plain, Size: 6647 bytes --]

On 14.11.23 21:53, Julien Grall wrote:
> Hi Juergen,
> 
> On 14/11/2023 09:26, Juergen Gross wrote:
>> On 14.11.23 10:10, Julien Grall wrote:
>>> Hi Juergen,
>>>
>>> On 14/11/2023 06:45, Juergen Gross wrote:
>>>> On 13.11.23 23:25, Julien Grall wrote:
>>>>> Hi Juergen,
>>>>>
>>>>> On 10/11/2023 16:08, Juergen Gross wrote:
>>>>>> Add some helpers for handling filenames which might need different
>>>>>> implementations between stubdom and daemon environments:
>>>>>>
>>>>>> - expansion of relative filenames (those are not really defined today,
>>>>>>    just expand them to be relative to /var/lib/xen/xenstore)
>>>>>> - expansion of xenstore_daemon_rundir() (used e.g. for saving the state
>>>>>>    file in case of live update - needs to be unchanged in the daemon
>>>>>>    case, but should result in /var/lib/xen/xenstore for stubdom)
>>>>>>
>>>>>> Signed-off-by: Juergen Gross <jgross@suse.com>
>>>>>> Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
>>>>>> ---
>>>>>>   tools/xenstored/core.c      | 9 ++++++++-
>>>>>>   tools/xenstored/core.h      | 3 +++
>>>>>>   tools/xenstored/lu_daemon.c | 4 ++--
>>>>>>   tools/xenstored/minios.c    | 5 +++++
>>>>>>   tools/xenstored/posix.c     | 5 +++++
>>>>>>   5 files changed, 23 insertions(+), 3 deletions(-)
>>>>>>
>>>>>> diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
>>>>>> index 4a9d874f17..77befd24c9 100644
>>>>>> --- a/tools/xenstored/core.c
>>>>>> +++ b/tools/xenstored/core.c
>>>>>> @@ -158,6 +158,13 @@ void trace_destroy(const void *data, const char *type)
>>>>>>           trace("obj: DESTROY %s %p\n", type, data);
>>>>>>   }
>>>>>> +char *absolute_filename(const void *ctx, const char *filename)
>>>>>
>>>>> Can the return be const?
>>>>
>>>> I'll have a look.
>>>>
>>>>>
>>>>>> +{
>>>>>> +    if (filename[0] != '/')
>>>>>> +        return talloc_asprintf(ctx, XENSTORE_LIB_DIR "/%s", filename);
>>>>>
>>>>> Looking at the rest of patch, you will be using xenstore_rundir(). I wonder 
>>>>> whether it would not be better to switch to xenstore_rundir() so...
>>>>>
>>>>>> +    return talloc_strdup(ctx, filename);
>>>>>> +}
>>>>>> +
>>>>>>   /**
>>>>>>    * Signal handler for SIGHUP, which requests that the trace log is reopened
>>>>>>    * (in the main loop).  A single byte is written to reopen_log_pipe, to 
>>>>>> awaken
>>>>>> @@ -2983,7 +2990,7 @@ int main(int argc, char *argv[])
>>>>>>       signal(SIGHUP, trigger_reopen_log);
>>>>>>       if (tracefile)
>>>>>> -        tracefile = talloc_strdup(NULL, tracefile);
>>>>>> +        tracefile = absolute_filename(NULL, tracefile);
>>>>>>   #ifndef NO_LIVE_UPDATE
>>>>>>       /* Read state in case of live update. */
>>>>>> diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
>>>>>> index a0d3592961..51e1dddb22 100644
>>>>>> --- a/tools/xenstored/core.h
>>>>>> +++ b/tools/xenstored/core.h
>>>>>> @@ -393,6 +393,9 @@ void early_init(void);
>>>>>>   void mount_9pfs(void);
>>>>>>   #endif
>>>>>> +const char *xenstore_rundir(void);
>>>>>> +char *absolute_filename(const void *ctx, const char *filename);
>>>>>> +
>>>>>>   /* Write out the pidfile */
>>>>>>   void write_pidfile(const char *pidfile);
>>>>>> diff --git a/tools/xenstored/lu_daemon.c b/tools/xenstored/lu_daemon.c
>>>>>> index 71bcabadd3..6351111ab0 100644
>>>>>> --- a/tools/xenstored/lu_daemon.c
>>>>>> +++ b/tools/xenstored/lu_daemon.c
>>>>>> @@ -24,7 +24,7 @@ void lu_get_dump_state(struct lu_dump_state *state)
>>>>>>       state->size = 0;
>>>>>>       state->filename = talloc_asprintf(NULL, "%s/state_dump",
>>>>>> -                      xenstore_daemon_rundir());
>>>>>> +                      xenstore_rundir());
>>>>>
>>>>> ... call and ...
>>>>>
>>>>>>       if (!state->filename)
>>>>>>           barf("Allocation failure");
>>>>>> @@ -65,7 +65,7 @@ FILE *lu_dump_open(const void *ctx)
>>>>>>       int fd;
>>>>>>       filename = talloc_asprintf(ctx, "%s/state_dump",
>>>>>> -                   xenstore_daemon_rundir());
>>>>>> +                   xenstore_rundir());
>>>>>
>>>>> ... this one could be replaced with absolute_filename().
>>>>
>>>> No, I don't think this is a good idea.
>>>>
>>>> I don't want the daemon to store trace files specified as relative files
>>>> to be stored in /var/run/xen, while I want all files of the stubdom to be
>>>> stored under /var/lib/xen.
>>>
>>> Why? This is a bit odd to have a different behavior between stubdom and 
>>> daemon. It would be much easier for the user if they knew all the files would 
>>> be at the same place regardless the version used.
>>
>> The main difference is that stubdom has access to only _one_ directory in dom0.
> 
> Would you be able to explain why we can only give access to a single directory? 
> Is this because of the 9pfs protocol?

Yes. I can mount a specific dom0 directory in the guest.

> 
>> I /could/ give it access to "/", but do we really want that?
> 
> I don't think we want to give access to "/".
> 
>>
>> We can't get rid of the /var/run/xen access in xenstored, as it is used for
>> live update, so the old and the new xenstored need to agree on the location of
>> the state file.
> 
> Well, Xenstored Live-Update is technically a tech preview feature. So we *could* 
> break it and allow the state file to be specified on the command line.
> 
> Anyway, I am ok if you want them to have the live-update state in a separate 
> however...
> 
> 
>> And we can't drop the possibility of specifying absolute paths
>> for e.g. trace files, as those might be in use by users already.
>>
>>> Also, regarding the background of my question. You are introducing a function 
>>> call absolute_filename(). From the name, there is nothing indicating that 
>>> this should only be used for trace files. If this is only indented for 
>>> tracefile, then I think this should be renamed to something like 
>>> absolute_tracefile(...).
>>
>> After the last patch of this series "xenstore-control memreport <file>" will use
>> it, too.
> 
> ... this doesn't change my point here. The function name doesn't *tell* me why 
> it can't be used for live-update files.
> 
> If this can't be clarified in the name, then it should be clarified in a 
> comment. Maybe one top of the Live-Update code.

I think a comment before the absolute_filename() function would be the best
fit.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 28/29] tools/xenstored: support complete log capabilities in stubdom
  2023-11-14 20:57           ` Julien Grall
@ 2023-11-15  6:17             ` Juergen Gross
  0 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-15  6:17 UTC (permalink / raw)
  To: Julien Grall, xen-devel; +Cc: Wei Liu, Anthony PERARD, Jason Andryuk


[-- Attachment #1.1.1: Type: text/plain, Size: 3427 bytes --]

On 14.11.23 21:57, Julien Grall wrote:
> Hi Juergen,
> 
> On 14/11/2023 09:20, Juergen Gross wrote:
>> On 14.11.23 10:05, Julien Grall wrote:
>>> Hi,
>>>
>>> On 14/11/2023 06:45, Juergen Gross wrote:
>>>> On 13.11.23 23:40, Julien Grall wrote:
>>>>> Hi Juergen,
>>>>>
>>>>> On 10/11/2023 16:08, Juergen Gross wrote:
>>>>>> With 9pfs being fully available in Xenstore-stubdom now, there is no
>>>>>> reason to not fully support all logging capabilities in stubdom.
>>>>>>
>>>>>> Open the logfile on stubdom only after the 9pfs file system has been
>>>>>> mounted.
>>>>>>
>>>>>> Signed-off-by: Juergen Gross <jgross@suse.com>
>>>>>> Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
>>>>>> ---
>>>>>>   tools/hotplug/Linux/launch-xenstore.in |  1 +
>>>>>>   tools/xenstored/control.c              | 30 +++++++++++++-------------
>>>>>>   tools/xenstored/minios.c               |  3 +++
>>>>>>   3 files changed, 19 insertions(+), 15 deletions(-)
>>>>>>
>>>>>> diff --git a/tools/hotplug/Linux/launch-xenstore.in 
>>>>>> b/tools/hotplug/Linux/launch-xenstore.in
>>>>>> index e854ca1eb8..da4eeca7c5 100644
>>>>>> --- a/tools/hotplug/Linux/launch-xenstore.in
>>>>>> +++ b/tools/hotplug/Linux/launch-xenstore.in
>>>>>> @@ -98,6 +98,7 @@ test -f @CONFIG_DIR@/@CONFIG_LEAF_DIR@/xencommons && . 
>>>>>> @CONFIG_DIR@/@CONFIG_LEAF
>>>>>>       [ -z "$XENSTORE_DOMAIN_SIZE" ] && XENSTORE_DOMAIN_SIZE=8
>>>>>>       XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS --memory 
>>>>>> $XENSTORE_DOMAIN_SIZE"
>>>>>>       [ -z "$XENSTORE_MAX_DOMAIN_SIZE" ] || 
>>>>>> XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS --maxmem 
>>>>>> $XENSTORE_MAX_DOMAIN_SIZE"
>>>>>> +    [ -z "$XENSTORED_TRACE" ] || 
>>>>>> XENSTORE_DOMAIN_ARGS="$XENSTORE_DOMAIN_ARGS -T xenstored-trace.log"
>>>>>
>>>>> I am probably missing something, but any reason to not use 
>>>>> @XEN_LOG_DIR@/xenstored-trace.log as we do for xenstored?
>>>>
>>>> Yes. Stubdom has no access to XEN_LOG_DIR.
>>>
>>> Ok. This restriction is not that obvious... The documentation in 
>>> sysconfig.xencommons.in implies that it will be written in XEN_LOG_DIR:
>>>
>>> ## Type: string
>>> ## Default: ""
>>> #
>>> # Additional commandline arguments to start xenstored,
>>> # like "--trace-file @XEN_LOG_DIR@/xenstored-trace.log"
>>> # See "@sbindir@/xenstored --help" for possible options.
>>> # Only evaluated if XENSTORETYPE is "daemon".
>>> XENSTORED_ARGS=
>>>
>>> Also, we are saying this is only supported when Xenstored is daemonized. So I 
>>> think there are some documentation update necessary in this patch.
>>
>> This is for the daemon. And the documentation example here is using an
>> absolute filename, so this is very clear where the trace file will be written.
> 
> Ah yes. Sorry I got confused.
> 
>>
>> For stubdom a related parameter "XENSTORE_DOMAIN_ARGS" is available. I can add
>> a sentence to the explanation of that parameter describing setting of a
>> possible trace file specification.
> 
> Do you mean in the following comment:
> 
> ## Type: string
> ## Default: Not defined, tracing off
> #
> # Log xenstored messages
> # Only evaluated if XENSTORETYPE is "daemon".
> #XENSTORED_TRACE=[yes|on|1]
> 
> I think here we need to remove the "Only...".

Oh, I missed that one. It needs to be considered in the stubdom case, too.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 03/29] tools/xenlogd: connect to frontend
  2023-11-10 16:07 ` [PATCH v2 03/29] tools/xenlogd: connect to frontend Juergen Gross
@ 2023-11-20 15:49   ` Jason Andryuk
  2023-11-21  7:08     ` Juergen Gross
  0 siblings, 1 reply; 86+ messages in thread
From: Jason Andryuk @ 2023-11-20 15:49 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel, Wei Liu, Anthony PERARD

On Fri, Nov 10, 2023 at 1:04 PM Juergen Gross <jgross@suse.com> wrote:
>
> Add the code for connecting to frontends to xenlogd.
>
> Signed-off-by: Juergen Gross <jgross@suse.com>

> diff --git a/tools/xen-9pfsd/xen-9pfsd.c b/tools/xen-9pfsd/xen-9pfsd.c
> index c365b35fe5..cc5734402d 100644
> --- a/tools/xen-9pfsd/xen-9pfsd.c
> +++ b/tools/xen-9pfsd/xen-9pfsd.c

>
> +static int check_host_path(device *device)
> +{
> +    struct stat statbuf;
> +    char *path, *p;
> +    int ret = 1;
> +
> +    if ( !device->host_path )
> +        return 1;
> +
> +    if ( device->host_path[0] != '/' )
> +        return 1;
> +

From v1, you stated for alloc_fid_mem(device, fid, path):
> No, "path" is always starting with a "/" if it is not empty.

And then
snprintf(fidp->path, pathlen, "%s%s", device->host_path, path);

While alloc_fid_mem() uses "%s%s"

And p9_create() uses "%s/%s"

p9_walk does:
const char *rel_path = path + strlen(device->host_path)
...
alloc_fid_mem(device, fid, rel_path);

So host_path is expected not to have a tailing '/' to ensure that
rel_path starts with a '/'.  So you want to error out for a trailing
'/' (or overwrite with '\0')?

It seems like alloc_fid_mem() should also check to ensure path is "'/'
if it is not empty".

This is all subtle and security relevant, so it's important to get
this right.  A code comment explaining the expectation of paths for
host_path vs. fids would be good.

Also, maybe using openat() would be a better approach?  Create the
dirfd pointing at the 9pfs export and then use relative paths for the
paths inside.  This would cut down on the manual path manipulations.

> +    path = strdup(device->host_path);
> +    if ( !path )
> +    {
> +        syslog(LOG_CRIT, "memory allocation failure!");
> +        return 1;
> +    }
> +
> +    for ( p = path; p; )
> +    {
> +        p = strchr(p + 1, '/');
> +        if ( p )
> +            *p = 0;
> +        if ( !stat(path, &statbuf) )
> +        {
> +            if ( !(statbuf.st_mode & S_IFDIR) )
> +                break;
> +            if ( !p )
> +            {
> +                ret = 0;
> +                break;
> +            }
> +            *p = '/';
> +            continue;
> +        }
> +        if ( mkdir(path, 0777) )
> +            break;
> +        if ( p )
> +            *p = '/';
> +    }
> +
> +    free(path);
> +    return ret;
> +}
> +

> +
> +static int write_backend_node(device *device, const char *node, const char *val)
> +{
> +    struct path p;
> +    struct xs_permissions perms[2] = {
> +        { .id = 0, .perms = XS_PERM_NONE },

This hard codes dom0.  If xs_permissions supported DOMID_SELF, it
wouldn't need to be looked up.

> +        { .id = device->domid, .perms = XS_PERM_READ }
> +    };
> +
> +    construct_backend_path(device, node, &p);
> +    if ( !xs_write(xs, XBT_NULL, p.path, val, strlen(val)) )
> +    {
> +        syslog(LOG_ERR, "error writing bacḱend node \"%s\" for device %u/%u",
> +               node, device->domid, device->devid);
> +        return 1;
> +    }
> +
> +    if ( !xs_set_permissions(xs, XBT_NULL, p.path, perms, 2) )
> +    {
> +        syslog(LOG_ERR, "error setting permissions for \"%s\"", p.path);
> +        return 1;
> +    }
> +
> +    return 0;
> +}
> +

> +
> +static void connect_device(device *device)
> +{
> +    unsigned int val;
> +    unsigned int ring_idx;
> +    char node[20];
> +    struct ring *ring;
> +    xenevtchn_port_or_error_t evtchn;
> +
> +    val = read_frontend_node_uint(device, "version", 0);
> +    if ( val != 1 )
> +        return connect_err(device, "frontend specifies illegal version");
> +    device->num_rings = read_frontend_node_uint(device, "num-rings", 0);
> +    if ( device->num_rings < 1 || device->num_rings > MAX_RINGS )
> +        return connect_err(device, "frontend specifies illegal ring number");
> +
> +    for ( ring_idx = 0; ring_idx < device->num_rings; ring_idx++ )
> +    {
> +        ring = calloc(1, sizeof(*ring));
> +        if ( !ring )
> +            return connect_err(device, "could not allocate ring memory");
> +        device->ring[ring_idx] = ring;
> +        ring->device = device;
> +        pthread_cond_init(&ring->cond, NULL);
> +        pthread_mutex_init(&ring->mutex, NULL);
> +
> +

extra blank line.

Regards,
Jason


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 04/29] tools/xenlogd: add transport layer
  2023-11-10 16:07 ` [PATCH v2 04/29] tools/xenlogd: add transport layer Juergen Gross
@ 2023-11-20 16:12   ` Jason Andryuk
  0 siblings, 0 replies; 86+ messages in thread
From: Jason Andryuk @ 2023-11-20 16:12 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel, Wei Liu, Anthony PERARD

On Fri, Nov 10, 2023 at 1:27 PM Juergen Gross <jgross@suse.com> wrote:
>
> Add the transport layer of 9pfs. This is basically the infrastructure
> to receive requests from the frontend and to send the related answers
> via the rings.
>
> In order to avoid unaligned accesses e.g. on Arm, add the definition of
> __packed to the common-macros.h header.
>
> Signed-off-by: Juergen Gross <jgross@suse.com>

Reviewed-by: Jason Andryuk <jandryuk@gmail.com>

Thanks,
Jason


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 05/29] tools/xenlogd: add 9pfs response generation support
  2023-11-10 16:07 ` [PATCH v2 05/29] tools/xenlogd: add 9pfs response generation support Juergen Gross
@ 2023-11-20 16:57   ` Jason Andryuk
  2023-12-01 19:30   ` Jason Andryuk
  1 sibling, 0 replies; 86+ messages in thread
From: Jason Andryuk @ 2023-11-20 16:57 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel, Wei Liu, Anthony PERARD

On Fri, Nov 10, 2023 at 1:41 PM Juergen Gross <jgross@suse.com> wrote:
>
> Add support for generation a 9pfs protocol response via a format based
> approach.
>
> Strings are stored in a per device string buffer and they are
> referenced via their offset in this buffer. This allows to avoid
> having to dynamically allocate memory for each single string.
>
> As a first user of the response handling add a generic p9_error()
> function which will be used to return any error to the client.
>
> Add all format parsing variants in order to avoid additional code churn
> later when adding the users of those variants. Prepare a special case
> for the "read" case already (format character 'D'): in order to avoid
> adding another buffer for read data support doing the read I/O directly
> into the response buffer.
>
> Signed-off-by: Juergen Gross <jgross@suse.com>

Reviewed-by: Jason Andryuk <jandryuk@gmail.com>

Thanks,
Jason


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 07/29] tools/xenlogd: add 9pfs attach request support
  2023-11-10 16:07 ` [PATCH v2 07/29] tools/xenlogd: add 9pfs attach " Juergen Gross
@ 2023-11-20 20:35   ` Jason Andryuk
  0 siblings, 0 replies; 86+ messages in thread
From: Jason Andryuk @ 2023-11-20 20:35 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel, Wei Liu, Anthony PERARD

On Fri, Nov 10, 2023 at 11:09 AM Juergen Gross <jgross@suse.com> wrote:
>
> Add the attach request of the 9pfs protocol. This introduces the "fid"
> scheme of the 9pfs protocol.
>
> As this will be needed later, use a dedicated memory allocation
> function in alloc_fid() and prepare a fid reference count.
>
> For filling the qid data take the approach from the qemu 9pfs backend
> implementation.
>
> Signed-off-by: Juergen Gross <jgross@suse.com>

Reviewed-by: Jason Andryuk <jandryuk@gmail.com>


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 03/29] tools/xenlogd: connect to frontend
  2023-11-20 15:49   ` Jason Andryuk
@ 2023-11-21  7:08     ` Juergen Gross
  0 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-11-21  7:08 UTC (permalink / raw)
  To: Jason Andryuk; +Cc: xen-devel, Wei Liu, Anthony PERARD


[-- Attachment #1.1.1: Type: text/plain, Size: 5225 bytes --]

On 20.11.23 16:49, Jason Andryuk wrote:
> On Fri, Nov 10, 2023 at 1:04 PM Juergen Gross <jgross@suse.com> wrote:
>>
>> Add the code for connecting to frontends to xenlogd.
>>
>> Signed-off-by: Juergen Gross <jgross@suse.com>
> 
>> diff --git a/tools/xen-9pfsd/xen-9pfsd.c b/tools/xen-9pfsd/xen-9pfsd.c
>> index c365b35fe5..cc5734402d 100644
>> --- a/tools/xen-9pfsd/xen-9pfsd.c
>> +++ b/tools/xen-9pfsd/xen-9pfsd.c
> 
>>
>> +static int check_host_path(device *device)
>> +{
>> +    struct stat statbuf;
>> +    char *path, *p;
>> +    int ret = 1;
>> +
>> +    if ( !device->host_path )
>> +        return 1;
>> +
>> +    if ( device->host_path[0] != '/' )
>> +        return 1;
>> +
> 
>  From v1, you stated for alloc_fid_mem(device, fid, path):
>> No, "path" is always starting with a "/" if it is not empty.
> 
> And then
> snprintf(fidp->path, pathlen, "%s%s", device->host_path, path);
> 
> While alloc_fid_mem() uses "%s%s"
> 
> And p9_create() uses "%s/%s"

Of course it does, as this is the concatenation of the current path with
the new file name, which is relative to the current path.

> p9_walk does:
> const char *rel_path = path + strlen(device->host_path)
> ...
> alloc_fid_mem(device, fid, rel_path);
> 
> So host_path is expected not to have a tailing '/' to ensure that
> rel_path starts with a '/'.  So you want to error out for a trailing
> '/' (or overwrite with '\0')?

I can add that.

> It seems like alloc_fid_mem() should also check to ensure path is "'/'
> if it is not empty".

I'll add an assert().

> This is all subtle and security relevant, so it's important to get
> this right.  A code comment explaining the expectation of paths for
> host_path vs. fids would be good.

Agreed.

> Also, maybe using openat() would be a better approach?  Create the
> dirfd pointing at the 9pfs export and then use relative paths for the
> paths inside.  This would cut down on the manual path manipulations.

I'll look into that. I'll have to trade special casing accessing the root
directory vs. reducing path operations.

> 
>> +    path = strdup(device->host_path);
>> +    if ( !path )
>> +    {
>> +        syslog(LOG_CRIT, "memory allocation failure!");
>> +        return 1;
>> +    }
>> +
>> +    for ( p = path; p; )
>> +    {
>> +        p = strchr(p + 1, '/');
>> +        if ( p )
>> +            *p = 0;
>> +        if ( !stat(path, &statbuf) )
>> +        {
>> +            if ( !(statbuf.st_mode & S_IFDIR) )
>> +                break;
>> +            if ( !p )
>> +            {
>> +                ret = 0;
>> +                break;
>> +            }
>> +            *p = '/';
>> +            continue;
>> +        }
>> +        if ( mkdir(path, 0777) )
>> +            break;
>> +        if ( p )
>> +            *p = '/';
>> +    }
>> +
>> +    free(path);
>> +    return ret;
>> +}
>> +
> 
>> +
>> +static int write_backend_node(device *device, const char *node, const char *val)
>> +{
>> +    struct path p;
>> +    struct xs_permissions perms[2] = {
>> +        { .id = 0, .perms = XS_PERM_NONE },
> 
> This hard codes dom0.  If xs_permissions supported DOMID_SELF, it
> wouldn't need to be looked up.

DOMID_SELF isn't supported. But you are right, I need to avoid hard coding dom0
here. This can be achieved by reading the permissions after creating the node
and use the result for the first permission entry.

> 
>> +        { .id = device->domid, .perms = XS_PERM_READ }
>> +    };
>> +
>> +    construct_backend_path(device, node, &p);
>> +    if ( !xs_write(xs, XBT_NULL, p.path, val, strlen(val)) )
>> +    {
>> +        syslog(LOG_ERR, "error writing bacḱend node \"%s\" for device %u/%u",
>> +               node, device->domid, device->devid);
>> +        return 1;
>> +    }
>> +
>> +    if ( !xs_set_permissions(xs, XBT_NULL, p.path, perms, 2) )
>> +    {
>> +        syslog(LOG_ERR, "error setting permissions for \"%s\"", p.path);
>> +        return 1;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
> 
>> +
>> +static void connect_device(device *device)
>> +{
>> +    unsigned int val;
>> +    unsigned int ring_idx;
>> +    char node[20];
>> +    struct ring *ring;
>> +    xenevtchn_port_or_error_t evtchn;
>> +
>> +    val = read_frontend_node_uint(device, "version", 0);
>> +    if ( val != 1 )
>> +        return connect_err(device, "frontend specifies illegal version");
>> +    device->num_rings = read_frontend_node_uint(device, "num-rings", 0);
>> +    if ( device->num_rings < 1 || device->num_rings > MAX_RINGS )
>> +        return connect_err(device, "frontend specifies illegal ring number");
>> +
>> +    for ( ring_idx = 0; ring_idx < device->num_rings; ring_idx++ )
>> +    {
>> +        ring = calloc(1, sizeof(*ring));
>> +        if ( !ring )
>> +            return connect_err(device, "could not allocate ring memory");
>> +        device->ring[ring_idx] = ring;
>> +        ring->device = device;
>> +        pthread_cond_init(&ring->cond, NULL);
>> +        pthread_mutex_init(&ring->mutex, NULL);
>> +
>> +
> 
> extra blank line.

Will remove it.


Thanks,

Juergen


[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3743 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 08/29] tools/xenlogd: add 9pfs walk request support
  2023-11-10 16:07 ` [PATCH v2 08/29] tools/xenlogd: add 9pfs walk " Juergen Gross
@ 2023-11-28 15:04   ` Jason Andryuk
  0 siblings, 0 replies; 86+ messages in thread
From: Jason Andryuk @ 2023-11-28 15:04 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel, Wei Liu, Anthony PERARD

On Fri, Nov 10, 2023 at 1:16 PM Juergen Gross <jgross@suse.com> wrote:
>
> Add the walk request of the 9pfs protocol.
>
> Signed-off-by: Juergen Gross <jgross@suse.com>

Reviewed-by: Jason Andryuk <jandryuk@gmail.com>

9P2000.u has support for symlinks which you're explicitly not
supporting.  A symlink would only be present if someone on the backend
side created one.  So there could be some corner case that is
disallowed, but it is probably better to just disallow them.

Regards,
Jason


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 09/29] tools/xenlogd: add 9pfs open request support
  2023-11-10 16:07 ` [PATCH v2 09/29] tools/xenlogd: add 9pfs open " Juergen Gross
@ 2023-11-28 15:49   ` Jason Andryuk
  0 siblings, 0 replies; 86+ messages in thread
From: Jason Andryuk @ 2023-11-28 15:49 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel, Wei Liu, Anthony PERARD

On Fri, Nov 10, 2023 at 12:16 PM Juergen Gross <jgross@suse.com> wrote:
>
> Add the open request of the 9pfs protocol.
>
> Signed-off-by: Juergen Gross <jgross@suse.com>

Reviewed-by: Jason Andryuk <jandryuk@gmail.com>


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 10/29] tools/xenlogd: add 9pfs clunk request support
  2023-11-10 16:07 ` [PATCH v2 10/29] tools/xenlogd: add 9pfs clunk " Juergen Gross
@ 2023-11-28 20:15   ` Jason Andryuk
  0 siblings, 0 replies; 86+ messages in thread
From: Jason Andryuk @ 2023-11-28 20:15 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel, Wei Liu, Anthony PERARD

On Fri, Nov 10, 2023 at 11:22 AM Juergen Gross <jgross@suse.com> wrote:
>
> Add the clunk request of the 9pfs protocol.
>
> Signed-off-by: Juergen Gross <jgross@suse.com>

Reviewed-by: Jason Andryuk <jandryuk@gmail.com>


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 11/29] tools/xenlogd: add 9pfs create request support
  2023-11-10 16:07 ` [PATCH v2 11/29] tools/xenlogd: add 9pfs create " Juergen Gross
@ 2023-11-28 20:22   ` Jason Andryuk
  0 siblings, 0 replies; 86+ messages in thread
From: Jason Andryuk @ 2023-11-28 20:22 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel, Wei Liu, Anthony PERARD

On Fri, Nov 10, 2023 at 12:14 PM Juergen Gross <jgross@suse.com> wrote:
>
> Add the create request of the 9pfs protocol.
>
> Signed-off-by: Juergen Gross <jgross@suse.com>

Reviewed-by: Jason Andryuk <jandryuk@gmail.com>


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 16/29] tools/xl: support new 9pfs backend xen-9pfsd
  2023-11-10 16:07 ` [PATCH v2 16/29] tools/xl: support new 9pfs backend xen-9pfsd Juergen Gross
@ 2023-11-28 20:25   ` Jason Andryuk
  0 siblings, 0 replies; 86+ messages in thread
From: Jason Andryuk @ 2023-11-28 20:25 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel, Wei Liu, Anthony PERARD

On Fri, Nov 10, 2023 at 11:19 AM Juergen Gross <jgross@suse.com> wrote:
>
> Add support for the new 9pfs backend "xen-9pfsd". For this backend type
> the tag defaults to "Xen" and the host side path to
> "/var/log/xen/guests/<dom-name>".
>
> Signed-off-by: Juergen Gross <jgross@suse.com>

Reviewed-by: Jason Andryuk <jandryuk@gmail.com>


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 18/29] tools/xenstored: rename xenbus_evtchn()
  2023-11-10 16:07 ` [PATCH v2 18/29] tools/xenstored: rename xenbus_evtchn() Juergen Gross
@ 2023-11-28 20:26   ` Jason Andryuk
  0 siblings, 0 replies; 86+ messages in thread
From: Jason Andryuk @ 2023-11-28 20:26 UTC (permalink / raw)
  To: Juergen Gross
  Cc: xen-devel, Wei Liu, Julien Grall, Anthony PERARD, Julien Grall

On Fri, Nov 10, 2023 at 11:23 AM Juergen Gross <jgross@suse.com> wrote:
>
> Rename the xenbus_evtchn() function to get_xenbus_evtchn() in order to
> avoid two externally visible symbols with the same name when Xenstore-
> stubdom is being built with a Mini-OS with CONFIG_XENBUS set.
>
> Signed-off-by: Juergen Gross <jgross@suse.com>
> Reviewed-by: Julien Grall <jgrall@amazon.com>

Reviewed-by: Jason Andryuk <jandryuk@gmail.com>


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 27/29] tools/xenstored: add helpers for filename handling
  2023-11-15  6:14             ` Juergen Gross
@ 2023-11-28 20:42               ` Jason Andryuk
  2023-12-01 10:14                 ` Juergen Gross
  0 siblings, 1 reply; 86+ messages in thread
From: Jason Andryuk @ 2023-11-28 20:42 UTC (permalink / raw)
  To: Juergen Gross; +Cc: Julien Grall, xen-devel, Wei Liu, Anthony PERARD

On Wed, Nov 15, 2023 at 1:14 AM Juergen Gross <jgross@suse.com> wrote:
>
> On 14.11.23 21:53, Julien Grall wrote:
> > Hi Juergen,
> >
> > On 14/11/2023 09:26, Juergen Gross wrote:
> >> On 14.11.23 10:10, Julien Grall wrote:
> >>> Hi Juergen,
> >>>
> >>> On 14/11/2023 06:45, Juergen Gross wrote:
> >>>> On 13.11.23 23:25, Julien Grall wrote:
> >>>>> Hi Juergen,
> >>>>>
> >>>>> On 10/11/2023 16:08, Juergen Gross wrote:
> >>>>>> diff --git a/tools/xenstored/lu_daemon.c b/tools/xenstored/lu_daemon.c
> >>>>>> index 71bcabadd3..6351111ab0 100644
> >>>>>> --- a/tools/xenstored/lu_daemon.c
> >>>>>> +++ b/tools/xenstored/lu_daemon.c
> >>>>>> @@ -24,7 +24,7 @@ void lu_get_dump_state(struct lu_dump_state *state)
> >>>>>>       state->size = 0;
> >>>>>>       state->filename = talloc_asprintf(NULL, "%s/state_dump",
> >>>>>> -                      xenstore_daemon_rundir());
> >>>>>> +                      xenstore_rundir());
> >>>>>
> >>>>> ... call and ...
> >>>>>
> >>>>>>       if (!state->filename)
> >>>>>>           barf("Allocation failure");
> >>>>>> @@ -65,7 +65,7 @@ FILE *lu_dump_open(const void *ctx)
> >>>>>>       int fd;
> >>>>>>       filename = talloc_asprintf(ctx, "%s/state_dump",
> >>>>>> -                   xenstore_daemon_rundir());
> >>>>>> +                   xenstore_rundir());
> >>>>>
> >>>>> ... this one could be replaced with absolute_filename().
> >>>>
> >>>> No, I don't think this is a good idea.
> >>>>
> >>>> I don't want the daemon to store trace files specified as relative files
> >>>> to be stored in /var/run/xen, while I want all files of the stubdom to be
> >>>> stored under /var/lib/xen.
> >>>
> >>> Why? This is a bit odd to have a different behavior between stubdom and
> >>> daemon. It would be much easier for the user if they knew all the files would
> >>> be at the same place regardless the version used.
> >>
> >> The main difference is that stubdom has access to only _one_ directory in dom0.
> >
> > Would you be able to explain why we can only give access to a single directory?
> > Is this because of the 9pfs protocol?
>
> Yes. I can mount a specific dom0 directory in the guest.

I'm fine with a single directory being used for stubdom.  Two
directories could be exported, and mini-os would need to use the "tag"
to differentiate the two.  That may not be worth the added code.  QEMU
can provide multiple 9pfs exports and Linux can mount them by tag
name.

Regards,
Jason


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 27/29] tools/xenstored: add helpers for filename handling
  2023-11-28 20:42               ` Jason Andryuk
@ 2023-12-01 10:14                 ` Juergen Gross
  0 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-12-01 10:14 UTC (permalink / raw)
  To: Jason Andryuk; +Cc: Julien Grall, xen-devel, Wei Liu, Anthony PERARD


[-- Attachment #1.1.1: Type: text/plain, Size: 3045 bytes --]

On 28.11.23 21:42, Jason Andryuk wrote:
> On Wed, Nov 15, 2023 at 1:14 AM Juergen Gross <jgross@suse.com> wrote:
>>
>> On 14.11.23 21:53, Julien Grall wrote:
>>> Hi Juergen,
>>>
>>> On 14/11/2023 09:26, Juergen Gross wrote:
>>>> On 14.11.23 10:10, Julien Grall wrote:
>>>>> Hi Juergen,
>>>>>
>>>>> On 14/11/2023 06:45, Juergen Gross wrote:
>>>>>> On 13.11.23 23:25, Julien Grall wrote:
>>>>>>> Hi Juergen,
>>>>>>>
>>>>>>> On 10/11/2023 16:08, Juergen Gross wrote:
>>>>>>>> diff --git a/tools/xenstored/lu_daemon.c b/tools/xenstored/lu_daemon.c
>>>>>>>> index 71bcabadd3..6351111ab0 100644
>>>>>>>> --- a/tools/xenstored/lu_daemon.c
>>>>>>>> +++ b/tools/xenstored/lu_daemon.c
>>>>>>>> @@ -24,7 +24,7 @@ void lu_get_dump_state(struct lu_dump_state *state)
>>>>>>>>        state->size = 0;
>>>>>>>>        state->filename = talloc_asprintf(NULL, "%s/state_dump",
>>>>>>>> -                      xenstore_daemon_rundir());
>>>>>>>> +                      xenstore_rundir());
>>>>>>>
>>>>>>> ... call and ...
>>>>>>>
>>>>>>>>        if (!state->filename)
>>>>>>>>            barf("Allocation failure");
>>>>>>>> @@ -65,7 +65,7 @@ FILE *lu_dump_open(const void *ctx)
>>>>>>>>        int fd;
>>>>>>>>        filename = talloc_asprintf(ctx, "%s/state_dump",
>>>>>>>> -                   xenstore_daemon_rundir());
>>>>>>>> +                   xenstore_rundir());
>>>>>>>
>>>>>>> ... this one could be replaced with absolute_filename().
>>>>>>
>>>>>> No, I don't think this is a good idea.
>>>>>>
>>>>>> I don't want the daemon to store trace files specified as relative files
>>>>>> to be stored in /var/run/xen, while I want all files of the stubdom to be
>>>>>> stored under /var/lib/xen.
>>>>>
>>>>> Why? This is a bit odd to have a different behavior between stubdom and
>>>>> daemon. It would be much easier for the user if they knew all the files would
>>>>> be at the same place regardless the version used.
>>>>
>>>> The main difference is that stubdom has access to only _one_ directory in dom0.
>>>
>>> Would you be able to explain why we can only give access to a single directory?
>>> Is this because of the 9pfs protocol?
>>
>> Yes. I can mount a specific dom0 directory in the guest.
> 
> I'm fine with a single directory being used for stubdom.  Two
> directories could be exported, and mini-os would need to use the "tag"
> to differentiate the two.  That may not be worth the added code.  QEMU
> can provide multiple 9pfs exports and Linux can mount them by tag
> name.

The main thing is that the daemon is meant to solve exactly one problem:
having a way to enable infrastructure domains (Xenstore-stubdom, driver
domains, device-model stubdoms) to access some few files in dom0, e.g. for
logging or config purposes.

The daemon should be as simple as possible and, of course, have ways to
control resource usage (file system space) used by the domUs configured to
use it.

It should _not_ be a a replacement of the full-blown backend in e.g. qemu.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3743 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 05/29] tools/xenlogd: add 9pfs response generation support
  2023-11-10 16:07 ` [PATCH v2 05/29] tools/xenlogd: add 9pfs response generation support Juergen Gross
  2023-11-20 16:57   ` Jason Andryuk
@ 2023-12-01 19:30   ` Jason Andryuk
  2023-12-05  6:32     ` Juergen Gross
  1 sibling, 1 reply; 86+ messages in thread
From: Jason Andryuk @ 2023-12-01 19:30 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel, Wei Liu, Anthony PERARD

On Fri, Nov 10, 2023 at 1:41 PM Juergen Gross <jgross@suse.com> wrote:
> +static void fill_buffer(struct ring *ring, uint8_t cmd, uint16_t tag,
> +                        const char *fmt, ...)
> +{
> +    struct p9_header *hdr = ring->buffer;
> +    void *data = hdr + 1;
> +    const char *f;
> +    const void *par;
> +    const char *str_val;
> +    const struct p9_qid *qid;
> +    unsigned int len;
> +    va_list ap;
> +    unsigned int array_sz = 0;
> +    unsigned int elem_sz = 0;
> +
> +    hdr->cmd = cmd;
> +    hdr->tag = tag;
> +
> +    va_start(ap, fmt);
> +
> +    for ( f = fmt; *f; f++ )
> +    {
> +        if ( !array_sz )
> +            par = va_arg(ap, const void *);
> +        else
> +        {
> +            par += elem_sz;
> +            array_sz--;
> +        }
> +
> +        switch ( *f )
> +        {
> +        case 'a':
> +            f++;
> +            if ( !*f || array_sz )
> +                fmt_err(fmt);
> +            array_sz = *(const unsigned int *)par;
> +            if ( array_sz > 0xffff )
> +            {
> +                syslog(LOG_CRIT, "array size %u in fill_buffer()", array_sz);
> +                exit(1);
> +            }
> +            *(__packed uint16_t *)data = array_sz;

Compiling on Fedora 39, gcc 13.2.1:

io.c: In function ‘fill_buffer’:
io.c:233:13: error: ‘packed’ attribute ignored for type ‘uint16_t *’
{aka ‘short unsigned int *’} [-Werror=attributes]
  233 |             *(__packed uint16_t *)data = array_sz;
      |             ^

For all these uses of __packed.

Regards,
Jason


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 05/29] tools/xenlogd: add 9pfs response generation support
  2023-12-01 19:30   ` Jason Andryuk
@ 2023-12-05  6:32     ` Juergen Gross
  0 siblings, 0 replies; 86+ messages in thread
From: Juergen Gross @ 2023-12-05  6:32 UTC (permalink / raw)
  To: Jason Andryuk; +Cc: xen-devel, Wei Liu, Anthony PERARD


[-- Attachment #1.1.1: Type: text/plain, Size: 1849 bytes --]

On 01.12.23 20:30, Jason Andryuk wrote:
> On Fri, Nov 10, 2023 at 1:41 PM Juergen Gross <jgross@suse.com> wrote:
>> +static void fill_buffer(struct ring *ring, uint8_t cmd, uint16_t tag,
>> +                        const char *fmt, ...)
>> +{
>> +    struct p9_header *hdr = ring->buffer;
>> +    void *data = hdr + 1;
>> +    const char *f;
>> +    const void *par;
>> +    const char *str_val;
>> +    const struct p9_qid *qid;
>> +    unsigned int len;
>> +    va_list ap;
>> +    unsigned int array_sz = 0;
>> +    unsigned int elem_sz = 0;
>> +
>> +    hdr->cmd = cmd;
>> +    hdr->tag = tag;
>> +
>> +    va_start(ap, fmt);
>> +
>> +    for ( f = fmt; *f; f++ )
>> +    {
>> +        if ( !array_sz )
>> +            par = va_arg(ap, const void *);
>> +        else
>> +        {
>> +            par += elem_sz;
>> +            array_sz--;
>> +        }
>> +
>> +        switch ( *f )
>> +        {
>> +        case 'a':
>> +            f++;
>> +            if ( !*f || array_sz )
>> +                fmt_err(fmt);
>> +            array_sz = *(const unsigned int *)par;
>> +            if ( array_sz > 0xffff )
>> +            {
>> +                syslog(LOG_CRIT, "array size %u in fill_buffer()", array_sz);
>> +                exit(1);
>> +            }
>> +            *(__packed uint16_t *)data = array_sz;
> 
> Compiling on Fedora 39, gcc 13.2.1:
> 
> io.c: In function ‘fill_buffer’:
> io.c:233:13: error: ‘packed’ attribute ignored for type ‘uint16_t *’
> {aka ‘short unsigned int *’} [-Werror=attributes]
>    233 |             *(__packed uint16_t *)data = array_sz;
>        |             ^
> 
> For all these uses of __packed.

Meh.

Okay, will add get_unaligned() and put_unaligned() for that purpose dealing
with the issue in a clean way.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3743 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 15/29] tools/libs/light: add backend type for 9pfs PV devices
  2023-11-10 16:07 ` [PATCH v2 15/29] tools/libs/light: add backend type for 9pfs PV devices Juergen Gross
@ 2023-12-06 13:17   ` Jason Andryuk
  2023-12-06 17:44     ` Nick Rosbrook
  0 siblings, 1 reply; 86+ messages in thread
From: Jason Andryuk @ 2023-12-06 13:17 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel, Wei Liu, Anthony PERARD

On Fri, Nov 10, 2023 at 11:09 AM Juergen Gross <jgross@suse.com> wrote:

> diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
> index 7d8bd5d216..82565c4c10 100644
> --- a/tools/libs/light/libxl_types.idl
> +++ b/tools/libs/light/libxl_types.idl
> @@ -150,6 +150,12 @@ libxl_nic_type = Enumeration("nic_type", [
>      (2, "VIF"),
>      ])
>
> +libxl_p9_type = Enumeration("p9_type", [
> +    (0, "unknown"),
> +    (1, "qemu"),
> +    (2, "xen_9pfsd"),
> +    ])
> +

FYI, these IDL changes will require golang binding regeneration.
(Maybe we shouldn't have generated code checked in...)

Regards,
Jason


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 15/29] tools/libs/light: add backend type for 9pfs PV devices
  2023-12-06 13:17   ` Jason Andryuk
@ 2023-12-06 17:44     ` Nick Rosbrook
  2023-12-06 18:53       ` Jason Andryuk
  0 siblings, 1 reply; 86+ messages in thread
From: Nick Rosbrook @ 2023-12-06 17:44 UTC (permalink / raw)
  To: Jason Andryuk; +Cc: Juergen Gross, xen-devel, Wei Liu, Anthony PERARD

On Wed, Dec 6, 2023 at 9:36 AM Jason Andryuk <jandryuk@gmail.com> wrote:
> FYI, these IDL changes will require golang binding regeneration.
> (Maybe we shouldn't have generated code checked in...)

The generated code needs to be checked in for it to work as a go module.

-Nick


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 15/29] tools/libs/light: add backend type for 9pfs PV devices
  2023-12-06 17:44     ` Nick Rosbrook
@ 2023-12-06 18:53       ` Jason Andryuk
  2024-01-02 20:16         ` Nick Rosbrook
  0 siblings, 1 reply; 86+ messages in thread
From: Jason Andryuk @ 2023-12-06 18:53 UTC (permalink / raw)
  To: Nick Rosbrook; +Cc: Juergen Gross, xen-devel, Wei Liu, Anthony PERARD

On Wed, Dec 6, 2023 at 12:44 PM Nick Rosbrook <rosbrookn@gmail.com> wrote:
>
> On Wed, Dec 6, 2023 at 9:36 AM Jason Andryuk <jandryuk@gmail.com> wrote:
> > FYI, these IDL changes will require golang binding regeneration.
> > (Maybe we shouldn't have generated code checked in...)
>
> The generated code needs to be checked in for it to work as a go module.

I don't follow. The build system generates the *.gen.go binding files
if they are missing.  They can then be used, installed or packaged.
Why do they need to be checked into the git repo?  Checked in, they
have a tendency to go stale.

Regards,
Jason


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 15/29] tools/libs/light: add backend type for 9pfs PV devices
  2023-12-06 18:53       ` Jason Andryuk
@ 2024-01-02 20:16         ` Nick Rosbrook
  0 siblings, 0 replies; 86+ messages in thread
From: Nick Rosbrook @ 2024-01-02 20:16 UTC (permalink / raw)
  To: Jason Andryuk; +Cc: Juergen Gross, xen-devel, Wei Liu, Anthony PERARD

On Wed, Dec 6, 2023 at 1:53 PM Jason Andryuk <jandryuk@gmail.com> wrote:
>
> On Wed, Dec 6, 2023 at 12:44 PM Nick Rosbrook <rosbrookn@gmail.com> wrote:
> >
> > On Wed, Dec 6, 2023 at 9:36 AM Jason Andryuk <jandryuk@gmail.com> wrote:
> > > FYI, these IDL changes will require golang binding regeneration.
> > > (Maybe we shouldn't have generated code checked in...)
> >
> > The generated code needs to be checked in for it to work as a go module.
>
> I don't follow. The build system generates the *.gen.go binding files
> if they are missing.  They can then be used, installed or packaged.
> Why do they need to be checked into the git repo?  Checked in, they
> have a tendency to go stale.
>

That's not how go modules are typically consumed. E.g., the Debian
packages with go source code are only there to satisfy Build-Depends
of other packages. One can use locally installed go modules as
overrides at build-time, but normally go modules are fetched via git
(internally by the go tooling) according to what is specified in a
project's go.mod file. See https://go.dev/blog/using-go-modules for
more.

-Nick


^ permalink raw reply	[flat|nested] 86+ messages in thread

end of thread, other threads:[~2024-01-02 20:17 UTC | newest]

Thread overview: 86+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-10 16:07 [PATCH v2 00/29] tools: enable xenstore-stubdom to use 9pfs Juergen Gross
2023-11-10 16:07 ` [PATCH v2 01/29] xen/public: add some more 9pfs xenstore paths Juergen Gross
2023-11-13 17:14   ` Jason Andryuk
2023-11-10 16:07 ` [PATCH v2 02/29] tools: add a new xen logging daemon Juergen Gross
2023-11-10 16:13   ` Andrew Cooper
2023-11-10 16:14     ` Juergen Gross
2023-11-13 17:36   ` Jason Andryuk
2023-11-14  6:21     ` Juergen Gross
2023-11-10 16:07 ` [PATCH v2 03/29] tools/xenlogd: connect to frontend Juergen Gross
2023-11-20 15:49   ` Jason Andryuk
2023-11-21  7:08     ` Juergen Gross
2023-11-10 16:07 ` [PATCH v2 04/29] tools/xenlogd: add transport layer Juergen Gross
2023-11-20 16:12   ` Jason Andryuk
2023-11-10 16:07 ` [PATCH v2 05/29] tools/xenlogd: add 9pfs response generation support Juergen Gross
2023-11-20 16:57   ` Jason Andryuk
2023-12-01 19:30   ` Jason Andryuk
2023-12-05  6:32     ` Juergen Gross
2023-11-10 16:07 ` [PATCH v2 06/29] tools/xenlogd: add 9pfs version request support Juergen Gross
2023-11-10 16:07 ` [PATCH v2 07/29] tools/xenlogd: add 9pfs attach " Juergen Gross
2023-11-20 20:35   ` Jason Andryuk
2023-11-10 16:07 ` [PATCH v2 08/29] tools/xenlogd: add 9pfs walk " Juergen Gross
2023-11-28 15:04   ` Jason Andryuk
2023-11-10 16:07 ` [PATCH v2 09/29] tools/xenlogd: add 9pfs open " Juergen Gross
2023-11-28 15:49   ` Jason Andryuk
2023-11-10 16:07 ` [PATCH v2 10/29] tools/xenlogd: add 9pfs clunk " Juergen Gross
2023-11-28 20:15   ` Jason Andryuk
2023-11-10 16:07 ` [PATCH v2 11/29] tools/xenlogd: add 9pfs create " Juergen Gross
2023-11-28 20:22   ` Jason Andryuk
2023-11-10 16:07 ` [PATCH v2 12/29] tools/xenlogd: add 9pfs stat " Juergen Gross
2023-11-10 16:07 ` [PATCH v2 13/29] tools/xenlogd: add 9pfs write " Juergen Gross
2023-11-10 16:07 ` [PATCH v2 14/29] tools/xenlogd: add 9pfs read " Juergen Gross
2023-11-10 16:07 ` [PATCH v2 15/29] tools/libs/light: add backend type for 9pfs PV devices Juergen Gross
2023-12-06 13:17   ` Jason Andryuk
2023-12-06 17:44     ` Nick Rosbrook
2023-12-06 18:53       ` Jason Andryuk
2024-01-02 20:16         ` Nick Rosbrook
2023-11-10 16:07 ` [PATCH v2 16/29] tools/xl: support new 9pfs backend xen-9pfsd Juergen Gross
2023-11-28 20:25   ` Jason Andryuk
2023-11-10 16:07 ` [PATCH v2 17/29] tools/helpers: allocate xenstore event channel for xenstore stubdom Juergen Gross
2023-11-10 16:07 ` [PATCH v2 18/29] tools/xenstored: rename xenbus_evtchn() Juergen Gross
2023-11-28 20:26   ` Jason Andryuk
2023-11-10 16:07 ` [PATCH v2 19/29] stubdom: extend xenstore stubdom configs Juergen Gross
2023-11-10 16:07 ` [PATCH v2 20/29] tools: add 9pfs device to xenstore-stubdom Juergen Gross
2023-11-10 16:07 ` [PATCH v2 21/29] tools/xenstored: add early_init() function Juergen Gross
2023-11-10 17:31   ` Julien Grall
2023-11-13 10:27     ` Juergen Gross
2023-11-10 16:07 ` [PATCH v2 22/29] tools/xenstored: get own domid in stubdom case Juergen Gross
2023-11-10 17:36   ` Julien Grall
2023-11-13  9:03     ` Juergen Gross
2023-11-13 21:59   ` Julien Grall
2023-11-14  6:21     ` Juergen Gross
2023-11-10 16:07 ` [PATCH v2 23/29] tools/xenstored: rework ring page (un)map functions Juergen Gross
2023-11-10 17:51   ` Julien Grall
2023-11-10 16:07 ` [PATCH v2 24/29] tools/xenstored: split domain_init() Juergen Gross
2023-11-10 18:05   ` Julien Grall
2023-11-13  8:58     ` Juergen Gross
2023-11-13 11:37       ` Juergen Gross
2023-11-10 16:08 ` [PATCH v2 25/29] tools/xenstored: map stubdom interface Juergen Gross
2023-11-13 22:04   ` Julien Grall
2023-11-14  6:33     ` Juergen Gross
2023-11-14  8:56       ` Julien Grall
2023-11-14  9:12         ` Juergen Gross
2023-11-14 20:48           ` Julien Grall
2023-11-15  6:07             ` Juergen Gross
2023-11-10 16:08 ` [PATCH v2 26/29] tools/xenstored: mount 9pfs device in stubdom Juergen Gross
2023-11-13 22:09   ` Julien Grall
2023-11-14  6:40     ` Juergen Gross
2023-11-14  9:00       ` Julien Grall
2023-11-14  9:13         ` Juergen Gross
2023-11-10 16:08 ` [PATCH v2 27/29] tools/xenstored: add helpers for filename handling Juergen Gross
2023-11-13 22:25   ` Julien Grall
2023-11-14  6:45     ` Juergen Gross
2023-11-14  9:10       ` Julien Grall
2023-11-14  9:26         ` Juergen Gross
2023-11-14 20:53           ` Julien Grall
2023-11-15  6:14             ` Juergen Gross
2023-11-28 20:42               ` Jason Andryuk
2023-12-01 10:14                 ` Juergen Gross
2023-11-10 16:08 ` [PATCH v2 28/29] tools/xenstored: support complete log capabilities in stubdom Juergen Gross
2023-11-13 22:40   ` Julien Grall
2023-11-14  6:45     ` Juergen Gross
2023-11-14  9:05       ` Julien Grall
2023-11-14  9:20         ` Juergen Gross
2023-11-14 20:57           ` Julien Grall
2023-11-15  6:17             ` Juergen Gross
2023-11-10 16:08 ` [PATCH v2 29/29] tools/xenstored: have a single do_control_memreport() Juergen Gross

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.