23 #include <boost/functional/hash.hpp>
28 #include <sys/types.h>
33 using namespace EL::msgEventLoop;
45 void reportErrno (
int myerrno)
60 std::pair<Detail::ManagerOrder,std::string> SubmitDirManager ::
61 getManagerOrder ()
const noexcept
63 return std::make_pair (ManagerOrder::SUBMIT_DIR,
"");
73 case ManagerStep::updateSubmitDir:
78 if (
data.submitDir[0] !=
'/')
79 data.submitDir = gSystem->WorkingDirectory () + (
"/" +
data.submitDir);
82 const std::regex identityEndExpr {
"(/$)|(/\\.$)"};
83 while (std::regex_search (
data.submitDir,
match, identityEndExpr))
86 if (std::regex_search (
data.submitDir,
match, relativeEndExpr))
89 return ::StatusCode::FAILURE;
98 const std::regex identityExpr {
"(/\\./)|(//)|(^/\\.\\./)"};
99 while (std::regex_search (
data.submitDir,
match, identityExpr))
101 const std::regex relativeExpr {
"/[^/]+/\\.\\./"};
102 while (std::regex_search (
data.submitDir,
match, relativeExpr))
105 if (
data.submitDir.find (
"/pnfs/") == 0)
108 return ::StatusCode::FAILURE;
115 case ManagerStep::extractOptions:
120 if (
mode ==
"no-clobber")
121 data.submitDirMode = SubmitDirMode::NO_CLOBBER;
122 else if (
mode ==
"overwrite")
123 data.submitDirMode = SubmitDirMode::OVERWRITE;
124 else if (
mode ==
"unique")
125 data.submitDirMode = SubmitDirMode::UNIQUE;
126 else if (
mode ==
"unique-link")
127 data.submitDirMode = SubmitDirMode::UNIQUE_LINK;
131 ANA_MSG_ERROR (
"known modes: no-clobber, overwrite, unique, unique-link");
132 return ::StatusCode::FAILURE;
140 ANA_MSG_ERROR (
"can't specify both an explicit submit-dir mode and optRemoveSubmitDir");
141 return ::StatusCode::FAILURE;
143 data.submitDirMode = SubmitDirMode::OVERWRITE;
148 case ManagerStep::createSubmitDir:
152 bool success {
false};
155 std::size_t
hash {0};
156 while (success ==
false && tries < 10)
160 switch (
data.submitDirMode)
162 case SubmitDirMode::NO_CLOBBER:
163 case SubmitDirMode::OVERWRITE:
167 case SubmitDirMode::UNIQUE:
168 case SubmitDirMode::UNIQUE_LINK:
172 if (gettimeofday (&tv,
nullptr) == -1 ||
173 localtime_r (&tv.tv_sec, &tvSplit) ==
nullptr)
177 return ::StatusCode::FAILURE;
179 const std::string uniqueDateFormat {
184 uniqueDateFormat.c_str(), &tvSplit);
187 boost::hash_combine (
hash, std::hash<pid_t>() (getpid()));
188 boost::hash_combine (
hash, std::hash<suseconds_t>() (tv.tv_usec));
189 std::size_t hash16 {
hash};
190 while (hash16 > 0xffff)
191 hash16 = (hash16&0xffff) ^ (hash16 >> 16);
214 const int myerrno {errno};
215 if (myerrno == EEXIST)
217 switch (
data.submitDirMode)
219 case SubmitDirMode::NO_CLOBBER:
221 ANA_MSG_ERROR (
"change the name or remove file/directory already there");
222 return ::StatusCode::FAILURE;
223 case SubmitDirMode::OVERWRITE:
228 return ::StatusCode::FAILURE;
231 gSystem->Exec ((
"rm -rf " +
submitDir).c_str());
233 case SubmitDirMode::UNIQUE:
234 case SubmitDirMode::UNIQUE_LINK:
241 reportErrno (myerrno);
243 return ::StatusCode::FAILURE;
251 switch (
data.submitDirMode)
253 case SubmitDirMode::OVERWRITE:
254 case SubmitDirMode::NO_CLOBBER:
255 case SubmitDirMode::UNIQUE:
259 case SubmitDirMode::UNIQUE_LINK:
261 if (unlink (
data.submitDir.c_str()) == -1 && errno != ENOENT)
265 return ::StatusCode::FAILURE;
269 if (symlink (
file.c_str(),
data.submitDir.c_str()) == -1)
273 return ::StatusCode::FAILURE;
282 ANA_MSG_ERROR (
"tried " << tries <<
" times to create directory and failed: " <<
data.submitDir);
284 return ::StatusCode::FAILURE;
293 return ::StatusCode::SUCCESS;