diff options
author | Guido Günther <agx@sigxcpu.org> | 2014-10-02 07:22:54 +0200 |
---|---|---|
committer | Guido Günther <agx@sigxcpu.org> | 2014-10-02 07:22:54 +0200 |
commit | 2d120a7cdfdfcbfdf1be62d6dc4cfe4cd758e88f (patch) | |
tree | 1c4437acbc17989a611e7843eee99513dde0df41 /src | |
parent | 8707039d5fcb05230d3ad5b21de4113ccf86cf1c (diff) |
New upstream version 1.2.9
Diffstat (limited to 'src')
-rw-r--r-- | src/conf/domain_conf.c | 2 | ||||
-rw-r--r-- | src/cpu/cpu_x86.c | 14 | ||||
-rw-r--r-- | src/qemu/qemu_driver.c | 50 | ||||
-rw-r--r-- | src/qemu/qemu_migration.c | 22 | ||||
-rw-r--r-- | src/qemu/qemu_monitor.c | 14 | ||||
-rw-r--r-- | src/qemu/qemu_monitor.h | 6 | ||||
-rw-r--r-- | src/qemu/qemu_monitor_json.c | 111 | ||||
-rw-r--r-- | src/qemu/qemu_monitor_json.h | 4 | ||||
-rw-r--r-- | src/qemu/qemu_process.c | 5 |
9 files changed, 105 insertions, 123 deletions
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b11473754..6ea25df40 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -20560,7 +20560,7 @@ virDomainListPopulate(void *payload, /* just count the machines */ if (!data->domains) { data->ndomains++; - return; + goto cleanup; } if (!(dom = virGetDomain(data->conn, vm->def->name, vm->def->uuid))) { diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index a98a84772..57f343c60 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -2068,7 +2068,8 @@ x86UpdateCustom(virCPUDefPtr guest, static int x86UpdateHostModel(virCPUDefPtr guest, - const virCPUDef *host) + const virCPUDef *host, + bool passthrough) { virCPUDefPtr oldguest = NULL; const struct x86_map *map; @@ -2076,8 +2077,6 @@ x86UpdateHostModel(virCPUDefPtr guest, size_t i; int ret = -1; - guest->match = VIR_CPU_MATCH_EXACT; - if (!(map = virCPUx86GetMap())) goto cleanup; @@ -2100,8 +2099,7 @@ x86UpdateHostModel(virCPUDefPtr guest, } } } - - for (i = 0; i < oldguest->nfeatures; i++) { + for (i = 0; !passthrough && i < oldguest->nfeatures; i++) { if (virCPUDefUpdateFeature(guest, oldguest->features[i].name, oldguest->features[i].policy) < 0) @@ -2125,12 +2123,12 @@ x86Update(virCPUDefPtr guest, return x86UpdateCustom(guest, host); case VIR_CPU_MODE_HOST_MODEL: - return x86UpdateHostModel(guest, host); + guest->match = VIR_CPU_MATCH_EXACT; + return x86UpdateHostModel(guest, host, false); case VIR_CPU_MODE_HOST_PASSTHROUGH: guest->match = VIR_CPU_MATCH_MINIMUM; - virCPUDefFreeModel(guest); - return virCPUDefCopyModel(guest, host, true); + return x86UpdateHostModel(guest, host, true); case VIR_CPU_MODE_LAST: break; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 6606154eb..e873d4570 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12023,12 +12023,6 @@ qemuDomainMigrateSetMaxDowntime(virDomainPtr dom, priv = vm->privateData; - if (priv->job.asyncJob != QEMU_ASYNC_JOB_MIGRATION_OUT) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("domain is not being migrated")); - goto endjob; - } - VIR_DEBUG("Setting migration downtime to %llums", downtime); qemuDomainObjEnterMonitor(driver, vm); ret = qemuMonitorSetMigrationDowntime(priv->mon, downtime); @@ -17922,24 +17916,18 @@ qemuDomainGetStatsBlock(virQEMUDriverPtr driver, { size_t i; int ret = -1; - int nstats = dom->def->ndisks; - qemuBlockStatsPtr stats = NULL; + int rc; + virHashTablePtr stats = NULL; qemuDomainObjPrivatePtr priv = dom->privateData; if (!HAVE_JOB(privflags) || !virDomainObjIsActive(dom)) return 0; /* it's ok, just go ahead silently */ - if (VIR_ALLOC_N(stats, nstats) < 0) - return -1; - qemuDomainObjEnterMonitor(driver, dom); - - nstats = qemuMonitorGetAllBlockStatsInfo(priv->mon, NULL, - stats, nstats); - + rc = qemuMonitorGetAllBlockStatsInfo(priv->mon, &stats); qemuDomainObjExitMonitor(driver, dom); - if (nstats < 0) { + if (rc < 0) { virResetLastError(); ret = 0; /* still ok, again go ahead silently */ goto cleanup; @@ -17947,32 +17935,38 @@ qemuDomainGetStatsBlock(virQEMUDriverPtr driver, QEMU_ADD_COUNT_PARAM(record, maxparams, "block", dom->def->ndisks); - for (i = 0; i < nstats; i++) { - QEMU_ADD_NAME_PARAM(record, maxparams, - "block", i, dom->def->disks[i]->dst); + for (i = 0; i < dom->def->ndisks; i++) { + qemuBlockStats *entry; + virDomainDiskDefPtr disk = dom->def->disks[i]; + + QEMU_ADD_NAME_PARAM(record, maxparams, "block", i, disk->dst); + + if (!disk->info.alias || + !(entry = virHashLookup(stats, disk->info.alias))) + continue; QEMU_ADD_BLOCK_PARAM_LL(record, maxparams, i, - "rd.reqs", stats[i].rd_req); + "rd.reqs", entry->rd_req); QEMU_ADD_BLOCK_PARAM_LL(record, maxparams, i, - "rd.bytes", stats[i].rd_bytes); + "rd.bytes", entry->rd_bytes); QEMU_ADD_BLOCK_PARAM_LL(record, maxparams, i, - "rd.times", stats[i].rd_total_times); + "rd.times", entry->rd_total_times); QEMU_ADD_BLOCK_PARAM_LL(record, maxparams, i, - "wr.reqs", stats[i].wr_req); + "wr.reqs", entry->wr_req); QEMU_ADD_BLOCK_PARAM_LL(record, maxparams, i, - "wr.bytes", stats[i].wr_bytes); + "wr.bytes", entry->wr_bytes); QEMU_ADD_BLOCK_PARAM_LL(record, maxparams, i, - "wr.times", stats[i].wr_total_times); + "wr.times", entry->wr_total_times); QEMU_ADD_BLOCK_PARAM_LL(record, maxparams, i, - "fl.reqs", stats[i].flush_req); + "fl.reqs", entry->flush_req); QEMU_ADD_BLOCK_PARAM_LL(record, maxparams, i, - "fl.times", stats[i].flush_total_times); + "fl.times", entry->flush_total_times); } ret = 0; cleanup: - VIR_FREE(stats); + virHashFree(stats); return ret; } diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 6b38592d1..284cd5adb 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1714,18 +1714,20 @@ qemuMigrationIsAllowed(virQEMUDriverPtr driver, virDomainObjPtr vm, return false; } - for (i = 0; def->cpu && i < def->cpu->nfeatures; i++) { - virCPUFeatureDefPtr feature = &def->cpu->features[i]; + if (def->cpu && def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH) { + for (i = 0; i < def->cpu->nfeatures; i++) { + virCPUFeatureDefPtr feature = &def->cpu->features[i]; - if (feature->policy != VIR_CPU_FEATURE_REQUIRE) - continue; + if (feature->policy != VIR_CPU_FEATURE_REQUIRE) + continue; - /* QEMU blocks migration and save with invariant TSC enabled */ - if (STREQ(feature->name, "invtsc")) { - virReportError(VIR_ERR_OPERATION_INVALID, - _("domain has CPU feature: %s"), - feature->name); - return false; + /* QEMU blocks migration and save with invariant TSC enabled */ + if (STREQ(feature->name, "invtsc")) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("domain has CPU feature: %s"), + feature->name); + return false; + } } } diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index c25f00208..543384dc1 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1763,23 +1763,17 @@ int qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon, */ int qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon, - const char *dev_name, - qemuBlockStatsPtr stats, - int nstats) + virHashTablePtr *ret_stats) { - int ret; - VIR_DEBUG("mon=%p dev=%s", mon, dev_name); + VIR_DEBUG("mon=%p ret_stats=%p", mon, ret_stats); - if (mon->json) { - ret = qemuMonitorJSONGetAllBlockStatsInfo(mon, dev_name, - stats, nstats); - } else { + if (!mon->json) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("unable to query all block stats with this QEMU")); return -1; } - return ret; + return qemuMonitorJSONGetAllBlockStatsInfo(mon, ret_stats); } /* Return 0 and update @nparams with the number of block stats diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 6b91e2990..adf18ab5e 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -361,10 +361,8 @@ struct _qemuBlockStats { }; int qemuMonitorGetAllBlockStatsInfo(qemuMonitorPtr mon, - const char *dev_name, - qemuBlockStatsPtr stats, - int nstats) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3); + virHashTablePtr *ret_stats) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); int qemuMonitorGetBlockStatsParamsNumber(qemuMonitorPtr mon, int *nparams); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index a3d7c2c79..b3b645101 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -1734,7 +1734,8 @@ int qemuMonitorJSONGetBlockStatsInfo(qemuMonitorPtr mon, long long *flush_total_times, long long *errs) { - qemuBlockStats stats; + qemuBlockStats *stats; + virHashTablePtr blockstats = NULL; int ret = -1; *rd_req = *rd_bytes = -1; @@ -1749,56 +1750,61 @@ int qemuMonitorJSONGetBlockStatsInfo(qemuMonitorPtr mon, if (flush_total_times) *flush_total_times = -1; - if (qemuMonitorJSONGetAllBlockStatsInfo(mon, dev_name, &stats, 1) != 1) + if (qemuMonitorJSONGetAllBlockStatsInfo(mon, &blockstats) < 0) goto cleanup; - *rd_req = stats.rd_req; - *rd_bytes = stats.rd_bytes; - *wr_req = stats.wr_req; - *wr_bytes = stats.wr_bytes; + if (!(stats = virHashLookup(blockstats, dev_name))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot find statistics for device '%s'"), dev_name); + goto cleanup; + } + + *rd_req = stats->rd_req; + *rd_bytes = stats->rd_bytes; + *wr_req = stats->wr_req; + *wr_bytes = stats->wr_bytes; *errs = -1; /* QEMU does not have this */ if (rd_total_times) - *rd_total_times = stats.rd_total_times; + *rd_total_times = stats->rd_total_times; if (wr_total_times) - *wr_total_times = stats.wr_total_times; + *wr_total_times = stats->wr_total_times; if (flush_req) - *flush_req = stats.flush_req; + *flush_req = stats->flush_req; if (flush_total_times) - *flush_total_times = stats.flush_total_times; + *flush_total_times = stats->flush_total_times; ret = 0; cleanup: + virHashFree(blockstats); return ret; } int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon, - const char *dev_name, - qemuBlockStatsPtr bstats, - int nstats) + virHashTablePtr *ret_stats) { - int ret, count; + int ret = -1; + int rc; size_t i; - virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-blockstats", - NULL); + virJSONValuePtr cmd; virJSONValuePtr reply = NULL; virJSONValuePtr devices; + qemuBlockStatsPtr bstats = NULL; + virHashTablePtr hash = NULL; - if (!cmd) + if (!(cmd = qemuMonitorJSONMakeCommand("query-blockstats", NULL))) return -1; - if (!bstats || nstats <= 0) - return -1; + if (!(hash = virHashCreate(10, virHashValueFree))) + goto cleanup; - ret = qemuMonitorJSONCommand(mon, cmd, &reply); + if ((rc = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) + goto cleanup; - if (ret == 0) - ret = qemuMonitorJSONCheckError(cmd, reply); - if (ret < 0) + if (qemuMonitorJSONCheckError(cmd, reply) < 0) goto cleanup; - ret = -1; devices = virJSONValueObjectGet(reply, "return"); if (!devices || devices->type != VIR_JSON_TYPE_ARRAY) { @@ -1807,10 +1813,14 @@ int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon, goto cleanup; } - count = 0; - for (i = 0; i < virJSONValueArraySize(devices) && count < nstats; i++) { + for (i = 0; i < virJSONValueArraySize(devices); i++) { virJSONValuePtr dev = virJSONValueArrayGet(devices, i); virJSONValuePtr stats; + const char *dev_name; + + if (VIR_ALLOC(bstats) < 0) + goto cleanup; + if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("blockstats device entry was not " @@ -1818,29 +1828,16 @@ int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon, goto cleanup; } - /* If dev_name is specified, we are looking for a specific device, - * so we must be stricter. - */ - if (dev_name) { - const char *thisdev = virJSONValueObjectGetString(dev, "device"); - if (!thisdev) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("blockstats device entry was not " - "in expected format")); - goto cleanup; - } - - /* New QEMU has separate names for host & guest side of the disk - * and libvirt gives the host side a 'drive-' prefix. The passed - * in dev_name is the guest side though - */ - if (STRPREFIX(thisdev, QEMU_DRIVE_HOST_PREFIX)) - thisdev += strlen(QEMU_DRIVE_HOST_PREFIX); - - if (STRNEQ(thisdev, dev_name)) - continue; + if (!(dev_name = virJSONValueObjectGetString(dev, "device"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("blockstats device entry was not " + "in expected format")); + goto cleanup; } + if (STRPREFIX(dev_name, QEMU_DRIVE_HOST_PREFIX)) + dev_name += strlen(QEMU_DRIVE_HOST_PREFIX); + if ((stats = virJSONValueObjectGet(dev, "stats")) == NULL || stats->type != VIR_JSON_TYPE_OBJECT) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -1910,22 +1907,18 @@ int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon, goto cleanup; } - count++; - bstats++; - - if (dev_name && count) - break; - } - - if (dev_name && !count) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot find statistics for device '%s'"), dev_name); - goto cleanup; + if (virHashAddEntry(hash, dev_name, bstats) < 0) + goto cleanup; + bstats = NULL; } - ret = count; + *ret_stats = hash; + hash = NULL; + ret = 0; cleanup: + VIR_FREE(bstats); + virHashFree(hash); virJSONValueFree(cmd); virJSONValueFree(reply); return ret; diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index d366179ea..ef9b55256 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -80,9 +80,7 @@ int qemuMonitorJSONGetBlockStatsInfo(qemuMonitorPtr mon, long long *flush_total_times, long long *errs); int qemuMonitorJSONGetAllBlockStatsInfo(qemuMonitorPtr mon, - const char *dev_name, - qemuBlockStatsPtr stats, - int nstats); + virHashTablePtr *ret_stats); int qemuMonitorJSONGetBlockStatsParamsNumber(qemuMonitorPtr mon, int *nparams); int qemuMonitorJSONGetBlockExtent(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 1b8931ea2..11eeb3ca3 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3787,6 +3787,11 @@ qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver, bool ret = false; size_t i; + /* no features are passed to QEMU with -cpu host + * so it makes no sense to verify them */ + if (def->cpu && def->cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) + return true; + switch (arch) { case VIR_ARCH_I686: case VIR_ARCH_X86_64: |