Skip to content

Commit

Permalink
lib: make tst_detach_device_by_fd() also close dev_fd
Browse files Browse the repository at this point in the history
Since commit 18048c1af783 ("loop: Fix a race between loop detach and loop open")
detach operation is deferred to the last close of the device.

Make tst_detach_device_by_fd() also close dev_fd, and leave it up to
caller to re-open it for further use.

Closes: #1175

Reported-by: Gulam Mohamed <[email protected]>
Signed-off-by: Jan Stancek <[email protected]>
Reviewed-by: Petr Vorel <[email protected]>
Tested-by: Petr Vorel <[email protected]>
Reviewed-by: Li Wang <[email protected]>
  • Loading branch information
jstancek committed Aug 19, 2024
1 parent 642c027 commit c02d8dd
Show file tree
Hide file tree
Showing 8 changed files with 21 additions and 4 deletions.
4 changes: 3 additions & 1 deletion include/tst_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ int tst_attach_device(const char *dev_path, const char *file_path);
uint64_t tst_get_device_size(const char *dev_path);

/*
* Detaches a file from a loop device fd.
* Detaches a file from a loop device fd. @dev_fd needs to be the
* last descriptor opened. Call to this function will close it,
* it is up to caller to open it again for further usage.
*
* @dev_path Path to the loop device e.g. /dev/loop0
* @dev_fd a open fd for the loop device
Expand Down
10 changes: 8 additions & 2 deletions lib/tst_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,17 +243,23 @@ int tst_detach_device_by_fd(const char *dev, int dev_fd)

/* keep trying to clear LOOPDEV until we get ENXIO, a quick succession
* of attach/detach might not give udev enough time to complete
*
* Since 18048c1af783 ("loop: Fix a race between loop detach and loop open")
* device is detached only after last close.
*/
for (i = 0; i < 40; i++) {
ret = ioctl(dev_fd, LOOP_CLR_FD, 0);

if (ret && (errno == ENXIO))
if (ret && (errno == ENXIO)) {
SAFE_CLOSE(NULL, dev_fd);
return 0;
}

if (ret && (errno != EBUSY)) {
tst_resm(TWARN,
"ioctl(%s, LOOP_CLR_FD, 0) unexpectedly failed with: %s",
dev, tst_strerrno(errno));
SAFE_CLOSE(NULL, dev_fd);
return 1;
}

Expand All @@ -262,6 +268,7 @@ int tst_detach_device_by_fd(const char *dev, int dev_fd)

tst_resm(TWARN,
"ioctl(%s, LOOP_CLR_FD, 0) no ENXIO for too long", dev);
SAFE_CLOSE(NULL, dev_fd);
return 1;
}

Expand All @@ -276,7 +283,6 @@ int tst_detach_device(const char *dev)
}

ret = tst_detach_device_by_fd(dev, dev_fd);
close(dev_fd);
return ret;
}

Expand Down
1 change: 1 addition & 0 deletions testcases/kernel/syscalls/ioctl/ioctl09.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ static void verify_ioctl(void)
check_partition(2, true);

tst_detach_device_by_fd(dev_path, dev_fd);
dev_fd = SAFE_OPEN(dev_path, O_RDWR);
attach_flag = 0;
}

Expand Down
1 change: 1 addition & 0 deletions testcases/kernel/syscalls/ioctl/ioctl_loop01.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ static void verify_ioctl_loop(void)
check_loop_value(0, LO_FLAGS_PARTSCAN, 0);

tst_detach_device_by_fd(dev_path, dev_fd);
dev_fd = SAFE_OPEN(dev_path, O_RDWR);
attach_flag = 0;
}

Expand Down
1 change: 1 addition & 0 deletions testcases/kernel/syscalls/ioctl/ioctl_loop02.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ static void verify_ioctl_loop(unsigned int n)

SAFE_CLOSE(file_fd);
tst_detach_device_by_fd(dev_path, dev_fd);
dev_fd = SAFE_OPEN(dev_path, O_RDWR);
attach_flag = 0;
}

Expand Down
1 change: 1 addition & 0 deletions testcases/kernel/syscalls/ioctl/ioctl_loop04.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ static void verify_ioctl_loop(void)

SAFE_CLOSE(file_fd);
tst_detach_device_by_fd(dev_path, dev_fd);
dev_fd = SAFE_OPEN(dev_path, O_RDWR);
unlink("test.img");
attach_flag = 0;
}
Expand Down
5 changes: 4 additions & 1 deletion testcases/kernel/syscalls/ioctl/ioctl_loop06.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@ static void verify_ioctl_loop(unsigned int n)

if (TST_RET == 0) {
tst_res(TFAIL, "Set block size succeed unexpectedly");
if (tcases[n].ioctl_flag == LOOP_CONFIGURE)
if (tcases[n].ioctl_flag == LOOP_CONFIGURE) {
tst_detach_device_by_fd(dev_path, dev_fd);
dev_fd = SAFE_OPEN(dev_path, O_RDWR);
}
return;
}
if (TST_ERR == EINVAL)
Expand Down Expand Up @@ -87,6 +89,7 @@ static void run(unsigned int n)
}
if (attach_flag) {
tst_detach_device_by_fd(dev_path, dev_fd);
dev_fd = SAFE_OPEN(dev_path, O_RDWR);
attach_flag = 0;
}
loopconfig.block_size = *(tc->setvalue);
Expand Down
2 changes: 2 additions & 0 deletions testcases/kernel/syscalls/ioctl/ioctl_loop07.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ static void verify_ioctl_loop(unsigned int n)
/*Reset*/
if (tc->ioctl_flag == LOOP_CONFIGURE) {
tst_detach_device_by_fd(dev_path, dev_fd);
dev_fd = SAFE_OPEN(dev_path, O_RDWR);
} else {
loopinfo.lo_sizelimit = 0;
TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_STATUS, &loopinfo), TST_RETVAL_EQ0);
Expand Down Expand Up @@ -101,6 +102,7 @@ static void run(unsigned int n)
}
if (attach_flag) {
tst_detach_device_by_fd(dev_path, dev_fd);
dev_fd = SAFE_OPEN(dev_path, O_RDWR);
attach_flag = 0;
}
loopconfig.info.lo_sizelimit = tc->set_sizelimit;
Expand Down

0 comments on commit c02d8dd

Please sign in to comment.