mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-22 13:33:56 +03:00
repart: when keeping ref to backing inode/devnode, use fd_reopen() rathern than F_DUPFD
Via the "backing_fd" variable we intend to pin the backing inode through
our entire code. So far we typically created the fd via F_DUPFD_CLOEXEC,
and thus any BSD lock taken one the original fd is shared with our
backing_fd reference. And if the origina fd is closed but our backing_fd
is not, we'll keep the BSD lock open, even if we then reopen the block
device through the backing_fd. If hit, this results in a deadlock.
Let's fix that by creating the backing_fd via fd_reopen(), so that the
locks are no longer shared, and if the original fd is closed all BSD
locks on it that are in effect are auto-released.
(Note the deadlock is only triggered if multiple operations on the same
backing inode are executed, i.e. factory reset, resize and applying of
partitions.)
Replaces: #24181
(cherry picked from commit 38f81e9374
)
This commit is contained in:
parent
7384d152c8
commit
d3e84e4703
@ -1611,9 +1611,9 @@ static int context_load_partition_table(
|
||||
|
||||
if (*backing_fd < 0) {
|
||||
/* If we have no fd referencing the device yet, make a copy of the fd now, so that we have one */
|
||||
*backing_fd = fcntl(fdisk_get_devfd(c), F_DUPFD_CLOEXEC, 3);
|
||||
*backing_fd = fd_reopen(fdisk_get_devfd(c), O_RDONLY|O_CLOEXEC);
|
||||
if (*backing_fd < 0)
|
||||
return log_error_errno(errno, "Failed to duplicate fdisk fd: %m");
|
||||
return log_error_errno(*backing_fd, "Failed to duplicate fdisk fd: %m");
|
||||
}
|
||||
|
||||
/* Tell udev not to interfere while we are processing the device */
|
||||
|
Loading…
Reference in New Issue
Block a user