CIFS字节范围锁定是否可以在Windows作为服务器的多个Linux客户端节点上运行?

时间:2017-12-04 11:16:37

标签: smb concurrentmodification file-locking cifs filelock

尝试让不同的 Linux节点上的多个进程写入Windows共享文件夹中的共享CSV文件。

我通过在不同节点上启动2个进程来测试它是否有效,每个节点都向文件追加10k行。然后我检查行数是否为20k。不幸的是,行数几乎总是小于那个。我正在使用Linux 3.0.51和Windows Server 2008 R2。但是,锁定多个进程 1节点内的确可以使用flock(),但不能用于fcntl()。

以下是我尝试过的其他一些事情:

  1. 使用NFS - 确实有效! (有时行数是19999)

  2. 使用Linux内核4.10并挂载为SMB 3.02 - 不起作用

  3. 使用Samba作为服务器 - 即使使用严格锁定= yes也不起作用 如下所述:

  4. https://www.samba.org/samba/docs/man/Samba-HOWTO-Collection/locking.html

    有没有人让它工作或知道无法完成(以及配置)?这是我的测试程序:

    #include <unistd.h>
    #include <fcntl.h>
    #include <iostream>
    #include <errno.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sys/file.h>
    #include <boost/interprocess/sync/file_lock.hpp>
    // method 0: fcntl() - works for NFS and across multiple nodes, but not for CIFS/SMB
    // method 1: flock() - works for SMB within 1 node, but not accross multiple nodes
    // method 2: Boost   (internally uses fcntl)
    #define METHOD 1
    using namespace std;
    class FileLock
    {
    public:
    #if METHOD == 2
      FileLock(const char *path) : lock(path)
      {
      }
    #else
      FileLock(int f)
      {
        file = f;
    #if METHOD == 0
        lock.l_whence = SEEK_SET;
        lock.l_start = 0;
        lock.l_len = 0;
    #endif
      }
    #endif
      bool Lock()
      {
    #if METHOD == 0
        lock.l_type = F_WRLCK;
        return fcntl(file, F_SETLKW, &lock) == 0;
    #elif METHOD == 1
        return flock(file, LOCK_EX) == 0;
    #elif METHOD == 2
        lock.lock();
        return true;
    #endif
      }
      bool Unlock()
      {
    #if METHOD == 0
        lock.l_type = F_UNLCK;
        return fcntl(file, F_SETLKW, &lock) == 0;
    #elif METHOD == 1
        return flock(file, LOCK_UN) == 0;
    #elif METHOD == 2
        lock.unlock();
        return true;
    #endif
      }
      int file;
    #if METHOD == 0
      struct flock lock;
    #elif METHOD == 2
      boost::interprocess::file_lock lock;
    #endif
    };
    
    int main(int argc, char **argv)
    {
      int repeats = 100;
      double interval = 0.1;
      char message[256];
      sprintf(message, "testing 123\n");
    
      if (argc >= 2)
        repeats = atoi(argv[1]);
      if (argc >= 3)
        interval = atof(argv[2]);
      if (argc >= 4)
      {
        sprintf(message, "%s\n", argv[3]);
      }
      FILE *f = fopen("a.txt", "a");
      if (f == NULL)
      {
        cout << "can't open" << endl;
        return 1;
      }
    #if METHOD == 2
      FileLock lock("a.txt");
    #else
      FileLock lock(fileno(f));
    #endif
      for (int i = 0; i < repeats; ++i)
      {
        if (!lock.Lock())
         cout << "error locking " << strerror(errno) <<  "\n";
    
        // file in append mode will automatically write to end, but does it work when there are multiple writers?
        fseek(f, 0, SEEK_END);
        fwrite(message, 1, strlen(message), f);
    
        if (!lock.Unlock())
          cout << "error unlocking\n";
        usleep(interval * 1000000);
      }
      fclose(f);
      return 0;
    }
    

0 个答案:

没有答案