NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/60056: tap(4) loses carrier randomly



The following reply was made to PR kern/60056; it has been noted by GNATS.

From: Martin Husemann <martin%duskware.de@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: 
Subject: Re: kern/60056: tap(4) loses carrier randomly
Date: Fri, 17 Apr 2026 17:39:28 +0200

 I looked at ktrace output from the emulator and tried to build 
 do the same in simple code.
 
 I can reproduce it -- but not without gdb interaction. Something magic
 going on.
 
 Compile the code below with: cc -O2 -g -Wall pr60056.c
 Prepare the tap as described in the original PR.
 
 Then do:
 
 Reading symbols from ./a.out...
 (gdb) break 35
 Breakpoint 1 at 0x4015ce: file pr60056.c, line 35.
 (gdb) run 3
 Starting program: /tmp/a.out 3
 opening /dev/tap0...
 ... and closing it again
 
 Breakpoint 1, main (argc=<optimized out>, argv=<optimized out>) at pr60056.c:35
 35                      close(dev);
 
 
 check status: ifconfig tap0 | fgrep status:
         status: active
 
 now remove the breakpoint and continue:
 
 (gdb) delete 1
 (gdb) c
 Continuing.
 opening /dev/tap0...
 ... and closing it again
 opening /dev/tap0...
 ... and closing it again
 finally opening it for real!
 waiting, check carrier
 
 
 and check carrier status again:
 
 ifconfig tap0 | fgrep status:
         status: no carrier
 
 but it should be active!
 
 I have not managed to create a reproducer w/o the gdb interaction.
 
 Martin
 
 /*
  * minimal reproducer for
  *	https://gnats.netbsd.org/60056
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <fcntl.h>
 #include <unistd.h>
 
 #define DEVICE	"/dev/tap0"
 
 int main(int argc, char **argv)
 {
 	if (argc < 2)
 		return 1;
 
 	int others[3];
 	int cnt = atoi(argv[1]);
 	int dev;
 
 	for (int i = 0; i < cnt; i++) {
 
 		if (i == 0) {
 			for (size_t j = 0; j <
 			    sizeof(others)/sizeof(others[0]); j++)
 				others[j] = open("/dev/zero", O_RDONLY);
 		}
 
 		printf("opening %s...\n", DEVICE);
 		dev = open(DEVICE, O_RDWR|O_NONBLOCK);
 		if (dev == -1)
 			return 1;
 		printf("... and closing it again\n");
 		close(dev);
 
 		if (i == 0) {
 			for (size_t j = 0; j <
 			    sizeof(others)/sizeof(others[0]); j++)
 				close(others[j]);
 		}
 	}
 	printf("finally opening it for real!\n");
 	dev = open(DEVICE, O_RDWR|O_NONBLOCK);
 	printf("waiting, check carrier\n");
 	sleep(20);
 	printf("terminating...");
 	return 0;
 }
 



Home | Main Index | Thread Index | Old Index