+-------------------------------------------------------------------
+Fri Jan 18 10:45:54 CET 2019 - aschnell@suse.com
+
+- avoid deadlock for special btrfs directory comparison
+ (bsc#1049574)
+
-------------------------------------------------------------------
Wed Nov 21 18:59:09 CET 2018 - gergo@borus.hu
};
+ struct FdCloser
+ {
+ FdCloser(int fd)
+ : fd(fd)
+ {
+ }
+
+ ~FdCloser()
+ {
+ if (fd > -1 )
+ ::close(fd);
+ }
+
+ void reset()
+ {
+ fd = -1;
+ }
+
+ int close()
+ {
+ int r = ::close(fd);
+ fd = -1;
+ return r;
+ }
+
+ private:
+
+ int fd;
+
+ };
+
+
bool
StreamProcessor::dumper(int fd)
{
+ FdCloser fd_closer(fd);
+
while (true)
{
boost::this_thread::interruption_point();
if (r < 0)
{
- y2err("btrfs_read_and_process_send_stream failed");
+ y2err("btrfs_read_and_process_send_stream failed " << r);
#if BOOST_VERSION < 104100
dumper_ret = false;
SN_THROW(BtrfsSendReceiveException());
}
+ // Use RAII to help close fds.
+ FdCloser fd0_closer(pipefd[0]);
+ FdCloser fd1_closer(pipefd[1]);
+
struct btrfs_ioctl_send_args io_send;
memset(&io_send, 0, sizeof(io_send));
io_send.send_fd = pipefd[1];
boost::thread task(boost::move(pt));
+ fd0_closer.reset();
+
int r2 = ioctl(dir2.fd(), BTRFS_IOC_SEND, &io_send);
if (r2 < 0)
{
y2err("send ioctl failed errno:" << errno << " (" << stringerror(errno) << ")");
}
- close(pipefd[1]);
+ fd1_closer.close();
uf.wait();
- close(pipefd[0]);
-
if (r2 < 0 || !uf.get())
{
SN_THROW(BtrfsSendReceiveException());
boost::thread dumper_thread(boost::bind(&StreamProcessor::dumper, this, pipefd[0]));
+ fd0_closer.reset();
+
int r2 = ioctl(dir2.fd(), BTRFS_IOC_SEND, &io_send);
if (r2 < 0)
{
y2err("send ioctl failed errno:" << errno << " (" << stringerror(errno) << ")");
}
- close(pipefd[1]);
+ fd1_closer.close();
dumper_thread.join();
- close(pipefd[0]);
-
if (r2 < 0 || !dumper_ret)
{
SN_THROW(BtrfsSendReceiveException());