неверный размер файла, когда другой компьютер изменяет файл - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть два узла в кластерной среде 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 ;
}
...