[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] libxl/xl: add support for Xen 9pfs



Add functions to libxl to setup a Xen 9pfs frontend/backend connection.
Add support to xl to parse a xen_9pfs option in the VM config file, in
the following format:

xen_9pfs=["tag=share_dir,security_model=none,path=/path/share_dir"]

where tag identifies the 9p share and it is required to mount it on the
guest side, path is the path of the filesystem to share and the only
security_model supported is "none" which means that files are stored
using the same credentials as they are created on the guest (no user
ownership squash or remap).

Signed-off-by: Stefano Stabellini <stefano@xxxxxxxxxxx>
CC: wei.liu2@xxxxxxxxxx
CC: ian.jackson@xxxxxxxxxxxxx
---
 docs/man/xl.cfg.pod.5.in             | 31 +++++++++++++
 tools/libxl/Makefile                 |  2 +-
 tools/libxl/libxl.h                  | 10 +++++
 tools/libxl/libxl_9pfs.c             | 87 ++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_create.c           |  3 ++
 tools/libxl/libxl_internal.h         |  6 +++
 tools/libxl/libxl_types.idl          | 10 +++++
 tools/libxl/libxl_types_internal.idl |  1 +
 tools/xl/xl_parse.c                  | 55 ++++++++++++++++++++++-
 9 files changed, 203 insertions(+), 2 deletions(-)
 create mode 100644 tools/libxl/libxl_9pfs.c

diff --git a/docs/man/xl.cfg.pod.5.in b/docs/man/xl.cfg.pod.5.in
index 505c111..699a644 100644
--- a/docs/man/xl.cfg.pod.5.in
+++ b/docs/man/xl.cfg.pod.5.in
@@ -516,6 +516,37 @@ value is optional if this is a guest domain.
 
 =back
 
+=item B<xen_9pfs=[ "XEN_9PFS_SPEC_STRING", "XEN_9PFS_SPEC_STRING", ...]>
+
+Creates a Xen 9pfs connection to share a filesystem from backend to
+frontend.
+
+Each B<XEN_9PFS_SPEC_STRING> is a comma-separated list of C<KEY=VALUE>
+settings, from the following list:
+
+=over 4
+
+=item C<tag=STRING>
+
+9pfs tag to identify the filesystem share. The tag is needed on the
+guest side to mount it.
+
+=item C<security_model="none">
+
+Only "none" is supported today, which means that files are stored using
+the same credentials as they are created on the guest (no user ownership
+squash or remap).
+
+=item C<path=STRING>
+
+Filesystem path on the backend to export.
+
+=item C<backend=DOMAIN>
+
+Specify the backend domain name or id, defaults to dom0.
+
+=back
+
 =item B<vfb=[ "VFB_SPEC_STRING", "VFB_SPEC_STRING", ...]>
 
 Specifies the paravirtual framebuffer devices which should be supplied
diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index f00d9ef..5911940 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -138,7 +138,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o 
libxl_pci.o \
                        libxl_dom_suspend.o libxl_dom_save.o libxl_usb.o \
                        libxl_vtpm.o libxl_nic.o libxl_disk.o libxl_console.o \
                        libxl_cpupool.o libxl_mem.o libxl_sched.o libxl_tmem.o \
-                       libxl_domain.o \
+                       libxl_9pfs.o libxl_domain.o \
                         $(LIBXL_OBJS-y)
 LIBXL_OBJS += libxl_genid.o
 LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 92f1751..eec3ae9 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1859,6 +1859,16 @@ int libxl_device_vfb_destroy(libxl_ctx *ctx, uint32_t 
domid,
                              const libxl_asyncop_how *ao_how)
                              LIBXL_EXTERNAL_CALLERS_ONLY;
 
+/* 9pfs */
+int libxl_device_xen_9pfs_remove(libxl_ctx *ctx, uint32_t domid,
+                            libxl_device_xen_9pfs *xen_9pfs,
+                            const libxl_asyncop_how *ao_how)
+                             LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_device_xen_9pfs_destroy(libxl_ctx *ctx, uint32_t domid,
+                             libxl_device_xen_9pfs *xen_9pfs,
+                             const libxl_asyncop_how *ao_how)
+                             LIBXL_EXTERNAL_CALLERS_ONLY;
+
 /* PCI Passthrough */
 int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
                          libxl_device_pci *pcidev,
