2017-07-11 5 views
-1

私はサーバのグループを持っていますが、私たちはNFSを使って各サーバから他のすべてのドライブをマウントしています。私たちは何の問題もなくドライブをマウントすることができました。私はmkdirをコマンドラインからnfsのマウントされたドライブの1つに呼び出すことができ、すべて正常に動作します。しかし、私がCで書かれたプログラムからmkdirを実行しようとすると、mkdirを実行しようとするとファイルまたはディレクトリが存在しないと言われます。それは、複数のレベルのディレクトリやそのようなものを作成しようとしていません。これはまったく同じ特権を持つ同じ場所で試していますが、何らかの理由でCからmkdirを呼び出すと、ファイルが存在しないというメッセージが表示されます(私は親ディレクトリを意味すると仮定しています)。mkdirはコマンドラインからは動作しますが、NFSを使用するとC++で失敗します

#include <sys/stat.h> 

#include <vector> 
#include <dirent.h> 
#include <string> 
#include <mutex> 
#include <iosfwd> 
#include <iostream> 
#include <fstream> 
#include <thread> 
#include <string.h> 
#include <chrono> 
#include <cerrno> 

#include <dirent.h> 
#include <fcntl.h> // O_RDONLY 
#include <unistd.h> // read 
#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <sys/stat.h> 
#include <sys/syscall.h> 



    #define FILE_PERMISSION_BITS_MODE 0700 
    int makeDir(std::string folderPath){ 

     bool dirExists = false; 
     int success = -1; 
     struct stat sb; 
     if (stat(folderPath.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)){ 
      dirExists = true; 
      success = 0; 
     } 

     if (!dirExists){ 
      int success = mkdir(folderPath.c_str(),FILE_PERMISSION_BITS_MODE); 

      int countInvalids = 0; 

      while (success != 0){ 

       if (success == -1 && stat(folderPath.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)){ // if failed, check again if it exists or not 
        success = 0; 
        break; 
       } 

       int fileRetryDelay = 20; 
       const int sleep_milliseconds = (countInvalids+1)*fileRetryDelay; 
       std::this_thread::sleep_for(std::chrono::milliseconds(sleep_milliseconds)); 

       if (countInvalids % 5 == 0){ 
        const std::string sysError(std::strerror(errno)); 

        std::cout<<"ERROR: FileUtil::makeDir failed to make directory: " << folderPath<<" try number "<<countInvalids << " Error was: "<< sysError << " (" << errno << ")"<<std::endl; 
       } 
       countInvalids++; 

       success = mkdir(folderPath.c_str(),FILE_PERMISSION_BITS_MODE); 

       if (countInvalids > 10000){ 
        break; 
       } 
      } 
      if (success == 0 && countInvalids > 0){ 
       std::cout<<"FileUtil::makeDir finally succeeded making directory: " << folderPath << " Succeeded after "<<countInvalids<<" tries"<<std::endl; 
      } 
     } 

     if (success == -1 && stat(folderPath.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)){ // if failed, check again if it exists or not 
      success = 0; 
     } 

     return success; 

    } 


int main(){ 
    makeDir("/some/path"); 
} 
+2

失敗したプログラムの[最小限の、完全で検証可能な例](http://stackoverflow.com/help/mcve)を作成して表示してください。 –

+0

おそらくディレクトリを作成するコード行なしでこれに答えることはできますか? – camelccc

+0

コマンドライン "mkdir"はCで書かれています。独自の実装はおそらく間違っているか、2つの異なるコンテキストで2つの実行を比較します。 – user803422

答えて

1

何か掘り下げた後、私たちは何が起こっているのか把握しました。

  1. 数ミリ秒後にキャプチャされるerrnoが同じではなかったため、コール直後にerrnoをキャプチャする必要がありました。

  2. NFSを使用し、rootとしてアプリケーションを実行する場合は、アクセスしているファイルシステムに書き込むためにno_root_squashオプションを使用する必要があります。

代わりの明白な理由のために安全ではオプションにno_root_squashを使用して、我々は我々のアプリケーションは、sudoの下またはrootユーザーによって実行されていなかったことを確認しました。

関連する問題