2004-06-14 18:09:36

by Steve French (smfltc)

[permalink] [raw]
Subject: upcalls from kernel code to user space daemons

Is there a good terse example of an upcall from a kernel module (such as
filesystem) to an optional user space helper daemon? The NFS RPC
example seems more complicated than what I would like as does the
captive ioctl approach which I see in a few places.

I simply need to poke a userspace daemon (e.g. launched by mount) to do
in userspace these two optional functions which are not available in
kernel and pass a small (under 64K) amount of data back to the kernel
module:
1) getHostByName: when the kernel cifs code detects a server crashes
and fails reconnecting the socket and the kernel code wants to see if
the hostname now has a new ip address.
2) package a kerberos ticket ala RFC2478 (SPNEGO)

And an only very loosely related question -
The proc interface for returning debug information or stats is somewhat
awkward to use for returned data greater than about 1K - I had trouble
finding a good example of kernel code using /proc to return debug data
larger than that since it involves repeated calls into the pseudofile's
proc read function with careful setting of some offset/lengths which can
be hard when iterating through dynamically generated variable length
debug information. Is there a good example of that?




2004-06-14 18:31:58

by Chris Friesen

[permalink] [raw]
Subject: Re: upcalls from kernel code to user space daemons

Steve French wrote:
> Is there a good terse example of an upcall from a kernel module (such as
> filesystem) to an optional user space helper daemon? The NFS RPC
> example seems more complicated than what I would like as does the
> captive ioctl approach which I see in a few places.
>
> I simply need to poke a userspace daemon (e.g. launched by mount) to do
> in userspace these two optional functions which are not available in
> kernel and pass a small (under 64K) amount of data back to the kernel
> module:
> 1) getHostByName: when the kernel cifs code detects a server crashes
> and fails reconnecting the socket and the kernel code wants to see if
> the hostname now has a new ip address.
> 2) package a kerberos ticket ala RFC2478 (SPNEGO)

One way to do it (or is this what you meant by captive ioctl?)

userspace daemon loops on ioctl()
kernel portion of ioctl call goes to sleep until something to do
when needed, fill in data and return to userspace
userspace does stuff, then passes data back down via ioctl()
ioctl() puts userspace back to sleep and continues on with other work

Chris

2004-06-14 21:41:18

by Oliver Neukum

[permalink] [raw]
Subject: Re: upcalls from kernel code to user space daemons

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


> > 1) getHostByName: when the kernel cifs code detects a server crashes
> > and fails reconnecting the socket and the kernel code wants to see if
> > the hostname now has a new ip address.

Is that possible at all? It looks like that might deadlock in the page
out code path.

> > 2) package a kerberos ticket ala RFC2478 (SPNEGO)
>
> One way to do it (or is this what you meant by captive ioctl?)
>
> userspace daemon loops on ioctl()
> kernel portion of ioctl call goes to sleep until something to do
> when needed, fill in data and return to userspace
> userspace does stuff, then passes data back down via ioctl()
> ioctl() puts userspace back to sleep and continues on with other work

You could just as well implement an ordinary read()

Regards
Oliver
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFAzhtxbuJ1a+1Sn8oRAvupAJ0T6K8PMeKwWanDTHUmeYtpmsPnKQCeLZbk
cZC0HjRPQSN3Xmkp1tSKFIA=
=tZMS
-----END PGP SIGNATURE-----

2004-06-14 21:57:30

by Chris Friesen

[permalink] [raw]
Subject: Re: upcalls from kernel code to user space daemons

Oliver Neukum wrote:

> > userspace daemon loops on ioctl()
> > kernel portion of ioctl call goes to sleep until something to do
> > when needed, fill in data and return to userspace
> > userspace does stuff, then passes data back down via ioctl()
> > ioctl() puts userspace back to sleep and continues on with other work
>
> You could just as well implement an ordinary read()

Not quite. The userspace is passing data down as well. I don't know how you'd
do that with read().

Chris

2004-06-14 22:09:00

by Bernd Petrovitsch

[permalink] [raw]
Subject: Re: upcalls from kernel code to user space daemons

On Mon, 2004-06-14 at 23:57, Chris Friesen wrote:
> Oliver Neukum wrote:
>
> > > userspace daemon loops on ioctl()
> > > kernel portion of ioctl call goes to sleep until something to do
> > > when needed, fill in data and return to userspace
> > > userspace does stuff, then passes data back down via ioctl()
> > > ioctl() puts userspace back to sleep and continues on with other work
> >
> > You could just as well implement an ordinary read()
>
> Not quite. The userspace is passing data down as well. I don't know how you'd
> do that with read().

For this you use write().

Bernd
--
Firmix Software GmbH http://www.firmix.at/
mobil: +43 664 4416156 fax: +43 1 7890849-55
Embedded Linux Development and Services


2004-06-14 22:23:36

by Chris Friesen

[permalink] [raw]
Subject: Re: upcalls from kernel code to user space daemons

Bernd Petrovitsch wrote:
> On Mon, 2004-06-14 at 23:57, Chris Friesen wrote:
> > Oliver Neukum wrote:
> >
> > > > userspace daemon loops on ioctl()
> > > > kernel portion of ioctl call goes to sleep until something to do
> > > > when needed, fill in data and return to userspace
> > > > userspace does stuff, then passes data back down via ioctl()
> > > > ioctl() puts userspace back to sleep and continues on with other
> work
> > >
> > > You could just as well implement an ordinary read()
> >
> > Not quite. The userspace is passing data down as well. I don't know
> how you'd
> > do that with read().
>
> For this you use write().

