Skip to content

Commit

Permalink
tools/libs/light: add backend type for 9pfs PV devices
Browse files Browse the repository at this point in the history
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>
Acked-by: George Dunlap <george.dunlap@cloud.com> # Golang bits
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
  • Loading branch information
jgross1 authored and andyhhp committed Feb 23, 2024
1 parent 098d868 commit ab5a6b5
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 7 deletions.
10 changes: 10 additions & 0 deletions tools/golang/xenlight/helpers.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions tools/golang/xenlight/types.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions tools/include/libxl.h
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,13 @@
*/
#define LIBXL_HAVE_HVM_PIRQ 1

/*
* LIBXL_HAVE_XEN_9PFS indicates the presence of the xen-9pfsd related
* fields in libxl_device_p9: type, max_space, max_files, max_open_files and
* auto_delete.
*/
#define LIBXL_HAVE_XEN_9PFS 1

/*
* libxl memory management
*
Expand Down
157 changes: 154 additions & 3 deletions tools/libs/light/libxl_9pfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,171 @@ 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;
};

static void xen9pfsd_confirm(libxl__egc *egc, libxl__spawn_state *spawn,
const char *xsdata);
static void xen9pfsd_failed(libxl__egc *egc, libxl__spawn_state *spawn, int rc);
static void xen9pfsd_detached(libxl__egc *egc, libxl__spawn_state *spawn);
static void xen9pfsd_spawn_outcome(libxl__egc *egc, libxl__aop9_state *aop9,
int rc);

/*
* Spawn the xen-9pfsd daemon if needed.
* returns:
* < 0 if error
* 0 if no daemon needs to be spawned
* 1 if daemon was spawned
*/
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;
libxl_device_p9_copy(CTX, &aop9->p9, p9);
aop9->domid = domid;

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 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 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 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,
);
4 changes: 1 addition & 3 deletions tools/libs/light/libxl_create.c
Original file line number Diff line number Diff line change
Expand Up @@ -1761,9 +1761,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]);
Expand Down Expand Up @@ -1900,6 +1897,7 @@ const libxl__device_type *device_type_tbl[] = {
&libxl__vdispl_devtype,
&libxl__vsnd_devtype,
&libxl__virtio_devtype,
&libxl__p9_devtype,
NULL
};

Expand Down
2 changes: 1 addition & 1 deletion tools/libs/light/libxl_dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3771,7 +3771,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;
}
Expand Down
11 changes: 11 additions & 0 deletions tools/libs/light/libxl_types.idl
Original file line number Diff line number Diff line change
Expand Up @@ -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"),

Expand Down Expand Up @@ -944,6 +950,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", [
Expand Down
1 change: 1 addition & 0 deletions tools/libs/light/libxl_types_internal.idl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ libxl__device_kind = Enumeration("device_kind", [
(17, "VIRTIO_DISK"),
(18, "VIRTIO"),
(19, "VBD3"),
(20, "XEN_9PFS"),
])

libxl__console_backend = Enumeration("console_backend", [
Expand Down

0 comments on commit ab5a6b5

Please sign in to comment.