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
This commit is contained in:
Alan Somers committed 2026-10-15 06:16:16 -06:00
1 parent f84cdc2584
commit 802f5e4d69
4 files changed
+33 -43

No files matched your search

+13 -8
View File
@@ -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);
+3 -1
View File
@@ -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);
}
-3
View File
@@ -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>
+17 -31
View File
@@ -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