git: 802f5e4d6926 - main - ggate: fix test intermittency
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 15 Oct 2026 12:16:33 UTC
The branch main has been updated by asomers:
URL: https://cgit.FreeBSD.org/src/commit/?id=802f5e4d6926f0be9294d71c6cadcbe872dbddf2
commit 802f5e4d6926f0be9294d71c6cadcbe872dbddf2
Author: Alan Somers <asomers@FreeBSD.org>
AuthorDate: 2026-10-13 17:40:22 +0000
Commit: Alan Somers <asomers@FreeBSD.org>
CommitDate: 2026-10-15 12:16:16 +0000
ggate: fix test intermittency
* ggatel: fix piped output. Flush stdout before daemonizing, so the
output can be read when it's in a command pipeline.
* ggated: bind the port _before_ daemonizing, so an invoking script can
be sure that the port is bound as soon as the command returns.
* tests: allow ggatec or ggatel to automatically allocate a device
number instead of choosing one in a racy way.
With all of these changes I can no run the tests 1000 times without
fail. And in parallel, too.
MFC after: 1 week
Sponsored by: ConnectWise
PR: 298942
Reported by: siva
Reviewed by: ngie
Differential Revision: https://reviews.freebsd.org/D60707
---
sbin/ggate/ggated/ggated.c | 21 +++++++++------
sbin/ggate/ggatel/ggatel.c | 4 ++-
tests/sys/geom/class/gate/Makefile | 3 ---
tests/sys/geom/class/gate/ggate_test.sh | 48 ++++++++++++---------------------
4 files changed, 33 insertions(+), 43 deletions(-)
diff --git a/sbin/ggate/ggated/ggated.c b/sbin/ggate/ggated/ggated.c
index ef7b61cb13c4..dd6c53c80ccf 100644
--- a/sbin/ggate/ggated/ggated.c
+++ b/sbin/ggate/ggated/ggated.c
@@ -1100,14 +1100,6 @@ main(int argc, char *argv[])
err(EXIT_FAILURE, "Cannot open/create pidfile");
}
- if (!g_gate_verbose) {
- /* Run in daemon mode. */
- if (daemon(0, 0) == -1)
- g_gate_xlog("Cannot daemonize: %s", strerror(errno));
- }
-
- pidfile_write(pfh);
-
signal(SIGCHLD, SIG_IGN);
sfd = socket(AF_INET, SOCK_STREAM, 0);
@@ -1129,6 +1121,19 @@ main(int argc, char *argv[])
signal(SIGHUP, huphandler);
+ if (!g_gate_verbose) {
+ /*
+ * Run in daemon mode. Daemonize _after_ opening the socket,
+ * so consumers may connect as soon as the ggated command
+ * returns, but _before_ writing the pidfile, because daemon()
+ * changes the pid.
+ */
+ if (daemon(0, 0) == -1)
+ g_gate_xlog("Cannot daemonize: %s", strerror(errno));
+ }
+
+ pidfile_write(pfh);
+
for (;;) {
fromlen = sizeof(from);
tmpsfd = accept(sfd, &from, &fromlen);
diff --git a/sbin/ggate/ggatel/ggatel.c b/sbin/ggate/ggatel/ggatel.c
index 1cbb6af28b7e..cafa6a385457 100644
--- a/sbin/ggate/ggatel/ggatel.c
+++ b/sbin/ggate/ggatel/ggatel.c
@@ -191,8 +191,10 @@ g_gatel_create(void)
ggioc.gctl_maxcount = 0;
strlcpy(ggioc.gctl_info, path, sizeof(ggioc.gctl_info));
g_gate_ioctl(G_GATE_CMD_CREATE, &ggioc);
- if (unit == -1)
+ if (unit == -1) {
printf("%s%u\n", G_GATE_PROVIDER_NAME, ggioc.gctl_unit);
+ fflush(stdout);
+ }
unit = ggioc.gctl_unit;
g_gatel_serve(fd);
}
diff --git a/tests/sys/geom/class/gate/Makefile b/tests/sys/geom/class/gate/Makefile
index 5ebc1d9304e0..8ecb2e1a3751 100644
--- a/tests/sys/geom/class/gate/Makefile
+++ b/tests/sys/geom/class/gate/Makefile
@@ -4,7 +4,4 @@ TESTSDIR= ${TESTSBASE}/sys/geom/class/${.CURDIR:T}
ATF_TESTS_SH+= ggate_test
-# Tests listen on the same port.
-TEST_METADATA.ggate_test+= is_exclusive=true
-
.include <bsd.test.mk>
diff --git a/tests/sys/geom/class/gate/ggate_test.sh b/tests/sys/geom/class/gate/ggate_test.sh
index 4cbc5d80ae89..398d5bee6d80 100644
--- a/tests/sys/geom/class/gate/ggate_test.sh
+++ b/tests/sys/geom/class/gate/ggate_test.sh
@@ -16,14 +16,14 @@ ggatec_trim_body()
load_ggate
port=33080
- us=$(alloc_ggate_dev)
work=$(alloc_md)
atf_check -e ignore -o ignore dd if=/dev/random of=/dev/$work bs=1m count=1 conv=notrunc
echo $CONF >> $PLAINFILES
echo "localhost RW /dev/$work" > $CONF
atf_check ggated -p $port -F $PIDFILE $CONF
- atf_check ggatec create -p $port -u $us localhost /dev/$work
- ggate_dev=/dev/ggate${us}
+ atf_check -o save:ggateu ggatec create -p $port localhost /dev/$work
+ ggate_dev=/dev/`cat ggateu`
+ cat ggateu | sed 's:ggate::' >> ggate.devs
wait_for_ggate_device ${ggate_dev}
# ggatec only supports read or write.
@@ -55,7 +55,6 @@ ggated_body()
load_ggate
port=33081
- us=$(alloc_ggate_dev)
work=$(alloc_md)
src=$(alloc_md)
@@ -68,16 +67,16 @@ ggated_body()
echo "127.0.0.1 RW /dev/$work" > $CONF
atf_check ggated -p $port -F $PIDFILE $CONF
- atf_check ggatec create -p $port -u $us 127.0.0.1 /dev/$work
-
- ggate_dev=/dev/ggate${us}
+ atf_check -o save:ggateu ggatec create -p $port 127.0.0.1 /dev/$work
+ ggate_dev=/dev/`cat ggateu`
+ cat ggateu | sed 's:ggate::' >> ggate.devs
wait_for_ggate_device ${ggate_dev}
atf_check -e ignore -o ignore \
dd if=/dev/${src} of=${ggate_dev} bs=1m count=1 conv=notrunc
- checksum /dev/$src /dev/$work
+ checksum /dev/$src /dev/$work $ggate_dev
}
ggated_cleanup()
@@ -98,22 +97,21 @@ ggatel_file_body()
{
load_ggate
- us=$(alloc_ggate_dev)
echo src work >> ${PLAINFILES}
dd if=/dev/random of=work bs=1m count=1
dd if=/dev/random of=src bs=1m count=1
- atf_check ggatel create -u $us work
-
- ggate_dev=/dev/ggate${us}
+ atf_check -o save:ggateu ggatel create work
+ ggate_dev=/dev/`cat ggateu`
+ cat ggateu | sed 's:ggate::' >> ggate.devs
wait_for_ggate_device ${ggate_dev}
atf_check -e ignore -o ignore \
dd if=src of=${ggate_dev} bs=1m count=1 conv=notrunc
- checksum src work
+ checksum src work $ggate_dev
}
ggatel_file_cleanup()
@@ -134,7 +132,6 @@ ggatel_md_body()
{
load_ggate
- us=$(alloc_ggate_dev)
work=$(alloc_md)
src=$(alloc_md)
@@ -143,16 +140,16 @@ ggatel_md_body()
atf_check -e ignore -o ignore \
dd if=/dev/random of=$src bs=1m count=1 conv=notrunc
- atf_check ggatel create -u $us /dev/$work
-
- ggate_dev=/dev/ggate${us}
+ atf_check -o save:ggateu ggatel create /dev/$work
+ ggate_dev=/dev/`cat ggateu`
+ cat ggateu | sed 's:ggate::' >> ggate.devs
wait_for_ggate_device ${ggate_dev}
atf_check -e ignore -o ignore \
dd if=/dev/$src of=${ggate_dev} bs=1m count=1 conv=notrunc
- checksum /dev/$src /dev/$work
+ checksum /dev/$src /dev/$work $ggate_dev
}
ggatel_md_cleanup()
@@ -168,18 +165,6 @@ atf_init_test_cases()
atf_add_test_case ggatec_trim
}
-alloc_ggate_dev()
-{
- local us
-
- us=0
- while [ -c /dev/ggate${us} ]; do
- : $(( us += 1 ))
- done
- echo ${us} > ggate.devs
- echo ${us}
-}
-
alloc_md()
{
local md
@@ -195,6 +180,7 @@ checksum()
local src work
src=$1
work=$2
+ ggate_dev=$3
src_checksum=$(md5 -q $src)
work_checksum=$(md5 -q $work)
@@ -203,7 +189,7 @@ checksum()
atf_fail "work md5 checksum didn't match"
fi
- ggate_checksum=$(md5 -q /dev/ggate${us})
+ ggate_checksum=$(md5 -q $ggate_dev)
if [ "$ggate_checksum" != "$src_checksum" ]; then
atf_fail "ggate md5 checksum didn't match"
fi