]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
qemu: assume 'info chardev' is always available
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 5 Nov 2015 11:00:17 +0000 (11:00 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 10 Nov 2015 10:38:01 +0000 (10:38 +0000)
As of QEMU 0.11.0 the 'info chardev' monitor command can be
used to report on allocated chardev paths, so we can drop
support for parsing QEMU stderr to locate the PTY paths.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
src/qemu/qemu_capabilities.c
src/qemu/qemu_capabilities.h
src/qemu/qemu_process.c

index 55c310cfc23c7a4fc2b362c9c7451b8b4ecaf295..a7fba5734df6a3325d84735c627662de86d08a53 100644 (file)
@@ -3842,11 +3842,6 @@ virQEMUCapsCacheFree(virQEMUCapsCachePtr cache)
     VIR_FREE(cache);
 }
 
-bool
-virQEMUCapsUsedQMP(virQEMUCapsPtr qemuCaps)
-{
-    return qemuCaps->usedQMP;
-}
 
 bool
 virQEMUCapsSupportsChardev(virDomainDefPtr def,
index af30759bc2790d2d1af2e58ae2535844ebc0e054..10658a4eb3c1ae0767dd74cfe6d1a7c2cbc5c3a4 100644 (file)
@@ -427,7 +427,6 @@ int virQEMUCapsParseDeviceStr(virQEMUCapsPtr qemuCaps, const char *str);
 
 VIR_ENUM_DECL(virQEMUCaps);
 
-bool virQEMUCapsUsedQMP(virQEMUCapsPtr qemuCaps);
 bool virQEMUCapsSupportsChardev(virDomainDefPtr def,
                                 virQEMUCapsPtr qemuCaps,
                                 virDomainChrDefPtr chr);
index 524072c6e18289fa05e4bc08cf8ff3099d830c5e..69a0f979f57a9c1b454d16fa51074b3744678eea 100644 (file)
@@ -52,7 +52,6 @@
 #include "virhook.h"
 #include "virfile.h"
 #include "virpidfile.h"
-#include "c-ctype.h"
 #include "nodeinfo.h"
 #include "domain_audit.h"
 #include "domain_nwfilter.h"
@@ -1675,76 +1674,6 @@ qemuProcessReadLog(int fd, char *buf, int buflen, int off, bool skipchar)
     return off;
 }
 
