[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 4/7] Mini-OS: add 9pfs frontend
Juergen Gross, le ven. 10 févr. 2023 11:46:25 +0100, a ecrit: > Add a frontend for the 9pfs PV device. For now add only the code needed > to connect to the backend and the related disconnect functionality. The > 9pfs protocol support will be added later. > > Due to its nature (ability to access files) the whole code is guarded > by "#ifdef HAVE_LIBC". > > Signed-off-by: Juergen Gross <jgross@xxxxxxxx> Reviewed-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx> > --- > V2: > - add better error handling to version parsing (Samuel Thibault) > --- > 9pfront.c | 286 ++++++++++++++++++++++++++++++++++ > Config.mk | 1 + > Makefile | 1 + > arch/x86/testbuild/all-no | 1 + > arch/x86/testbuild/all-yes | 1 + > arch/x86/testbuild/newxen-yes | 1 + > include/9pfront.h | 7 + > 7 files changed, 298 insertions(+) > create mode 100644 9pfront.c > create mode 100644 include/9pfront.h > > diff --git a/9pfront.c b/9pfront.c > new file mode 100644 > index 00000000..89ecb3a1 > --- /dev/null > +++ b/9pfront.c > @@ -0,0 +1,286 @@ > +/* > + * Minimal 9pfs PV frontend for Mini-OS. > + * Copyright (c) 2023 Juergen Gross, SUSE Software Solution GmbH > + */ > + > +#include <mini-os/os.h> > +#include <mini-os/lib.h> > +#include <mini-os/events.h> > +#include <mini-os/gnttab.h> > +#include <mini-os/xenbus.h> > +#include <mini-os/xmalloc.h> > +#include <errno.h> > +#include <xen/io/9pfs.h> > +#include <mini-os/9pfront.h> > + > +#ifdef HAVE_LIBC > +struct dev_9pfs { > + int id; > + char nodename[20]; > + unsigned int dom; > + char *backend; > + > + char *tag; > + const char *mnt; > + > + struct xen_9pfs_data_intf *intf; > + struct xen_9pfs_data data; > + RING_IDX prod_pvt_out; > + RING_IDX cons_pvt_in; > + > + grant_ref_t ring_ref; > + evtchn_port_t evtchn; > + unsigned int ring_order; > + xenbus_event_queue events; > +}; > + > +#define DEFAULT_9PFS_RING_ORDER 4 > + > +static unsigned int ftype_9pfs; > + > +static void intr_9pfs(evtchn_port_t port, struct pt_regs *regs, void *data) > +{ > +} > + > +static int open_9pfs(struct mount_point *mnt, const char *pathname, int > flags, > + mode_t mode) > +{ > + errno = ENOSYS; > + > + return -1; > +} > + > +static void free_9pfront(struct dev_9pfs *dev) > +{ > + unsigned int i; > + > + if ( dev->data.in && dev->intf ) > + { > + for ( i = 0; i < (1 << dev->ring_order); i++ ) > + gnttab_end_access(dev->intf->ref[i]); > + free_pages(dev->data.in, dev->ring_order); > + } > + unbind_evtchn(dev->evtchn); > + gnttab_end_access(dev->ring_ref); > + free_page(dev->intf); > + free(dev->backend); > + free(dev->tag); > + free(dev); > +} > + > +void *init_9pfront(unsigned int id, const char *mnt) > +{ > + struct dev_9pfs *dev; > + char *msg; > + char *reason = ""; > + xenbus_transaction_t xbt; > + int retry = 1; > + char bepath[64] = { 0 }; > + XenbusState state; > + unsigned int i; > + void *addr; > + char *version; > + char *v; > + > + printk("9pfsfront add %u, for mount at %s\n", id, mnt); > + dev = malloc(sizeof(*dev)); > + memset(dev, 0, sizeof(*dev)); > + snprintf(dev->nodename, sizeof(dev->nodename), "device/9pfs/%u", id); > + dev->id = id; > + > + msg = xenbus_read_unsigned(XBT_NIL, dev->nodename, "backend-id", > &dev->dom); > + if ( msg ) > + goto err; > + msg = xenbus_read_string(XBT_NIL, dev->nodename, "backend", > &dev->backend); > + if ( msg ) > + goto err; > + msg = xenbus_read_string(XBT_NIL, dev->nodename, "tag", &dev->tag); > + if ( msg ) > + goto err; > + > + snprintf(bepath, sizeof(bepath), "%s/state", dev->backend); > + free(xenbus_watch_path_token(XBT_NIL, bepath, bepath, &dev->events)); > + state = xenbus_read_integer(bepath); > + while ( msg == NULL && state < XenbusStateInitWait ) > + msg = xenbus_wait_for_state_change(bepath, &state, &dev->events); > + if ( msg || state != XenbusStateInitWait ) > + { > + reason = "illegal backend state"; > + goto err; > + } > + > + msg = xenbus_read_unsigned(XBT_NIL, dev->backend, "max-ring-page-order", > + &dev->ring_order); > + if ( msg ) > + goto err; > + if ( dev->ring_order > DEFAULT_9PFS_RING_ORDER ) > + dev->ring_order = DEFAULT_9PFS_RING_ORDER; > + > + msg = xenbus_read_string(XBT_NIL, dev->backend, "versions", &version); > + if ( msg ) > + goto err; > + for ( v = version; *v; v++ ) > + { > + if ( strtoul(v, &v, 10) == 1 && (*v == ',' || *v == 0) ) > + { > + v = NULL; > + break; > + } > + if ( *v != ',' && *v != 0 ) > + { > + reason = "backend published illegal version string"; > + free(version); > + goto err; > + } > + } > + free(version); > + if ( v ) > + { > + reason = "backend doesn't support version 1"; > + goto err; > + } > + > + dev->ring_ref = gnttab_alloc_and_grant((void **)&dev->intf); > + memset(dev->intf, 0, PAGE_SIZE); > + if ( evtchn_alloc_unbound(dev->dom, intr_9pfs, dev, &dev->evtchn) ) > + { > + reason = "no event channel"; > + goto err; > + } > + dev->intf->ring_order = dev->ring_order; > + dev->data.in = (void *)alloc_pages(dev->ring_order); > + dev->data.out = dev->data.in + XEN_FLEX_RING_SIZE(dev->ring_order); > + for ( i = 0; i < (1 << dev->ring_order); i++ ) > + { > + addr = dev->data.in + i * PAGE_SIZE; > + dev->intf->ref[i] = gnttab_grant_access(dev->dom, virt_to_mfn(addr), > 0); > + } > + > + while ( retry ) > + { > + msg = xenbus_transaction_start(&xbt); > + if ( msg ) > + { > + free(msg); > + msg = NULL; > + reason = "starting transaction"; > + goto err; > + } > + > + msg = xenbus_printf(xbt, dev->nodename, "version", "%u", 1); > + if ( msg ) > + goto err_tr; > + msg = xenbus_printf(xbt, dev->nodename, "num-rings", "%u", 1); > + if ( msg ) > + goto err_tr; > + msg = xenbus_printf(xbt, dev->nodename, "ring-ref0", "%u", > + dev->ring_ref); > + if ( msg ) > + goto err_tr; > + msg = xenbus_printf(xbt, dev->nodename, "event-channel-0", "%u", > + dev->evtchn); > + if ( msg ) > + goto err_tr; > + msg = xenbus_printf(xbt, dev->nodename, "state", "%u", > + XenbusStateInitialised); > + if ( msg ) > + goto err_tr; > + > + free(xenbus_transaction_end(xbt, 0, &retry)); > + } > + > + state = xenbus_read_integer(bepath); > + while ( msg == NULL && state < XenbusStateConnected ) > + msg = xenbus_wait_for_state_change(bepath, &state, &dev->events); > + if ( msg || state != XenbusStateConnected ) > + { > + reason = "illegal backend state"; > + goto err; > + } > + > + msg = xenbus_printf(XBT_NIL, dev->nodename, "state", "%u", > + XenbusStateConnected); > + if ( msg ) > + goto err; > + > + unmask_evtchn(dev->evtchn); > + > + dev->mnt = mnt; > + if ( mount(dev->mnt, dev, open_9pfs) ) > + { > + reason = "mount failed"; > + goto err; > + } > + > + return dev; > + > + err_tr: > + free(xenbus_transaction_end(xbt, 1, &retry)); > + > + err: > + if ( bepath[0] ) > + free(xenbus_unwatch_path_token(XBT_NIL, bepath, bepath)); > + if ( msg ) > + printk("9pfsfront add %u failed, error %s accessing Xenstore\n", > + id, msg); > + else > + printk("9pfsfront add %u failed, %s\n", id, reason); > + free_9pfront(dev); > + free(msg); > + return NULL; > +} > + > +void shutdown_9pfront(void *dev) > +{ > + struct dev_9pfs *dev9p = dev; > + char bepath[64]; > + XenbusState state; > + char *msg; > + char *reason = ""; > + > + umount(dev9p->mnt); > + snprintf(bepath, sizeof(bepath), "%s/state", dev9p->backend); > + > + msg = xenbus_printf(XBT_NIL, dev9p->nodename, "state", "%u", > + XenbusStateClosing); > + if ( msg ) > + goto err; > + > + state = xenbus_read_integer(bepath); > + while ( msg == NULL && state < XenbusStateClosing) > + msg = xenbus_wait_for_state_change(bepath, &state, &dev9p->events); > + if ( msg || state != XenbusStateClosing ) > + { > + reason = "illegal backend state"; > + goto err; > + } > + > + msg = xenbus_printf(XBT_NIL, dev9p->nodename, "state", "%u", > + XenbusStateClosed); > + if ( msg ) > + goto err; > + > + free_9pfront(dev9p); > + > + return; > + > + err: > + if ( msg ) > + printk("9pfsfront shutdown %u failed, error %s accessing Xenstore\n", > + dev9p->id, msg); > + else > + printk("9pfsfront shutdown %u failed, %s\n", dev9p->id, reason); > + free(msg); > +} > + > +static const struct file_ops ops_9pfs = { > + .name = "9pfs", > +}; > + > +__attribute__((constructor)) > +static void initialize_9pfs(void) > +{ > + ftype_9pfs = alloc_file_type(&ops_9pfs); > +} > + > +#endif /* HAVE_LIBC */ > diff --git a/Config.mk b/Config.mk > index 1a24b30e..677e93df 100644 > --- a/Config.mk > +++ b/Config.mk > @@ -187,6 +187,7 @@ CONFIG-n += CONFIG_QEMU_XS_ARGS > CONFIG-n += CONFIG_TEST > CONFIG-n += CONFIG_PCIFRONT > CONFIG-n += CONFIG_TPMFRONT > +CONFIG-n += CONFIG_9PFRONT > CONFIG-n += CONFIG_TPM_TIS > CONFIG-n += CONFIG_TPMBACK > CONFIG-n += CONFIG_BALLOON > diff --git a/Makefile b/Makefile > index 747c7c01..7ee181a2 100644 > --- a/Makefile > +++ b/Makefile > @@ -39,6 +39,7 @@ SUBDIRS := lib > src-$(CONFIG_BLKFRONT) += blkfront.c > src-$(CONFIG_CONSFRONT) += consfront.c > src-$(CONFIG_TPMFRONT) += tpmfront.c > +src-$(CONFIG_9PFRONT) += 9pfront.c > src-$(CONFIG_TPM_TIS) += tpm_tis.c > src-$(CONFIG_TPMBACK) += tpmback.c > src-y += console.c > diff --git a/arch/x86/testbuild/all-no b/arch/x86/testbuild/all-no > index f79a1012..5b3e99ed 100644 > --- a/arch/x86/testbuild/all-no > +++ b/arch/x86/testbuild/all-no > @@ -12,6 +12,7 @@ CONFIG_NETFRONT = n > CONFIG_FBFRONT = n > CONFIG_KBDFRONT = n > CONFIG_CONSFRONT = n > +CONFIG_9PFRONT = n > CONFIG_XENBUS = n > CONFIG_LIBXS = n > CONFIG_LWIP = n > diff --git a/arch/x86/testbuild/all-yes b/arch/x86/testbuild/all-yes > index faa3af32..8ae489a4 100644 > --- a/arch/x86/testbuild/all-yes > +++ b/arch/x86/testbuild/all-yes > @@ -12,6 +12,7 @@ CONFIG_NETFRONT = y > CONFIG_FBFRONT = y > CONFIG_KBDFRONT = y > CONFIG_CONSFRONT = y > +CONFIG_9PFRONT = y > CONFIG_XENBUS = y > CONFIG_LIBXS = y > CONFIG_BALLOON = y > diff --git a/arch/x86/testbuild/newxen-yes b/arch/x86/testbuild/newxen-yes > index dc83e670..ee27a328 100644 > --- a/arch/x86/testbuild/newxen-yes > +++ b/arch/x86/testbuild/newxen-yes > @@ -12,6 +12,7 @@ CONFIG_NETFRONT = y > CONFIG_FBFRONT = y > CONFIG_KBDFRONT = y > CONFIG_CONSFRONT = y > +CONFIG_9PFRONT = y > CONFIG_XENBUS = y > CONFIG_LIBXS = y > CONFIG_BALLOON = y > diff --git a/include/9pfront.h b/include/9pfront.h > new file mode 100644 > index 00000000..722ec564 > --- /dev/null > +++ b/include/9pfront.h > @@ -0,0 +1,7 @@ > +#ifndef __9PFRONT_H__ > +#define __9PFRONT_H__ > + > +void *init_9pfront(unsigned int id, const char *mnt); > +void shutdown_9pfront(void *dev); > + > +#endif /* __9PFRONT_H__ */ > -- > 2.35.3 > -- Samuel --- Pour une évaluation indépendante, transparente et rigoureuse ! Je soutiens la Commission d'Évaluation de l'Inria.
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |