summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGuido Günther <agx@sigxcpu.org>2014-10-02 07:22:54 +0200
committerGuido Günther <agx@sigxcpu.org>2014-10-02 07:22:54 +0200
commit2d120a7cdfdfcbfdf1be62d6dc4cfe4cd758e88f (patch)
tree1c4437acbc17989a611e7843eee99513dde0df41 /src
parent8707039d5fcb05230d3ad5b21de4113ccf86cf1c (diff)
New upstream version 1.2.9
Diffstat (limited to 'src')
-rw-r--r--src/conf/domain_conf.c2
-rw-r--r--src/cpu/cpu_x86.c14
-rw-r--r--src/qemu/qemu_driver.c50
-rw-r--r--src/qemu/qemu_migration.c22
-rw-r--r--src/qemu/qemu_monitor.c14
-rw-r--r--src/qemu/qemu_monitor.h6
-rw-r--r--src/qemu/qemu_monitor_json.c111
-rw-r--r--src/qemu/qemu_monitor_json.h4
-rw-r--r--src/qemu/qemu_process.c5
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: