We've been doing some thinking about a more general way to enable access to
CP system services from Linux, and I'd like to get some opinions on one
approach we've considered.

One of the useful ideas in Plan 9 (the OS that the Bell Labs people started
working on when they got bored with Unix) is the idea of representing
*everything* as a filesystem-like structure (much along the lines of the way
/proc is done) -- network connections, serial ports, etc.  Configuration is
done by writing text strings to specially named files, which cause changes
to be made, and data is returned via pseudofiles.

There's a excellent paper available from
http://www.cs.bell-labs.com/sys/doc/net/net.pdf on how Plan 9 represents
network connections that explains this better -- check out pages 3 and 4 for
the most interesting part of the discussion.


Here's the idea for DIAGnoses:

IMHO, there's 4 steps to this:

- create a Linux-referencable connection to reserve workspace and set up the
call to the DIAGnose
- supplying requests to the DIAGnose
- getting the data back from the DIAGnose
- destroying the Linux-referencable connection to the service when you're
done with it.


1) Creating a connection to a DIAGnose:

The idea we had was to create a similar structure for IUCV and DIAG
functions (provisionally /cp/iucv and /cp/diag).  Each of these would have a
clone "file" (example /cp/iucv/clone). Opening the clone pseudofile and
reading from it would create a new kernel connection buffer (in the case of
IUCV) or buffer for the DIAG, create a new pseudofile directory entry and
some special files within the directory pointing to the new entry, and
return a "connection number" to the reading process indicating where in the
/cp/iucv or /cp/diag tree to go next, eg:

program opens /cp/diag/clone using fopen() and issues fread on the file
pointer returned by fopen().  Kernel creates buffer for DIAG, looks through
it's tables and determines that the next free pseudofile # is 2, creates
/cp/diag/2 , /cp/diag/2/ctl and /cp/diag/2/data, and returns "2" to the
fread call.  program then knows that it can interact with the CP service via
the pseudofiles in /cp/diag/2.

2) Supplying requests to the CP service

As part of the connection creation, we created two pseudofiles: ctl and
data.  The ctl pseudofile supplies information to the service. In the
example above, let's say we want to do a DIAG 8 and execute CP QUERY USERID.
We could then open /cp/diag/2/ctl, write  "8,CP QUERY USERID" and close
/cp/diag/2/ctl using normal file I/O calls.  The act of writing to the ctl
pseudofile causes the DIAG 8 to be executed, and the error code returned on
the write can indicate success or failure. closing the ctl file causes the
output to be transferred to the data buffer for the pseudodevice.

Note that the driver for /cp/diag/2/ctl could potentially also do
authentication inside the kernel, thus allowing ACL control over what DIAGs
can be executed from what Linux users.

3) getting the data back from the CP service

To get the data back, we read from /cp/diag/2/data until EOF.
fstat(/cp/diag/2/data) would return the amount of data in the buffer. Since
the close of the /cp/diag/2/ctl file establishes the buffer as stable, you
can read the /cp/diag/2/data file as many times as you want (until you do a
new write to /cp/diag/2/ctl, which clears the buffer and places the new
output as the stable value).

4) destroying the Linux reference to the DIAGnose:

To terminate the connection and free the kernel buffer, write "TERMINATE" to
/cp/diag/2/ctl.  The psuedofile entries are deleted, the connection number
is marked as available, and the kernel buffer is released.

/cp/iucv can be handled in a similar manner (more complex psuedofile
structure to allow more control, but the same idea).

My questions to the list are:

a) does this sound like a usable paradigm?
b) is it worth implementing?
c) what am I missing?

I haven't started implementing yet, but I'd like to get as many reactions as
possible. Discuss...8-)



-- db

David Boyes
Sine Nomine Associates

Reply via email to