diff --git a/tools/libxl/libxl_9pfs.c b/tools/libxl/libxl_9pfs.c
new file mode 100644
index 0000000..8cb0772
--- /dev/null
+++ b/tools/libxl/libxl_9pfs.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017      Aporeto
+ * Author Stefano Stabellini <stefano@xxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#include "libxl_osdeps.h"
+
+#include "libxl_internal.h"
+
+int libxl__device_xen_9pfs_setdefault(libxl__gc *gc, libxl_device_xen_9pfs 
*xen_9pfs)
+{
+    int rc;
+
+    rc = libxl__resolve_domid(gc, xen_9pfs->backend_domname, 
&xen_9pfs->backend_domid);
+    return rc;
+}
+
+static int libxl__device_from_xen_9pfs(libxl__gc *gc, uint32_t domid,
+                                   libxl_device_xen_9pfs *xen_9pfs,
+                                   libxl__device *device)
+{
+   device->backend_devid   = xen_9pfs->devid;
+   device->backend_domid   = xen_9pfs->backend_domid;
+   device->backend_kind    = LIBXL__DEVICE_KIND_9PFS;
+   device->devid           = xen_9pfs->devid;
+   device->domid           = domid;
+   device->kind            = LIBXL__DEVICE_KIND_9PFS;
+
+   return 0;
+}
+
+
+int libxl__device_xen_9pfs_add(libxl__gc *gc, uint32_t domid,
+                           libxl_device_xen_9pfs *xen_9pfs)
+{
+    flexarray_t *front;
+    flexarray_t *back;
+    libxl__device device;
+    int rc;
+
+    rc = libxl__device_xen_9pfs_setdefault(gc, xen_9pfs);
+    if (rc) goto out;
+
+    front = flexarray_make(gc, 16, 1);
+    back = flexarray_make(gc, 16, 1);
+
+    if (xen_9pfs->devid == -1) {
+        if ((xen_9pfs->devid = libxl__device_nextid(gc, domid, "9pfs")) < 0) {
+            rc = ERROR_FAIL;
+            goto out;
+        }
+    }
+
+    rc = libxl__device_from_xen_9pfs(gc, domid, xen_9pfs, &device);
+    if (rc != 0) goto out;
+
+    flexarray_append_pair(back, "frontend-id", libxl__sprintf(gc, "%d", 
domid));
+    flexarray_append_pair(back, "online", "1");
+    flexarray_append_pair(back, "state", GCSPRINTF("%d", 
XenbusStateInitialising));
+    flexarray_append_pair(front, "backend-id",
+                          libxl__sprintf(gc, "%d", xen_9pfs->backend_domid));
+    flexarray_append_pair(front, "state", GCSPRINTF("%d", 
XenbusStateInitialising));
+    flexarray_append_pair(front, "tag", xen_9pfs->tag);
+    flexarray_append_pair(back, "path", xen_9pfs->path);
+    flexarray_append_pair(back, "security_model", xen_9pfs->security_model);
+
+    libxl__device_generic_add(gc, XBT_NULL, &device,
+                              libxl__xs_kvs_of_flexarray(gc, back),
+                              libxl__xs_kvs_of_flexarray(gc, front),
+                              NULL);
+    rc = 0;
+out:
+    return rc;
+}
+
+LIBXL_DEFINE_DEVICE_REMOVE(xen_9pfs)
+
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index e741b9a..c9aa9be 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -1332,6 +1332,9 @@ static void domcreate_launch_dm(libxl__egc *egc, 
libxl__multidev *multidev,
         libxl__device_console_dispose(&console);
     }
 