-typedef int qemuProcessLogHandleOutput(virDomainObjPtr vm,
-                                       const char *output,
-                                       int fd);
-
-/*
- * Returns -1 for error, 0 on success
- */
-static int
-qemuProcessReadLogOutput(virDomainObjPtr vm,
-                         int fd,
-                         char *buf,
-                         size_t buflen,
-                         qemuProcessLogHandleOutput func,
-                         const char *what,
-                         int timeout)
-{
-    int retries = (timeout*10);
-    int got = 0;
-    int ret = -1;
-
-    buf[0] = '\0';
-
-    while (retries) {
-        ssize_t func_ret;
-        bool isdead;
-
-        func_ret = func(vm, buf, fd);
-
-        isdead = kill(vm->pid, 0) == -1 && errno == ESRCH;
-
-        got = qemuProcessReadLog(fd, buf, buflen, got, false);
-        if (got < 0) {
-            virReportSystemError(errno,
-                                 _("Failure while reading %s log output"),
-                                 what);
-            goto cleanup;
-        }
-
-        if (got == buflen-1) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("Out of space while reading %s log output: %s"),
-                           what, buf);
-            goto cleanup;
-        }
-
-        if (isdead) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("Process exited while reading %s log output: %s"),
-                           what, buf);
-            goto cleanup;
-        }
-
-        if (func_ret <= 0) {
-            ret = func_ret;
-            goto cleanup;
-        }
-
-        usleep(100*1000);
-        retries--;
-    }
-
-    virReportError(VIR_ERR_INTERNAL_ERROR,
-                   _("Timed out while reading %s log output: %s"),
-                   what, buf);
-
- cleanup:
-    return ret;
-}
-
-
 /*
  * Read domain log and probably overwrite error if there's one in
  * the domain log file. This function exists to cover the small
@@ -1809,54 +1738,6 @@ qemuProcessReadChildErrors(virQEMUDriverPtr driver,
 }
 
 
-/*
- * Look at a chunk of data from the QEMU stdout logs and try to
- * find a TTY device, as indicated by a line like
- *
- * char device redirected to /dev/pts/3
- *
- * Returns -1 for error, 0 success, 1 continue reading
- */
-static int
-qemuProcessExtractTTYPath(const char *haystack,
-                          size_t *offset,
-                          char **path)
-{
-    static const char needle[] = "char device redirected to";
-    char *tmp, *dev;
-
-    VIR_FREE(*path);
-    /* First look for our magic string */
-    if (!(tmp = strstr(haystack + *offset, needle)))
-        return 1;
-    tmp += sizeof(needle);
-    dev = tmp;
-
-    /*
-     * And look for first whitespace character and nul terminate
-     * to mark end of the pty path
-     */
-    while (*tmp) {
-        if (c_isspace(*tmp)) {
-            if (VIR_STRNDUP(*path, dev, tmp - dev) < 0)
-                return -1;
-
-            /* ... now further update offset till we get EOL */
-            *offset = tmp - haystack;
-            return 0;
-        }
-        tmp++;
-    }
-
-    /*
-     * We found a path, but didn't find any whitespace,
-     * so it must be still incomplete - we should at
-     * least see a \n - indicate that we want to carry
-     * on trying again
-     */
-    return 1;
-}
-
 static int
 qemuProcessLookupPTYs(virDomainDefPtr def,
                       virQEMUCapsPtr qemuCaps,
@@ -1954,72 +1835,6 @@ qemuProcessFindCharDevicePTYsMonitor(virDomainObjPtr vm,
     return 0;
 }
 
-static int
-qemuProcessFindCharDevicePTYs(virDomainObjPtr vm,
-                              const char *output,
-                              int fd ATTRIBUTE_UNUSED)
-{
-    size_t offset = 0;
-    int ret;
-    size_t i;
-
-    /* The order in which QEMU prints out the PTY paths is
-       the order in which it procsses its serial and parallel
-       device args. This code must match that ordering.... */
-
-    /* first comes the serial devices */
-    for (i = 0; i < vm->def->nserials; i++) {
-        virDomainChrDefPtr chr = vm->def->serials[i];
-        if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY) {
-            if ((ret = qemuProcessExtractTTYPath(output, &offset,
-                                                 &chr->source.data.file.path)) != 0)
-                return ret;
-        }
-    }
-
-    /* then the parallel devices */
-    for (i = 0; i < vm->def->nparallels; i++) {
-        virDomainChrDefPtr chr = vm->def->parallels[i];
-        if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY) {
-            if ((ret = qemuProcessExtractTTYPath(output, &offset,
-                                                 &chr->source.data.file.path)) != 0)
-                return ret;
-        }
-    }
-
-    /* then the channel devices */
-    for (i = 0; i < vm->def->nchannels; i++) {
-        virDomainChrDefPtr chr = vm->def->channels[i];
-        if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY) {
-            if ((ret = qemuProcessExtractTTYPath(output, &offset,
-                                                 &chr->source.data.file.path)) != 0)
-                return ret;
-        }
-    }
-
-    for (i = 0; i < vm->def->nconsoles; i++) {
-        virDomainChrDefPtr chr = vm->def->consoles[i];
-        /* For historical reasons, console[0] can be just an alias
-         * for serial[0]; That's why we need to update it as well */
-        if (i == 0 && vm->def->nserials &&
-            chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
-            chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) {
-            if ((ret = virDomainChrSourceDefCopy(&chr->source,
-                                                 &((vm->def->serials[0])->source))) != 0)
-                return ret;
-        } else {
-            if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY &&
-                chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO) {
-                if ((ret = qemuProcessExtractTTYPath(output, &offset,
-                                                     &chr->source.data.file.path)) != 0)
-                    return ret;
-            }
-        }
-    }
-
-    return 0;
-}
-
 
 static int
 qemuProcessRefreshChannelVirtioState(virQEMUDriverPtr driver,
@@ -2140,15 +1955,6 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
         (logfd = qemuDomainOpenLog(driver, vm, pos)) < 0)
         return -1;
 
-    if (logfd != -1 && !virQEMUCapsUsedQMP(qemuCaps)) {
-        if (VIR_ALLOC_N(buf, buf_size) < 0)
-            goto closelog;
-
-        if (qemuProcessReadLogOutput(vm, logfd, buf, buf_size,
-                                     qemuProcessFindCharDevicePTYs,
-                                     "console", 30) < 0)
-            goto closelog;
-    }
 
     VIR_DEBUG("Connect monitor to %p '%s'", vm, vm->def->name);
     if (qemuConnectMonitor(driver, vm, asyncJob, logfd) < 0)
@@ -2180,20 +1986,16 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
     virHashFree(info);
 
     if (pos != -1 && kill(vm->pid, 0) == -1 && errno == ESRCH) {
-        int len;
         /* VM is dead, any other error raised in the interim is probably
          * not as important as the qemu cmdline output */
-        if (virQEMUCapsUsedQMP(qemuCaps)) {
-            if (VIR_ALLOC_N(buf, buf_size) < 0)
-                goto closelog;
-        }
+        if (VIR_ALLOC_N(buf, buf_size) < 0)
+            goto closelog;
 
-        len = strlen(buf);
         /* best effort seek - we need to reset to the original position, so that
          * a possible read of the fd in the monitor code doesn't influence this
          * error delivery option */
         ignore_value(lseek(logfd, pos, SEEK_SET));
-        qemuProcessReadLog(logfd, buf + len, buf_size - len - 1, 0, true);
+        qemuProcessReadLog(logfd, buf, buf_size - 1, 0, true);
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("process exited while connecting to monitor: %s"),
                        buf);