selftests: ublk: make sure _add_ublk_dev can return in sub-shell

Detach ublk daemon from the starting process completely by double-fork and
clearing its process group, so that `_add_ublk_dev` can return from sub-shell.

Then it is more friendly for writing shell test script for adding/recovering
ublk device.

Prepare for running ublk test in parallel.

Signed-off-by: Ming Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20250412023035.2649275-5-ming.lei@redhat.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Ming Lei 2025-04-12 10:30:20 +08:00 committed by Jens Axboe
parent 8d31a7e505
commit 573840ab90
4 changed files with 39 additions and 22 deletions

View File

@ -654,6 +654,8 @@ static int ublk_send_dev_event(const struct dev_ctx *ctx, int dev_id)
if (write(evtfd, &id, sizeof(id)) != sizeof(id))
return -EINVAL;
close(evtfd);
return 0;
}
@ -889,24 +891,40 @@ static int cmd_dev_add(struct dev_ctx *ctx)
exit(-1);
}
setsid();
res = fork();
if (res == 0) {
int res2;
setsid();
res2 = fork();
if (res2 == 0) {
/* prepare for detaching */
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
run:
res = __cmd_dev_add(ctx);
return res;
res = __cmd_dev_add(ctx);
return res;
} else {
/* detached from the foreground task */
exit(EXIT_SUCCESS);
}
} else if (res > 0) {
uint64_t id;
int exit_code = EXIT_FAILURE;
res = read(ctx->_evtfd, &id, sizeof(id));
close(ctx->_evtfd);
if (res == sizeof(id) && id != ERROR_EVTFD_DEVID) {
ctx->dev_id = id - 1;
return __cmd_dev_list(ctx);
if (__cmd_dev_list(ctx) >= 0)
exit_code = EXIT_SUCCESS;
}
exit(EXIT_FAILURE);
/* wait for child and detach from it */
wait(NULL);
exit(exit_code);
} else {
return res;
exit(EXIT_FAILURE);
}
}

View File

@ -170,7 +170,6 @@ _have_feature()
}
_add_ublk_dev() {
local kublk_temp;
local dev_id;
if [ ! -c /dev/ublk-control ]; then
@ -182,17 +181,17 @@ _add_ublk_dev() {
fi
fi
kublk_temp=$(mktemp /tmp/kublk-XXXXXX)
if ! "${UBLK_PROG}" add "$@" > "${kublk_temp}" 2>&1; then
if ! dev_id=$("${UBLK_PROG}" add "$@" | grep "dev id" | awk -F '[ :]' '{print $3}'); then
echo "fail to add ublk dev $*"
rm -f "${kublk_temp}"
return 255
fi
dev_id=$(grep "dev id" "${kublk_temp}" | awk -F '[ :]' '{print $3}')
udevadm settle
rm -f "${kublk_temp}"
echo "${dev_id}"
if [[ "$dev_id" =~ ^[0-9]+$ ]]; then
echo "${dev_id}"
else
return 255
fi
}
# kill the ublk daemon and return ublk device state

View File

@ -4,19 +4,19 @@
. "$(cd "$(dirname "$0")" && pwd)"/test_common.sh
TID="stress_01"
ERR_CODE=0
DEV_ID=-1
ublk_io_and_remove()
{
local size=$1
local dev_id
shift 1
DEV_ID=$(_add_ublk_dev "$@")
dev_id=$(_add_ublk_dev "$@")
_check_add_dev $TID $?
[ "$UBLK_TEST_QUIET" -eq 0 ] && echo "run ublk IO vs. remove device(ublk add $*)"
if ! __run_io_and_remove "${DEV_ID}" "${size}" "no"; then
echo "/dev/ublkc${DEV_ID} isn't removed"
if ! __run_io_and_remove "$dev_id" "${size}" "no"; then
echo "/dev/ublkc$dev_id isn't removed"
exit 255
fi
}

View File

@ -4,19 +4,19 @@
. "$(cd "$(dirname "$0")" && pwd)"/test_common.sh
TID="stress_02"
ERR_CODE=0
DEV_ID=-1
ublk_io_and_kill_daemon()
{
local size=$1
local dev_id
shift 1
DEV_ID=$(_add_ublk_dev "$@")
dev_id=$(_add_ublk_dev "$@")
_check_add_dev $TID $?
[ "$UBLK_TEST_QUIET" -eq 0 ] && echo "run ublk IO vs kill ublk server(ublk add $*)"
if ! __run_io_and_remove "${DEV_ID}" "${size}" "yes"; then
echo "/dev/ublkc${DEV_ID} isn't removed res ${res}"
if ! __run_io_and_remove "$dev_id" "${size}" "yes"; then
echo "/dev/ublkc$dev_id isn't removed res ${res}"
exit 255
fi
}