On Tue, Dec 09, 2008 at 01:35:53PM +0100, Jan Luebbe wrote: > As this bug makes kvm with serial console/libvirt unusable, i'd like to > get an unblock for this version. The diff is available here: > http://git.debian.org/?p=collab-maint/kvm.git;a=commitdiff;h=8743bd86d205d0873844fd0796ffd96eecab7984 > > The new version has been in unstable for 18 days and no regressions have > been found. The same bugfix has been applied in qemu 0.9.1-8, been in testing for 12 days. If kvm is found appropriate for lenny, please unblock qemu as well. Debdiff attached. -- "rm -rf" only sounds scary if you don't have backups
diff -u qemu-0.9.1/debian/changelog qemu-0.9.1/debian/changelog
--- qemu-0.9.1/debian/changelog
+++ qemu-0.9.1/debian/changelog
@@ -1,3 +1,11 @@
+qemu (0.9.1-8) unstable; urgency=low
+
+ * debian/patches:
+ - cherry-pick from svn: 61_pseudotty.patch 62_fix-ptyblocking.patch
+ closes: #494831
+
+ -- Riku Voipio <riku@debian.org> Wed, 19 Nov 2008 23:21:43 +0200
+
qemu (0.9.1-7) unstable; urgency=low
* debian/qemu-make-debian-root:
diff -u qemu-0.9.1/debian/patches/series qemu-0.9.1/debian/patches/series
--- qemu-0.9.1/debian/patches/series
+++ qemu-0.9.1/debian/patches/series
@@ -23,6 +23,8 @@
53_openbios_size.patch
55_unmux_socketcall.patch
60_ppc_ld.patch
+61_pseudotty.patch
+62_fix-ptyblocking.patch
63_sparc_build.patch -p0
64_ppc_asm_constraints.patch
65_kfreebsd.patch
only in patch2:
unchanged:
--- qemu-0.9.1.orig/debian/patches/62_fix-ptyblocking.patch
+++ qemu-0.9.1/debian/patches/62_fix-ptyblocking.patch
@@ -0,0 +1,169 @@
+--- trunk/vl.c 2008/07/23 15:19:59 4927
++++ trunk/vl.c 2008/07/28 18:55:32 4956
+@@ -2464,21 +2464,162 @@
+ #endif
+
+ #if defined(__linux__) || defined(__sun__)
++
++typedef struct {
++ int fd;
++ int connected;
++ int polling;
++ int read_bytes;
++ QEMUTimer *timer;
++} PtyCharDriver;
++
++static void pty_chr_update_read_handler(CharDriverState *chr);
++static void pty_chr_state(CharDriverState *chr, int connected);
++
++static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
++{
++ PtyCharDriver *s = chr->opaque;
++
++ if (!s->connected) {
++ /* guest sends data, check for (re-)connect */
++ pty_chr_update_read_handler(chr);
++ return 0;
++ }
++ return unix_write(s->fd, buf, len);
++}
++
++static int pty_chr_read_poll(void *opaque)
++{
++ CharDriverState *chr = opaque;
++ PtyCharDriver *s = chr->opaque;
++
++ s->read_bytes = qemu_chr_can_read(chr);
++ return s->read_bytes;
++}
++
++static void pty_chr_read(void *opaque)
++{
++ CharDriverState *chr = opaque;
++ PtyCharDriver *s = chr->opaque;
++ int size, len;
++ uint8_t buf[1024];
++
++ len = sizeof(buf);
++ if (len > s->read_bytes)
++ len = s->read_bytes;
++ if (len == 0)
++ return;
++ size = read(s->fd, buf, len);
++ if ((size == -1 && errno == EIO) ||
++ (size == 0)) {
++ pty_chr_state(chr, 0);
++ return;
++ }
++ if (size > 0) {
++ pty_chr_state(chr, 1);
++ qemu_chr_read(chr, buf, size);
++ }
++}
++
++static void pty_chr_update_read_handler(CharDriverState *chr)
++{
++ PtyCharDriver *s = chr->opaque;
++
++ qemu_set_fd_handler2(s->fd, pty_chr_read_poll,
++ pty_chr_read, NULL, chr);
++ s->polling = 1;
++ /*
++ * Short timeout here: just need wait long enougth that qemu makes
++ * it through the poll loop once. When reconnected we want a
++ * short timeout so we notice it almost instantly. Otherwise
++ * read() gives us -EIO instantly, making pty_chr_state() reset the
++ * timeout to the normal (much longer) poll interval before the
++ * timer triggers.
++ */
++ qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 10);
++}
++
++static void pty_chr_state(CharDriverState *chr, int connected)
++{
++ PtyCharDriver *s = chr->opaque;
++
++ if (!connected) {
++ qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
++ s->connected = 0;
++ s->polling = 0;
++ /* (re-)connect poll interval for idle guests: once per second.
++ * We check more frequently in case the guests sends data to
++ * the virtual device linked to our pty. */
++ qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 1000);
++ } else {
++ if (!s->connected)
++ qemu_chr_reset(chr);
++ s->connected = 1;
++ }
++}
++
++void pty_chr_timer(void *opaque)
++{
++ struct CharDriverState *chr = opaque;
++ PtyCharDriver *s = chr->opaque;
++
++ if (s->connected)
++ return;
++ if (s->polling) {
++ /* If we arrive here without polling being cleared due
++ * read returning -EIO, then we are (re-)connected */
++ pty_chr_state(chr, 1);
++ return;
++ }
++
++ /* Next poll ... */
++ pty_chr_update_read_handler(chr);
++}
++
++static void pty_chr_close(struct CharDriverState *chr)
++{
++ PtyCharDriver *s = chr->opaque;
++
++ qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
++ close(s->fd);
++ qemu_free(s);
++}
++
+ static CharDriverState *qemu_chr_open_pty(void)
+ {
++ CharDriverState *chr;
++ PtyCharDriver *s;
+ struct termios tty;
+- int master_fd, slave_fd;
++ int slave_fd;
+
+- if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) < 0) {
++ chr = qemu_mallocz(sizeof(CharDriverState));
++ if (!chr)
++ return NULL;
++ s = qemu_mallocz(sizeof(PtyCharDriver));
++ if (!s) {
++ qemu_free(chr);
++ return NULL;
++ }
++
++ if (openpty(&s->fd, &slave_fd, NULL, NULL, NULL) < 0) {
+ return NULL;
+ }
+
+ /* Set raw attributes on the pty. */
+ cfmakeraw(&tty);
+ tcsetattr(slave_fd, TCSAFLUSH, &tty);
++ close(slave_fd);
++
++ fprintf(stderr, "char device redirected to %s\n", ptsname(s->fd));
+
+- fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
+- return qemu_chr_open_fd(master_fd, master_fd);
++ chr->opaque = s;
++ chr->chr_write = pty_chr_write;
++ chr->chr_update_read_handler = pty_chr_update_read_handler;
++ chr->chr_close = pty_chr_close;
++
++ s->timer = qemu_new_timer(rt_clock, pty_chr_timer, chr);
++
++ return chr;
+ }
+
+ static void tty_serial_init(int fd, int speed,
only in patch2:
unchanged:
--- qemu-0.9.1.orig/debian/patches/61_pseudotty.patch
+++ qemu-0.9.1/debian/patches/61_pseudotty.patch
@@ -0,0 +1,95 @@
+Index: qemu-0.9.1/vl.c
+===================================================================
+--- qemu-0.9.1.orig/vl.c 2008-11-19 23:20:46.000000000 +0200
++++ qemu-0.9.1/vl.c 2008-11-19 23:20:49.000000000 +0200
+@@ -2203,28 +2203,78 @@
+ return chr;
+ }
+
++#ifdef __sun__
++/* Once Solaris has openpty(), this is going to be removed. */
++int openpty(int *amaster, int *aslave, char *name,
++ struct termios *termp, struct winsize *winp)
++{
++ const char *slave;
++ int mfd = -1, sfd = -1;
++
++ *amaster = *aslave = -1;
++
++ mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
++ if (mfd < 0)
++ goto err;
++
++ if (grantpt(mfd) == -1 || unlockpt(mfd) == -1)
++ goto err;
++
++ if ((slave = ptsname(mfd)) == NULL)
++ goto err;
++
++ if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1)
++ goto err;
++
++ if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
++ (termp != NULL && tcgetattr(sfd, termp) < 0))
++ goto err;
++
++ if (amaster)
++ *amaster = mfd;
++ if (aslave)
++ *aslave = sfd;
++ if (winp)
++ ioctl(sfd, TIOCSWINSZ, winp);
++
++ return 0;
++
++err:
++ if (sfd != -1)
++ close(sfd);
++ close(mfd);
++ return -1;
++}
++
++void cfmakeraw (struct termios *termios_p)
++{
++ termios_p->c_iflag &=
++ ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
++ termios_p->c_oflag &= ~OPOST;
++ termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
++ termios_p->c_cflag &= ~(CSIZE|PARENB);
++ termios_p->c_cflag |= CS8;
++
++ termios_p->c_cc[VMIN] = 0;
++ termios_p->c_cc[VTIME] = 0;
++}
++#endif
++
+ #if defined(__linux__) || defined(__sun__)
+ static CharDriverState *qemu_chr_open_pty(void)
+ {
+ struct termios tty;
+- char slave_name[1024];
+ int master_fd, slave_fd;
+
+-#if defined(__linux__)
+- /* Not satisfying */
+- if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
++ if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) < 0) {
+ return NULL;
+ }
+-#endif
+
+- /* Disabling local echo and line-buffered output */
+- tcgetattr (master_fd, &tty);
+- tty.c_lflag &= ~(ECHO|ICANON|ISIG);
+- tty.c_cc[VMIN] = 1;
+- tty.c_cc[VTIME] = 0;
+- tcsetattr (master_fd, TCSAFLUSH, &tty);
++ /* Set raw attributes on the pty. */
++ cfmakeraw(&tty);
++ tcsetattr(slave_fd, TCSAFLUSH, &tty);
+
+- fprintf(stderr, "char device redirected to %s\n", slave_name);
++ fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
+ return qemu_chr_open_fd(master_fd, master_fd);
+ }
+
Attachment:
signature.asc
Description: Digital signature