RE: proposal for generic interface to /proc text files

Keith Owens (kaos@audio.apana.org.au)
Tue, 1 Oct 1996 09:58:20 +1000 (EST)


On Mon, 30 Sep 1996, Rob Riggs wrote:
> On 01-Oct-96 Keith Owens wrote:
> >I would like to see a clean break to tagged text for *all* proc files. [snip]
>
> How often do common /proc entries change? Very infrequently. This
> is overkill for a rare problem. [snip]
>
> Would a /proc/procversion file work for you? [snip]

Yes, that is an alternative. However even introducing this would
require changes to all user applications before we could start changing
the /proc entries compatibly. The downside of version information is
that it tells you that something has changed but applications can still
fail, with some form of tags you get a warning and the user code still
works. If we have to change the user code to handle versions we can
change them to do anything, including tagged text.

> >The other problem that needs to be addressed in /proc is handling output of
> >more than 4K. The only indication the procinfo routine gets is the "offset"
> >into the generated output, the procinfo code is expected to somehow
> >reposition itself and pick up where it left off. Since the underlying tables
> >are continually changing, this suffers from race conditions. Some of the
> >work arounds are not very nice.
>
> I will be looking into this. Which /proc entries have this problem?

Almost anything that could generate more than 4K of data, net routines
in particular. Some of the net routines pad their records to fixed
lengths just to help resynchronise on the second and subsequent call
from the procinfo driver.

> Currently, the way *most* of the /proc routines work is to pass a
> pointer to a 4K buffer and **char to the service routine. The general
> assumption is that if the 4K page ain't big enough, the service routine
> will kmalloc a big enough area and pass the pointer back through in the
> **char variable.

Would be nice if the code did work that way, but it does not seem to.
fs/proc/array.c array_read initialises start to NULL and checks it
afterwards, if not null it copies the data to user. fs/proc/net.c never
initialises start, it expects the called routine to *always* set start
to point into the (single) assigned page, the net routines are called
repeatedly until they return a length of 0, some "nice" race conditions.

In both cases it is not clear where (if anywhere) the storage could be
freed. Who keeps track of how big the new area is so it can be freed
correctly? That's why I suggested the driver routine be responsible for
getting the storage and freeing it. Allocation in one routine and
freeing in another is often a recipe for memory leaks.

Many if not all of the procinfo generating routines are complicated by
the need to test the initial offset to see if they should print a
heading first and if they need to resync. Some also have to test for
end of page and return partial data. It would be far simpler to use a
method that called the underlying routine *once*, no offsets, simpler
code in the underlying routines, less race conditions.