【发布时间】:2019-11-18 11:21:30
【问题描述】:
我正在开发小型 Raspberry PI 集群,我的主机程序创建 IP 数据包片段并将它们发送到多个中继程序。中继接收这些数据包片段并使用原始套接字将它们转发到目的地。由于原始套接字,我的中继程序必须在 sudo 权限下运行。我的设置涉及 RPi 3 B v2 和 RPi 2 B v1。 SSH 已经设置好了,节点可以在没有密码的情况下通过 SSH 登录,尽管我必须在每个节点上运行 ssh-agent 和 ssh-add 我的密钥。我已经设法运行从一个节点向另一个节点发送等级的程序(2 个不同的 RPis)。我以 MPMD 方式运行 MPI 程序,因为我只有 2 个 RPis 我在节点 #1 上运行主机和中继,并在节点 #2 上中继。主机程序将文件路径作为命令行参数发送。
如果我跑:
mpirun --oversubscribe -n 1 --host localhost /home/pi/Desktop/host /some.jpeg : -n 2 --host localhost,rpi2 /home/pi/Desktop/relay
它运行了,但显然程序失败了,因为没有 sudo 权限,中继无法打开原始套接字。
如果我跑:
mpirun --oversubscribe -n 1 --host localhost /home/pi/Desktop/host /some.jpeg : -n 2 --host localhost,rpi2 sudo /home/pi/Desktop/relay
relays 报告世界大小:1 并且主机程序挂起。
如果我跑:
mpirun --oversubscribe -n 1 --host localhost sudo /home/pi/Desktop/host /some.jpeg : -n 2 --host localhost,rpi2 sudo /home/pi/Desktop/relay
所有中继和主机报告世界大小为 1。
我在这里发现了类似的问题:OpenMPI / mpirun or mpiexec with sudo permission
按照我运行的简短回答:
mpirun --oversubscribe -n 1 --host localhost /home/pi/Desktop/host /some.jpeg : -n 2 --host localhost,rpi2 sudo -E /home/pi/Desktop/relay
导致:
[raspberrypi:00979] OPAL ERROR: Unreachable in file ext2x_client.c at line 109
[raspberrypi:00980] OPAL ERROR: Unreachable in file ext2x_client.c at line 109
*** An error occurred in MPI_Init
*** An error occurred in MPI_Init
*** on a NULL communicator
*** MPI_ERRORS_ARE_FATAL (processes in this communicator will now abort,
*** and potentially your MPI job)
[raspberrypi:00979] Local abort before MPI_INIT completed completed successfully, but am not able to aggregate error messages, and not able to guarantee that all other processes were killed!
*** on a NULL communicator
*** MPI_ERRORS_ARE_FATAL (processes in this communicator will now abort,
*** and potentially your MPI job)
[raspberrypi:00980] Local abort before MPI_INIT completed completed successfully, but am not able to aggregate error messages, and not able to guarantee that all other processes were killed!
--------------------------------------------------------------------------
Primary job terminated normally, but 1 process returned
a non-zero exit code. Per user-direction, the job has been aborted.
--------------------------------------------------------------------------
--------------------------------------------------------------------------
mpirun detected that one or more processes exited with non-zero status, thus causing
the job to be terminated. The first process to do so was:
Process name: [[32582,1],1]
Exit code: 1
--------------------------------------------------------------------------
我已经运行了 sudo visudo 并且我在两个节点上的文件看起来像这样:
# User privilege specification
root ALL=(ALL:ALL) ALL
pi ALL = NOPASSWD:SETENV: /etc/alternatives/mpirun
pi ALL=NOPASSWD:SETENV: /usr/bin/orterun
pi ALL=NOPASSWD:SETENV: /usr/bin/mpirun
当我在一个节点上运行所有东西时,它就可以工作:
sudo mpirun --alow-run-as-root --oversubscribe -n 1 --host localhost /home/pi/Desktop/host /some.jpeg : -n 2 --host localhost,localhost /home/pi/Desktop/relay
//主机
int main(int argc, char *argv[]) {
MPI_Init(&argc, &argv);
int world_size = []() {
int size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
return size;
}();
int id = []() {
int id;
MPI_Comm_rank(MPI_COMM_WORLD, &id);
return id;
}();
if (argc != 2) {
std::cerr << "Filepath not passed\n";
MPI_Finalize();
return 0;
}
const std::filesystem::path filepath(argv[1]);
if (not std::filesystem::exists(filepath)) {
std::cerr << "File doesn't exist\n";
MPI_Finalize();
return 0;
}
std::cout << "World size: " << world_size << '\n';
MPI_Finalize();
return 0;
}
//relay
int main(int argc, char *argv[]) {
MPI_Init(&argc, &argv);
int world_size = []() {
int size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
return size;
}();
int id = []() {
int id;
MPI_Comm_rank(MPI_COMM_WORLD, &id);
return id;
}();
std::cout << "World size: " << world_size << '\n';
MPI_Finalize();
return 0;
}
如何配置节点以允许它们使用 sudo 运行 MPI 程序?
【问题讨论】:
-
如果您
sudo mpirun --alow-run-as-root有多个主机怎么办?请注意,您必须能够以 root 身份进行无密码 ssh(例如sudo ssh remotehost hostname应该可以正常工作)。您也可以考虑将suid位设置为您的二进制文件并在没有sudo的情况下运行它(注意安全隐患),或者甚至使用为您创建原始套接字的助手。 -
如果我运行
sudo mpirun --alow-run-as-root,一切都会挂起。我尝试设置中继程序的 suid,sudo -i,chmod u+s relay_program并在一个节点上运行它们,但它仍然无法打开。我不知道如何配置对 root 的无密码 ssh 访问。助手是什么意思? -
从您的用户帐户运行所有内容,在
MPI_Init()之前您可以fork&exec sudo helper。 helper 的目的是创建原始套接字,然后通过 fd 传递将它们传递给 MPI 程序。另一种选择是让您的 MPI 应用程序 setuid 和由 root 拥有,在MPI_Init()之前为用户创建原始套接字和 setuid,然后从您的用户帐户中运行 mpirun。 -
我做了一个小程序,它创建原始套接字然后初始化 MPI pastebin.com/RRTX9kzr。然后
sudo -i并用mpic++ 编译程序,用chmod u+s a.out更改suid,使其成为root 拥有并在执行-rwsr-xr-x 1 root root 36316 lip 9 23:28 a.out时具有sudo 权限。当我像普通程序./a.out一样简单地运行它时,它可以工作,但是当我使用mpirun -n 1 /home/pi/Desktop/a.out运行它时,它会因错误pastebin.com/x2Q8iGvH 而崩溃。如果我使用--allow-run-as-root运行它,它会挂起,我错过了什么? -
好吧,我错过了将uid设置回用户的事情,基本上我所做的是用mpic++编译程序,
sudo -i,然后用chown 0:0 a.out将所有者更改为root,并将suid设置为rootchmod u+s a.out。在两个节点上重复它并以mpirun -n 2 --host localhost, rpi1 /home/pi/Desktop/a.out的用户身份运行 MPI 程序,一切正常。在代码中,我使用setreuid(geteuid(), getuid());在 MPI_Init 之前更改了 uid。这是一个很好的解决方案,我很高兴我可以进一步开发和测试我的应用程序!虽然我必须在它准备好用于商业用途之前正确解决问题。
标签: linux sockets raspberry-pi mpi openmpi