У меня есть два узла в кластерной среде AWS.
В узле A я запускаю тест под названием «чтение», чтобы сохранить размер файла для чтения. файл находится под смонтированным путем (файловая система EFS в AWS). например ./read /dir/text.txt
В узле B я запускаю тест под названием «запись», чтобы продолжить редактирование того же файла. например ./write /dir/text.txt
Я обнаружил, что иногда размер файла равен 0, даже если я использовал блокировку файла.
Я попытался запустить чтение и запись в одном узле. проблема не может быть воспроизведена.
Я попытался запустить в другой среде, которая не является AWS, проблема не может быть воспроизведена.
Я хочу знать, если что-то не так с моим кодом, или это ограничение для AWS EFS.
Спасибо.
код для теста:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <iostream>
using namespace std;
void printSize(int fildes)
{
struct stat buffer;
int status;
status = fstat(fildes, &buffer);
if (status != 0)
{
perror("fstat");
return;
}
if (buffer.st_size == 0)
{
cout << buffer.st_size << endl;
cout << "press to continue" << endl;
char a;
cin >> a;
}
}
int main(int argc, char** argv) {
if (argc < 2)
return 0;
int signal = 0;
while (true)
{
if (++signal % 100 == 0)
{
int time = (signal / 100) % 10;
for (int i = 0; i < time; i++)
{
cout << '*';
}
cout << endl;
}
int lFileHandle = open(argv[1], O_RDONLY | O_NOCTTY);
if (lFileHandle < 0)
{
perror("open");
continue;
}
struct flock lFileLock;
lFileLock.l_type = F_RDLCK;
lFileLock.l_start = 0;
lFileLock.l_whence = SEEK_SET;
lFileLock.l_len = 0;
lFileLock.l_pid = 0;
while (true)
{
const int lLockingResult = fcntl(lFileHandle, F_SETLK, &lFileLock);
if (lLockingResult != 0)
{
//perror("lock");
}
else
{
break;
}
}
int lResult = 0;
{
lResult = fsync(lFileHandle);
if (lResult != 0)
{
perror("fsync");
continue;
}
}
printSize(lFileHandle);
lResult = close(lFileHandle);
if (lResult != 0)
{
perror("close");
continue;
}
}
return 0;
}
код для тестовой записи
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
if (argc < 2)
return 0;
int signal = 0;
while (true)
{
if (++signal % 100 == 0)
{
int time = (signal / 100) % 10;
for (int i = 0; i < time; i++)
{
cout << '*';
}
cout << endl;
}
int lFileHandle = open(argv[1], O_WRONLY | O_CREAT | O_NOCTTY);
if (lFileHandle < 0)
{
perror("open");
continue;
}
struct flock lFileLock;
lFileLock.l_type = F_WRLCK;
lFileLock.l_start = 0;
lFileLock.l_whence = SEEK_SET;
lFileLock.l_len = 0;
lFileLock.l_pid = 0;
while (true)
{
const int lLockingResult = fcntl(lFileHandle, F_SETLK, &lFileLock);
if (lLockingResult == 0)
{
break;
}
else
{
//perror("lock");
}
}
int lResult = ftruncate(lFileHandle, 0);
if (lResult != 0)
{
perror("truncate");
continue;
}
const int len = 1600;
std::string lContent(len, 'A');
const size_t lBytesWritten = write(lFileHandle, lContent.c_str(), len);
if (lBytesWritten == -1 || lBytesWritten < len)
{
perror("write");
continue;
}
{
lResult = fsync(lFileHandle);
if (lResult != 0)
{
perror("fsync");
continue;
}
}
lResult = close(lFileHandle);
if (lResult != 0)
{
perror("close");
continue;
}
}
return 0 ;
}