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