$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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