Hello,
Wei has suggested I "send a summarised email on [my] work to xen-devel so that people are aware of [my] work." To that end, and to save Wei from reinventing the wheel, I am providing the following:

First to correct a misconception, I followed the state change protocol of xen, as outlined by Ian Campbell in his 6/11 email on "Re:[xen-devel]grant tables and driver handshaking". This was tested early in the summer when I passed a small amount of data between my initial front and back ends. The code resides in the files p9_front.c, p9_front_driver.c on the front end and xen_9pif.c on the backend. I am attaching an updated version of a writeup I made this summer. It's table of contents is:
    1.  The state of the project
    2.  The approach I took
    3.  How to build my project
    4.  How to use it.

Sincerely,

Linda Jacobson


I.  PROJECT STATUS

The project compiles and builds.  The backend initialization works.  The front
end works partway through initialization. It dies in probe.  This is because I
initialized the mount path in the backend using the xenstore backend path, and
tried to access it in the frontend with its path.  Currently this path is 
hardcoded
in the init code in xen_9pif.c.  As I wrote in my commit message, this should be
done in initialization.  Ideally, to handle multiple mounts, the xenstore path
should have a "mount directory" that contains all the file system mount paths.

In addition, all of the front and backend code to manage the ring and the
one entry grant table, as well as transferring data to and from the shared page
has been tested and works.

Most of the code for the entire project has been written.

What I was going to do next (in this order) was:
   
    1.  Test:
        a.  That the data transferred accurately.
        b.  That the organization of the data being transferred is as I
        understand it.
    2.  Add and test transferring > 1 page of data.  If 3b is AIUI, this is
       trivial.
    3.  Restore some of the configuration dependencies in the makefiles in qemu,
        and set them in the configure file.  (See notes below)
    4.  Fix the white space in the different files.  

II.  APPROACH

I re-used a fair amount of virtio 9p code to produce the above.
In this respect, the front-end required more code, but less modification to
existing code.

II. A.  Front-end
When I began, I assumed the code should eventually reside in net/9p.
Only one file in this directory trans_virtio.c contains code that is virtio
specific.  The files client.c and mod.c, while technically part of virtio,
could be used as is, and my code calls functions in these files.

What I realized, in writing the backend, is that virtio provided the code that
takes the initial client request, massages it, and "unmarshals" these requests
in the backend.  Client.c and mod.c, do this massaging in the front-end.  The
format of the data that client.c sends in a request is easily moved to a
scatter-gather list.

p9_front_driver.c contains all the functions specified in the xenbus_driver
struct.  The module initialization registers the front end with xenbus, and
calls the 9p initialization code (in trans_xen9p.c) to register the 9p
transport.

The functions in trans_xen9p.c mimic their counterparts in trans_virtio.c, in
that they provide the same functionality.  They are the interface between the
functions in client.c and the xen protocol.  They receive requests from the 
client
and call functions in p9_front.c to issue the request.  The function in
trans_xen9p.c, that handles these requests, is specified in the 9p 
initialization
code.

p9_front.c contains the code that talks to the back end.  It contains the
p9_connect function, which is invoked when the front and back-end are 
connected.  It
also manages the ring, and the grant table (which, at present has only one 
entry),
receives requests from trans_xen9p.c, transfers the data into a shared page,
and issues the request to the backend.  When it receives a response, it passes
the response information to req_done (in trans_xen9p.c), which processes it, 
and calls the client callback function.

FYI - in linux/fs/fsdev there is the core of the 9p client code.  I did not 
touch
this code.

II. B. Backend
This was more complicated so I'll break it down into Background and What I did.

Background:
The virtio 9p backend code is composed of many files:  virtio-9p.c contains most
of the code to interpret the request from the client, and a few virtio-specific
functions.  virtio-9p-xattr.c and virtio-9p-xattr-user.c handle extended
attribute requests.  These files reside in qemu/hw/9pfs.

virtio-9p-co*.c contain co-routines for all the functions in virtio-9p.c and
virtio-xattr.c.

virtio-9p-proxy.c, virtio-9p-synth.c, virtio-9p-local.c implement the various
file systems that virtio supports.

virtio-9p-device.c contains an implementation of the qemu object model for 9p.

What I Did:

I broke virtio-9p.c into two files:  virtio-9p.c and v9fs_server.c.
virtio-9p.c now contains three functions:  complete_pdu, handle_9p_output, and a
"constructor", virtio_9p_set_fd_limit.

I created a "wrapper"header file for virtio-9p.h, v9fs_server.h.  This
wrapper creates a container for the V9fsState struct, V9GenericFsState,
that contains a pointer to xen-specific data, and a pointer to a complete
function, that can replace complete_pdu.  There are other function pointers that
I commented out, because they turned out not to be necessary.

v9pfs_server.h also defines GENERIC_9P_SERVER.  In virtio-9p.h, if
GENERIC_9P_SERVER is defined, complete_pdu is defined to translate
to the complete function in V9GenericFsState; if GENERIC_9P_SERVER  is not
defined, complete_pdu is simply declared.  This is the only ifdef I added.

I wrote a new file xen-9p.c that contains a complete_pdu function,
xen_complete_pdu, xen_pdu_handle, and set_fd_limit.  pdu's are the data
structures that are passed among all the functions that handle file requests.
They contain the meta-data necessary to process, and keep track of the request.

xen_pdu_handle takes a requests and creates a pdu for the existing functions to
handle the request.

xen_complete_pdu takes a completed request, frees memory and calls
p9_send_response in xen_9pif.c to handle the response.

The rest of xen_9pif.c contains the code that interacts directly with the xenbus
and indirectly with the front-end.  Much of it was modeled after xen_disk.c, and
tested when I was just passing small amounts of data back and forth.

The backend also contains files in qemu/fsdev that set up the QemuOptsList
tables and massage the data.  I added qemu-xen-fsdev-opts.c, that was patterned
after qemu-fsdev-opts.c.  I also modified qemu-fsdev.c to add debugging
statements.

I modified vl.c and qemu-options.def, in the qemu directory to match what
was done for virtio.  Some of this works, but not all of it.

I also modified xen_backend.h and xen_pv_machine.c to recognize this new
backend.  This code works.

I mentioned I modified the Makefiles, in qemu/hw/9pfs, qemu/fsdev, in qemu/hw,
and in qemu, inappropriately.  I did not learn until the end of my internship
exactly how to manipulate the configure files.  Therefore, I removed or changed
configuration dependencies, rather than change the makefiles.  This should be
fixed.

Some FIXME statements that I put in to remind myself what I needed to do,
actually got done, but I didn't remove the comment.

III.  How to Build My Project

My code now resides only on my github:  lindajac.
The front-end code is in lindajac/lindap9/p9/p9front.

To build it, assemble the front end files (p9_front.c p9_front_driver.c
trans_xen9p.c and p9.h) in a directory with the Makefile.  Copy from
linux/net/9p, the header file trans_common.h, to this directory.
This obviously has to change, when the front end has a permanent home directory.

Type make.  This will give you the front-end module.

My backend resides under the github: lindajac/qemu on the branch mychanges.

Because so much time has passed since my internship, it would have been more
work than I was willing to do for free, for me to sync my project with the
current qemu.   Therefore, this needs to be done.  The files that need to be
merged manually are qemu/vl.c and qemu/hw/9pfs/virtio-9p.c.  Given this caveat,
if you checkout this branch, it will build, and create a usable qemu.

IV.  How to 'Use' My Project

Here are the steps I follow.  These steps have to be followed to test or to run
the Xen 9p system.

1.  Create and pause a guest ( -p option ).
2.  Run xenstore-ls and edit the file to see what the domain number of the guest
is.
3.  Change the xenstore entries per the statements in the shell script
lindap9/p9/p9front/p9xsupdate.sh.  The parameter to this script is the
domain number of the guest.
4.  Start qemu.  The qemu line I have been using (in a shell script) is
<your path to qemu-system-i386> -xen-domid $1 -chardev socket,\
id=libxl-cmd,path=/var/run/xen/qmp-libxl-$1,server,nowait -no-shutdown\
-mon chardev=libxl-cmd,mode=control -chardev socket,id=libxenstat-cmd,\
path=/var/run/xen/qmp-libxenstat-$1,server,nowait -mon chardev=libxenstat-cmd,\
mode=control -nodefaults -xen-attach -name testg -vnc 127.0.0.1:0,to=99
-display none -machine xenpv -m 2048\
-xen9pfs local,security_model=passthrough,id=fsdev0,path=/mnt,mount_tag=P9Mount

where the last line is specific to 9p; all the rest is copied from the qemu
parameters I captured using a shell script, early in this project.  $1 is the
guest domain.
5.  Unpause the guest.
6.  xl console <guest>
7.  enter password.
8.  scp the .ko of the front end to the guest
9.  To run the front-end you need to modprobe my .ko, as well as the kernel 
modules
linux/net/9p and linux/fs/9p, but they do not need to be built specially, for
things to work.

That's it.



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

Reply via email to