+    for (i = 0; i < d_config->num_xen_9pfs; i++)
+        libxl__device_xen_9pfs_add(gc, domid, &d_config->xen_9pfs[i]);
+
     switch (d_config->c_info.type) {
     case LIBXL_DOMAIN_TYPE_HVM:
     {
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 5bbede5..b96eab8 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1248,6 +1248,8 @@ _hidden int libxl__device_vkb_setdefault(libxl__gc *gc, 
libxl_device_vkb *vkb);
 _hidden int libxl__device_pci_setdefault(libxl__gc *gc, libxl_device_pci *pci);
 _hidden void libxl__rdm_setdefault(libxl__gc *gc,
                                    libxl_domain_build_info *b_info);
+_hidden int libxl__device_xen_9pfs_setdefault(libxl__gc *gc,
+                                              libxl_device_xen_9pfs *xen_9pfs);
 
 _hidden const char *libxl__device_nic_devname(libxl__gc *gc,
                                               uint32_t domid,
@@ -2662,6 +2664,10 @@ _hidden int libxl__device_vkb_add(libxl__gc *gc, 
uint32_t domid,
 _hidden int libxl__device_vfb_add(libxl__gc *gc, uint32_t domid,
                                   libxl_device_vfb *vfb);
 
+/* Internal function to connect a xen_9pfs device */
+_hidden int libxl__device_xen_9pfs_add(libxl__gc *gc, uint32_t domid,
+                                  libxl_device_xen_9pfs *xen_9pfs);
+
 /* Waits for the passed device to reach state XenbusStateInitWait.
  * This is not really useful by itself, but is important when executing
  * hotplug scripts, since we need to be sure the device is in the correct
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index a612d1f..d7e8228 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -692,6 +692,15 @@ libxl_device_vtpm = Struct("device_vtpm", [
     ("uuid",             libxl_uuid),
 ])
 
+libxl_device_xen_9pfs = Struct("device_xen_9pfs", [
+    ("backend_domid",    libxl_domid),
+    ("backend_domname",  string),
+    ("tag",              string),
+    ("path",             string),
+    ("security_model",   string),
+    ("devid",            libxl_devid),
+])
+
 libxl_device_channel = Struct("device_channel", [
     ("backend_domid", libxl_domid),
     ("backend_domname", string),
@@ -716,6 +725,7 @@ libxl_domain_config = Struct("domain_config", [
     ("vfbs", Array(libxl_device_vfb, "num_vfbs")),
     ("vkbs", Array(libxl_device_vkb, "num_vkbs")),
     ("vtpms", Array(libxl_device_vtpm, "num_vtpms")),
+    ("xen_9pfs", Array(libxl_device_xen_9pfs, "num_xen_9pfs")),
     # a channel manifests as a console with a name,
     # see docs/misc/channels.txt
     ("channels", Array(libxl_device_channel, "num_channels")),
diff --git a/tools/libxl/libxl_types_internal.idl 
b/tools/libxl/libxl_types_internal.idl
index 82e5c07..7dc4d0f 100644
--- a/tools/libxl/libxl_types_internal.idl
+++ b/tools/libxl/libxl_types_internal.idl
@@ -25,6 +25,7 @@ libxl__device_kind = Enumeration("device_kind", [
     (8, "VTPM"),
     (9, "VUSB"),
     (10, "QUSB"),
+    (11, "9PFS"),
     ])
 
 libxl__console_backend = Enumeration("console_backend", [
diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index 1ef0c27..275b72f 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -716,7 +716,7 @@ void parse_config_data(const char *config_source,
     long l, vcpus = 0;
     XLU_Config *config;
     XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms,
-                   *usbctrls, *usbdevs;
+                   *usbctrls, *usbdevs, *xen_9pfs_opts;
     XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian, *dtdevs;
     int num_ioports, num_irqs, num_iomem, num_cpus, num_viridian;
     int pci_power_mgmt = 0;
@@ -1251,6 +1251,59 @@ void parse_config_data(const char *config_source,
         }
     }
 
+    if (!xlu_cfg_get_list(config, "xen_9pfs", &xen_9pfs_opts, 0, 0)) {
+        libxl_device_xen_9pfs *xen_9pfs;
+        char *security_model = NULL;
+        char *path = NULL;
+        char *tag = NULL;
+        char *backend = NULL;
+        char *p, *p2, *buf2;
+
+        d_config->num_xen_9pfs = 0;
+        d_config->xen_9pfs = NULL;
+        while ((buf = xlu_cfg_get_listitem (xen_9pfs_opts, 
d_config->num_xen_9pfs)) != NULL) {
+            xen_9pfs = ARRAY_EXTEND_INIT(d_config->xen_9pfs,
+                    d_config->num_xen_9pfs,
+                    libxl_device_xen_9pfs_init);
+            libxl_device_xen_9pfs_init(xen_9pfs);
+
+            buf2 = strdup(buf);
+            p = strtok(buf2, ",");
+            if(p) {
+               do {
+                  while(*p == ' ')
+                     ++p;
+                  if ((p2 = strchr(p, '=')) == NULL)
+                     break;
+                  *p2 = '\0';
+                  if (!strcmp(p, "security_model")) {
+                     security_model = strdup(p2 + 1);
+                  } else if(!strcmp(p, "path")) {
+                     path = strdup(p2 + 1);
+                  } else if(!strcmp(p, "tag")) {
+                     tag = strdup(p2 + 1);
+                  } else if(!strcmp(p, "backend")) {
+                     backend = strdup(p2 + 1);
+                  } else {
+                     fprintf(stderr, "Unknown string `%s' in xen_9pfs spec\n", 
p);
+                     exit(1);
+                  }
+               } while ((p = strtok(NULL, ",")) != NULL);
+            }
+            if (!path || !security_model || !tag) {
+               fprintf(stderr, "xen_9pfs spec missing required field!\n");
+               exit(1);
+            }
+            free(buf2);
+
+            replace_string(&xen_9pfs->tag, tag);
+            replace_string(&xen_9pfs->security_model, security_model);
+            replace_string(&xen_9pfs->path, path);
+            if (backend)
+                    replace_string(&xen_9pfs->backend_domname, backend);
+        }
+    }
+
     if (!xlu_cfg_get_list(config, "vtpm", &vtpms, 0, 0)) {
         d_config->num_vtpms = 0;
         d_config->vtpms = NULL;
-- 
1.9.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.