75 lines
2.3 KiB
Text
75 lines
2.3 KiB
Text
|
--------------------------------------------------------------------------------
|
||
|
Thoughts about different UNIX-IPC, Nico Schottelius 2005-04-28
|
||
|
--------------------------------------------------------------------------------
|
||
|
|
||
|
Howto cinit communicates with
|
||
|
a) cinit-forks
|
||
|
b) any other program
|
||
|
|
||
|
a) cinit-forks
|
||
|
|
||
|
a.1) shared memory
|
||
|
|
||
|
Access could generally be done with shared memory. The problem with
|
||
|
that is, that -lrt is required, which implicits -lpthread, which
|
||
|
makes linking staticly problematic (at least for glibc).
|
||
|
|
||
|
a.2) pipes
|
||
|
|
||
|
A maximum of ~510 pipes could be used ( (1024-3)/2),
|
||
|
1024=max fds, -3=already opened (stderr/stdin/stdout), /2=
|
||
|
two fds needed per clients).
|
||
|
|
||
|
Pipes cannot be use easily through forks of forks.
|
||
|
|
||
|
a.3) fifos
|
||
|
|
||
|
FIFOs are easy to use, but you would need to create two FIFOs
|
||
|
for _every_ service, as with only two FIFOs we cannot reliable
|
||
|
detect, _who_ is writting to us currently and who wants to read.
|
||
|
|
||
|
a.4) system-v-ipc
|
||
|
|
||
|
No documentation found nor tested.
|
||
|
|
||
|
a.5) sockets
|
||
|
|
||
|
Are indeed a very clean way. There's only one problem:
|
||
|
bind() fails on read-only mounted devices:
|
||
|
|
||
|
- The socket either does not exists and cannot be created
|
||
|
- or the socket exists, but bind() refuses to reuse it
|
||
|
(error: Address already in use)
|
||
|
|
||
|
Imho bind() should even honour the socket-option SO_REUSEADDR,
|
||
|
which allows to re-use a socket, if there's no other program bound to.
|
||
|
|
||
|
As far as I can see, SO_REUSEADDR is only honoured, if socket is of
|
||
|
type PF_INET (we use PF_UNIX) and POSIX does only specify how to
|
||
|
check for support, but not that sockets have to be able to use
|
||
|
SO_REUSEADDR.
|
||
|
|
||
|
That way, we are forced to mount a temporary filesystem on
|
||
|
/etc/cinit/tmp and create the socket below this directory. This is not
|
||
|
the clean and easy solution one would wish. Still, sockets
|
||
|
seem to be the cleanest and most reliable way to have IPC for
|
||
|
this situation.
|
||
|
|
||
|
See socket(2), bind(2), listen(2), accept(2), socket(7) and unix(7)
|
||
|
for help.
|
||
|
|
||
|
b) any other program
|
||
|
|
||
|
What you can do is to tell cinit to
|
||
|
- reboot,
|
||
|
- halt and
|
||
|
- poweroff.
|
||
|
|
||
|
Simple send cinit a signal, what todo:
|
||
|
SIGUSR1: reboot
|
||
|
SIGUSR2: poweroff
|
||
|
TERM: halt
|
||
|
|
||
|
See signal(2) and signal(7) for help and serv/sig_reboot.c for implementation.
|
||
|
--------------------------------------------------------------------------------
|