При использовании NFSv4, мой клиент сообщил, что их программа MPI иногда сообщает об ошибке, что файл не открывается или файл не найден.
Я скомпилировал образец программы MPI-IO и подтвердил, что если процессы MPI на вычислительных узлах пытаются получить доступ к одному и тому же файлу, совместно используемому из NFS, программа завершится ошибкой. После нескольких проверок выясняется, что изменение монтирования NFS с v4.1 на v3 устранило эту проблему.
Я все же хотел бы использовать NFSv4 из-за его безопасности и потенциального увеличения скорости. Поэтому я хотел бы знать, какие аргументы я должен добавить, чтобы это работало.
ОС: CentOS 7.6 обновлен до последней версии, nfs-utils 1.3.0, ядро 3.10.0-957.12.2
Экспорт сервера:
/ home 10.0.214.0/24(rw,no_subtree_check,no_root_squash)
Client fstab:
ib-orion-io1: / home / home nfs defaults, rdma, port = 20049, nodev, nosuid 0 2
Монтирование клиента NFSv4:
ib-orion-io1: / home on / home type nfs4 (rw, nosuid, nodev, relatime, vers = 4.1, rsize = 1048576, wsize = 1048576, namlen = 255, hard, proto = rdma, port = 20049, timeo = 600, retrans = 2, sec = sys, clientaddr = 10.0.214.11, local_lock = none, addr = 10.0.214.5)
Монтирование клиента NFSv3
ib-orion-io1: / home on / home тип nfs (rw, nosuid, nodev, relatime, vers = 3, rsize = 1048576, wsize = 1048576, namlen = 255, hard, proto = rdma, port = 20049, timeo = 600, retrans = 2, sec = sys, mountaddr = 10.0.214.5, mountvers = 3, mountproto = tcp, local_lock = none, addr = 10.0.214.5)
Ошибка на клиенте NFSv4
Testing simple MPIO program with 112 processes accessing file tttestfile
(Filename can be specified via program argument)
Proc 0: hostname=node001
Proc 0: MPI_File_open failed (Other I/O error , error stack:
ADIO_OPEN(219): open failed on a remote node)
Proc 66: MPI_File_open failed (File does not exist, error stack:
ADIOI_UFS_OPEN(39): File tttestfile does not exist)
Proc 1: MPI_File_open failed (Other I/O error , error stack:
ADIO_OPEN(219): open failed on a remote node)
Proc 84: MPI_File_open failed (File does not exist, error stack:
ADIOI_UFS_OPEN(39): File tttestfile does not exist)
Пример программы параллельного ввода-вывода файлов MPI взят из HDF5.
См. Абзац "==> Sample_mpio.c <==" в https://support.hdfgroup.org/ftp/HDF5/current/src/unpacked/release_docs/INSTALL_parallel
Я выяснил, что это потому, что NFSv4 по умолчанию имеет значение «ac». Таким образом, когда ранг 0 в MPI создал файл, другие процессы начали его открывать через несколько миллисекунд. Клиент NFS вернул кэшированную информацию, и там идет «файл не найден».
Когда добавлен параметр «noac», все снова пошло гладко.
Правка: запись все еще оказалась с ошибкой. Я попробую использовать NFSv3 позже. Пример кода:
#include <mpi.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char hostname[16];
char readhost[16];
int mpi_size, mpi_rank;
MPI_File fh;
char *filename = "./mpirw.data";
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
gethostname(hostname, 16);
if (mpi_rank == 0)
{
MPI_File_open(MPI_COMM_SELF, filename,
MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh);
printf("%d@%s created file\n", mpi_rank, hostname);
MPI_File_close(&fh);
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_File_open(MPI_COMM_WORLD, filename,
MPI_MODE_RDWR, MPI_INFO_NULL, &fh);
printf("%d@%s opened file\n", mpi_rank, hostname);
MPI_Status status;
int count = strlen(hostname);
MPI_File_write_at(fh, mpi_rank * 16,
hostname, count + 1, MPI_CHAR, &status);
printf("%d@%s wrote OK\n", mpi_rank, hostname);
MPI_Barrier(MPI_COMM_WORLD);
if (mpi_rank == 0)
MPI_File_write_at(fh, mpi_size * 16, "\n", 1, MPI_CHAR, &status);
MPI_File_read_at(fh, mpi_rank * 16,
readhost, count + 1, MPI_CHAR, &status);
if (strcmp(hostname, readhost) != 0)
printf("%d@%s read ERROR, got %s\n", mpi_rank, hostname, readhost);
else
printf("%d@%s read OK, got %s\n", mpi_rank, hostname, readhost);
MPI_File_close(&fh);
}
Хотя программа может сообщать "прочитано ОК", но шестнадцатеричный дамп вывод показывает, что вывод усечен.