From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.33) id 1BxW8E-0006XG-85 for qemu-devel@nongnu.org; Wed, 18 Aug 2004 15:29:58 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.33) id 1BxW8D-0006Wa-Cj for qemu-devel@nongnu.org; Wed, 18 Aug 2004 15:29:57 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1BxW8D-0006WI-B0 for qemu-devel@nongnu.org; Wed, 18 Aug 2004 15:29:57 -0400 Received: from [64.142.19.5] (helo=b.mail.sonic.net) by monty-python.gnu.org with esmtp (TLSv1:DES-CBC3-SHA:168) (Exim 4.34) id 1BxW3o-0007pX-Kc for qemu-devel@nongnu.org; Wed, 18 Aug 2004 15:25:25 -0400 Received: from windmill.dloo.org (adsl-209-204-144-115.sonic.net [209.204.144.115]) (authenticated bits=0) by b.mail.sonic.net (8.12.11/8.12.11) with ESMTP id i7IJPLBs003224 (version=TLSv1/SSLv3 cipher=RC4-MD5 bits=128 verify=NO) for ; Wed, 18 Aug 2004 12:25:22 -0700 From: Nile Geisinger Date: Wed, 18 Aug 2004 12:16:28 +0000 MIME-Version: 1.0 Content-Disposition: inline Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Message-Id: <200408181216.28425.nile@dloo.com> Subject: [Qemu-devel] Serial Port Bug: HOWTO reproduce Reply-To: nile@dloo.com, qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Hi everyone, First of all, a big thanks to the individual(s) who recently cleaned up the serial code. It is significantly easier to understand than before and has been nicely refactored. Qemu is advancing very rapidlly. In the process, though, one bug appears to have been fixed and another introduced. Previously, in the 0.60 release, additional serial ports would allow the guest to transfer data to the host, but would be unreliable in the other direction. In the latest, the problem has been exactly flipped, as Darryl discovered (most of the time it allows no data transfer at all). I've verified the bug independently using named pipes and separate programs. I haven't been able to solve the bug yet and would appreciate any help. The postscript to this email contains 4 simple steps for reproducing the bug. thanks, Nile P.S. To reproduce the bug, do the following. I've attached the two files read.c and write.c below. 1. First download and apply Darryl's patch from www.dad-answers.com/qemu/patches/Serial/ to the latest snapshot. 2. Create a named pipe and test it on the host. a. Create the pipe on the host mkfifo mypipe b. Test the pipe: cat < mypipe & echo hello > mypipe (should print hello) 3. Start up a guest operating system (preferably i386/Linux for these tests) and pass qemu the option "-com2_serial mypipe" (Supply your own kernel and hard drive image names below): ./qemu -nographic -com2-serial mypipe -hda myimage -kernel mykernel -append "console=ttyS0 root=/dev/hda1 sb=0x220,5,1,5 ide2=noprobe ide3=noprobe ide4=noprobe ide5=noprobe" 4. Test the bug: a. Copy read.c and write.c to the guest. Compile them as the programs 'read' and 'write' gcc read.c -o read gcc write.c -o write b. Verify that reading works In guest: ./read /dev/ttyS1 In host: echo hello > mypipe (hello will appear in the guest) c. Verify that writing doesn't In host: cat < mypipe In guest: ./write /dev/ttyS1 (both will hang) Given the fact that this bug is recent, there's probably some small change that caused it. Any help would be appreciated! =========================== read.c =========================== #include #include #include #include /* Read example */ main(int argc, char *argv[]) { struct termios initial_tp; struct termios tp; int fd; int datalength = 6; int bytes_read = 0; char data_buffer[4096]; long baud = B38400; if ((fd = open(argv[1], O_RDONLY)) < 0) { perror("bad terminal device, try another"); exit(-1); } if (tcgetattr(fd, &initial_tp) < 0) { perror("Couldn't get term attributes"); exit(-1); } /* 8 bits + baud rate + local control */ tp = initial_tp; tp.c_cflag = CS8|CLOCAL|baud|CREAD; tp.c_oflag = 0; /* XON/XOFF flow control, ignore CR, ignore parity */ tp.c_iflag = IGNCR|IGNPAR; tp.c_lflag = 0; /* set output and input baud rates */ cfsetospeed(&tp, baud); cfsetispeed(&tp, baud); if (tcsetattr(fd, TCSANOW, &tp) < 0) { perror("Couldn't set term attributes"); exit(-1); } /* read the data */ printf("Trying to read %d bytes of data from %s.\n", datalength, argv[1]); bytes_read = read(fd, data_buffer, datalength); data_buffer[bytes_read] = '\0'; printf("Successfully read %d bytes of data (%s).\n", bytes_read, data_buffer); /* reset the term attributes */ if (tcsetattr(fd, TCSANOW, &initial_tp) < 0) { perror("Couldn't set term attributes"); exit(-1); } exit(0); } =========================== write.c =========================== #include #include #include #include #include /* Write example */ main(int argc, char *argv[]) { struct termios initial_tp; struct termios tp; int fd; int bytes_written = 0; long baud = B38400; char * data = "goodbye"; int datalength; datalength = strlen(data); if ((fd = open(argv[1], O_RDWR)) < 0) { perror("bad terminal device, try another"); exit(-1); } if (tcgetattr(fd, &initial_tp) < 0) { perror("Couldn't get term attributes"); exit(-1); } /* 8 bits + baud rate + local control */ tp = initial_tp; tp.c_cflag = CS8|CLOCAL|baud; tp.c_oflag = 0; /* XON/XOFF flow control, ignore CR, ignore parity */ tp.c_iflag = IXON|IGNBRK|IGNCR|IGNPAR; tp.c_lflag = 0; /* set output and input baud rates */ cfsetospeed(&tp, baud); cfsetispeed(&tp, baud); if (tcsetattr(fd, TCSANOW, &tp) < 0) { perror("Couldn't set term attributes"); exit(-1); } /* write the data */ printf("Trying to write data %s to %s.\n", data, argv[1]); bytes_written = write(fd, data, datalength); printf("Wrote %d bytes of the data.\n", bytes_written); /* reset the term attributes */ if (tcsetattr(fd, TCSANOW, &initial_tp) < 0) { perror("Couldn't set term attributes"); exit(-1); } exit(0); }