Re: [9fans] Why do we need syspipe() ?



On Jan 4, 2009, at 10:20 PM, Russ Cox wrote:
I don't believe you can write a race-free implementation of
the pipe system call using #|.

Could you, please, elaborate on what particular race do you have
in mind? Indeed, I ran into a problem with devpipe implementation,
but it isn't a race, its a dreaded implicit ->attach that namec()
does when it evaluates names with the first character being #.

The closest you can come in user space to implementing pipe is:

int
pipe(int *fd)
{
bind("#|", "/mnt", MREPL);
fd[0] = open("/mnt/data", ORDWR);
fd[1] = open("/mnt/data1", ORDWR);
unmount("/mnt");
return 0;
}

but if there are multiple processes running pipe()
in the same name space, the binds will step
on each other and the pipes might get crossed.
Even if not, maybe something else was already
mounted on /mnt (or whatever mount point you
choose), and now there's nothing there.

Well, strictly speaking, there's another possibility:

int
pipe(int *fd)
{
chdir("#|");
fd[0] = open("data", ORDWR);
fd[1] = open("data1", ORDWR);
return 0;
}

which avoids a race, but trashes your current directory.

On related note: it is a bit sad, though, that I can't stash
a channel to the current directory away in a file
descriptor and use it instead of a symbolic name
in a call similar to chdir. I can amost do it:
int stash_cwd = open(".", ORDWR);
but not quite :-(


There are some devices in Plan 9 that simply don't "virtualize",
because at a deep level they are tied to process state that
doesn't go through the file system.

Agreed. I think it would be fair to call them drivers for the
kernel services. As opposed to drivers for physical devices.

Dup manipulates the file descriptor table, not files themselves.
Pipe accesses files that have no name in the file system.

I have always thought of pipes as in-kernel buffers. That's
a service the kernel provides. #| is just a driver for that service.

For example, suppose a process wants to know . If getpid read
from /dev/pid
instead of #c/pid, then running "iostats rc -c 'echo $pid'"
would show iostats's pid, not rc's. What then if rc wants to send
itself (or, more likely, its note group) a note, or fiddle with
one of its /proc files? It would be manipulating iostats, not
itself.

This is a very good point. Thank you for bringing it up. I now
see how being able to *always* go directly to the #c/pid
makes things easier implementation-wise. And may be
it is a good-enough justification for #X. But before I agree
100% and shut up ;-) here's one though: isn't the
situation here, to quote Charles, rather simple: you asked
for fish; you get fish? If iostats tries to interpose on everything
in the filesystem -- well, may be that should be *everything*.
Not ifs or buts. And yes it would mean the weird behaviour
of rc you've alluded to. Because it *is* everything.

A write to devsrv is even more magical: when you write "23"
to #s/newfile, your process's fd 23 gets taken over by the
kernel. For this reason you can't use iostats on any program
that writes to /srv/newfile instead of #s/newfile--when the program
writes "23", the kernel sees the request come from iostats
instead of the original program, and it takes over the wrong fd.
(Most of those programs are 9P servers that fork into the
background, and iostats isn't too useful on those anyway,
so no one has bothered to address this.)

Right. But its not that the problem is insurmountable. Its just that,
literally, nobody bothered to complicate the implementation
of iostats.


The # device syntax is very useful to mean the kernel device
and none other in these situations. There's definitely
something unsatisfactory about it, but it works.


Once again -- thanks a million for a very clear post. It is now
obvious that #X has more, how shall I put it, capabilities
than a pure namespace-based approach. It really wasn't
obvious to me before.

Thanks,
Roman.

.



Relevant Pages

  • Re: [9fans] Why do we need syspipe() ?
    ... Indeed, I ran into a problem with devpipe implementation, ... The closest you can come in user space to implementing pipe is: ... feature rich than dup. ... For this reason you can't use iostats on any program ...
    (comp.os.plan9)
  • problem with linux 2.6.11 and sa
    ... I recall a problem a while back with a pipe from ... kernel and my spamassassin setup. ... sent on to my local MDA. ... To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ ...
    (Linux-Kernel)
  • problem with linux 2.6.11 and sa
    ... I recall a problem a while back with a pipe from ... /proc/kmsg that was sent by root to a program with a ... The fix was to run the logging program as ... kernel and my spamassassin setup. ...
    (Linux-Kernel)
  • Re: create named pipe in kernel driver?
    ... Though I can give you example how to open pipes within kernel mode, but it won't help you with remoting. ... In kernel pipe name has different ... my driver on a remote machine aswell, without any extra code for sending it over the network. ... create a named pipe from a kernel driver? ...
    (microsoft.public.win32.programmer.kernel)
  • Re: [patch 00/11] ANNOUNCE: "Syslets", generic asynchronous system call support
    ... the same thread is allowed to continue execution even if the system call ... the kernel switches the user-space ... returns to user-space as if nothing happened - allowing the user-space ... context to 'fill the pipe' as much as it can. ...
    (Linux-Kernel)