And you eat another syscall per userspace call. For the ioctl() case, you only
need to issue a single call to ioctl(). You pass the result of the previous
request down, and then when it returns you get the data for the next request.

Although I have to admit it's not pretty, and the performance improvements may
not be worth the obfuscation of the code.

Chris

2004-06-14 22:56:42

by Steve French (smfltc)

[permalink] [raw]
Subject: Re: upcalls from kernel code to user space daemons

On Mon, 2004-06-14 at 16:40, Oliver Neukum wrote:
> > > 1) getHostByName: when the kernel cifs code detects a server crashes
> > > and fails reconnecting the socket and the kernel code wants to see if
> > > the hostname now has a new ip address.
>
> Is that possible at all? It looks like that might deadlock in the page
> out code path.
>

Yes - since an upcall (indirectly) to a different process while in write
could cause writepage to write out memory to a mount - which could hang
if on an already dead tcp session, this (reconnection - failover to new
ip address if the server ip address changes after failure) may be too
risky to do in the context of writepage, but there may be a way to keep
refusing to do writepage while in the midst of this harder form of mount
reconnection - which isn't likely to be any worse than not
reconnecting. Fortunately, most tcp reconnection cases are much
simpler.


2004-06-14 22:59:06

by Tim Hockin

[permalink] [raw]
Subject: Re: upcalls from kernel code to user space daemons

On Mon, Jun 14, 2004 at 06:22:48PM -0400, Chris Friesen wrote:
> > > Not quite. The userspace is passing data down as well. I don't know
> >how you'd
> > > do that with read().
> >
> >For this you use write().

> Although I have to admit it's not pretty, and the performance improvements
> may not be worth the obfuscation of the code.

You know, I've never understood why people hate ioctl. Sometimes, it
really is what you want. Why impose structured data onto a 2-way
unstructred system (read/write) when you have a structured system at hand
(ioctl).

I like ioctl() when it makes sense. read() and write() are for data.
ioctl is for (tada!) control.

2004-06-14 23:14:20

by Randy.Dunlap

[permalink] [raw]
Subject: Re: upcalls from kernel code to user space daemons

On Mon, 14 Jun 2004 15:54:38 -0700 Tim Hockin wrote:

| On Mon, Jun 14, 2004 at 06:22:48PM -0400, Chris Friesen wrote:
| > > > Not quite. The userspace is passing data down as well. I don't know
| > >how you'd
| > > > do that with read().
| > >
| > >For this you use write().
|
| > Although I have to admit it's not pretty, and the performance improvements
| > may not be worth the obfuscation of the code.
|
| You know, I've never understood why people hate ioctl. Sometimes, it
| really is what you want. Why impose structured data onto a 2-way
| unstructred system (read/write) when you have a structured system at hand
| (ioctl).
|
| I like ioctl() when it makes sense. read() and write() are for data.
| ioctl is for (tada!) control.
^^^^
Looks like data in nuxi format.

Anyway, I agree with you.

--
~Randy

2004-06-15 09:06:45

by Oliver Neukum

[permalink] [raw]
Subject: Re: upcalls from kernel code to user space daemons

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Am Dienstag, 15. Juni 2004 00:54 schrieb Steve French:
> On Mon, 2004-06-14 at 16:40, Oliver Neukum wrote:
> > > > 1) getHostByName: when the kernel cifs code detects a server crashes
> > > > and fails reconnecting the socket and the kernel code wants to see if
> > > > the hostname now has a new ip address.
> >
> > Is that possible at all? It looks like that might deadlock in the page
> > out code path.
> >
>
> Yes - since an upcall (indirectly) to a different process while in write
> could cause writepage to write out memory to a mount - which could hang
> if on an already dead tcp session, this (reconnection - failover to new
> ip address if the server ip address changes after failure) may be too
> risky to do in the context of writepage, but there may be a way to keep
> refusing to do writepage while in the midst of this harder form of mount
> reconnection - which isn't likely to be any worse than not
> reconnecting. Fortunately, most tcp reconnection cases are much
> simpler.

Well, unless you want to mlock() all libraries connected with name
resolution or code dns in kernel, you'll have to either fail the io, which
is bad, or use a fallback that is local. I suggest that you write the block
in question to a local disk (swap space?) and fire of a user space helper
asynchronously. That helper then could reestablish the connection.

Regards
Oliver
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFAzrwUbuJ1a+1Sn8oRAv2kAJ444nIrog/fnOPqlxTCAjAnaHtDUQCePe15
cGBjATSxNNRhCHGplhV703o=
=kjJe
-----END PGP SIGNATURE-----

2004-06-18 23:22:59

by H. Peter Anvin

[permalink] [raw]
Subject: Re: upcalls from kernel code to user space daemons

Followup to: <[email protected]>
By author: Steve French <[email protected]>
In newsgroup: linux.dev.kernel
>
> Is there a good terse example of an upcall from a kernel module (such as
> filesystem) to an optional user space helper daemon? The NFS RPC
> example seems more complicated than what I would like as does the
> captive ioctl approach which I see in a few places.
>

autofs does this by having the kernel write to the write-end of a
pipe, and have the userspace daemon read from the read end of the same
pipe.

The same thing can be done with sockets.

-hpa