Reputation: 8289
I have a system built using the RTAI extension to Linux. It has a process that runs as root on startup. It creates some named pipes and chmod 777 them. The pipes are owned by root and have the permissions prwxrwxrwx but none of the user processes can write to or read from them. The pipes are made (in C) like this
unlink(pipename);
mkfifo(pipename, 0777);
chmod(pipename, 0777);
If I login as the user, su to root, kill the process and restart it, come out of root, the named pipes are still owned by root and have the permissions prwxrwxrwx but this time, the user processes can read and write from them.
Question: what else do I need to do so that the named pipes are accessible if the program is run as part of the boot process.
Also, how do I make sure that it is the very last process that is executed after all the comms mechanisms have been set up.
Edit
I've changed the title (old one was Setting pipe permissions for boot process)
I have finally got it working by shifting the process into rc.local. Since the coder was using RTAI, he thought that the process had to be started at the same time as all the other RTAI processes. The other processes didn't use any of the Unix comms mechanisms so it didn't matter. When he started using pipes, it had to be shifted to the end of the multiuser level.
This is the part I cannot find an explanation for: at what point in the boot process would it be OK to use pipes? I have shifted it to the end but it could be earlier.
Upvotes: 0
Views: 300
Reputation: 8289
Finally got to the bottom of the problem.
In short, the fix was
The answer to my question is put it in rc.local for Ubuntu, Centos and Debian, after.local for SuSE.
Upvotes: 0
Reputation: 4893
Took a while to figure out how to find out what state the process was in. All the programs just block on open. I could try O_NONBLOCK but I don't know how well that will work. I also hate polling.
Whether a process hangs on open()
depends on opening mode (O_RDONLY
, O_WRONLY
, O_RDWR
).
Without O_NONBLOCK
:
O_RDONLY
, open()
will block until fifo is opened for writing from any process;O_WRONLY
, open()
will block until fifo is opened for reading any process;O_RDWR
, open()
will return immediately.With O_NONBLOCK
:
O_RDONLY
, open()
will return immediately;O_WRONLY
, open()
will return error if fifo is not opened for reading from any process;O_RDWR
, open()
will return immediately.See details in open(3)
(O_NONBLOCK
section) and fifo(7)
.
If your open()
hangs, it indicates that:
O_RDONLY
or O_WRONLY
without O_NONBLOCK
;If you expected fifo to be already opened from another process, check why it's not. Probably a process that should keep it opened died, or you're starting processes in the wrong order, or there is a race condition.
Otherwise, you can do one of the following:
Use O_RDWR
opening mode, and open()
will return immediately.
However, note that you'll never get EOF
when reading from fifo (because you're keeping reading end opened) or SIGPIPE
when writing to fifo (because you're keeping writing end opened).
Use O_RDONLY | O_NONBLOCK
, and open()
will return immediately.
Note that read()
will return EOF
if fifo is not opened for reading from any process.
Open fifo later, when another process has already opened other end of fifo.
Upvotes: 0