在启动过程的什么时候可以使用管道
At what point of the boot process is it ok to use pipes
我有一个使用 Linux 的 RTAI 扩展构建的系统。它有一个 运行 在启动时以 root 身份运行的进程。它创建了一些命名管道和 chmod 777 它们。管道由 root 拥有并具有 prwxrwxrwx 权限,但 none 的用户进程可以写入或读取它们。管道是这样制作的(在 C 中)
unlink(pipename);
mkfifo(pipename, 0777);
chmod(pipename, 0777);
如果我以用户身份登录,su 到 root,终止进程并重新启动它,从 root 退出,命名管道仍然由 root 拥有并具有 prwxrwxrwx 权限,但这次,用户进程可以读取并从他们那里写信。
问题:如果程序 运行 作为启动过程的一部分,我还需要做什么才能访问命名管道。
此外,我如何确保它是在所有通信机制设置完成后执行的最后一个进程。
编辑
我更改了标题(旧标题是为启动进程设置管道权限)
我终于通过将流程转移到 rc.local 使其正常工作。由于编码员使用的是 RTAI,他认为该进程必须与所有其他 RTAI 进程同时启动。其他进程不使用任何 Unix 通信机制,因此无关紧要。当他开始使用管道时,它不得不被转移到多用户级别的末尾。
这是我找不到解释的部分:在启动过程中的什么时候可以使用管道?我已经把它移到了最后,但它可能更早。
问题
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.
进程是否挂起 open()
取决于打开模式(O_RDONLY
、O_WRONLY
、O_RDWR
)。
没有O_NONBLOCK
:
- with
O_RDONLY
, open()
将阻塞,直到打开 fifo 以从任何进程写入;
- with
O_WRONLY
, open()
将阻塞直到打开 fifo 以读取任何进程;
- 与
O_RDWR
、open()
将立即return。
与O_NONBLOCK
:
- 与
O_RDONLY
、open()
将立即return;
- with
O_WRONLY
, open()
将 return 如果未打开 fifo 以从任何进程读取错误;
- 与
O_RDWR
、open()
将立即return。
详见open(3)
(O_NONBLOCK
section) and fifo(7)
。
如果您的 open()
挂起,则表明:
- 您正在使用
O_RDONLY
或 O_WRONLY
而没有 O_NONBLOCK
;
- fifo 未在任何其他进程中打开以进行写入或读取。
解决方案
如果您预计 fifo 已从另一个进程打开,请检查为什么没有打开。可能应该保持打开状态的进程已死,或者您以错误的顺序启动进程,或者存在竞争条件。
否则,您可以执行以下操作之一:
使用O_RDWR
开启方式,open()
会立即return。
但是,请注意,从 fifo 读取时(因为您一直打开读取端)或写入 fifo 时永远不会得到 EOF
(因为您一直在写入)结束打开)。
使用O_RDONLY | O_NONBLOCK
,open()
会立即return。
请注意,如果未打开 fifo 以从任何进程读取,read()
将 return EOF
。
稍后打开fifo,当另一个进程已经打开fifo的另一端时。
终于追根究底了
- 我添加了延迟,但没有任何区别。
- 然后我发现虽然我mkfifo是666,但是权限还是644。由于FIFO是root所有的,其他进程不能写入。结果我在mkfifo后面加了一个chmod。这使得 FIFO 可写。
- 写作问题已解决,但作者仍然没有return公开。
- 这是一个特定于 SuSE 的问题。该过程于 boot.local 开始,为时过早。在其他系统上,它可以在 rc.local 上启动,但在 SuSE 上,它必须在 after.local 上启动。将程序移动到 after.local,一切都神奇地开始工作。
简而言之,修复是
- 创建 FIFO 后的 chmod
- 在 SuSE
上将可执行文件移动到 after.local
对于 Ubuntu、Centos 和 Debian,我的问题的答案放在 rc.local 中,对于 SuSE,放在 after.local 中。
我有一个使用 Linux 的 RTAI 扩展构建的系统。它有一个 运行 在启动时以 root 身份运行的进程。它创建了一些命名管道和 chmod 777 它们。管道由 root 拥有并具有 prwxrwxrwx 权限,但 none 的用户进程可以写入或读取它们。管道是这样制作的(在 C 中)
unlink(pipename);
mkfifo(pipename, 0777);
chmod(pipename, 0777);
如果我以用户身份登录,su 到 root,终止进程并重新启动它,从 root 退出,命名管道仍然由 root 拥有并具有 prwxrwxrwx 权限,但这次,用户进程可以读取并从他们那里写信。
问题:如果程序 运行 作为启动过程的一部分,我还需要做什么才能访问命名管道。
此外,我如何确保它是在所有通信机制设置完成后执行的最后一个进程。
编辑
我更改了标题(旧标题是为启动进程设置管道权限)
我终于通过将流程转移到 rc.local 使其正常工作。由于编码员使用的是 RTAI,他认为该进程必须与所有其他 RTAI 进程同时启动。其他进程不使用任何 Unix 通信机制,因此无关紧要。当他开始使用管道时,它不得不被转移到多用户级别的末尾。
这是我找不到解释的部分:在启动过程中的什么时候可以使用管道?我已经把它移到了最后,但它可能更早。
问题
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.
进程是否挂起 open()
取决于打开模式(O_RDONLY
、O_WRONLY
、O_RDWR
)。
没有
O_NONBLOCK
:- with
O_RDONLY
,open()
将阻塞,直到打开 fifo 以从任何进程写入; - with
O_WRONLY
,open()
将阻塞直到打开 fifo 以读取任何进程; - 与
O_RDWR
、open()
将立即return。
- with
与
O_NONBLOCK
:- 与
O_RDONLY
、open()
将立即return; - with
O_WRONLY
,open()
将 return 如果未打开 fifo 以从任何进程读取错误; - 与
O_RDWR
、open()
将立即return。
- 与
详见open(3)
(O_NONBLOCK
section) and fifo(7)
。
如果您的 open()
挂起,则表明:
- 您正在使用
O_RDONLY
或O_WRONLY
而没有O_NONBLOCK
; - fifo 未在任何其他进程中打开以进行写入或读取。
解决方案
如果您预计 fifo 已从另一个进程打开,请检查为什么没有打开。可能应该保持打开状态的进程已死,或者您以错误的顺序启动进程,或者存在竞争条件。
否则,您可以执行以下操作之一:
使用
O_RDWR
开启方式,open()
会立即return。但是,请注意,从 fifo 读取时(因为您一直打开读取端)或写入 fifo 时永远不会得到
EOF
(因为您一直在写入)结束打开)。使用
O_RDONLY | O_NONBLOCK
,open()
会立即return。请注意,如果未打开 fifo 以从任何进程读取,
read()
将 returnEOF
。稍后打开fifo,当另一个进程已经打开fifo的另一端时。
终于追根究底了
- 我添加了延迟,但没有任何区别。
- 然后我发现虽然我mkfifo是666,但是权限还是644。由于FIFO是root所有的,其他进程不能写入。结果我在mkfifo后面加了一个chmod。这使得 FIFO 可写。
- 写作问题已解决,但作者仍然没有return公开。
- 这是一个特定于 SuSE 的问题。该过程于 boot.local 开始,为时过早。在其他系统上,它可以在 rc.local 上启动,但在 SuSE 上,它必须在 after.local 上启动。将程序移动到 after.local,一切都神奇地开始工作。
简而言之,修复是
- 创建 FIFO 后的 chmod
- 在 SuSE 上将可执行文件移动到 after.local
对于 Ubuntu、Centos 和 Debian,我的问题的答案放在 rc.local 中,对于 SuSE,放在 after.local 中。