mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
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 9pfs option in the VM config file, in the following format: p9=["tag=share_dir,security_model=none,path=/root/share_dir"] where tag identifies the 9pfs 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@aporeto.com> Acked-by: Wei Liu <wei.liu2@citrix.com>
This commit is contained in:
1 parent
4c8153d97e
commit
b53b4037ce
9 files changed
+203
-2
No files matched your search
@@ -516,6 +516,37 @@ value is optional if this is a guest domain.
|
||||
|
||||
=back
|
||||
|
||||
=item B<p9=[ "9PFS_SPEC_STRING", "9PFS_SPEC_STRING", ...]>
|
||||
|
||||
Creates a Xen 9pfs connection to share a filesystem from backend to
|
||||
frontend.
|
||||
|
||||
Each B<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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1871,6 +1871,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_p9_remove(libxl_ctx *ctx, uint32_t domid,
|
||||
libxl_device_p9 *p9,
|
||||
const libxl_asyncop_how *ao_how)
|
||||
LIBXL_EXTERNAL_CALLERS_ONLY;
|
||||
int libxl_device_p9_destroy(libxl_ctx *ctx, uint32_t domid,
|
||||
libxl_device_p9 *p9,
|
||||
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,
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Aporeto
|
||||
* Author Stefano Stabellini <stefano@aporeto.com>
|
||||
*
|
||||
* 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_p9_setdefault(libxl__gc *gc, libxl_device_p9 *p9)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = libxl__resolve_domid(gc, p9->backend_domname, &p9->backend_domid);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int libxl__device_from_p9(libxl__gc *gc, uint32_t domid,
|
||||
libxl_device_p9 *p9,
|
||||
libxl__device *device)
|
||||
{
|
||||
device->backend_devid = p9->devid;
|
||||
device->backend_domid = p9->backend_domid;
|
||||
device->backend_kind = LIBXL__DEVICE_KIND_9PFS;
|
||||
device->devid = p9->devid;
|
||||
device->domid = domid;
|
||||
device->kind = LIBXL__DEVICE_KIND_9PFS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int libxl__device_p9_add(libxl__gc *gc, uint32_t domid,
|
||||
libxl_device_p9 *p9)
|
||||
{
|
||||
flexarray_t *front;
|
||||
flexarray_t *back;
|
||||
libxl__device device;
|
||||
int rc;
|
||||
|
||||
rc = libxl__device_p9_setdefault(gc, p9);
|
||||
if (rc) goto out;
|
||||
|
||||
front = flexarray_make(gc, 16, 1);
|
||||
back = flexarray_make(gc, 16, 1);
|
||||
|
||||
if (p9->devid == -1) {
|
||||
if ((p9->devid = libxl__device_nextid(gc, domid, "9pfs")) < 0) {
|
||||
rc = ERROR_FAIL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
rc = libxl__device_from_p9(gc, domid, p9, &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", p9->backend_domid));
|
||||
flexarray_append_pair(front, "state", GCSPRINTF("%d", XenbusStateInitialising));
|
||||
flexarray_append_pair(front, "tag", p9->tag);
|
||||
flexarray_append_pair(back, "path", p9->path);
|
||||
flexarray_append_pair(back, "security_model", p9->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(p9)
|
||||
|
||||
@@ -1322,6 +1322,9 @@ 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_p9_add(gc, domid, &d_config->p9[i]);
|
||||
|
||||
switch (d_config->c_info.type) {
|
||||
case LIBXL_DOMAIN_TYPE_HVM:
|
||||
{
|
||||
|
||||
@@ -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_p9_setdefault(libxl__gc *gc,
|
||||
libxl_device_p9 *p9);
|
||||
|
||||
_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 9pfs device */
|
||||
_hidden int libxl__device_p9_add(libxl__gc *gc, uint32_t domid,
|
||||
libxl_device_p9 *p9);
|
||||
|
||||
/* 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
|
||||
|
||||
@@ -742,6 +742,15 @@ libxl_device_vtpm = Struct("device_vtpm", [
|
||||
("uuid", libxl_uuid),
|
||||
])
|
||||
|
||||
libxl_device_p9 = Struct("device_p9", [
|
||||
("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),
|
||||
@@ -766,6 +775,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")),
|
||||
("p9", Array(libxl_device_p9, "num_p9s")),
|
||||
# a channel manifests as a console with a name,
|
||||
# see docs/misc/channels.txt
|
||||
("channels", Array(libxl_device_channel, "num_channels")),
|
||||
|
||||
@@ -25,6 +25,7 @@ libxl__device_kind = Enumeration("device_kind", [
|
||||
(8, "VTPM"),
|
||||
(9, "VUSB"),
|
||||
(10, "QUSB"),
|
||||
(11, "9PFS"),
|
||||
])
|
||||
|
||||
libxl__console_backend = Enumeration("console_backend", [
|
||||
|
||||
+54
-1
@@ -812,7 +812,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, *p9devs;
|
||||
XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian, *dtdevs;
|
||||
int num_ioports, num_irqs, num_iomem, num_cpus, num_viridian;
|
||||
int pci_power_mgmt = 0;
|
||||
@@ -1347,6 +1347,59 @@ void parse_config_data(const char *config_source,
|
||||
}
|
||||
}
|
||||
|
||||
if (!xlu_cfg_get_list(config, "p9", &p9devs, 0, 0)) {
|
||||
libxl_device_p9 *p9;
|
||||
char *security_model = NULL;
|
||||
char *path = NULL;
|
||||
char *tag = NULL;
|
||||
char *backend = NULL;
|
||||
char *p, *p2, *buf2;
|
||||
|
||||
d_config->num_p9s = 0;
|
||||
d_config->p9 = NULL;
|
||||
while ((buf = xlu_cfg_get_listitem (p9devs, d_config->num_p9s)) != NULL) {
|
||||
p9 = ARRAY_EXTEND_INIT(d_config->p9,
|
||||
d_config->num_p9s,
|
||||
libxl_device_p9_init);
|
||||
libxl_device_p9_init(p9);
|
||||
|
||||
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 9pfs spec\n", p);
|
||||
exit(1);
|
||||
}
|
||||
} while ((p = strtok(NULL, ",")) != NULL);
|
||||
}
|
||||
if (!path || !security_model || !tag) {
|
||||
fprintf(stderr, "9pfs spec missing required field!\n");
|
||||
exit(1);
|
||||
}
|
||||
free(buf2);
|
||||
|
||||
replace_string(&p9->tag, tag);
|
||||
replace_string(&p9->security_model, security_model);
|
||||
replace_string(&p9->path, path);
|
||||
if (backend)
|
||||
replace_string(&p9->backend_domname, backend);
|
||||
}
|
||||
}
|
||||
|
||||
if (!xlu_cfg_get_list(config, "vtpm", &vtpms, 0, 0)) {
|
||||
d_config->num_vtpms = 0;
|
||||
d_config->vtpms = NULL;
|
||||
|
||||