Boost logo

Boost :

Subject: Re: [boost] [filesystems] file for rename not found
From: Florian Lindner (mailinglists_at_[hidden])
Date: 2019-03-14 11:29:58


Am 14.03.19 um 10:11 schrieb Andrey Semashev via Boost:
> On 3/14/19 12:04 PM, Florian Lindner via Boost wrote:
>> Sorry for the missing subject, hit the send button accidentally.
>>
>> Am 14.03.19 um 09:31 schrieb Florian Lindner via Boost:
>>> Hello,
>>>
>>> I have this innocent piece of code:
>>>
>>>    namespace fs = boost::filesystem;
>>>    auto path = getFilename(); // returns a string
>>>    fs::create_directories(fs::path(path).parent_path());
>>>    std::ofstream ofs(path + "~");
>>>    ofs << info;
>>>    ofs.close();
>>>    fs::rename(path + "~", path);
>>>
>>> which causes the exception:
>>>
>>> boost::filesystem::rename: No such file or directory: "../9f/061b4f7a5e529c964659226eedd4e5~", "../9f/061b4f7a5e529c964659226eedd4e5"
>>>
>>> However, I have no idea how that could happen. I use the rename, so that a reading process never sees an empty file, but only no file or filed with info. Is there any race involved between ofs.close() and fs:rename()? The code was executed on a distributed network filesystem (lustre).
>>>
>>> Any ideas anyone?
>
> I haven't had experience with Lustre, but I'm guessing it may be related. Did you try calling fsync between close and rename?

No, I was assuming that close() does this. I have modified the code to

{
  namespace fs = boost::filesystem;
  auto path = getFilename();
  auto tmp = fs::path(path + "~");
  fs::create_directories(tmp.parent_path());
  boost::iostreams::stream<boost::iostreams::file_descriptor_sink> ofs(tmp);
  ofs << info;
  ::fdatasync(ofs->handle());
  ofs.close();
  fs::rename(tmp, path);
}

Reproducing the bug is hard, as so far, it only has appeared on really huge runs with more than 4000 processors.

Best,
Florian


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk