[libvirt] [PATCH v6 30/33] qemu_driver: Identify using libvirt as a distinct way to compute baseline

2019-01-12 Thread Chris Venteicher
Hypervisor baseline cpu can be computed locally using libvirt utility
functions or remotely using QEMU QMP commands.

Likewise, cpu feature expansion can be computed locally using libvirt
utility functions or remotely using QEMU QMP commands.

This patch identifies using libvirt as a distinct case in the hypervisor
baseline logic and triggers that case when the X86 architecture is being
baselined.

There is one functionality change introduced by this patch.

Local libvirt functions are only used for feature expansion when the
local utility functions are used for CPU baseline and an error is
generated when no method is available to expand cpu featues.

The useQEMU option will be introduced in a future patch for using QEMU
to compute baseline rather than using libvirt.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_driver.c | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2a030bed2f..e9f5686dbe 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13763,6 +13763,7 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 bool migratable;
 virCPUDefPtr cpu = NULL;
 char *cpustr = NULL;
+bool useLibvirt = false;
 
 virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES |
   VIR_CONNECT_BASELINE_CPU_MIGRATABLE, NULL);
@@ -13782,7 +13783,9 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 if (!qemuCaps)
 goto cleanup;
 
-if (ARCH_IS_X86(arch)) {
+useLibvirt = ARCH_IS_X86(arch);
+
+if (useLibvirt) {
 migratable = !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE);
 
 if (qemuConnectBaselineHypervisorCPUViaLibvirt(qemuCaps, migratable,
@@ -13798,9 +13801,17 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 
 cpu->fallback = VIR_CPU_FALLBACK_FORBID;
 
-if ((flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
-virCPUExpandFeatures(arch, cpu) < 0)
-goto cleanup;
+if (flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) {
+if (useLibvirt && virCPUExpandFeatures(arch, cpu) < 0) {
+goto cleanup;
+} else {
+virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+   _("expand features while "
+ "computing baseline hypervisor CPU is not 
supported "
+ "for arch %s"), virArchToString(arch));
+goto cleanup;
+}
+}
 
 cpustr = virCPUDefFormat(cpu, NULL);
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 31/33] qemu_driver: Support baseline calculation using QEMU

2019-01-12 Thread Chris Venteicher
Add capability to calculate hypervisor baseline using QMP message
exchanges with QEMU in addition to existing capability to calculate
baseline using libvirt utility functions.

A new utility function encapsulates the core logic for interacting with QEMU
using QMP baseline messages. The QMP messages only allow two cpu models
to be evaluated at a time so a sequence of QMP baseline messages must be
used to include all the models in the baseline when more than 2 cpu
models are input.

A QEMU process must be started prior to sending the series of QEMU
messages to compute baseline.

The QEMU process is started and maintained in the main hypervisor
baseline function and only a pointer to the QEMU process monitor is
passed to the baseline utility function.

The QEMU process is maintained in the main hypervisor baseline function
because the process will also be used for feature expansion (via QEMU)
in a later patch.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_driver.c | 97 ++
 1 file changed, 97 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e9f5686dbe..5068805f51 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13696,6 +13696,78 @@ qemuConnectBaselineCPU(virConnectPtr conn 
ATTRIBUTE_UNUSED,
 }
 
 
+/* in:
+ *  cpus[0]->model = "z14";
+ *  cpus[0]->features[0].name = "xxx";
+ *  cpus[0]->features[1].name = "yyy";
+ *  ***
+ *  cpus[n]->model = "z13";
+ *  cpus[n]->features[0].name = "xxx";
+ *  cpus[n]->features[1].name = "yyy";
+ *
+ * out:
+ *  *baseline->model = "z13-base";
+ *  *baseline->features[0].name = "yyy";
+ */
+static int
+qemuConnectBaselineHypervisorCPUViaQEMU(qemuMonitorPtr mon,
+virCPUDefPtr *cpus,
+virCPUDefPtr *baseline)
+{
+qemuMonitorCPUModelInfoPtr model_baseline = NULL;
+qemuMonitorCPUModelInfoPtr new_model_baseline = NULL;
+qemuMonitorCPUModelInfoPtr next_model = NULL;
+bool migratable = true;
+int ret = -1;
+size_t i;
+
+*baseline = NULL;
+
+if (!cpus || !cpus[0]) {
+virReportError(VIR_ERR_INVALID_ARG, "%s", _("no cpus"));
+goto cleanup;
+}
+
+for (i = 0; cpus[i]; i++) {  /* cpus terminated by NULL element */
+virCPUDefPtr cpu = cpus[i];
+
+VIR_DEBUG("cpu[%lu]->model = %s", i, NULLSTR(cpu->model));
+
+if (!(next_model = virQEMUCapsCPUModelInfoFromCPUDef(cpu)))
+goto cleanup;
+
+if (i == 0) {
+model_baseline = next_model;
+continue;
+}
+
+if (qemuMonitorGetCPUModelBaseline(mon, model_baseline,
+   next_model, _model_baseline) < 
0)
+goto cleanup;
+
+qemuMonitorCPUModelInfoFree(model_baseline);
+qemuMonitorCPUModelInfoFree(next_model);
+
+next_model = NULL;
+
+model_baseline = new_model_baseline;
+}
+
+if (!(*baseline = virQEMUCapsCPUModelInfoToCPUDef(model_baseline, 
migratable)))
+goto cleanup;
+
+VIR_DEBUG("baseline->model = %s", (*baseline)->model);
+
+ret = 0;
+
+ cleanup:
+qemuMonitorCPUModelInfoFree(model_baseline);
+qemuMonitorCPUModelInfoFree(next_model);
+
+return ret;
+}
+
+
 static int
 qemuConnectBaselineHypervisorCPUViaLibvirt(
 virQEMUCapsPtr qemuCaps,
@@ -13764,6 +13836,11 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 virCPUDefPtr cpu = NULL;
 char *cpustr = NULL;
 bool useLibvirt = false;
+bool useQemu = false;
+bool forceTCG = false;
+qemuMonitorCPUModelInfoPtr modelInfo = NULL;
+qemuMonitorCPUModelInfoPtr expansion = NULL;
+qemuProcessQMPPtr proc = NULL;
 
 virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES |
   VIR_CONNECT_BASELINE_CPU_MIGRATABLE, NULL);
@@ -13784,6 +13861,7 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 goto cleanup;
 
 useLibvirt = ARCH_IS_X86(arch);
+useQemu = ARCH_IS_S390(arch);
 
 if (useLibvirt) {
 migratable = !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE);
@@ -13792,6 +13870,21 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
virttype, arch,
cpus, ncpus, ) < 0)
 goto cleanup;
+
+} else if (useQemu) {
+const char *binary = virQEMUCapsGetBinary(qemuCaps);
+virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+
+if (!(proc = qemuProcessQMPNew(binary, cfg->libDir,
+  cfg->user, cfg->group, forceTCG)))
+goto cleanup;
+
+if (qemuProcessQMPStart(proc) < 0)
+goto cleanup;
+
+ 

[libvirt] [PATCH v6 33/33] qemu_monitor: Default props to migratable when expanding cpu model

2019-01-12 Thread Chris Venteicher
QEMU only returns migratable props when expanding model unless
explicitly told to also include non-migratable props.

Props will be marked migratable when we are certain QEMU returned only
migratable props resulting in consistent information and expansion output
for s390 that is consistent with x86.

After this change,
immediately default prop->migratable = _YES for all props
when we know QEMU only included migratable props in CPU Model.

Set model->migratability = true when we have set prop->migratable.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_monitor.c   | 55 +++-
 src/qemu/qemu_monitor.h   |  7 +-
 .../caps_2.10.0.s390x.xml | 60 -
 .../caps_2.11.0.s390x.xml | 58 -
 .../caps_2.12.0.s390x.xml | 56 
 .../qemucapabilitiesdata/caps_2.8.0.s390x.xml | 32 +-
 .../qemucapabilitiesdata/caps_2.9.0.s390x.xml | 34 +-
 .../qemucapabilitiesdata/caps_3.0.0.s390x.xml | 64 +--
 8 files changed, 211 insertions(+), 155 deletions(-)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 56a3bbcea1..d9171dbf83 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3687,12 +3687,31 @@ qemuMonitorGetCPUModelExpansion(qemuMonitorPtr mon,
 qemuMonitorCPUModelInfoPtr *expansion
)
 {
+int ret = -1;
+qemuMonitorCPUModelInfoPtr tmp;
+
 VIR_DEBUG("type=%d model_name=%s migratable=%d",
   type, input->name, migratable);
 
+*expansion = NULL;
+
 QEMU_CHECK_MONITOR(mon);
 
-return qemuMonitorJSONGetCPUModelExpansion(mon, type, input, migratable, 
expansion);
+if ((ret = qemuMonitorJSONGetCPUModelExpansion(mon, type, input, 
migratable, )) < 0)
+goto cleanup;
+
+if (migratable) {
+/* Only migratable props were included in expanded CPU model */
+*expansion = qemuMonitorCPUModelInfoCopyDefaultMigratable(tmp);
+} else {
+VIR_STEAL_PTR(*expansion, tmp);
+}
+
+ret = 0;
+
+ cleanup:
+qemuMonitorCPUModelInfoFree(tmp);
+return ret;
 }
 
 
@@ -3742,7 +3761,7 @@ qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo 
*orig)
 qemuMonitorCPUModelInfoPtr copy = NULL;
 size_t i;
 
-if (!(copy = qemuMonitorCPUModelInfoNew(orig->name)))
+if (!orig || !(copy = qemuMonitorCPUModelInfoNew(orig->name)))
 goto error;
 
 if (VIR_ALLOC_N(copy->props, orig->nprops) < 0)
@@ -3785,6 +3804,38 @@ qemuMonitorCPUModelInfoCopy(const 
qemuMonitorCPUModelInfo *orig)
 }
 
 
+qemuMonitorCPUModelInfoPtr
+qemuMonitorCPUModelInfoCopyDefaultMigratable(const qemuMonitorCPUModelInfo 
*orig)
+{
+qemuMonitorCPUModelInfoPtr ret = NULL;
+qemuMonitorCPUModelInfoPtr tmp = NULL;
+qemuMonitorCPUPropertyPtr prop = NULL;
+size_t i;
+
+if (!(tmp = qemuMonitorCPUModelInfoCopy(orig)))
+goto cleanup;
+
+for (i = 0; i < tmp->nprops; i++) {
+prop = tmp->props + i;
+
+/* Default prop thats in cpu model (true) to migratable (_YES)
+ * unless prop already explicitly set not migratable (_NO)
+ */
+if (prop->type == QEMU_MONITOR_CPU_PROPERTY_BOOLEAN &&
+prop->value.boolean &&
+prop->migratable != VIR_TRISTATE_BOOL_NO)
+prop->migratable = VIR_TRISTATE_BOOL_YES;
+}
+
+tmp->migratability = true; /* prop->migratable = YES/NO for all CPU props 
*/
+
+VIR_STEAL_PTR(ret, tmp);
+
+ cleanup:
+return ret;
+}
+
+
 /* Squash CPU Model Info property list
  * removing props of type boolean matching value */
 void
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index c54f311632..0487cc2ca3 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1050,7 +1050,7 @@ struct _qemuMonitorCPUModelInfo {
 char *name;
 size_t nprops;
 qemuMonitorCPUPropertyPtr props;
-bool migratability;
+bool migratability; /* true if prop->migratable is YES/NO for all CPU 
props */
 };
 
 typedef enum {
@@ -1073,6 +1073,11 @@ qemuMonitorCPUModelInfoPtr 
qemuMonitorCPUModelInfoNew(const char *name);
 qemuMonitorCPUModelInfoPtr
 qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig);
 
+qemuMonitorCPUModelInfoPtr
+qemuMonitorCPUModelInfoCopyDefaultMigratable(const qemuMonitorCPUModelInfo 
*orig)
+ATTRIBUTE_NONNULL(1);
+
+
 int qemuMonitorCPUModelInfoBoolPropAdd(qemuMonitorCPUModelInfoPtr model,
const char *prop_name,
bool prop_value)
diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml 
b/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml
index 180a688ba2..07f4da579b 100644
--- a/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml
+++ b/tests/q

[libvirt] [PATCH v6 26/33] qemu_capabilities: Introduce virCPUDef to CPUModelInfo function

2019-01-12 Thread Chris Venteicher
Create public function to convert virCPUDef data structure into
qemuMonitorCPUModelInfoPtr data structure.

There was no existing code to reuse to create this function
so this new virQEMUCapsCPUModelInfoFromCPUDef function was based on
reversing the action of the existing virQEMUCapsCPUModelInfoToCPUDef
function.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 52 
 src/qemu/qemu_capabilities.h |  1 +
 2 files changed, 53 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2bb56763b0..d0a2a42c97 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3664,6 +3664,58 @@ virQEMUCapsLoadCache(virArch hostArch,
 }
 
 
+/**
+ * virQEMUCapsCPUModelInfoFromCPUDef:
+ * @cpuDef: input model
+ *
+ * virCPUDef model => qemuMonitorCPUModelInfo name
+ * virCPUDef features => qemuMonitorCPUModelInfo boolean properties
+ *
+ * property have true value if feature policy is undefined (-1), FORCE or 
REQUIRE
+ * These semantics may need to be modified for other cases.
+ */
+qemuMonitorCPUModelInfoPtr
+virQEMUCapsCPUModelInfoFromCPUDef(const virCPUDef *cpuDef)
+{
+size_t i;
+qemuMonitorCPUModelInfoPtr cpuModel = NULL;
+qemuMonitorCPUModelInfoPtr ret = NULL;
+
+VIR_DEBUG("cpuDef = %p, cpuDef->model = %s", cpuDef, NULLSTR(cpuDef ? 
cpuDef->model : NULL));
+
+if (!cpuDef || (VIR_ALLOC(cpuModel) < 0))
+goto cleanup;
+
+if (VIR_STRDUP(cpuModel->name, cpuDef->model) < 0 ||
+VIR_ALLOC_N(cpuModel->props, cpuDef->nfeatures) < 0)
+goto cleanup;
+
+cpuModel->nprops = 0;
+
+for (i = 0; i < cpuDef->nfeatures; i++) {
+qemuMonitorCPUPropertyPtr prop = &(cpuModel->props[cpuModel->nprops]);
+virCPUFeatureDefPtr feature = &(cpuDef->features[i]);
+
+if (VIR_STRDUP(prop->name, feature->name) < 0)
+goto cleanup;
+
+prop->type = QEMU_MONITOR_CPU_PROPERTY_BOOLEAN;
+
+prop->value.boolean = feature->policy == -1 || /* policy undefined */
+  feature->policy == VIR_CPU_FEATURE_FORCE ||
+  feature->policy == VIR_CPU_FEATURE_REQUIRE;
+
+cpuModel->nprops++;
+}
+
+VIR_STEAL_PTR(ret, cpuModel);
+
+ cleanup:
+qemuMonitorCPUModelInfoFree(cpuModel);
+return ret;
+}
+
+
 /**
  * virQEMUCapsCPUModelInfoToCPUDef:
  * @model: input model
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 834844c1be..e05596ae06 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -583,6 +583,7 @@ int virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps,
 void virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps,
 const char *machineType);
 
+qemuMonitorCPUModelInfoPtr virQEMUCapsCPUModelInfoFromCPUDef(const virCPUDef 
*cpuDef);
 virCPUDefPtr virQEMUCapsCPUModelInfoToCPUDef(qemuMonitorCPUModelInfoPtr model,
  bool migratable);
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 17/33] qemu_process: Cleanup qemuProcessQMPStop function

2019-01-12 Thread Chris Venteicher
qemuProcessQMPStop is one of the 4 public functions used to create and
manage a Qemu process for QMP command exchanges.

Add comment header and debug message.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 58842a0f1c..fb14ed35f9 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8459,12 +8459,21 @@ qemuProcessQMPStart(qemuProcessQMPPtr proc)
 }
 
 
+/**
+ * qemuProcessStop:
+ * @proc: Stores process and connection state
+ *
+ * Stop monitor connection and QEMU process
+ */
 void
 qemuProcessQMPStop(qemuProcessQMPPtr proc)
 {
 if (!proc)
 return;
 
+VIR_DEBUG("proc=%p emulator=%s mon=%p pid=%lld",
+  proc, proc->binary, proc->mon, (long long)proc->pid);
+
 if (proc->mon) {
 virObjectUnlock(proc->mon);
 qemuMonitorClose(proc->mon);
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 15/33] qemu_process: Stop retaining Monitor config in qemuProcessQMP

2019-01-12 Thread Chris Venteicher
The monitor config data is removed from the qemuProcessQMP struct.

The monitor config data can be initialized immediately before call to
qemuMonitorOpen and does not need to be maintained after the call
because qemuMonitorOpen copies any strings it needs.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 9 +
 src/qemu/qemu_process.h | 1 -
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 430136251d..91532c19ce 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8357,13 +8357,14 @@ qemuProcessQMPConnectMonitor(qemuProcessQMPPtr proc)
 {
 int ret = -1;
 virDomainXMLOptionPtr xmlopt = NULL;
+virDomainChrSourceDef monConfig;
 
 VIR_DEBUG("proc=%p, emulator=%s, proc->pid=%lld",
   proc, proc->binary, (long long)proc->pid);
 
-proc->config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
-proc->config.data.nix.path = proc->monpath;
-proc->config.data.nix.listen = false;
+monConfig.type = VIR_DOMAIN_CHR_TYPE_UNIX;
+monConfig.data.nix.path = proc->monpath;
+monConfig.data.nix.listen = false;
 
 if (!(xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL, NULL, NULL)) ||
 !(proc->vm = virDomainObjNew(xmlopt)))
@@ -8371,7 +8372,7 @@ qemuProcessQMPConnectMonitor(qemuProcessQMPPtr proc)
 
 proc->vm->pid = proc->pid;
 
-if (!(proc->mon = qemuMonitorOpen(proc->vm, >config, true, true,
+if (!(proc->mon = qemuMonitorOpen(proc->vm, , true, true,
   0, , NULL)))
 goto cleanup;
 
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index e07584c11c..0bf594ad2e 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -228,7 +228,6 @@ struct _qemuProcessQMP {
 char *pidfile;
 virCommandPtr cmd;
 qemuMonitorPtr mon;
-virDomainChrSourceDef config;
 pid_t pid;
 virDomainObjPtr vm;
 bool forceTCG;
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 11/33] qemu_process: Introduce qemuProcessQMPStart

2019-01-12 Thread Chris Venteicher
Move a step closer to the function structure used elsewhere in
qemu_process where qemuProcessStart and qemuProcessStop are the exposed
functions.

qemuProcessQMPStart mirrors qemuProcessStart in calling sub functions to
initialize, launch the process and connect the monitor to the QEMU
process.

static functions qemuProcessQMPInit, qemuProcessQMPLaunch and
qemuProcessQMPConnectMonitor are introduced.

qemuProcessQMPLaunch is just renamed from qemuProcessQMPRun and
encapsulates all of the original code.

qemuProcessQMPInit and qemuProcessQMPMonitor are nearly empty functions
acting as placeholders for later patches where blocks of semi-complicated code
are cut/pasted into these functions without modification
(hopefully making review easier.)

Looking forward, the patch series ultimately moves the code into this
partitioning:

- qemuProcessQMPInit
Becomes the location of ~25 lines of code to create storage
directory, in thread safe way, and initialize paths
for monpath, monarg and pidfile.

- qemuProcessQMPLaunch
Becomes the location of ~48 lines of code used to create and run the
QEMU command.

- qemuProcessQMPConnectMonitor
Becomes the final location of ~58 lines of code used to open and
initialize the monitor connection between libvirt and qemu.

Three smaller, purpose-identifying, functions of ~60 lines or less seem
better than a single large process "start" function of > 130 lines.

Being able to compare and contrast between the domain and non-domain
versions of process code is useful too.  There is some significant
overlap between what the non-domain and domain functions do.  There is
also significant additional functionality in the domain functions that
might be useful in the non-domain functions in the future.
Possibly there could be sharing between non-domain and
domain process code in the future but common code would have
to be carefully extracted from the domain process code (not trivial.)

Mirroring the domain process code has some value, but
partitioning the code into logical chunks of < 60 lines
is the main reason for the static functions.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c |  4 +-
 src/qemu/qemu_process.c  | 93 +++-
 src/qemu/qemu_process.h  |  2 +-
 3 files changed, 94 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index b833e0d11e..36d28ba5ea 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4383,7 +4383,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
runUid, runGid, false)))
 goto cleanup;
 
-if (qemuProcessQMPRun(proc) < 0) {
+if (qemuProcessQMPStart(proc) < 0) {
 if (proc->status != 0)
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to probe QEMU binary with QMP: %s"),
@@ -4405,7 +4405,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 procTCG = qemuProcessQMPNew(qemuCaps->binary, libDir,
 runUid, runGid, true);
 
-if (qemuProcessQMPRun(procTCG) < 0)
+if (qemuProcessQMPStart(procTCG) < 0)
 goto cleanup;
 
 if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, procTCG->mon) < 0)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 71c7fb58ad..3b785d64e5 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8270,8 +8270,27 @@ qemuProcessQMPNew(const char *binary,
 }
 
 
-int
-qemuProcessQMPRun(qemuProcessQMPPtr proc)
+/* Initialize configuration and paths prior to starting QEMU
+ */
+static int
+qemuProcessQMPInit(qemuProcessQMPPtr proc)
+{
+int ret = -1;
+
+VIR_DEBUG("proc=%p, emulator=%s",
+  proc, proc->binary);
+
+ret = 0;
+
+VIR_DEBUG("ret=%i", ret);
+return ret;
+}
+
+
+/* Launch QEMU Process
+ */
+static int
+qemuProcessQMPLaunch(qemuProcessQMPPtr proc)
 {
 virDomainXMLOptionPtr xmlopt = NULL;
 const char *machine;
@@ -8348,6 +8367,76 @@ qemuProcessQMPRun(qemuProcessQMPPtr proc)
 }
 
 
+/* Connect Monitor to QEMU Process
+ */
+static int
+qemuProcessQMPConnectMonitor(qemuProcessQMPPtr proc)
+{
+int ret = -1;
+
+VIR_DEBUG("proc=%p, emulator=%s, proc->pid=%lld",
+  proc, proc->binary, (long long)proc->pid);
+
+ret = 0;
+
+VIR_DEBUG("ret=%i", ret);
+return ret;
+}
+
+
+/**
+ * qemuProcessQMPStart:
+ * @proc: Stores process and connection state
+ *
+ * Start and connect to QEMU binary so QMP queries can be made.
+ *
+ * Usage:
+ *   proc = qemuProcessQMPNew(binary, libDir, runUid, runGid, forceTCG);
+ *   qemuProcessQMPStart(proc);
+ *   ** Send QMP Queries to QEMU using monitor (proc->mon) **
+ *   qemuProcessQMPStop(proc);
+ *   qemuProcessQMPFree(proc);
+ *
+ * Check monitor is not NULL before using.
+ *
+ * QEMU 

[libvirt] [PATCH v6 16/33] qemu_process: Cleanup qemuProcessQMP alloc function

2019-01-12 Thread Chris Venteicher
qemuProcessQMPNew is one of the 4 public functions used to create and
manage a qemu process for QMP command exchanges outside of domain
operations.

Add descriptive comment block, Debug statement and make source
consistent with the cleanup / VIR_STEAL_PTR format used elsewhere.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 29 -
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 91532c19ce..58842a0f1c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8220,6 +8220,18 @@ qemuProcessQMPFree(qemuProcessQMPPtr proc)
 }
 
 
+/**
+ * qemuProcessQMPNew:
+ * @binary: QEMU binary
+ * @libDir: Directory for process and connection artifacts
+ * @runUid: UserId for QEMU Process
+ * @runGid: GroupId for QEMU Process
+ * @forceTCG: Force TCG mode if true
+ *
+ * Allocate and initialize domain structure encapsulating
+ * QEMU Process state and monitor connection to QEMU
+ * for completing QMP Queries.
+ */
 qemuProcessQMPPtr
 qemuProcessQMPNew(const char *binary,
   const char *libDir,
@@ -8227,24 +8239,31 @@ qemuProcessQMPNew(const char *binary,
   gid_t runGid,
   bool forceTCG)
 {
+qemuProcessQMPPtr ret = NULL;
 qemuProcessQMPPtr proc = NULL;
 
+VIR_DEBUG("exec=%s, libDir=%s, runUid=%u, runGid=%u, forceTCG=%d",
+  binary, libDir, runUid, runGid, forceTCG);
+
 if (VIR_ALLOC(proc) < 0)
-goto error;
+goto cleanup;
 
 if (VIR_STRDUP(proc->binary, binary) < 0 ||
 VIR_STRDUP(proc->libDir, libDir) < 0)
-goto error;
+goto cleanup;
 
 proc->runUid = runUid;
 proc->runGid = runGid;
 proc->forceTCG = forceTCG;
 
-return proc;
+VIR_STEAL_PTR(ret, proc);
 
- error:
+ cleanup:
 qemuProcessQMPFree(proc);
-return NULL;
+
+VIR_DEBUG("ret=%p", ret);
+
+return ret;
 }
 
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 19/33] qemu_process: Enter QMP command mode when starting QEMU Process

2019-01-12 Thread Chris Venteicher
qemuProcessQMPStart starts a QEMU process and monitor connection that
can be used by multiple functions possibly for multiple QMP commands.

The QMP exchange to exit capabilities negotiation mode and enter command mode
can only be performed once after the monitor connection is established.

Move responsibility for entering QMP command mode into the qemuProcessQMP
code so multiple functions can issue QMP commands in arbitrary orders.

This also simplifies the functions using the connection provided by
qemuProcessQMPStart to issue QMP commands.

Test code now needs to call qemuMonitorSetCapabilities to send the
message to switch to command mode because the test code does not use the
qemuProcessQMP command that internally calls qemuMonitorSetCapabilities.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 12 
 src/qemu/qemu_process.c  |  8 
 tests/qemucapabilitiestest.c |  7 +++
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 36d28ba5ea..bac8487a78 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4152,12 +4152,6 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
 
 /* @mon is supposed to be locked by callee */
 
-if (qemuMonitorSetCapabilities(mon) < 0) {
-VIR_DEBUG("Failed to set monitor capabilities %s",
-  virGetLastErrorMessage());
-goto cleanup;
-}
-
 if (qemuMonitorGetVersion(mon,
   , , ,
   ) < 0) {
@@ -4331,12 +4325,6 @@ virQEMUCapsInitQMPMonitorTCG(virQEMUCapsPtr qemuCaps 
ATTRIBUTE_UNUSED,
 {
 int ret = -1;
 
-if (qemuMonitorSetCapabilities(mon) < 0) {
-VIR_DEBUG("Failed to set monitor capabilities %s",
-  virGetLastErrorMessage());
-goto cleanup;
-}
-
 if (virQEMUCapsProbeQMPCPUDefinitions(qemuCaps, mon, true) < 0)
 goto cleanup;
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 15a38144f5..d2d067b1a6 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8412,6 +8412,14 @@ qemuProcessQMPConnectMonitor(qemuProcessQMPPtr proc)
 
 virObjectLock(proc->mon);
 
+/* Exit capabilities negotiation mode and enter QEMU command mode
+ * by issuing qmp_capabilities command to QEMU */
+if (qemuMonitorSetCapabilities(proc->mon) < 0) {
+VIR_DEBUG("Failed to set monitor capabilities %s",
+  virGetLastErrorMessage());
+goto cleanup;
+}
+
 ret = 0;
 
  cleanup:
diff --git a/tests/qemucapabilitiestest.c b/tests/qemucapabilitiestest.c
index b3a9a4b9fc..785b445672 100644
--- a/tests/qemucapabilitiestest.c
+++ b/tests/qemucapabilitiestest.c
@@ -58,6 +58,9 @@ testQemuCaps(const void *opaque)
 if (!(mon = qemuMonitorTestNewFromFileFull(repliesFile, >driver, 
NULL)))
 goto cleanup;
 
+if (qemuMonitorSetCapabilities(qemuMonitorTestGetMonitor(mon)) < 0)
+goto cleanup;
+
 if (!(capsActual = virQEMUCapsNew()) ||
 virQEMUCapsInitQMPMonitor(capsActual,
   qemuMonitorTestGetMonitor(mon)) < 0)
@@ -65,6 +68,10 @@ testQemuCaps(const void *opaque)
 
 if (virQEMUCapsGet(capsActual, QEMU_CAPS_KVM)) {
 qemuMonitorResetCommandID(qemuMonitorTestGetMonitor(mon));
+
+if (qemuMonitorSetCapabilities(qemuMonitorTestGetMonitor(mon)) < 0)
+goto cleanup;
+
 if (virQEMUCapsInitQMPMonitorTCG(capsActual,
  qemuMonitorTestGetMonitor(mon)) < 0)
 goto cleanup;
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 14/33] qemu_process: Setup paths within qemuProcessQMPInit

2019-01-12 Thread Chris Venteicher
Move code for setting paths and prepping file system from
qemuProcessQMPNew to qemuProcessQMPInit.

This keeps qemuProcessQMPNew limited to data structures
and path initialization is done in qemuProcessQMPInit.

The patch is a non-functional, cut / paste change,
however goto is now "cleanup" rather than "error".

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 44 +
 1 file changed, 23 insertions(+), 21 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index dc2237f0e6..430136251d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8240,14 +8240,33 @@ qemuProcessQMPNew(const char *binary,
 proc->runGid = runGid;
 proc->forceTCG = forceTCG;
 
+return proc;
+
+ error:
+qemuProcessQMPFree(proc);
+return NULL;
+}
+
+
+/* Initialize configuration and paths prior to starting QEMU
+ */
+static int
+qemuProcessQMPInit(qemuProcessQMPPtr proc)
+{
+int ret = -1;
+
+VIR_DEBUG("proc=%p, emulator=%s",
+  proc, proc->binary);
+
 /* the ".sock" sufix is important to avoid a possible clash with a qemu
  * domain called "capabilities"
  */
 if (virAsprintf(>monpath, "%s/%s", proc->libDir,
 "capabilities.monitor.sock") < 0)
-goto error;
+goto cleanup;
+
 if (virAsprintf(>monarg, "unix:%s,server,nowait", proc->monpath) < 0)
-goto error;
+goto cleanup;
 
 /* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
  * with a qemu domain called "capabilities"
@@ -8256,30 +8275,13 @@ qemuProcessQMPNew(const char *binary,
  * than libvirtd. So we're using libDir which QEMU can write to
  */
 if (virAsprintf(>pidfile, "%s/%s", proc->libDir, 
"capabilities.pidfile") < 0)
-goto error;
+goto cleanup;
 
 virPidFileForceCleanupPath(proc->pidfile);
 
-return proc;
-
- error:
-qemuProcessQMPFree(proc);
-return NULL;
-}
-
-
-/* Initialize configuration and paths prior to starting QEMU
- */
-static int
-qemuProcessQMPInit(qemuProcessQMPPtr proc)
-{
-int ret = -1;
-
-VIR_DEBUG("proc=%p, emulator=%s",
-  proc, proc->binary);
-
 ret = 0;
 
+ cleanup:
 VIR_DEBUG("ret=%i", ret);
 return ret;
 }
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 32/33] qemu_driver: Support feature expansion via QEMU when baselining cpu

2019-01-12 Thread Chris Venteicher
Support using QEMU to do feature expansion when also using QEMU to
compute hypervisor baseline.

A QEMU process is already created to send the QMP messages to baseline
using QEMU.
The same QEMU process is used for the CPU feature expansion.

QEMU only returns migratable features when expanding CPU model in
architectures where QEMU is used for baseline so no attempt is made to
ask for non-migratable features in expansions when using QEMU for
baseline.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_driver.c  | 25 +
 src/qemu/qemu_monitor.c | 30 ++
 src/qemu/qemu_monitor.h |  4 
 3 files changed, 59 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5068805f51..b57123b585 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13897,6 +13897,31 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 if (flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) {
 if (useLibvirt && virCPUExpandFeatures(arch, cpu) < 0) {
 goto cleanup;
+} else if (useQemu &&
+   virQEMUCapsGet(qemuCaps, 
QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) {
+
+if (!(modelInfo = virQEMUCapsCPUModelInfoFromCPUDef(cpu)))
+goto cleanup;
+
+virCPUDefFree(cpu);
+cpu = NULL;
+
+/* QEMU can only include migratable features
+   for all archs that use QEMU for baseline calculation */
+migratable = true;
+
+if (qemuMonitorGetCPUModelExpansion(proc->mon,
+
QEMU_MONITOR_CPU_MODEL_EXPANSION_FULL,
+modelInfo, migratable, 
) < 0)
+goto cleanup;
+
+/* Expansion enumerates all features
+ * Baselines output enumerates only in-model (true) features */
+qemuMonitorCPUModelInfoRemovePropByBoolValue(expansion, false);
+
+if (!(cpu = virQEMUCapsCPUModelInfoToCPUDef(expansion, 
migratable)))
+goto cleanup;
+
 } else {
 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("expand features while "
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 7d82f25fc2..56a3bbcea1 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3785,6 +3785,36 @@ qemuMonitorCPUModelInfoCopy(const 
qemuMonitorCPUModelInfo *orig)
 }
 
 
+/* Squash CPU Model Info property list
+ * removing props of type boolean matching value */
+void
+qemuMonitorCPUModelInfoRemovePropByBoolValue(qemuMonitorCPUModelInfoPtr model,
+ bool value)
+{
+qemuMonitorCPUPropertyPtr src;
+qemuMonitorCPUPropertyPtr dst;
+size_t i;
+size_t dst_nprops = 0;
+
+for (i = 0; i < model->nprops; i++) {
+src = &(model->props[i]);
+dst = &(model->props[dst_nprops]);
+
+if (src->type == QEMU_MONITOR_CPU_PROPERTY_BOOLEAN &&
+src->value.boolean == value)
+continue;
+
+*dst = *src;
+
+dst_nprops++;
+}
+
+model->nprops = dst_nprops;
+
+ignore_value(VIR_REALLOC_N_QUIET(model->props, dst_nprops));
+}
+
+
 int
 qemuMonitorCPUModelInfoBoolPropAdd(qemuMonitorCPUModelInfoPtr model,
const char *prop_name,
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 2b3ea6ab8e..c54f311632 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1078,6 +1078,10 @@ int 
qemuMonitorCPUModelInfoBoolPropAdd(qemuMonitorCPUModelInfoPtr model,
bool prop_value)
 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
+void qemuMonitorCPUModelInfoRemovePropByBoolValue(qemuMonitorCPUModelInfoPtr 
model,
+  bool value)
+ATTRIBUTE_NONNULL(1);
+
 int qemuMonitorGetCommands(qemuMonitorPtr mon,
char ***commands);
 int qemuMonitorGetEvents(qemuMonitorPtr mon,
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 29/33] qemu_driver: Decouple code for baseline using libvirt

2019-01-12 Thread Chris Venteicher
Create utility function encapsulating code to calculate
hypervisor baseline cpu using the local libvirt utility functions.

Similar function encapsulating code to calculating hypervisor baseline
using QEMU QMP messages will be introduced in later commit.

Patch is a cut and paste of existing code into a utility function
wrapper.

s/cpu/*baseline/ (change output variable name ) and
initialize variable "rc" are the only code changes.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_driver.c | 78 --
 1 file changed, 52 insertions(+), 26 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 161b82d229..2a030bed2f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13696,6 +13696,55 @@ qemuConnectBaselineCPU(virConnectPtr conn 
ATTRIBUTE_UNUSED,
 }
 
 
+static int
+qemuConnectBaselineHypervisorCPUViaLibvirt(
+virQEMUCapsPtr qemuCaps,
+bool migratable,
+virDomainVirtType virttype,
+virArch arch,
+virCPUDefPtr *cpus,
+unsigned int ncpus,
+virCPUDefPtr *baseline)
+{
+char **features = NULL;
+int ret = -1;
+int rc = -1;
+virDomainCapsCPUModelsPtr cpuModels;
+
+*baseline = NULL;
+
+if (!(cpuModels = virQEMUCapsGetCPUDefinitions(qemuCaps, virttype)) ||
+cpuModels->nmodels == 0) {
+virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+   _("QEMU '%s' does not support any CPU models for "
+ "virttype '%s'"),
+   virQEMUCapsGetBinary(qemuCaps),
+   virDomainVirtTypeToString(virttype));
+goto cleanup;
+}
+
+rc = virQEMUCapsGetCPUFeatures(qemuCaps, virttype,
+   migratable, );
+if (rc < 0)
+goto cleanup;
+if (features && rc == 0) {
+/* We got only migratable features from QEMU if we asked for them,
+ * no further filtering in virCPUBaseline is desired. */
+migratable = false;
+}
+
+if (!(*baseline = virCPUBaseline(arch, cpus, ncpus, cpuModels,
+ (const char **)features, migratable)))
+goto cleanup;
+
+ret = 0;
+
+ cleanup:
+virStringListFree(features);
+return ret;
+}
+
+
 static char *
 qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
  const char *emulator,
@@ -13714,7 +13763,6 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 bool migratable;
 virCPUDefPtr cpu = NULL;
 char *cpustr = NULL;
-char **features = NULL;
 
 virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES |
   VIR_CONNECT_BASELINE_CPU_MIGRATABLE, NULL);
@@ -13737,30 +13785,9 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 if (ARCH_IS_X86(arch)) {
 migratable = !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE);
 
-virDomainCapsCPUModelsPtr cpuModels;
-
-if (!(cpuModels = virQEMUCapsGetCPUDefinitions(qemuCaps, virttype)) ||
-cpuModels->nmodels == 0) {
-virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
-   _("QEMU '%s' does not support any CPU models for "
- "virttype '%s'"),
-   virQEMUCapsGetBinary(qemuCaps),
-   virDomainVirtTypeToString(virttype));
-goto cleanup;
-}
-
-int rc = virQEMUCapsGetCPUFeatures(qemuCaps, virttype,
-   migratable, );
-if (rc < 0)
-goto cleanup;
-if (features && rc == 0) {
-/* We got only migratable features from QEMU if we asked for them,
- * no further filtering in virCPUBaseline is desired. */
-migratable = false;
-}
-
-if (!(cpu = virCPUBaseline(arch, cpus, ncpus, cpuModels,
-   (const char **)features, migratable)))
+if (qemuConnectBaselineHypervisorCPUViaLibvirt(qemuCaps, migratable,
+   virttype, arch,
+   cpus, ncpus, ) < 0)
 goto cleanup;
 } else {
 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
@@ -13781,7 +13808,6 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 virCPUDefListFree(cpus);
 virCPUDefFree(cpu);
 virObjectUnref(qemuCaps);
-virStringListFree(features);
 
 return cpustr;
 }
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 25/33] qemu_capabilities: Introduce CPUModelInfo to virCPUDef function

2019-01-12 Thread Chris Venteicher
Move existing code to convert between cpu model info structures
(qemuMonitorCPUModelInfoPtr into virCPUDef)
into a reusable function.

The new function is used in this and future patches.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 88 ++--
 src/qemu/qemu_capabilities.h |  3 ++
 2 files changed, 68 insertions(+), 23 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 463c803416..2bb56763b0 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2834,7 +2834,8 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
 virCPUDefPtr cpu,
 bool migratable)
 {
-size_t i;
+virCPUDefPtr tmp = NULL;
+int ret = -1;
 
 if (!modelInfo) {
 if (type == VIR_DOMAIN_VIRT_KVM) {
@@ -2847,32 +2848,18 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
 return 2;
 }
 
-if (VIR_STRDUP(cpu->model, modelInfo->name) < 0 ||
-VIR_ALLOC_N(cpu->features, modelInfo->nprops) < 0)
-return -1;
+if (!(tmp = virQEMUCapsCPUModelInfoToCPUDef(modelInfo, migratable)))
+goto cleanup;
 
-cpu->nfeatures_max = modelInfo->nprops;
-cpu->nfeatures = 0;
+/* Free original then copy over model, vendor, vendor_id and features */
+virCPUDefStealModel(cpu, tmp, true);
 
-for (i = 0; i < modelInfo->nprops; i++) {
-virCPUFeatureDefPtr feature = cpu->features + cpu->nfeatures;
-qemuMonitorCPUPropertyPtr prop = modelInfo->props + i;
+ret = 0;
 
-if (prop->type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN)
-continue;
+ cleanup:
+virCPUDefFree(tmp);
 
-if (VIR_STRDUP(feature->name, prop->name) < 0)
-return -1;
-
-if (!prop->value.boolean ||
-(migratable && prop->migratable == VIR_TRISTATE_BOOL_NO))
-feature->policy = VIR_CPU_FEATURE_DISABLE;
-else
-feature->policy = VIR_CPU_FEATURE_REQUIRE;
-cpu->nfeatures++;
-}
-
-return 0;
+return ret;
 }
 
 
@@ -3677,6 +3664,61 @@ virQEMUCapsLoadCache(virArch hostArch,
 }
 
 
+/**
+ * virQEMUCapsCPUModelInfoToCPUDef:
+ * @model: input model
+ * @migratable: mark non-migratable features as disabled if true else allow all
+ *
+ * qemuMonitorCPUModelInfo name => virCPUDef model
+ * qemuMonitorCPUModelInfo boolean properties => virCPUDef features
+ */
+virCPUDefPtr
+virQEMUCapsCPUModelInfoToCPUDef(qemuMonitorCPUModelInfoPtr model,
+bool migratable)
+{
+virCPUDefPtr cpu = NULL;
+virCPUDefPtr ret = NULL;
+size_t i;
+
+VIR_DEBUG("model= %p, model->name= %s", model, NULLSTR(model ? model->name 
: NULL));
+
+if (!model || VIR_ALLOC(cpu) < 0)
+goto cleanup;
+
+if (VIR_STRDUP(cpu->model, model->name) < 0 ||
+VIR_ALLOC_N(cpu->features, model->nprops) < 0)
+goto cleanup;
+
+cpu->nfeatures_max = model->nprops;
+cpu->nfeatures = 0;
+
+for (i = 0; i < model->nprops; i++) {
+virCPUFeatureDefPtr feature = cpu->features + cpu->nfeatures;
+qemuMonitorCPUPropertyPtr prop = model->props + i;
+
+if (prop->type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN)
+continue;
+
+if (VIR_STRDUP(feature->name, prop->name) < 0)
+goto cleanup;
+
+if (!prop->value.boolean ||
+(migratable && prop->migratable == VIR_TRISTATE_BOOL_NO))
+feature->policy = VIR_CPU_FEATURE_DISABLE;
+else
+feature->policy = VIR_CPU_FEATURE_REQUIRE;
+
+cpu->nfeatures++;
+}
+
+VIR_STEAL_PTR(ret, cpu);
+
+ cleanup:
+virCPUDefFree(cpu);
+return ret;
+}
+
+
 static void
 virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsPtr qemuCaps,
   virBufferPtr buf,
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 6d5ed8a3cc..834844c1be 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -583,6 +583,9 @@ int virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps,
 void virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps,
 const char *machineType);
 
+virCPUDefPtr virQEMUCapsCPUModelInfoToCPUDef(qemuMonitorCPUModelInfoPtr model,
+ bool migratable);
+
 virFileCachePtr virQEMUCapsCacheNew(const char *libDir,
 const char *cacheDir,
 uid_t uid,
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 23/33] qemu_capabilities: Introduce virQEMuCapsMigratablePropsCalc

2019-01-12 Thread Chris Venteicher
Create an augmented CPUModelInfo identifying which props are/aren't
migratable based on a diff between migratable and non-migratable
inputs.

This patch pulls existing logic out of virQEMUCapsProbeQMPHostCPU
and wraps the existing logic in a standalone function hopefully
simplifying both functions and making the inputs and outputs clearer.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 130 ---
 1 file changed, 91 insertions(+), 39 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 02911a2a10..cd8d1439f6 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2394,14 +2394,91 @@ virQEMUCapsProbeQMPCPUDefinitions(virQEMUCapsPtr 
qemuCaps,
 }
 
 
+/* virQEMUCapsMigratablePropsCalc
+ * @migratable: input where all migratable props have value true
+ * and non-migratable and unsupported props have value false
+ *
+ * @nonMigratable: input where all migratable & non-migratable props
+ * have value true and unsupported props have value false
+ *
+ * @augmented: output including all props listed in @migratable but
+ * both migratable & non-migratable props have value true,
+ * unsupported props have value false,
+ * and prop->migratable is set to VIR_TRISTATE_BOOL_{YES/NO}
+ * for each supported prop
+ *
+ * Differences in expanded CPUModelInfo inputs @migratable and @nonMigratable 
are
+ * used to create output @augmented where individual props have 
prop->migratable
+ * set to indicate if prop is or isn't migratable.
+ */
+static int
+virQEMUCapsMigratablePropsCalc(qemuMonitorCPUModelInfoPtr migratable,
+   qemuMonitorCPUModelInfoPtr nonMigratable,
+   qemuMonitorCPUModelInfoPtr *augmented)
+{
+int ret = -1;
+qemuMonitorCPUModelInfoPtr tmp;
+qemuMonitorCPUPropertyPtr prop;
+qemuMonitorCPUPropertyPtr mProp;
+qemuMonitorCPUPropertyPtr nonmProp;
+virHashTablePtr hash = NULL;
+size_t i;
+
+*augmented = NULL;
+
+if (!(tmp = qemuMonitorCPUModelInfoCopy(migratable)))
+goto cleanup;
+
+if (!nonMigratable)
+goto done;
+
+if (!(hash = virHashCreate(0, NULL)))
+goto cleanup;
+
+for (i = 0; i < tmp->nprops; i++) {
+prop = tmp->props + i;
+
+if (virHashAddEntry(hash, prop->name, prop) < 0)
+goto cleanup;
+}
+
+for (i = 0; i < nonMigratable->nprops; i++) {
+nonmProp = nonMigratable->props + i;
+
+if (!(mProp = virHashLookup(hash, nonmProp->name)) ||
+mProp->type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN ||
+mProp->type != nonmProp->type)
+continue;  /* In non-migratable list but not in migratable list */
+
+if (mProp->value.boolean) {
+mProp->migratable = VIR_TRISTATE_BOOL_YES;
+} else if (nonmProp->value.boolean) {
+mProp->value.boolean = true;
+mProp->migratable = VIR_TRISTATE_BOOL_NO;
+}
+}
+
+tmp->migratability = true;
+
+ done:
+VIR_STEAL_PTR(*augmented, tmp);
+ret = 0;
+
+ cleanup:
+qemuMonitorCPUModelInfoFree(tmp);
+virHashFree(hash);
+return ret;
+}
+
+
 static int
 virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
qemuMonitorPtr mon,
bool tcg)
 {
-qemuMonitorCPUModelInfoPtr modelInfo = NULL;
+qemuMonitorCPUModelInfoPtr migratable = NULL;
 qemuMonitorCPUModelInfoPtr nonMigratable = NULL;
-virHashTablePtr hash = NULL;
+qemuMonitorCPUModelInfoPtr augmented = NULL;
 const char *model;
 qemuMonitorCPUModelExpansionType type;
 virDomainVirtType virtType;
@@ -2431,54 +2508,29 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
 else
 type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC;
 
-if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, ) < 
0)
+if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, ) < 
0)
 goto cleanup;
 
+if (!migratable) {
+ret = 0;  /* Qemu can't expand the model name, exit without error 
*/
+goto cleanup;
+}
+
 /* Try to check migratability of each feature. */
-if (modelInfo &&
-qemuMonitorGetCPUModelExpansion(mon, type, model, false,
+if (qemuMonitorGetCPUModelExpansion(mon, type, model, false,
 ) < 0)
 goto cleanup;
 
-if (nonMigratable) {
-qemuMonitorCPUPropertyPtr prop;
-qemuMonitorCPUPropertyPtr nmProp;
-size_t i;
+if (virQEMUCapsMigratablePropsCalc(migratable, nonMigratable, ) 
< 0)
+goto cleanup;
 
-if (!(hash = virHashCreate(0, NULL)))
-goto cleanup;
-
-for (i = 0; i < modelInfo->nprops; i++) {
-prop = modelInfo->props + i;
-if (virHashAddEntry(hash, prop->name, prop

[libvirt] [PATCH v6 08/33] qemu_process: All ProcessQMP errors are fatal

2019-01-12 Thread Chris Venteicher
In the past capabilities could be determined in other ways if QMP
messaging didn't succeed so a non-fatal error case was included in the
capabilities and QMP Process code.

For a while now, QMP capabilities failure has been a fatal case.

This patch makes QMP process failures return as a fatal error in all
cases consistent with 1) all failures actually being fatal in
QMP capabilities code and 2) the QMP process code being made generic.

The process changes impact the capabilities code because non-fatal
return codes are no longer returned.

The rest of the QMP associated capabilities code is updated to make all
errors fatal for consistency.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 14 ++
 src/qemu/qemu_process.c  | 15 +++
 2 files changed, 5 insertions(+), 24 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 35aac798d9..502bac5e43 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4155,7 +4155,6 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
 if (qemuMonitorSetCapabilities(mon) < 0) {
 VIR_DEBUG("Failed to set monitor capabilities %s",
   virGetLastErrorMessage());
-ret = 0;
 goto cleanup;
 }
 
@@ -4164,7 +4163,6 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
   ) < 0) {
 VIR_DEBUG("Failed to query monitor version %s",
   virGetLastErrorMessage());
-ret = 0;
 goto cleanup;
 }
 
@@ -4336,7 +4334,6 @@ virQEMUCapsInitQMPMonitorTCG(virQEMUCapsPtr qemuCaps 
ATTRIBUTE_UNUSED,
 if (qemuMonitorSetCapabilities(mon) < 0) {
 VIR_DEBUG("Failed to set monitor capabilities %s",
   virGetLastErrorMessage());
-ret = 0;
 goto cleanup;
 }
 
@@ -4362,17 +4359,13 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 qemuProcessQMPPtr proc = NULL;
 qemuProcessQMPPtr procTCG = NULL;
 int ret = -1;
-int rc;
 
 if (!(proc = qemuProcessQMPNew(qemuCaps->binary, libDir,
runUid, runGid, qmperr, false)))
 goto cleanup;
 
-if ((rc = qemuProcessQMPRun(proc)) != 0) {
-if (rc == 1)
-ret = 0;
+if (qemuProcessQMPRun(proc) < 0)
 goto cleanup;
-}
 
 if (virQEMUCapsInitQMPMonitor(qemuCaps, proc->mon) < 0)
 goto cleanup;
@@ -4387,11 +4380,8 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 procTCG = qemuProcessQMPNew(qemuCaps->binary, libDir,
 runUid, runGid, NULL, true);
 
-if ((rc = qemuProcessQMPRun(procTCG)) != 0) {
-if (rc == 1)
-ret = 0;
+if (qemuProcessQMPRun(procTCG) < 0)
 goto cleanup;
-}
 
 if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, procTCG->mon) < 0)
 goto cleanup;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 297a542e3d..f662b7d2ce 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8271,10 +8271,6 @@ qemuProcessQMPNew(const char *binary,
 }
 
 
-/* Returns -1 on fatal error,
- *  0 on success,
- *  1 when probing QEMU failed
- */
 int
 qemuProcessQMPRun(qemuProcessQMPPtr proc)
 {
@@ -8315,19 +8311,18 @@ qemuProcessQMPRun(qemuProcessQMPPtr proc)
 
 virCommandSetErrorBuffer(proc->cmd, proc->qmperr);
 
-/* Log, but otherwise ignore, non-zero status.  */
 if (virCommandRun(proc->cmd, ) < 0)
 goto cleanup;
 
 if (status != 0) {
 VIR_DEBUG("QEMU %s exited with status %d: %s",
   proc->binary, status, *proc->qmperr);
-goto ignore;
+goto cleanup;
 }
 
 if (virPidFileReadPath(proc->pidfile, >pid) < 0) {
 VIR_DEBUG("Failed to read pidfile %s", proc->pidfile);
-goto ignore;
+goto cleanup;
 }
 
 if (!(xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL, NULL, NULL)) ||
@@ -8338,7 +8333,7 @@ qemuProcessQMPRun(qemuProcessQMPPtr proc)
 
 if (!(proc->mon = qemuMonitorOpen(proc->vm, >config, true, true,
   0, , NULL)))
-goto ignore;
+goto cleanup;
 
 virObjectLock(proc->mon);
 
@@ -8350,10 +8345,6 @@ qemuProcessQMPRun(qemuProcessQMPPtr proc)
 virObjectUnref(xmlopt);
 
 return ret;
-
- ignore:
-ret = 1;
-goto cleanup;
 }
 
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 21/33] qemu_monitor: Introduce qemuMonitorCPUModelInfoNew

2019-01-12 Thread Chris Venteicher
Use a helper function to allocate and initializes CPU Model Info structs.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c |  8 
 src/qemu/qemu_monitor.c  | 27 ++-
 src/qemu/qemu_monitor.h  |  2 ++
 src/qemu/qemu_monitor_json.c |  5 +
 4 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index bac8487a78..02911a2a10 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3063,16 +3063,16 @@ virQEMUCapsLoadHostCPUModelInfo(virQEMUCapsPtr qemuCaps,
 goto cleanup;
 }
 
-if (VIR_ALLOC(hostCPU) < 0)
-goto cleanup;
-
-if (!(hostCPU->name = virXMLPropString(hostCPUNode, "model"))) {
+if (!(str = virXMLPropString(hostCPUNode, "model"))) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("missing host CPU model name in QEMU "
  "capabilities cache"));
 goto cleanup;
 }
 
+if (!(hostCPU = qemuMonitorCPUModelInfoNew(str)))
+goto cleanup;
+
 if (!(str = virXMLPropString(hostCPUNode, "migratability")) ||
 (val = virTristateBoolTypeFromString(str)) <= 0) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 7ce5bd668e..815a30c275 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3686,6 +3686,26 @@ qemuMonitorGetCPUModelExpansion(qemuMonitorPtr mon,
 }
 
 
+qemuMonitorCPUModelInfoPtr
+qemuMonitorCPUModelInfoNew(const char *name)
+{
+qemuMonitorCPUModelInfoPtr ret = NULL;
+qemuMonitorCPUModelInfoPtr model;
+
+if (VIR_ALLOC(model) < 0)
+return NULL;
+
+if (VIR_STRDUP(model->name, name) < 0)
+goto cleanup;
+
+VIR_STEAL_PTR(ret, model);
+
+ cleanup:
+qemuMonitorCPUModelInfoFree(model);
+return ret;
+}
+
+
 void
 qemuMonitorCPUModelInfoFree(qemuMonitorCPUModelInfoPtr model_info)
 {
@@ -3709,18 +3729,15 @@ qemuMonitorCPUModelInfoFree(qemuMonitorCPUModelInfoPtr 
model_info)
 qemuMonitorCPUModelInfoPtr
 qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig)
 {
-qemuMonitorCPUModelInfoPtr copy;
+qemuMonitorCPUModelInfoPtr copy = NULL;
 size_t i;
 
-if (VIR_ALLOC(copy) < 0)
+if (!(copy = qemuMonitorCPUModelInfoNew(orig->name)))
 goto error;
 
 if (VIR_ALLOC_N(copy->props, orig->nprops) < 0)
 goto error;
 
-if (VIR_STRDUP(copy->name, orig->name) < 0)
-goto error;
-
 copy->migratability = orig->migratability;
 copy->nprops = orig->nprops;
 
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 8fcac8850f..d17bda75c3 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1067,6 +1067,8 @@ int qemuMonitorGetCPUModelExpansion(qemuMonitorPtr mon,
 
 void qemuMonitorCPUModelInfoFree(qemuMonitorCPUModelInfoPtr model_info);
 
+qemuMonitorCPUModelInfoPtr qemuMonitorCPUModelInfoNew(const char *name);
+
 qemuMonitorCPUModelInfoPtr
 qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig);
 
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 1f7eb20a25..dcb468c747 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -5642,10 +5642,7 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mon,
 goto cleanup;
 }
 
-if (VIR_ALLOC(machine_model) < 0)
-goto cleanup;
-
-if (VIR_STRDUP(machine_model->name, cpu_name) < 0)
+if (!(machine_model = qemuMonitorCPUModelInfoNew(cpu_name)))
 goto cleanup;
 
 if (VIR_ALLOC_N(machine_model->props, 
virJSONValueObjectKeysNumber(cpu_props)) < 0)
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 13/33] qemu_process: Store libDir in qemuProcessQMP struct

2019-01-12 Thread Chris Venteicher
Store libDir path in the qemuProcessQMP struct in anticipation of moving
path construction code into qemuProcessQMPInit function.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 8 +---
 src/qemu/qemu_process.h | 1 +
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 5492ff5a19..dc2237f0e6 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8211,6 +8211,7 @@ qemuProcessQMPFree(qemuProcessQMPPtr proc)
 
 qemuProcessQMPStop(proc);
 VIR_FREE(proc->binary);
+VIR_FREE(proc->libDir);
 VIR_FREE(proc->monpath);
 VIR_FREE(proc->monarg);
 VIR_FREE(proc->pidfile);
@@ -8231,7 +8232,8 @@ qemuProcessQMPNew(const char *binary,
 if (VIR_ALLOC(proc) < 0)
 goto error;
 
-if (VIR_STRDUP(proc->binary, binary) < 0)
+if (VIR_STRDUP(proc->binary, binary) < 0 ||
+VIR_STRDUP(proc->libDir, libDir) < 0)
 goto error;
 
 proc->runUid = runUid;
@@ -8241,7 +8243,7 @@ qemuProcessQMPNew(const char *binary,
 /* the ".sock" sufix is important to avoid a possible clash with a qemu
  * domain called "capabilities"
  */
-if (virAsprintf(>monpath, "%s/%s", libDir,
+if (virAsprintf(>monpath, "%s/%s", proc->libDir,
 "capabilities.monitor.sock") < 0)
 goto error;
 if (virAsprintf(>monarg, "unix:%s,server,nowait", proc->monpath) < 0)
@@ -8253,7 +8255,7 @@ qemuProcessQMPNew(const char *binary,
  * -daemonize we need QEMU to be allowed to create them, rather
  * than libvirtd. So we're using libDir which QEMU can write to
  */
-if (virAsprintf(>pidfile, "%s/%s", libDir, "capabilities.pidfile") < 
0)
+if (virAsprintf(>pidfile, "%s/%s", proc->libDir, 
"capabilities.pidfile") < 0)
 goto error;
 
 virPidFileForceCleanupPath(proc->pidfile);
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 9938dd0a69..e07584c11c 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -218,6 +218,7 @@ typedef struct _qemuProcessQMP qemuProcessQMP;
 typedef qemuProcessQMP *qemuProcessQMPPtr;
 struct _qemuProcessQMP {
 char *binary;
+char *libDir;
 uid_t runUid;
 gid_t runGid;
 int status;
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 24/33] qemu_monitor: qemuMonitorGetCPUModelExpansion inputs and outputs CPUModelInfo

2019-01-12 Thread Chris Venteicher
A Full CPUModelInfo structure with props is sent to QEMU for expansion.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c |  8 +---
 src/qemu/qemu_monitor.c  | 20 +++-
 src/qemu/qemu_monitor.h  |  5 +++--
 src/qemu/qemu_monitor_json.c | 12 +++-
 src/qemu/qemu_monitor_json.h |  4 ++--
 tests/cputest.c  | 11 ---
 6 files changed, 40 insertions(+), 20 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index cd8d1439f6..463c803416 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2476,6 +2476,7 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
qemuMonitorPtr mon,
bool tcg)
 {
+qemuMonitorCPUModelInfoPtr input;
 qemuMonitorCPUModelInfoPtr migratable = NULL;
 qemuMonitorCPUModelInfoPtr nonMigratable = NULL;
 qemuMonitorCPUModelInfoPtr augmented = NULL;
@@ -2508,7 +2509,8 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
 else
 type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC;
 
-if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, ) < 
0)
+if (!(input = qemuMonitorCPUModelInfoNew(model)) ||
+qemuMonitorGetCPUModelExpansion(mon, type, input, true, ) < 
0)
 goto cleanup;
 
 if (!migratable) {
@@ -2517,8 +2519,7 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
 }
 
 /* Try to check migratability of each feature. */
-if (qemuMonitorGetCPUModelExpansion(mon, type, model, false,
-) < 0)
+if (qemuMonitorGetCPUModelExpansion(mon, type, input, false, 
) < 0)
 goto cleanup;
 
 if (virQEMUCapsMigratablePropsCalc(migratable, nonMigratable, ) 
< 0)
@@ -2528,6 +2529,7 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
 ret = 0;
 
  cleanup:
+qemuMonitorCPUModelInfoFree(input);
 qemuMonitorCPUModelInfoFree(migratable);
 qemuMonitorCPUModelInfoFree(nonMigratable);
 qemuMonitorCPUModelInfoFree(augmented);
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index ac9fc1cdc2..d6bb2488d1 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3669,20 +3669,30 @@ qemuMonitorCPUDefInfoFree(qemuMonitorCPUDefInfoPtr cpu)
 }
 
 
+/**
+ * qemuMonitorGetCPUModelExpansion:
+ * @mon:
+ * @type: qemuMonitorCPUModelExpansionType
+ * @input: Input model
+ * @migratable: Prompt QEMU to include non-migratable props for X86 models if 
false
+ * @expansion: Expanded output model (or NULL if QEMU rejects model or request)
+ *
+ * Re-represent @input CPU props using a new constructed CPUModelInfo
+*/
 int
 qemuMonitorGetCPUModelExpansion(qemuMonitorPtr mon,
 qemuMonitorCPUModelExpansionType type,
-const char *model_name,
+qemuMonitorCPUModelInfoPtr input,
 bool migratable,
-qemuMonitorCPUModelInfoPtr *model_info)
+qemuMonitorCPUModelInfoPtr *expansion
+   )
 {
 VIR_DEBUG("type=%d model_name=%s migratable=%d",
-  type, model_name, migratable);
+  type, input->name, migratable);
 
 QEMU_CHECK_MONITOR(mon);
 
-return qemuMonitorJSONGetCPUModelExpansion(mon, type, model_name,
-   migratable, model_info);
+return qemuMonitorJSONGetCPUModelExpansion(mon, type, input, migratable, 
expansion);
 }
 
 
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index bb74f29cb4..4440e2f3d6 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1061,9 +1061,10 @@ typedef enum {
 
 int qemuMonitorGetCPUModelExpansion(qemuMonitorPtr mon,
 qemuMonitorCPUModelExpansionType type,
-const char *model_name,
+qemuMonitorCPUModelInfoPtr input,
 bool migratable,
-qemuMonitorCPUModelInfoPtr *model_info);
+qemuMonitorCPUModelInfoPtr *expansion)
+ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(5);
 
 void qemuMonitorCPUModelInfoFree(qemuMonitorCPUModelInfoPtr model_info);
 
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index a3998decf0..e5e56747a7 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -5637,12 +5637,13 @@ 
qemuMonitorJSONBuildCPUModelInfoFromJSON(virJSONValuePtr cpu_model)
 return ret;
 }
 
+
 int
 qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mon,
 qemuMonitorCPUModelExpansionType type,
-const char *model_name,
+qemu

[libvirt] [PATCH v6 20/33] qemu_process: Use unique directories for QMP processes

2019-01-12 Thread Chris Venteicher
Multiple QEMU processes for QMP commands can operate concurrently.

Use a unique directory under libDir for each QEMU processes
to avoid pidfile and unix socket collision between processes.

The pid file name is changed from "capabilities.pidfile" to "qmp.pid"
because we no longer need to avoid a possible clash with a qemu domain
called "capabilities" now that the processes artifacts are stored in
their own unique temporary directories.

"Capabilities" was changed to "qmp" in the pid file name because these
processes are no longer specific to the capabilities usecase and are
more generic in terms of being used for any general purpose QMP message
exchanges with a QEMU process that is not associated with a domain.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 25 +++--
 src/qemu/qemu_process.h |  1 +
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index d2d067b1a6..79a914a627 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8227,6 +8227,7 @@ qemuProcessQMPFree(qemuProcessQMPPtr proc)
 
 VIR_FREE(proc->binary);
 VIR_FREE(proc->libDir);
+VIR_FREE(proc->uniqDir);
 VIR_FREE(proc->monpath);
 VIR_FREE(proc->monarg);
 VIR_FREE(proc->pidfile);
@@ -8287,32 +8288,33 @@ qemuProcessQMPNew(const char *binary,
 static int
 qemuProcessQMPInit(qemuProcessQMPPtr proc)
 {
+char *template = NULL;
 int ret = -1;
 
 VIR_DEBUG("proc=%p, emulator=%s",
   proc, proc->binary);
 
-/* the ".sock" sufix is important to avoid a possible clash with a qemu
- * domain called "capabilities"
- */
-if (virAsprintf(>monpath, "%s/%s", proc->libDir,
-"capabilities.monitor.sock") < 0)
+if (virAsprintf(, "%s/qmp-XX", proc->libDir) < 0)
+goto cleanup;
+
+if (!(proc->uniqDir = mkdtemp(template)))
+goto cleanup;
+
+if (virAsprintf(>monpath, "%s/%s", proc->uniqDir,
+"qmp.monitor") < 0)
 goto cleanup;
 
 if (virAsprintf(>monarg, "unix:%s,server,nowait", proc->monpath) < 0)
 goto cleanup;
 
-/* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
- * with a qemu domain called "capabilities"
+/*
  * Normally we'd use runDir for pid files, but because we're using
  * -daemonize we need QEMU to be allowed to create them, rather
  * than libvirtd. So we're using libDir which QEMU can write to
  */
-if (virAsprintf(>pidfile, "%s/%s", proc->libDir, 
"capabilities.pidfile") < 0)
+if (virAsprintf(>pidfile, "%s/%s", proc->uniqDir, "qmp.pid") < 0)
 goto cleanup;
 
-virPidFileForceCleanupPath(proc->pidfile);
-
 ret = 0;
 
  cleanup:
@@ -8528,4 +8530,7 @@ qemuProcessQMPStop(qemuProcessQMPPtr proc)
 
 if (proc->pidfile)
 unlink(proc->pidfile);
+
+if (proc->uniqDir)
+rmdir(proc->uniqDir);
 }
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 0bf594ad2e..d429c76723 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -226,6 +226,7 @@ struct _qemuProcessQMP {
 char *monarg;
 char *monpath;
 char *pidfile;
+char *uniqDir;
 virCommandPtr cmd;
 qemuMonitorPtr mon;
 pid_t pid;
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 18/33] qemu_process: Catch process free before process stop

2019-01-12 Thread Chris Venteicher
Catch execution paths where qemuProcessQMPFree is called before
qemuProcessQMPStop then report error and force stop before proceeding.

Also added public function header and debug message.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index fb14ed35f9..15a38144f5 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8203,13 +8203,28 @@ static qemuMonitorCallbacks callbacks = {
 };
 
 
+/**
+ * qemuProcessQMPFree:
+ * @proc: Stores process and connection state
+ *
+ * Free process data structure.
+ */
 void
 qemuProcessQMPFree(qemuProcessQMPPtr proc)
 {
 if (!proc)
 return;
 
-qemuProcessQMPStop(proc);
+VIR_DEBUG("proc=%p, proc->mon=%p", proc, proc->mon);
+
+/* This should never be non-NULL if we get here, but just in case... */
+if (proc->mon || proc->pid) {
+VIR_ERROR(_("Unexpected QEMU still active during process free"
+" emulator: %s, pid: %lld, mon: %p"),
+  proc->binary, (long long)proc->pid, proc->mon);
+qemuProcessQMPStop(proc);
+}
+
 VIR_FREE(proc->binary);
 VIR_FREE(proc->libDir);
 VIR_FREE(proc->monpath);
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 12/33] qemu_process: Collect monitor code in single function

2019-01-12 Thread Chris Venteicher
qemuMonitor code lives in qemuProcessQMPConnectMonitor rather than in
qemuProcessQMPNew and qemuProcessQMPLaunch.

This is consistent with existing structure in qemu_process.c where
qemuConnectMonitor function contains monitor code for domain process
activation.

Simple code moves in this patch.  Improvements in later patch.

Only intended functional change in this patch is we don't
move (include) code to initiate process stop on failure to create monitor.

As comments in qemuProcessQMPStart say... Client must always call
qemuProcessStop and qemuProcessQMPFree, even in error cases.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 48 -
 1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 3b785d64e5..5492ff5a19 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8258,10 +8258,6 @@ qemuProcessQMPNew(const char *binary,
 
 virPidFileForceCleanupPath(proc->pidfile);
 
-proc->config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
-proc->config.data.nix.path = proc->monpath;
-proc->config.data.nix.listen = false;
-
 return proc;
 
  error:
@@ -8292,7 +8288,6 @@ qemuProcessQMPInit(qemuProcessQMPPtr proc)
 static int
 qemuProcessQMPLaunch(qemuProcessQMPPtr proc)
 {
-virDomainXMLOptionPtr xmlopt = NULL;
 const char *machine;
 int ret = -1;
 
@@ -8344,6 +8339,28 @@ qemuProcessQMPLaunch(qemuProcessQMPPtr proc)
 goto cleanup;
 }
 
+ret = 0;
+
+ cleanup:
+return ret;
+}
+
+
+/* Connect Monitor to QEMU Process
+ */
+static int
+qemuProcessQMPConnectMonitor(qemuProcessQMPPtr proc)
+{
+int ret = -1;
+virDomainXMLOptionPtr xmlopt = NULL;
+
+VIR_DEBUG("proc=%p, emulator=%s, proc->pid=%lld",
+  proc, proc->binary, (long long)proc->pid);
+
+proc->config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
+proc->config.data.nix.path = proc->monpath;
+proc->config.data.nix.listen = false;
+
 if (!(xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL, NULL, NULL)) ||
 !(proc->vm = virDomainObjNew(xmlopt)))
 goto cleanup;
@@ -8359,27 +8376,8 @@ qemuProcessQMPLaunch(qemuProcessQMPPtr proc)
 ret = 0;
 
  cleanup:
-if (!proc->mon)
-qemuProcessQMPStop(proc);
+VIR_DEBUG("ret=%i", ret);
 virObjectUnref(xmlopt);
-
-return ret;
-}
-
-
-/* Connect Monitor to QEMU Process
- */
-static int
-qemuProcessQMPConnectMonitor(qemuProcessQMPPtr proc)
-{
-int ret = -1;
-
-VIR_DEBUG("proc=%p, emulator=%s, proc->pid=%lld",
-  proc, proc->binary, (long long)proc->pid);
-
-ret = 0;
-
-VIR_DEBUG("ret=%i", ret);
 return ret;
 }
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 04/33] qemu_process: Refer to proc not cmd in process code

2019-01-12 Thread Chris Venteicher
s/cmd/proc/ in process code imported from qemu_capabilities.

No functionality is changed.  Just variable renaming.

Process code imported from qemu_capabilities was oriented around
starting a process to issue a single QMP command.

Future usecases (ex. baseline, compare) expect to use a single process
to issue multiple different QMP commands.

This patch changes the variable naming from cmd to proc to put focus
on the process being maintained to issue commands.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c |  18 ++---
 src/qemu/qemu_process.c  | 140 +--
 src/qemu/qemu_process.h  |   4 +-
 3 files changed, 81 insertions(+), 81 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 60ad8ad68d..e062e4daa8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4359,39 +4359,39 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
gid_t runGid,
char **qmperr)
 {
-qemuProcessQMPPtr cmd = NULL;
+qemuProcessQMPPtr proc = NULL;
 int ret = -1;
 int rc;
 
-if (!(cmd = qemuProcessQMPNew(qemuCaps->binary, libDir,
-  runUid, runGid, qmperr)))
+if (!(proc = qemuProcessQMPNew(qemuCaps->binary, libDir,
+   runUid, runGid, qmperr)))
 goto cleanup;
 
-if ((rc = qemuProcessQMPRun(cmd, false)) != 0) {
+if ((rc = qemuProcessQMPRun(proc, false)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
 }
 
-if (virQEMUCapsInitQMPMonitor(qemuCaps, cmd->mon) < 0)
+if (virQEMUCapsInitQMPMonitor(qemuCaps, proc->mon) < 0)
 goto cleanup;
 
 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
-qemuProcessQMPAbort(cmd);
-if ((rc = qemuProcessQMPRun(cmd, true)) != 0) {
+qemuProcessQMPAbort(proc);
+if ((rc = qemuProcessQMPRun(proc, true)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
 }
 
-if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, cmd->mon) < 0)
+if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, proc->mon) < 0)
 goto cleanup;
 }
 
 ret = 0;
 
  cleanup:
-qemuProcessQMPFree(cmd);
+qemuProcessQMPFree(proc);
 return ret;
 }
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7e577f8e7b..e3f793d1e5 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8204,17 +8204,17 @@ static qemuMonitorCallbacks callbacks = {
 
 
 void
-qemuProcessQMPFree(qemuProcessQMPPtr cmd)
+qemuProcessQMPFree(qemuProcessQMPPtr proc)
 {
-if (!cmd)
+if (!proc)
 return;
 
-qemuProcessQMPAbort(cmd);
-VIR_FREE(cmd->binary);
-VIR_FREE(cmd->monpath);
-VIR_FREE(cmd->monarg);
-VIR_FREE(cmd->pidfile);
-VIR_FREE(cmd);
+qemuProcessQMPAbort(proc);
+VIR_FREE(proc->binary);
+VIR_FREE(proc->monpath);
+VIR_FREE(proc->monarg);
+VIR_FREE(proc->pidfile);
+VIR_FREE(proc);
 }
 
 
@@ -8225,25 +8225,25 @@ qemuProcessQMPNew(const char *binary,
   gid_t runGid,
   char **qmperr)
 {
-qemuProcessQMPPtr cmd = NULL;
+qemuProcessQMPPtr proc = NULL;
 
-if (VIR_ALLOC(cmd) < 0)
+if (VIR_ALLOC(proc) < 0)
 goto error;
 
-if (VIR_STRDUP(cmd->binary, binary) < 0)
+if (VIR_STRDUP(proc->binary, binary) < 0)
 goto error;
 
-cmd->runUid = runUid;
-cmd->runGid = runGid;
-cmd->qmperr = qmperr;
+proc->runUid = runUid;
+proc->runGid = runGid;
+proc->qmperr = qmperr;
 
 /* the ".sock" sufix is important to avoid a possible clash with a qemu
  * domain called "capabilities"
  */
-if (virAsprintf(>monpath, "%s/%s", libDir,
+if (virAsprintf(>monpath, "%s/%s", libDir,
 "capabilities.monitor.sock") < 0)
 goto error;
-if (virAsprintf(>monarg, "unix:%s,server,nowait", cmd->monpath) < 0)
+if (virAsprintf(>monarg, "unix:%s,server,nowait", proc->monpath) < 0)
 goto error;
 
 /* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
@@ -8252,19 +8252,19 @@ qemuProcessQMPNew(const char *binary,
  * -daemonize we need QEMU to be allowed to create them, rather
  * than libvirtd. So we're using libDir which QEMU can write to
  */
-if (virAsprintf(>pidfile, "%s/%s", libDir, "capabilities.pidfile") < 
0)
+if (virAsprintf(>pidfile, "%s/%s", libDir, "capabilities.pidfile") < 
0)
 goto error;
 
-virPidFileForceCleanupPath(cmd->pidfile);
+virPidFileForceCleanupPath(proc->pidfile);
 
-cmd->config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
-cmd-&

[libvirt] [PATCH v6 22/33] qemu_monitor: Introduce qemuMonitorCPUModelInfo / JSON conversion

2019-01-12 Thread Chris Venteicher
Conversion functions are used convert CPUModelInfo structs into
QMP JSON and the reverse.

QMP JSON is of form:
{"model": {"name": "IvyBridge", "props": {}}}

qemuMonitorCPUModelInfoBoolPropAdd is used to add boolean properties to
CPUModelInfo struct.

qemuMonitorJSONGetCPUModelExpansion makes full use of conversions and
propAdd in prep to support input of full cpu model in future.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_monitor.c  |  25 ++
 src/qemu/qemu_monitor.h  |   5 ++
 src/qemu/qemu_monitor_json.c | 152 +--
 3 files changed, 140 insertions(+), 42 deletions(-)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 815a30c275..ac9fc1cdc2 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3775,6 +3775,31 @@ qemuMonitorCPUModelInfoCopy(const 
qemuMonitorCPUModelInfo *orig)
 }
 
 
+int
+qemuMonitorCPUModelInfoBoolPropAdd(qemuMonitorCPUModelInfoPtr model,
+   const char *prop_name,
+   bool prop_value)
+{
+int ret = -1;
+qemuMonitorCPUProperty prop = {
+.type = QEMU_MONITOR_CPU_PROPERTY_BOOLEAN,
+.value.boolean = prop_value
+};
+
+if (VIR_STRDUP(prop.name, prop_name) < 0)
+goto cleanup;
+
+if (VIR_APPEND_ELEMENT(model->props, model->nprops, prop) < 0)
+goto cleanup;
+
+ret = 0;
+
+ cleanup:
+VIR_FREE(prop.name);
+return ret;
+}
+
+
 int
 qemuMonitorGetCommands(qemuMonitorPtr mon,
char ***commands)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index d17bda75c3..bb74f29cb4 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1072,6 +1072,11 @@ qemuMonitorCPUModelInfoPtr 
qemuMonitorCPUModelInfoNew(const char *name);
 qemuMonitorCPUModelInfoPtr
 qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig);
 
+int qemuMonitorCPUModelInfoBoolPropAdd(qemuMonitorCPUModelInfoPtr model,
+   const char *prop_name,
+   bool prop_value)
+ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
 int qemuMonitorGetCommands(qemuMonitorPtr mon,
char ***commands);
 int qemuMonitorGetEvents(qemuMonitorPtr mon,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index dcb468c747..a3998decf0 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -5541,6 +5541,102 @@ qemuMonitorJSONParseCPUModelProperty(const char *key,
 return 0;
 }
 
+
+/* model_json: {"name": "z13-base", "props": {}}
+ */
+static virJSONValuePtr
+qemuMonitorJSONBuildCPUModelInfoToJSON(qemuMonitorCPUModelInfoPtr model)
+{
+virJSONValuePtr cpu_props = NULL;
+virJSONValuePtr model_json = NULL;
+size_t i;
+
+if (!model)
+goto cleanup;
+
+if (model->nprops > 0 && !(cpu_props = virJSONValueNewObject()))
+goto cleanup;
+
+for (i = 0; i < model->nprops; i++) {
+qemuMonitorCPUPropertyPtr prop = &(model->props[i]);
+
+switch (prop->type) {
+case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN:
+if (virJSONValueObjectAppendBoolean(cpu_props, prop->name,
+prop->value.boolean) < 0)
+goto cleanup;
+break;
+
+case QEMU_MONITOR_CPU_PROPERTY_STRING:
+if (virJSONValueObjectAppendString(cpu_props, prop->name,
+   prop->value.string) < 0)
+goto cleanup;
+break;
+
+case QEMU_MONITOR_CPU_PROPERTY_NUMBER:
+if (virJSONValueObjectAppendNumberLong(cpu_props, prop->name,
+   prop->value.number) < 0)
+goto cleanup;
+break;
+
+case QEMU_MONITOR_CPU_PROPERTY_LAST:
+default:
+virReportEnumRangeError(qemuMonitorCPUPropertyPtr, prop->type);
+goto cleanup;
+}
+}
+
+ignore_value(virJSONValueObjectCreate(_json, "s:name", model->name,
+  "A:props", _props, NULL));
+
+ cleanup:
+virJSONValueFree(cpu_props);
+return model_json;
+}
+
+
+/* model_json: {"name": "IvyBridge", "props": {}}
+ */
+static qemuMonitorCPUModelInfoPtr
+qemuMonitorJSONBuildCPUModelInfoFromJSON(virJSONValuePtr cpu_model)
+{
+virJSONValuePtr cpu_props;
+qemuMonitorCPUModelInfoPtr model = NULL;
+qemuMonitorCPUModelInfoPtr ret = NULL;
+char const *cpu_name;
+
+if (!(cpu_name = virJSONValueObjectGetString(cpu_model, "name"))) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Parsed JSON reply missing 'nam

[libvirt] [PATCH v6 09/33] qemu_process: Expose process exit status code

2019-01-12 Thread Chris Venteicher
Expose the process exit status code so the status code can be used to
determine if stderr (qmperr) should be logged.

In the case of virQEMUCapsInitQmp,
we only log stderr (qmperr) if the -first- query process fails with a
non zero status code.

Logging functions are pulled inside virQEMUCapsInitQmp where we can
detect that the -first- (not subsequent) QEMU process activation failed
with nonzero status.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 73 ++--
 src/qemu/qemu_process.c  |  9 +++--
 src/qemu/qemu_process.h  |  1 +
 3 files changed, 42 insertions(+), 41 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 502bac5e43..12c4ed2eb5 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4349,23 +4349,49 @@ virQEMUCapsInitQMPMonitorTCG(virQEMUCapsPtr qemuCaps 
ATTRIBUTE_UNUSED,
 }
 
 
+#define MESSAGE_ID_CAPS_PROBE_FAILURE "8ae2f3fb-2dbe-498e-8fbd-012d40afa361"
+
+static void
+virQEMUCapsLogProbeFailure(const char *binary)
+{
+virLogMetadata meta[] = {
+{ .key = "MESSAGE_ID", .s = MESSAGE_ID_CAPS_PROBE_FAILURE, .iv = 0 },
+{ .key = "LIBVIRT_QEMU_BINARY", .s = binary, .iv = 0 },
+{ .key = NULL },
+};
+
+virLogMessage(,
+  VIR_LOG_WARN,
+  __FILE__, __LINE__, __func__,
+  meta,
+  _("Failed to probe capabilities for %s: %s"),
+  binary, virGetLastErrorMessage());
+}
+
+
 static int
 virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
const char *libDir,
uid_t runUid,
-   gid_t runGid,
-   char **qmperr)
+   gid_t runGid)
 {
 qemuProcessQMPPtr proc = NULL;
 qemuProcessQMPPtr procTCG = NULL;
+char *qmperr = NULL;
 int ret = -1;
 
 if (!(proc = qemuProcessQMPNew(qemuCaps->binary, libDir,
-   runUid, runGid, qmperr, false)))
+   runUid, runGid, , false)))
 goto cleanup;
 
-if (qemuProcessQMPRun(proc) < 0)
+if (qemuProcessQMPRun(proc) < 0) {
+if (proc->status != 0)
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Failed to probe QEMU binary with QMP: %s"),
+   qmperr ? qmperr : _("uknown error"));
+
 goto cleanup;
+}
 
 if (virQEMUCapsInitQMPMonitor(qemuCaps, proc->mon) < 0)
 goto cleanup;
@@ -4390,34 +4416,19 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 ret = 0;
 
  cleanup:
+if (ret < 0)
+virQEMUCapsLogProbeFailure(qemuCaps->binary);
+
 qemuProcessQMPStop(proc);
 qemuProcessQMPStop(procTCG);
 qemuProcessQMPFree(proc);
 qemuProcessQMPFree(procTCG);
+VIR_FREE(qmperr);
+
 return ret;
 }
 
 
-#define MESSAGE_ID_CAPS_PROBE_FAILURE "8ae2f3fb-2dbe-498e-8fbd-012d40afa361"
-
-static void
-virQEMUCapsLogProbeFailure(const char *binary)
-{
-virLogMetadata meta[] = {
-{ .key = "MESSAGE_ID", .s = MESSAGE_ID_CAPS_PROBE_FAILURE, .iv = 0 },
-{ .key = "LIBVIRT_QEMU_BINARY", .s = binary, .iv = 0 },
-{ .key = NULL },
-};
-
-virLogMessage(,
-  VIR_LOG_WARN,
-  __FILE__, __LINE__, __func__,
-  meta,
-  _("Failed to probe capabilities for %s: %s"),
-  binary, virGetLastErrorMessage());
-}
-
-
 virQEMUCapsPtr
 virQEMUCapsNewForBinaryInternal(virArch hostArch,
 const char *binary,
@@ -4429,7 +4440,6 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
 {
 virQEMUCapsPtr qemuCaps;
 struct stat sb;
-char *qmperr = NULL;
 
 if (!(qemuCaps = virQEMUCapsNew()))
 goto error;
@@ -4456,18 +4466,8 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
 goto error;
 }
 
-if (virQEMUCapsInitQMP(qemuCaps, libDir, runUid, runGid, ) < 0) {
-virQEMUCapsLogProbeFailure(binary);
+if (virQEMUCapsInitQMP(qemuCaps, libDir, runUid, runGid) < 0)
 goto error;
-}
-
-if (!qemuCaps->usedQMP) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("Failed to probe QEMU binary with QMP: %s"),
-   qmperr ? qmperr : _("unknown error"));
-virQEMUCapsLogProbeFailure(binary);
-goto error;
-}
 
 qemuCaps->libvirtCtime = virGetSelfLastChanged();
 qemuCaps->libvirtVersion = LIBVIR_VERSION_NUMBER;
@@ -4485,7 +4485,6 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
 }
 
  cleanup:
-VIR_FREE(qmperr);
 return qemuCaps;
 
  error:
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index f662b7d2ce..10e7bc5f11 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu

[libvirt] [PATCH v6 28/33] qemu_driver: Consolidate code to baseline using libvirt

2019-01-12 Thread Chris Venteicher
Simple cut/paste operations within function
qemuConnectBaselineHypervisorCPU to group together code specific to
computing baseline using only libvirt utility functions.

This is done in anticipation of creating new utility functions for
1) baseline using libvirt utilities (this code)
2) baseline using qemu qmp command (future)

Future patches are easier to follow if the code for using libvirt is
consolidated.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_driver.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1d961707cc..161b82d229 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13711,7 +13711,6 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 virQEMUCapsPtr qemuCaps = NULL;
 virArch arch;
 virDomainVirtType virttype;
-virDomainCapsCPUModelsPtr cpuModels;
 bool migratable;
 virCPUDefPtr cpu = NULL;
 char *cpustr = NULL;
@@ -13723,8 +13722,6 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 if (virConnectBaselineHypervisorCPUEnsureACL(conn) < 0)
 goto cleanup;
 
-migratable = !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE);
-
 if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_AUTO)))
 goto cleanup;
 
@@ -13737,17 +13734,21 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 if (!qemuCaps)
 goto cleanup;
 
-if (!(cpuModels = virQEMUCapsGetCPUDefinitions(qemuCaps, virttype)) ||
-cpuModels->nmodels == 0) {
-virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
-   _("QEMU '%s' does not support any CPU models for "
- "virttype '%s'"),
-   virQEMUCapsGetBinary(qemuCaps),
-   virDomainVirtTypeToString(virttype));
-goto cleanup;
-}
-
 if (ARCH_IS_X86(arch)) {
+migratable = !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE);
+
+virDomainCapsCPUModelsPtr cpuModels;
+
+if (!(cpuModels = virQEMUCapsGetCPUDefinitions(qemuCaps, virttype)) ||
+cpuModels->nmodels == 0) {
+virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+   _("QEMU '%s' does not support any CPU models for "
+ "virttype '%s'"),
+   virQEMUCapsGetBinary(qemuCaps),
+   virDomainVirtTypeToString(virttype));
+goto cleanup;
+}
+
 int rc = virQEMUCapsGetCPUFeatures(qemuCaps, virttype,
migratable, );
 if (rc < 0)
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 05/33] qemu_process: Use consistent name for stop process function

2019-01-12 Thread Chris Venteicher
s/qemuProcessQMPAbort/qemuProcessQMPStop/ applied to change function name
used to stop QEMU processes in process code moved from qemu_capabilities.

No functionality change.

The new name, qemuProcessQMPStop, is consistent with the existing
function qemuProcessStop used to stop Domain processes.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 2 +-
 src/qemu/qemu_process.c  | 6 +++---
 src/qemu/qemu_process.h  | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index e062e4daa8..2bacd5e40a 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4377,7 +4377,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 goto cleanup;
 
 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
-qemuProcessQMPAbort(proc);
+qemuProcessQMPStop(proc);
 if ((rc = qemuProcessQMPRun(proc, true)) != 0) {
 if (rc == 1)
 ret = 0;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e3f793d1e5..2ab1319ab9 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8209,7 +8209,7 @@ qemuProcessQMPFree(qemuProcessQMPPtr proc)
 if (!proc)
 return;
 
-qemuProcessQMPAbort(proc);
+qemuProcessQMPStop(proc);
 VIR_FREE(proc->binary);
 VIR_FREE(proc->monpath);
 VIR_FREE(proc->monarg);
@@ -8345,7 +8345,7 @@ qemuProcessQMPRun(qemuProcessQMPPtr proc,
 
  cleanup:
 if (!proc->mon)
-qemuProcessQMPAbort(proc);
+qemuProcessQMPStop(proc);
 virObjectUnref(xmlopt);
 
 return ret;
@@ -8357,7 +8357,7 @@ qemuProcessQMPRun(qemuProcessQMPPtr proc,
 
 
 void
-qemuProcessQMPAbort(qemuProcessQMPPtr proc)
+qemuProcessQMPStop(qemuProcessQMPPtr proc)
 {
 if (proc->mon)
 virObjectUnlock(proc->mon);
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 05bcf4f12b..28186a256f 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -242,6 +242,6 @@ void qemuProcessQMPFree(qemuProcessQMPPtr proc);
 int qemuProcessQMPRun(qemuProcessQMPPtr cmd,
   bool forceTCG);
 
-void qemuProcessQMPAbort(qemuProcessQMPPtr proc);
+void qemuProcessQMPStop(qemuProcessQMPPtr proc);
 
 #endif /* LIBVIRT_QEMU_PROCESS_H */
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 27/33] qemu_monitor: Support query-cpu-model-baseline QMP command

2019-01-12 Thread Chris Venteicher
Introduce monitor functions to use QEMU to compute baseline cpu
from an input of two cpu models.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_monitor.c  | 12 
 src/qemu/qemu_monitor.h  |  6 
 src/qemu/qemu_monitor_json.c | 60 
 src/qemu/qemu_monitor_json.h |  6 
 4 files changed, 84 insertions(+)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index d6bb2488d1..7d82f25fc2 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4526,3 +4526,15 @@ qemuMonitorGetPRManagerInfo(qemuMonitorPtr mon,
 virHashFree(info);
 return ret;
 }
+
+
+int
+qemuMonitorGetCPUModelBaseline(qemuMonitorPtr mon,
+   qemuMonitorCPUModelInfoPtr model_a,
+   qemuMonitorCPUModelInfoPtr model_b,
+   qemuMonitorCPUModelInfoPtr *model_baseline)
+{
+QEMU_CHECK_MONITOR(mon);
+
+return qemuMonitorJSONGetCPUModelBaseline(mon, model_a, model_b, 
model_baseline);
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 4440e2f3d6..2b3ea6ab8e 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1230,4 +1230,10 @@ struct _qemuMonitorPRManagerInfo {
 int qemuMonitorGetPRManagerInfo(qemuMonitorPtr mon,
 virHashTablePtr *retinfo);
 
+int qemuMonitorGetCPUModelBaseline(qemuMonitorPtr mon,
+   qemuMonitorCPUModelInfoPtr model_a,
+   qemuMonitorCPUModelInfoPtr model_b,
+   qemuMonitorCPUModelInfoPtr *model_baseline)
+ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
+
 #endif /* LIBVIRT_QEMU_MONITOR_H */
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index e5e56747a7..792c3a1e0a 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -8547,3 +8547,63 @@ qemuMonitorJSONGetPRManagerInfo(qemuMonitorPtr mon,
 return ret;
 
 }
+
+
+int
+qemuMonitorJSONGetCPUModelBaseline(qemuMonitorPtr mon,
+   qemuMonitorCPUModelInfoPtr model_a,
+   qemuMonitorCPUModelInfoPtr model_b,
+   qemuMonitorCPUModelInfoPtr *model_baseline)
+{
+int ret = -1;
+virJSONValuePtr cmd = NULL;
+virJSONValuePtr reply = NULL;
+virJSONValuePtr data = NULL;
+virJSONValuePtr modela = NULL;
+virJSONValuePtr modelb = NULL;
+virJSONValuePtr cpu_model = NULL;
+
+*model_baseline = NULL;
+
+if (!(modela = qemuMonitorJSONBuildCPUModelInfoToJSON(model_a)) ||
+!(modelb = qemuMonitorJSONBuildCPUModelInfoToJSON(model_b)))
+goto cleanup;
+
+if (!(cmd = qemuMonitorJSONMakeCommand("query-cpu-model-baseline",
+   "a:modela", ,
+   "a:modelb", ,
+   NULL)))
+goto cleanup;
+
+if (qemuMonitorJSONCommand(mon, cmd, ) < 0)
+goto cleanup;
+
+if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_OBJECT) < 0) {
+virReportError(VIR_ERR_INVALID_ARG,
+   _("QEMU doesn't support baseline or recognize model %s 
or %s"),
+   model_a->name,
+   model_b->name);
+goto cleanup;
+}
+
+data = virJSONValueObjectGetObject(reply, "return");
+
+if (!(cpu_model = virJSONValueObjectGetObject(data, "model"))) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("query-cpu-model-baseline reply data was missing 
'model'"));
+goto cleanup;
+}
+
+if (!(*model_baseline = 
qemuMonitorJSONBuildCPUModelInfoFromJSON(cpu_model)))
+goto cleanup;
+
+ret = 0;
+
+ cleanup:
+virJSONValueFree(cmd);
+virJSONValueFree(reply);
+virJSONValueFree(modela);
+virJSONValueFree(modelb);
+
+return ret;
+}
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 731f1ec010..df2759ca11 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -578,4 +578,10 @@ int qemuMonitorJSONGetPRManagerInfo(qemuMonitorPtr mon,
 virHashTablePtr info)
 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
+int qemuMonitorJSONGetCPUModelBaseline(qemuMonitorPtr mon,
+   qemuMonitorCPUModelInfoPtr model_a,
+   qemuMonitorCPUModelInfoPtr model_b,
+   qemuMonitorCPUModelInfoPtr 
*model_baseline)
+ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
+
 #endif /* LIBVIRT_QEMU_MONITOR_JSON_H */
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 00/33] BaselineHypervisorCPU using QEMU QMP exchanges

2019-01-12 Thread Chris Venteicher
mu_driver: Support feature expansion via QEMU when baselining cpu
qemu_driver: Remove unsupported props in expanded hypervisor baseline output
qemu_monitor: Default props to migratable when expanding cpu model


-
v5:

Fixes all process issues identified here:
https://www.redhat.com/archives/libvir-list/2018-November/msg00349.html

- Make the process code generic (not capabilities specific) for use by
BaselineHypervisorCPU

- Many of the process patches are simple code moves with implementation
changes in other distinct patches

- A thread safe library function creates a unique directory under libDir for 
each QEMU
process (for QMP messaging) to decouple processes in terms of sockets and
file system footprint.

The remaining (non-process) patches in v4 address all issues in v1-v4 of
'BaselineHypervisorCPU using QEMU QMP exchanges'


Thanks,
Chris


*** BLURB HERE ***

Chris Venteicher (33):
  qEmu_process: Move process code from qemu_capabilities to qemu_process
  qemu_process: Use qemuProcessQMP prefix
  qemu_process: Limit qemuProcessQMPNew to const input strings
  qemu_process: Refer to proc not cmd in process code
  qemu_process: Use consistent name for stop process function
  qemu_capabilities: Stop QEMU process before freeing
  qemu_process: Use qemuProcessQMP struct for a single process
  qemu_process: All ProcessQMP errors are fatal
  qemu_process: Expose process exit status code
  qemu_process: Persist stderr in qemuProcessQMP struct
  qemu_process: Introduce qemuProcessQMPStart
  qemu_process: Collect monitor code in single function
  qemu_process: Store libDir in qemuProcessQMP struct
  qemu_process: Setup paths within qemuProcessQMPInit
  qemu_process: Stop retaining Monitor config in qemuProcessQMP
  qemu_process: Cleanup qemuProcessQMP alloc function
  qemu_process: Cleanup qemuProcessQMPStop function
  qemu_process: Catch process free before process stop
  qemu_process: Enter QMP command mode when starting QEMU Process
  qemu_process: Use unique directories for QMP processes
  qemu_monitor: Introduce qemuMonitorCPUModelInfoNew
  qemu_monitor: Introduce qemuMonitorCPUModelInfo / JSON conversion
  qemu_capabilities: Introduce virQEMuCapsMigratablePropsCalc
  qemu_monitor: qemuMonitorGetCPUModelExpansion inputs and outputs
CPUModelInfo
  qemu_capabilities: Introduce CPUModelInfo to virCPUDef function
  qemu_capabilities: Introduce virCPUDef to CPUModelInfo function
  qemu_monitor: Support query-cpu-model-baseline QMP command
  qemu_driver: Consolidate code to baseline using libvirt
  qemu_driver: Decouple code for baseline using libvirt
  qemu_driver: Identify using libvirt as a distinct way to compute
baseline
  qemu_driver: Support baseline calculation using QEMU
  qemu_driver: Support feature expansion via QEMU when baselining cpu
  qemu_monitor: Default props to migratable when expanding cpu model

 src/qemu/qemu_capabilities.c  | 631 --
 src/qemu/qemu_capabilities.h  |   4 +
 src/qemu/qemu_driver.c| 216 +-
 src/qemu/qemu_monitor.c   | 165 -
 src/qemu/qemu_monitor.h   |  29 +-
 src/qemu/qemu_monitor_json.c  | 223 +--
 src/qemu/qemu_monitor_json.h  |  10 +-
 src/qemu/qemu_process.c   | 345 ++
 src/qemu/qemu_process.h   |  32 +
 tests/cputest.c   |  11 +-
 .../caps_2.10.0.s390x.xml |  60 +-
 .../caps_2.11.0.s390x.xml |  58 +-
 .../caps_2.12.0.s390x.xml |  56 +-
 .../qemucapabilitiesdata/caps_2.8.0.s390x.xml |  32 +-
 .../qemucapabilitiesdata/caps_2.9.0.s390x.xml |  34 +-
 .../qemucapabilitiesdata/caps_3.0.0.s390x.xml |  64 +-
 tests/qemucapabilitiestest.c  |   7 +
 17 files changed, 1375 insertions(+), 602 deletions(-)

-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 07/33] qemu_process: Use qemuProcessQMP struct for a single process

2019-01-12 Thread Chris Venteicher
In new process code, move from model where qemuProcessQMP struct can be
used to activate a series of Qemu processes to model where one
qemuProcessQMP struct is used for one and only one Qemu process.

By allowing only one process activation per qemuProcessQMP struct, the
struct can safely store process outputs like status and stderr, without
being overwritten, until qemuProcessQMPFree is called.

By doing this, process outputs like status and stderr can remain stored
in the qemuProcessQMP struct without being overwritten by subsequent
process activations.

The forceTCG parameter (use / don't use KVM) will be passed when the
qemuProcessQMP struct is initialized since the qemuProcessQMP struct
won't be reused.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 19 +++
 src/qemu/qemu_process.c  |  9 +
 src/qemu/qemu_process.h  |  7 ---
 3 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 73380fdc2b..35aac798d9 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4360,14 +4360,15 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
char **qmperr)
 {
 qemuProcessQMPPtr proc = NULL;
+qemuProcessQMPPtr procTCG = NULL;
 int ret = -1;
 int rc;
 
 if (!(proc = qemuProcessQMPNew(qemuCaps->binary, libDir,
-   runUid, runGid, qmperr)))
+   runUid, runGid, qmperr, false)))
 goto cleanup;
 
-if ((rc = qemuProcessQMPRun(proc, false)) != 0) {
+if ((rc = qemuProcessQMPRun(proc)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
@@ -4377,14 +4378,22 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 goto cleanup;
 
 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
+/* The second QEMU process probes for TCG capabilities
+ * in case the first process reported KVM as enabled
+ * (otherwise the first one already reported TCG capabilities). */
+
 qemuProcessQMPStop(proc);
-if ((rc = qemuProcessQMPRun(proc, true)) != 0) {
+
+procTCG = qemuProcessQMPNew(qemuCaps->binary, libDir,
+runUid, runGid, NULL, true);
+
+if ((rc = qemuProcessQMPRun(procTCG)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
 }
 
-if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, proc->mon) < 0)
+if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, procTCG->mon) < 0)
 goto cleanup;
 }
 
@@ -4392,7 +4401,9 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 
  cleanup:
 qemuProcessQMPStop(proc);
+qemuProcessQMPStop(procTCG);
 qemuProcessQMPFree(proc);
+qemuProcessQMPFree(procTCG);
 return ret;
 }
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 2208ff72b2..297a542e3d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8223,7 +8223,8 @@ qemuProcessQMPNew(const char *binary,
   const char *libDir,
   uid_t runUid,
   gid_t runGid,
-  char **qmperr)
+  char **qmperr,
+  bool forceTCG)
 {
 qemuProcessQMPPtr proc = NULL;
 
@@ -8236,6 +8237,7 @@ qemuProcessQMPNew(const char *binary,
 proc->runUid = runUid;
 proc->runGid = runGid;
 proc->qmperr = qmperr;
+proc->forceTCG = forceTCG;
 
 /* the ".sock" sufix is important to avoid a possible clash with a qemu
  * domain called "capabilities"
@@ -8274,15 +8276,14 @@ qemuProcessQMPNew(const char *binary,
  *  1 when probing QEMU failed
  */
 int
-qemuProcessQMPRun(qemuProcessQMPPtr proc,
-  bool forceTCG)
+qemuProcessQMPRun(qemuProcessQMPPtr proc)
 {
 virDomainXMLOptionPtr xmlopt = NULL;
 const char *machine;
 int status = 0;
 int ret = -1;
 
-if (forceTCG)
+if (proc->forceTCG)
 machine = "none,accel=tcg";
 else
 machine = "none,accel=kvm:tcg";
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 28186a256f..ccbdb33679 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -229,18 +229,19 @@ struct _qemuProcessQMP {
 virDomainChrSourceDef config;
 pid_t pid;
 virDomainObjPtr vm;
+bool forceTCG;
 };
 
 qemuProcessQMPPtr qemuProcessQMPNew(const char *binary,
 const char *libDir,
 uid_t runUid,
 gid_t runGid,
-char **qmperr);
+char **qmperr,
+bool forceTCG);
 
 void qemuProcessQMPFree(qemuProcessQMPPtr proc);
 
-int qemuProcessQMPRun(qemuProcessQMPPtr cmd,
-  bool forceTCG);

[libvirt] [PATCH v6 01/33] qemu_process: Move process code from qemu_capabilities to qemu_process

2019-01-12 Thread Chris Venteicher
Qemu process code in qemu_capabilities.c is moved to qemu_process.c in
order to make the code usable outside the original capabilities
usecases.

The moved code activates and manages Qemu processes without
establishing a guest domain.

** This patch is a straight cut/paste move between files. **

Then, subsequent patches modify the process code
to make function prefixes and variable names match qemu_process,
and make the code usable for more than the capabilities usecase.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 218 +--
 src/qemu/qemu_process.c  | 199 
 src/qemu/qemu_process.h  |  30 +
 3 files changed, 230 insertions(+), 217 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index f504db7d05..acd88d990e 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -45,6 +45,7 @@
 #define LIBVIRT_QEMU_CAPSPRIV_H_ALLOW
 #include "qemu_capspriv.h"
 #include "qemu_qapi.h"
+#include "qemu_process.h"
 
 #include 
 #include 
@@ -4056,18 +4057,6 @@ virQEMUCapsIsValid(void *data,
 }
 
 
-static void virQEMUCapsMonitorNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- void *opaque ATTRIBUTE_UNUSED)
-{
-}
-
-static qemuMonitorCallbacks callbacks = {
-.eofNotify = virQEMUCapsMonitorNotify,
-.errorNotify = virQEMUCapsMonitorNotify,
-};
-
-
 /**
  * virQEMUCapsInitQMPArch:
  * @qemuCaps: QEMU capabilities
@@ -4363,211 +4352,6 @@ virQEMUCapsInitQMPMonitorTCG(virQEMUCapsPtr qemuCaps 
ATTRIBUTE_UNUSED,
 }
 
 
-typedef struct _virQEMUCapsInitQMPCommand virQEMUCapsInitQMPCommand;
-typedef virQEMUCapsInitQMPCommand *virQEMUCapsInitQMPCommandPtr;
-struct _virQEMUCapsInitQMPCommand {
-char *binary;
-uid_t runUid;
-gid_t runGid;
-char **qmperr;
-char *monarg;
-char *monpath;
-char *pidfile;
-virCommandPtr cmd;
-qemuMonitorPtr mon;
-virDomainChrSourceDef config;
-pid_t pid;
-virDomainObjPtr vm;
-};
-
-
-static void
-virQEMUCapsInitQMPCommandAbort(virQEMUCapsInitQMPCommandPtr cmd)
-{
-if (cmd->mon)
-virObjectUnlock(cmd->mon);
-qemuMonitorClose(cmd->mon);
-cmd->mon = NULL;
-
-virCommandAbort(cmd->cmd);
-virCommandFree(cmd->cmd);
-cmd->cmd = NULL;
-
-if (cmd->monpath)
-unlink(cmd->monpath);
-
-virDomainObjEndAPI(>vm);
-
-if (cmd->pid != 0) {
-char ebuf[1024];
-
-VIR_DEBUG("Killing QMP caps process %lld", (long long)cmd->pid);
-if (virProcessKill(cmd->pid, SIGKILL) < 0 && errno != ESRCH)
-VIR_ERROR(_("Failed to kill process %lld: %s"),
-  (long long)cmd->pid,
-  virStrerror(errno, ebuf, sizeof(ebuf)));
-
-VIR_FREE(*cmd->qmperr);
-}
-if (cmd->pidfile)
-unlink(cmd->pidfile);
-cmd->pid = 0;
-}
-
-
-static void
-virQEMUCapsInitQMPCommandFree(virQEMUCapsInitQMPCommandPtr cmd)
-{
-if (!cmd)
-return;
-
-virQEMUCapsInitQMPCommandAbort(cmd);
-VIR_FREE(cmd->binary);
-VIR_FREE(cmd->monpath);
-VIR_FREE(cmd->monarg);
-VIR_FREE(cmd->pidfile);
-VIR_FREE(cmd);
-}
-
-
-static virQEMUCapsInitQMPCommandPtr
-virQEMUCapsInitQMPCommandNew(char *binary,
- const char *libDir,
- uid_t runUid,
- gid_t runGid,
- char **qmperr)
-{
-virQEMUCapsInitQMPCommandPtr cmd = NULL;
-
-if (VIR_ALLOC(cmd) < 0)
-goto error;
-
-if (VIR_STRDUP(cmd->binary, binary) < 0)
-goto error;
-
-cmd->runUid = runUid;
-cmd->runGid = runGid;
-cmd->qmperr = qmperr;
-
-/* the ".sock" sufix is important to avoid a possible clash with a qemu
- * domain called "capabilities"
- */
-if (virAsprintf(>monpath, "%s/%s", libDir,
-"capabilities.monitor.sock") < 0)
-goto error;
-if (virAsprintf(>monarg, "unix:%s,server,nowait", cmd->monpath) < 0)
-goto error;
-
-/* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
- * with a qemu domain called "capabilities"
- * Normally we'd use runDir for pid files, but because we're using
- * -daemonize we need QEMU to be allowed to create them, rather
- * than libvirtd. So we're using libDir which QEMU can write to
- */
-if (virAsprintf(>pidfile, "%s/%s", libDir, "capabilities.pidfile") < 
0)
-goto error;
-
-virPidFileForceCleanupPath(cmd->pidfile);
-
-cmd->config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
-cmd->config.data.ni

[libvirt] [PATCH v6 10/33] qemu_process: Persist stderr in qemuProcessQMP struct

2019-01-12 Thread Chris Venteicher
A qemuProcessQMP struct tracks the entire lifespan of a single QEMU Process
including storing error output when the process terminates or activation
fails.

Error output remains available until qemuProcessQMPFree is called.

The qmperr variable is renamed stderr (captures stderr from process.)

The stderr buffer no longer needs to be maintained outside of the
qemuProcessQMP structure because the structure is used for a single QEMU
process and the structures can be maintained as long as required
to retrieve the process error info.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 8 +++-
 src/qemu/qemu_process.c  | 9 +++--
 src/qemu/qemu_process.h  | 3 +--
 3 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 12c4ed2eb5..b833e0d11e 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4377,18 +4377,17 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 {
 qemuProcessQMPPtr proc = NULL;
 qemuProcessQMPPtr procTCG = NULL;
-char *qmperr = NULL;
 int ret = -1;
 
 if (!(proc = qemuProcessQMPNew(qemuCaps->binary, libDir,
-   runUid, runGid, , false)))
+   runUid, runGid, false)))
 goto cleanup;
 
 if (qemuProcessQMPRun(proc) < 0) {
 if (proc->status != 0)
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to probe QEMU binary with QMP: %s"),
-   qmperr ? qmperr : _("uknown error"));
+   proc->stderr ? proc->stderr : _("uknown error"));
 
 goto cleanup;
 }
@@ -4404,7 +4403,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 qemuProcessQMPStop(proc);
 
 procTCG = qemuProcessQMPNew(qemuCaps->binary, libDir,
-runUid, runGid, NULL, true);
+runUid, runGid, true);
 
 if (qemuProcessQMPRun(procTCG) < 0)
 goto cleanup;
@@ -4423,7 +4422,6 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 qemuProcessQMPStop(procTCG);
 qemuProcessQMPFree(proc);
 qemuProcessQMPFree(procTCG);
-VIR_FREE(qmperr);
 
 return ret;
 }
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 10e7bc5f11..71c7fb58ad 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8214,6 +8214,7 @@ qemuProcessQMPFree(qemuProcessQMPPtr proc)
 VIR_FREE(proc->monpath);
 VIR_FREE(proc->monarg);
 VIR_FREE(proc->pidfile);
+VIR_FREE(proc->stderr);
 VIR_FREE(proc);
 }
 
@@ -8223,7 +8224,6 @@ qemuProcessQMPNew(const char *binary,
   const char *libDir,
   uid_t runUid,
   gid_t runGid,
-  char **qmperr,
   bool forceTCG)
 {
 qemuProcessQMPPtr proc = NULL;
@@ -8236,7 +8236,6 @@ qemuProcessQMPNew(const char *binary,
 
 proc->runUid = runUid;
 proc->runGid = runGid;
-proc->qmperr = qmperr;
 proc->forceTCG = forceTCG;
 
 /* the ".sock" sufix is important to avoid a possible clash with a qemu
@@ -8308,7 +8307,7 @@ qemuProcessQMPRun(qemuProcessQMPPtr proc)
 virCommandSetGID(proc->cmd, proc->runGid);
 virCommandSetUID(proc->cmd, proc->runUid);
 
-virCommandSetErrorBuffer(proc->cmd, proc->qmperr);
+virCommandSetErrorBuffer(proc->cmd, &(proc->stderr));
 
 proc->status = 0;
 
@@ -8317,7 +8316,7 @@ qemuProcessQMPRun(qemuProcessQMPPtr proc)
 
 if (proc->status != 0) {
 VIR_DEBUG("QEMU %s exited with status %d: %s",
-  proc->binary, proc->status, *proc->qmperr);
+  proc->binary, proc->status, proc->stderr);
 goto cleanup;
 }
 
@@ -8381,8 +8380,6 @@ qemuProcessQMPStop(qemuProcessQMPPtr proc)
   (long long)proc->pid,
   virStrerror(errno, ebuf, sizeof(ebuf)));
 
-VIR_FREE(*proc->qmperr);
-
 proc->pid = 0;
 }
 
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 149829df52..b0b58f9424 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -221,7 +221,7 @@ struct _qemuProcessQMP {
 uid_t runUid;
 gid_t runGid;
 int status;
-char **qmperr;
+char *stderr;
 char *monarg;
 char *monpath;
 char *pidfile;
@@ -237,7 +237,6 @@ qemuProcessQMPPtr qemuProcessQMPNew(const char *binary,
 const char *libDir,
 uid_t runUid,
 gid_t runGid,
-char **qmperr,
 bool forceTCG);
 
 void qemuProcessQMPFree(qemuProcessQMPPtr proc);
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 06/33] qemu_capabilities: Stop QEMU process before freeing

2019-01-12 Thread Chris Venteicher
virQEMUCapsInitQMP now stops QEMU process in all execution paths,
before freeing the process structure.

The qemuProcessQMPStop function can be called multiple times without
problems... Won't attempt to stop processes and free resources multiple
times.

Follow the convention established in qemu_process of
1) alloc process structure
2) start process
3) use process
4) stop process
5) free process data structure

The process data structure persists after the process activation fails
or the process dies or is killed so stderr strings can be retrieved
until the process data structure is freed.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c |  1 +
 src/qemu/qemu_process.c  | 22 +++---
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2bacd5e40a..73380fdc2b 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4391,6 +4391,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 ret = 0;
 
  cleanup:
+qemuProcessQMPStop(proc);
 qemuProcessQMPFree(proc);
 return ret;
 }
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 2ab1319ab9..2208ff72b2 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8359,14 +8359,20 @@ qemuProcessQMPRun(qemuProcessQMPPtr proc,
 void
 qemuProcessQMPStop(qemuProcessQMPPtr proc)
 {
-if (proc->mon)
+if (!proc)
+return;
+
+if (proc->mon) {
 virObjectUnlock(proc->mon);
-qemuMonitorClose(proc->mon);
-proc->mon = NULL;
+qemuMonitorClose(proc->mon);
+proc->mon = NULL;
+}
 
-virCommandAbort(proc->cmd);
-virCommandFree(proc->cmd);
-proc->cmd = NULL;
+if (proc->cmd) {
+virCommandAbort(proc->cmd);
+virCommandFree(proc->cmd);
+proc->cmd = NULL;
+}
 
 if (proc->monpath)
 unlink(proc->monpath);
@@ -8383,8 +8389,10 @@ qemuProcessQMPStop(qemuProcessQMPPtr proc)
   virStrerror(errno, ebuf, sizeof(ebuf)));
 
 VIR_FREE(*proc->qmperr);
+
+proc->pid = 0;
 }
+
 if (proc->pidfile)
 unlink(proc->pidfile);
-proc->pid = 0;
 }
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 03/33] qemu_process: Limit qemuProcessQMPNew to const input strings

2019-01-12 Thread Chris Venteicher
Add the const qualifier on non modified strings
(string only copied inside qemuProcessQMPNew)
so that const strings can be used directly in calls to
qemuProcessQMPNew in future patches.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 2 +-
 src/qemu/qemu_process.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index dd3bd441e5..7e577f8e7b 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8219,7 +8219,7 @@ qemuProcessQMPFree(qemuProcessQMPPtr cmd)
 
 
 qemuProcessQMPPtr
-qemuProcessQMPNew(char *binary,
+qemuProcessQMPNew(const char *binary,
   const char *libDir,
   uid_t runUid,
   gid_t runGid,
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 4843210f76..fe79873967 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -231,7 +231,7 @@ struct _qemuProcessQMP {
 virDomainObjPtr vm;
 };
 
-qemuProcessQMPPtr qemuProcessQMPNew(char *binary,
+qemuProcessQMPPtr qemuProcessQMPNew(const char *binary,
 const char *libDir,
 uid_t runUid,
 gid_t runGid,
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 02/33] qemu_process: Use qemuProcessQMP prefix

2019-01-12 Thread Chris Venteicher
s/virQEMUCapsInitQMPCommand/qemuProcessQMP/

No functionality change.

Use file appropriate prefix in moved code.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 14 +++---
 src/qemu/qemu_process.c  | 28 ++--
 src/qemu/qemu_process.h  | 24 
 3 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index acd88d990e..60ad8ad68d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4359,15 +4359,15 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
gid_t runGid,
char **qmperr)
 {
-virQEMUCapsInitQMPCommandPtr cmd = NULL;
+qemuProcessQMPPtr cmd = NULL;
 int ret = -1;
 int rc;
 
-if (!(cmd = virQEMUCapsInitQMPCommandNew(qemuCaps->binary, libDir,
- runUid, runGid, qmperr)))
+if (!(cmd = qemuProcessQMPNew(qemuCaps->binary, libDir,
+  runUid, runGid, qmperr)))
 goto cleanup;
 
-if ((rc = virQEMUCapsInitQMPCommandRun(cmd, false)) != 0) {
+if ((rc = qemuProcessQMPRun(cmd, false)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
@@ -4377,8 +4377,8 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 goto cleanup;
 
 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
-virQEMUCapsInitQMPCommandAbort(cmd);
-if ((rc = virQEMUCapsInitQMPCommandRun(cmd, true)) != 0) {
+qemuProcessQMPAbort(cmd);
+if ((rc = qemuProcessQMPRun(cmd, true)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
@@ -4391,7 +4391,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 ret = 0;
 
  cleanup:
-virQEMUCapsInitQMPCommandFree(cmd);
+qemuProcessQMPFree(cmd);
 return ret;
 }
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 9698f5b9a1..dd3bd441e5 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8204,12 +8204,12 @@ static qemuMonitorCallbacks callbacks = {
 
 
 void
-virQEMUCapsInitQMPCommandFree(virQEMUCapsInitQMPCommandPtr cmd)
+qemuProcessQMPFree(qemuProcessQMPPtr cmd)
 {
 if (!cmd)
 return;
 
-virQEMUCapsInitQMPCommandAbort(cmd);
+qemuProcessQMPAbort(cmd);
 VIR_FREE(cmd->binary);
 VIR_FREE(cmd->monpath);
 VIR_FREE(cmd->monarg);
@@ -8218,14 +8218,14 @@ 
virQEMUCapsInitQMPCommandFree(virQEMUCapsInitQMPCommandPtr cmd)
 }
 
 
-virQEMUCapsInitQMPCommandPtr
-virQEMUCapsInitQMPCommandNew(char *binary,
- const char *libDir,
- uid_t runUid,
- gid_t runGid,
- char **qmperr)
+qemuProcessQMPPtr
+qemuProcessQMPNew(char *binary,
+  const char *libDir,
+  uid_t runUid,
+  gid_t runGid,
+  char **qmperr)
 {
-virQEMUCapsInitQMPCommandPtr cmd = NULL;
+qemuProcessQMPPtr cmd = NULL;
 
 if (VIR_ALLOC(cmd) < 0)
 goto error;
@@ -8264,7 +8264,7 @@ virQEMUCapsInitQMPCommandNew(char *binary,
 return cmd;
 
  error:
-virQEMUCapsInitQMPCommandFree(cmd);
+qemuProcessQMPFree(cmd);
 return NULL;
 }
 
@@ -8274,8 +8274,8 @@ virQEMUCapsInitQMPCommandNew(char *binary,
  *  1 when probing QEMU failed
  */
 int
-virQEMUCapsInitQMPCommandRun(virQEMUCapsInitQMPCommandPtr cmd,
- bool forceTCG)
+qemuProcessQMPRun(qemuProcessQMPPtr cmd,
+  bool forceTCG)
 {
 virDomainXMLOptionPtr xmlopt = NULL;
 const char *machine;
@@ -8345,7 +8345,7 @@ virQEMUCapsInitQMPCommandRun(virQEMUCapsInitQMPCommandPtr 
cmd,
 
  cleanup:
 if (!cmd->mon)
-virQEMUCapsInitQMPCommandAbort(cmd);
+qemuProcessQMPAbort(cmd);
 virObjectUnref(xmlopt);
 
 return ret;
@@ -8357,7 +8357,7 @@ virQEMUCapsInitQMPCommandRun(virQEMUCapsInitQMPCommandPtr 
cmd,
 
 
 void
-virQEMUCapsInitQMPCommandAbort(virQEMUCapsInitQMPCommandPtr cmd)
+qemuProcessQMPAbort(qemuProcessQMPPtr cmd)
 {
 if (cmd->mon)
 virObjectUnlock(cmd->mon);
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index f76613a7f7..4843210f76 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -214,9 +214,9 @@ int qemuProcessStartManagedPRDaemon(virDomainObjPtr vm);
 
 void qemuProcessKillManagedPRDaemon(virDomainObjPtr vm);
 
-typedef struct _virQEMUCapsInitQMPCommand virQEMUCapsInitQMPCommand;
-typedef virQEMUCapsInitQMPCommand *virQEMUCapsInitQMPCommandPtr;
-struct _virQEMUCapsInitQMPCommand {
+typedef struct _qemuProcessQMP qemuProcessQMP;
+typedef qemuProcessQMP *qemuProcessQMPPtr;
+struct _qemuProcessQMP {
 char *binary;
 uid_t runUid;
 gid_t runGid;
@@ -231,17 +231,17 @@ struct _virQEMUCapsInitQMPCommand {
 virDomainObjPtr vm;
 };
 
-virQEMUCapsInitQMPCommandPtr virQEMUCapsIni

Re: [libvirt] [PATCH v5 20/36] qemu_process: Enter QMP command mode when starting QEMU Process

2019-01-12 Thread Chris Venteicher
Quoting Jiri Denemark (2019-01-03 08:54:21)
> On Sun, Dec 02, 2018 at 23:10:14 -0600, Chris Venteicher wrote:
> > qemuProcessQmpStart starts a QEMU process and monitor connection that
> > can be used by multiple functions possibly for multiple QMP commands.
> > 
> > The QMP exchange to exit capabilities negotiation mode and enter command 
> > mode
> > can only be performed once after the monitor connection is established.
> > 
> > Move responsibility for entering QMP command mode into the qemuProcessQmp
> > code so multiple functions can issue QMP commands in arbitrary orders.
> > 
> > This also simplifies the functions using the connection provided by
> > qemuProcessQmpStart to issue QMP commands.
> > 
> > Test code now needs to call qemuMonitorSetCapabilities to send the
> > message to switch to command mode because the test code does not use the
> > qemuProcessQmp command that internally calls qemuMonitorSetCapabilities.
> > 
> > Signed-off-by: Chris Venteicher 
> > ---
> >  src/qemu/qemu_capabilities.c | 12 
> >  src/qemu/qemu_process.c  |  8 
> >  tests/qemucapabilitiestest.c |  7 +++
> >  3 files changed, 15 insertions(+), 12 deletions(-)
> > 
> > diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> > index ce60648897..038e3ecf7a 100644
> > --- a/src/qemu/qemu_capabilities.c
> > +++ b/src/qemu/qemu_capabilities.c
> > @@ -4035,12 +4035,6 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
> >  
> >  /* @mon is supposed to be locked by callee */
> >  
> > -if (qemuMonitorSetCapabilities(mon) < 0) {
> > -VIR_DEBUG("Failed to set monitor capabilities %s",
> > -  virGetLastErrorMessage());
> > -goto cleanup;
> > -}
> > -
> >  if (qemuMonitorGetVersion(mon,
> >, , ,
> >) < 0) {
> > @@ -4213,12 +4207,6 @@ virQEMUCapsInitQMPMonitorTCG(virQEMUCapsPtr qemuCaps 
> > ATTRIBUTE_UNUSED,
> >  {
> >  int ret = -1;
> >  
> > -if (qemuMonitorSetCapabilities(mon) < 0) {
> > -VIR_DEBUG("Failed to set monitor capabilities %s",
> > -  virGetLastErrorMessage());
> > -goto cleanup;
> > -}
> > -
> >  if (virQEMUCapsProbeQMPCPUDefinitions(qemuCaps, mon, true) < 0)
> >  goto cleanup;
> >  
> > diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> > index 24945b1d17..80b938cc0b 100644
> > --- a/src/qemu/qemu_process.c
> > +++ b/src/qemu/qemu_process.c
> > @@ -8332,6 +8332,14 @@ qemuProcessQmpConnectMonitor(qemuProcessQmpPtr proc)
> >  
> >  virObjectLock(proc->mon);
> >  
> > +/* Exit capabilities negotiation mode and enter QEMU command mode
> > + * by issuing qmp_capabilities command to QEMU */
> > +if (qemuMonitorSetCapabilities(proc->mon) < 0) {
> > +VIR_DEBUG("Failed to set monitor capabilities %s",
> > +  virGetLastErrorMessage());
> > +goto cleanup;
> > +}
> > +
> 
> It's quite unlikely, but we may eventually issue more commands to
> initialize the monitor, which would require us to update the code in
> qemucapabilitiestest.c again. Moreover, the test is supposed to test the
> QEMU capabilities probing code rather than individual monitor commands.
> Thus it should avoid direct qemuMonitor* calls.
> 
> For this reason, I think it would be better to separate this code into a
> new function called qemuProcessQMPInitMonitor. And you can remove the
> comment or transform it into a description of the new function. The new
> function will be called from here and from qemucapabilitiestest.c. Thus
> it cannot be static and its prototype should be placed in
> src/qemu/qemu_processpriv.h since the function will be externally called
> only from the test suite.
> 
> As a bonus, the code will be even more consistent with the VM startup
> code, where qemuProcessInitMonitor is doing similar thing.
> 
> Jirka

In the hypervisor baseline code (following patches) a series of different
QMP transactions are completed using the same QEMU process instance.

There are a series of QMP baseline messages followed by a QMP cpu
expansion message over the same connection to the same QEMU process.

Since qemuMonitorSetCapabilities must be called immediately and can only
be called once to put the connection monitor in the right state to
handle QMP messages we don't want to do qemuMonitorSetCapabilities in
individual functions to execute QMP basel

Re: [libvirt] [PATCH v5 10/36] qemu_process: Introduce qemuProcessQmpStart

2019-01-12 Thread Chris Venteicher
Quoting Jiri Denemark (2019-01-03 08:18:15)
> On Sun, Dec 02, 2018 at 23:10:04 -0600, Chris Venteicher wrote:
> > Move a step closer to the function structure used elsewhere in
> > qemu_process where qemuProcessStart and qemuProcessStop are the exposed
> > functions.
> > 
> > qemuProcessQmpStart mirrors qemuProcessStart in calling sub functions to
> > initialize, launch the process and connect the monitor to the QEMU
> > process.
> > 
> > static functions qemuProcessQmpInit, qemuProcessQmpLaunch and
> > qemuProcessQmpConnectMonitor are introduced.
> > 
> > qemuProcessQmpLaunch is just renamed from qemuProcessQmpRun and
> > encapsulates all of the original code.
> > 
> > qemuProcessQmpInit and qemuProcessQmpMonitor are nearly empty functions
> > acting as placeholders for later patches where blocks of semi-complicated 
> > code
> > are cut/pasted into these functions without modification
> > (hopefully making review easier.)
> > 
> > Looking forward, the patch series ultimately moves the code into this
> > partitioning:
> > 
> > - qemuProcessQmpInit
> > Becomes the location of ~25 lines of code to create storage
> > directory, in thread safe way, and initialize paths
> > for monpath, monarg and pidfile.
> > 
> > - qemuProcessQmpLaunch
> > Becomes the location of ~48 lines of code used to create and run the
> > QEMU command.
> > 
> > - qemuProcessQmpConnectMonitor
> > Becomes the final location of ~58 lines of code used to open and
> > initialize the monitor connection between libvirt and qemu.
> > 
> > Three smaller, purpose-identifying, functions of ~60 lines or less seem
> > better than a single large process "start" function of > 130 lines.
> > 
> > Being able to compare and contrast between the domain and non-domain
> > versions of process code is useful too.  There is some significant
> > overlap between what the non-domain and domain functions do.  There is
> > also significant additional functionality in the domain functions that
> > might be useful in the non-domain functions in the future.
> > Possibly there could be sharing between non-domain and
> > domain process code in the future but common code would have
> > to be carefully extracted from the domain process code (not trivial.)
> > 
> > Mirroring the domain process code has some value, but
> > partitioning the code into logical chunks of < 60 lines
> > is the main reason for the static functions.
> 
> Since the changes are all hidden inside qemuProcessQmpStart (formerly
> called qemuProcessQmpRun) and nothing is calling the new internal
> functions, all this refactoring could have been separated from this
> series. But since it's already wired in the series, there's no reason to
> separate it. Unless serious issues are found in which case it could be
> easier to separate the refactoring (and deal with the result) than
> fixing the issues. I don't expect such issues, though.
> 
> > Signed-off-by: Chris Venteicher 
> > ---
> >  src/qemu/qemu_capabilities.c |  4 +-
> >  src/qemu/qemu_process.c  | 94 +++-
> >  src/qemu/qemu_process.h  |  2 +-
> >  3 files changed, 95 insertions(+), 5 deletions(-)
> > 
> > diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> > index 997f8c19d5..ce60648897 100644
> > --- a/src/qemu/qemu_capabilities.c
> > +++ b/src/qemu/qemu_capabilities.c
> > @@ -4265,7 +4265,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
> > runUid, runGid, false)))
> >  goto cleanup;
> >  
> > -if (qemuProcessQmpRun(proc) < 0) {
> > +if (qemuProcessQmpStart(proc) < 0) {
> >  if (proc->status != 0)
> >  virReportError(VIR_ERR_INTERNAL_ERROR,
> > _("Failed to probe QEMU binary with QMP: %s"),
> > @@ -4288,7 +4288,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
> >  procTCG = qemuProcessQmpNew(qemuCaps->binary, libDir,
> >  runUid, runGid, true);
> >  
> > -if (qemuProcessQmpRun(procTCG) < 0)
> > +if (qemuProcessQmpStart(procTCG) < 0)
> >  goto cleanup;
> >  
> >  if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, procTCG->mon) < 0)
> > diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> > index 8ad685f3ea..938d328235 100644
> > --- a/src/qemu/qemu_process.c
> > +++ b/src/qemu/qemu_process

[libvirt] [PATCH v5 34/36] qemu_driver: Support feature expansion via QEMU when baselining cpu

2018-12-02 Thread Chris Venteicher
Support using QEMU to do feature expansion when also using QEMU to
compute hypervisor baseline.

A QEMU process is already created to send the QMP messages to baseline
using QEMU.
The same QEMU process is used for the CPU feature expansion.

QEMU only returns migratable features when expanding CPU model in
architectures where QEMU is used for baseline so no attempt is made to
ask for non-migratable features in expansions when using QEMU for
baseline.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_driver.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8c6838f584..4149e4794a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13843,6 +13843,27 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 if (flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) {
 if (useLibvirt && virCPUExpandFeatures(arch, cpu) < 0) {
 goto cleanup;
+} else if (useQemu &&
+   virQEMUCapsGet(qemuCaps, 
QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) {
+
+if (!(modelInfo = virQEMUCapsCPUModelInfoFromCPUDef(cpu)))
+goto cleanup;
+
+virCPUDefFree(cpu);
+cpu = NULL;
+
+/* QEMU can only include migratable features
+   for all archs that use QEMU for baseline calculation */
+migratable = true;
+
+if (qemuMonitorGetCPUModelExpansion(proc->mon,
+
QEMU_MONITOR_CPU_MODEL_EXPANSION_FULL,
+migratable, modelInfo, 
) < 0)
+goto cleanup;
+
+if (!(cpu = virQEMUCapsCPUModelInfoToCPUDef(migratable, 
expansion)))
+goto cleanup;
+
 } else {
 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("expand features while "
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 33/36] qemu_driver: Support baseline calculation using QEMU

2018-12-02 Thread Chris Venteicher
Add capability to calculate hypervisor baseline using QMP message
exchanges with QEMU in addition to existing capability to calculate
baseline using libvirt utility functions.

A new utility function encapsulates the core logic for interacting with QEMU
using QMP baseline messages. The QMP messages only allow two cpu models
to be evaluated at a time so a sequence of QMP baseline messages must be
used to include all the models in the baseline when more than 2 cpu
models are input.

A QEMU process must be started prior to sending the series of QEMU
messages to compute baseline.

The QEMU process is started and maintained in the main hypervisor
baseline function and only a pointer to the QEMU process monitor is
passed to the baseline utility function.

The QEMU process is maintained in the main hypervisor baseline function
because the process will also be used for feature expansion (via QEMU)
in a later patch.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_driver.c | 97 ++
 1 file changed, 97 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4e8a3902d3..8c6838f584 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13642,6 +13642,78 @@ qemuConnectBaselineCPU(virConnectPtr conn 
ATTRIBUTE_UNUSED,
 }
 
 
+/* in:
+ *  cpus[0]->model = "z14";
+ *  cpus[0]->features[0].name = "xxx";
+ *  cpus[0]->features[1].name = "yyy";
+ *  ***
+ *  cpus[n]->model = "z13";
+ *  cpus[n]->features[0].name = "xxx";
+ *  cpus[n]->features[1].name = "yyy";
+ *
+ * out:
+ *  *baseline->model = "z13-base";
+ *  *baseline->features[0].name = "yyy";
+ */
+static int
+qemuConnectBaselineHypervisorCPUViaQEMU(qemuMonitorPtr mon,
+virCPUDefPtr *cpus,
+virCPUDefPtr *baseline)
+{
+qemuMonitorCPUModelInfoPtr model_baseline = NULL;
+qemuMonitorCPUModelInfoPtr new_model_baseline = NULL;
+qemuMonitorCPUModelInfoPtr next_model = NULL;
+bool migratable = true;
+int ret = -1;
+size_t i;
+
+*baseline = NULL;
+
+if (!cpus || !cpus[0]) {
+virReportError(VIR_ERR_INVALID_ARG, "%s", _("no cpus"));
+goto cleanup;
+}
+
+for (i = 0; cpus[i]; i++) {  /* cpus terminated by NULL element */
+virCPUDefPtr cpu = cpus[i];
+
+VIR_DEBUG("cpu[%lu]->model = %s", i, NULLSTR(cpu->model));
+
+if (!(next_model = virQEMUCapsCPUModelInfoFromCPUDef(cpu)))
+goto cleanup;
+
+if (i == 0) {
+model_baseline = next_model;
+continue;
+}
+
+if (qemuMonitorGetCPUModelBaseline(mon, model_baseline,
+   next_model, _model_baseline) < 
0)
+goto cleanup;
+
+qemuMonitorCPUModelInfoFree(model_baseline);
+qemuMonitorCPUModelInfoFree(next_model);
+
+next_model = NULL;
+
+model_baseline = new_model_baseline;
+}
+
+if (!(*baseline = virQEMUCapsCPUModelInfoToCPUDef(migratable, 
model_baseline)))
+goto cleanup;
+
+VIR_DEBUG("baseline->model = %s", (*baseline)->model);
+
+ret = 0;
+
+ cleanup:
+qemuMonitorCPUModelInfoFree(model_baseline);
+qemuMonitorCPUModelInfoFree(next_model);
+
+return ret;
+}
+
+
 static int
 qemuConnectBaselineHypervisorCPUViaLibvirt(
 virQEMUCapsPtr qemuCaps,
@@ -13710,6 +13782,11 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 virCPUDefPtr cpu = NULL;
 char *cpustr = NULL;
 bool useLibvirt = false;
+bool useQemu = false;
+bool forceTCG = false;
+qemuMonitorCPUModelInfoPtr modelInfo = NULL;
+qemuMonitorCPUModelInfoPtr expansion = NULL;
+qemuProcessQmpPtr proc = NULL;
 
 virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES |
   VIR_CONNECT_BASELINE_CPU_MIGRATABLE, NULL);
@@ -13730,6 +13807,7 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 goto cleanup;
 
 useLibvirt = ARCH_IS_X86(arch);
+useQemu = ARCH_IS_S390(arch);
 
 if (useLibvirt) {
 migratable = !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE);
@@ -13738,6 +13816,21 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
virttype, arch,
cpus, ncpus, ) < 0)
 goto cleanup;
+
+} else if (useQemu) {
+const char *binary = virQEMUCapsGetBinary(qemuCaps);
+virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+
+if (!(proc = qemuProcessQmpNew(binary, cfg->libDir,
+  cfg->user, cfg->group, forceTCG)))
+goto cleanup;
+
+if (qemuProcessQmpStart(proc) < 0)
+goto cleanup;
+
+ 

[libvirt] [PATCH v5 32/36] qemu_driver: Identify using libvirt as a distinct way to compute baseline

2018-12-02 Thread Chris Venteicher
Hypervisor baseline cpu can be computed locally using libvirt utility
functions or remotely using QEMU QMP commands.

Likewise, cpu feature expansion can be computed locally using libvirt
utility functions or remotely using QEMU QMP commands.

This patch identifies using libvirt as a distinct case in the hypervisor
baseline logic and triggers that case when the X86 architecture is being
baselined.

There is one functionality change introduced by this patch.

Local libvirt functions are only used for feature expansion when the
local utility functions are used for CPU baseline and an error is
generated when no method is available to expand cpu featues.

The useQEMU option will be introduced in a future patch for using QEMU
to compute baseline rather than using libvirt.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_driver.c | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 86fc5aa249..4e8a3902d3 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13709,6 +13709,7 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 bool migratable;
 virCPUDefPtr cpu = NULL;
 char *cpustr = NULL;
+bool useLibvirt = false;
 
 virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES |
   VIR_CONNECT_BASELINE_CPU_MIGRATABLE, NULL);
@@ -13728,7 +13729,9 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 if (!qemuCaps)
 goto cleanup;
 
-if (ARCH_IS_X86(arch)) {
+useLibvirt = ARCH_IS_X86(arch);
+
+if (useLibvirt) {
 migratable = !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE);
 
 if (qemuConnectBaselineHypervisorCPUViaLibvirt(qemuCaps, migratable,
@@ -13744,9 +13747,17 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 
 cpu->fallback = VIR_CPU_FALLBACK_FORBID;
 
-if ((flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
-virCPUExpandFeatures(arch, cpu) < 0)
-goto cleanup;
+if (flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) {
+if (useLibvirt && virCPUExpandFeatures(arch, cpu) < 0) {
+goto cleanup;
+} else {
+virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+   _("expand features while "
+ "computing baseline hypervisor CPU is not 
supported "
+ "for arch %s"), virArchToString(arch));
+goto cleanup;
+}
+}
 
 cpustr = virCPUDefFormat(cpu, NULL);
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 35/36] qemu_driver: Remove unsupported props in expanded hypervisor baseline output

2018-12-02 Thread Chris Venteicher
Hypervisor baseline has an expansion mode where the cpu property /
feature list is fully expanded to list all supported (true) features.

The output (expanded) cpu model should not list properties that are
false (unsupported.)

QEMU expansion output enumerates both true (supported) and false
(unsupported) properties.  This patch removes the false (unsupported)
entries from the output cpu property list.

This change makes the expanded output consistent when both the internal
libvirt utility functions and QEMU QMP commands are used to expand the
property list.

qemu_monitor: Introduce removal of true/false CPUModelInfo props

A utility function is created to squash CPU properties list in
qemuMonitorCPUmodelInfo structure by removing boolean properties
of matching value.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_driver.c  |  4 
 src/qemu/qemu_monitor.c | 30 ++
 src/qemu/qemu_monitor.h |  4 
 3 files changed, 38 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4149e4794a..4f338f1b37 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13861,6 +13861,10 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 migratable, modelInfo, 
) < 0)
 goto cleanup;
 
+/* Expansion enumerates all features
+ * Baselines output enumerates only in-model (true) features */
+qemuMonitorCPUModelInfoRemovePropByBoolValue(expansion, false);
+
 if (!(cpu = virQEMUCapsCPUModelInfoToCPUDef(migratable, 
expansion)))
 goto cleanup;
 
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index c5266b6767..0c7d7b4b55 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3785,6 +3785,36 @@ qemuMonitorCPUModelInfoCopy(const 
qemuMonitorCPUModelInfo *orig)
 }
 
 
+/* Squash CPU Model Info property list
+ * removing props of type boolean matching value */
+void
+qemuMonitorCPUModelInfoRemovePropByBoolValue(qemuMonitorCPUModelInfoPtr model,
+ bool value)
+{
+qemuMonitorCPUPropertyPtr src;
+qemuMonitorCPUPropertyPtr dst;
+size_t i;
+size_t dst_nprops = 0;
+
+for (i = 0; i < model->nprops; i++) {
+src = &(model->props[i]);
+dst = &(model->props[dst_nprops]);
+
+if (src->type == QEMU_MONITOR_CPU_PROPERTY_BOOLEAN &&
+src->value.boolean == value)
+continue;
+
+*dst = *src;
+
+dst_nprops++;
+}
+
+model->nprops = dst_nprops;
+
+ignore_value(VIR_REALLOC_N_QUIET(model->props, dst_nprops));
+}
+
+
 int
 qemuMonitorCPUModelInfoBoolPropAdd(qemuMonitorCPUModelInfoPtr model,
const char *prop_name,
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index c87a2d5e47..7aaecd97dd 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1053,6 +1053,10 @@ int 
qemuMonitorCPUModelInfoBoolPropAdd(qemuMonitorCPUModelInfoPtr model,
bool prop_value)
 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
+void qemuMonitorCPUModelInfoRemovePropByBoolValue(qemuMonitorCPUModelInfoPtr 
model,
+  bool value)
+ATTRIBUTE_NONNULL(1);
+
 int qemuMonitorGetCommands(qemuMonitorPtr mon,
char ***commands);
 int qemuMonitorGetEvents(qemuMonitorPtr mon,
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 36/36] qemu_monitor: Default props to migratable when expanding cpu model

2018-12-02 Thread Chris Venteicher
QEMU only returns migratable props when expanding model unless
explicitly told to also include non-migratable props.

Props will be marked migratable when we are certain QEMU returned only
migratable props resulting in consistent information and expansion output
for s390 that is consistent with x86.

After this change,
immediately default prop->migratable = _YES for all props
when we know QEMU only included migratable props in CPU Model.

Set model->migratability = true when we have set prop->migratable.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_monitor.c   | 53 ++-
 src/qemu/qemu_monitor.h   |  7 +-
 .../caps_2.10.0.s390x.xml | 60 -
 .../caps_2.11.0.s390x.xml | 58 -
 .../caps_2.12.0.s390x.xml | 56 
 .../qemucapabilitiesdata/caps_2.8.0.s390x.xml | 32 +-
 .../qemucapabilitiesdata/caps_2.9.0.s390x.xml | 34 +-
 .../qemucapabilitiesdata/caps_3.0.0.s390x.xml | 64 +--
 8 files changed, 210 insertions(+), 154 deletions(-)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 0c7d7b4b55..23a9c2ff2b 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3682,12 +3682,31 @@ qemuMonitorGetCPUModelExpansion(qemuMonitorPtr mon,
 qemuMonitorCPUModelInfoPtr *expansion
)
 {
+int ret = -1;
+qemuMonitorCPUModelInfoPtr tmp;
+
 VIR_DEBUG("type=%d model_name=%s migratable=%d",
   type, input->name, migratable);
 
+*expansion = NULL;
+
 QEMU_CHECK_MONITOR(mon);
 
-return qemuMonitorJSONGetCPUModelExpansion(mon, type, migratable, input, 
expansion);
+if ((ret = qemuMonitorJSONGetCPUModelExpansion(mon, type, migratable, 
input, )) < 0)
+goto cleanup;
+
+if (migratable) {
+/* Only migratable props were included in expanded CPU model */
+*expansion = qemuMonitorCPUModelInfoCopyDefaultMigratable(tmp);
+} else {
+VIR_STEAL_PTR(*expansion, tmp);
+}
+
+ret = 0;
+
+ cleanup:
+qemuMonitorCPUModelInfoFree(tmp);
+return ret;
 }
 
 
@@ -3785,6 +3804,38 @@ qemuMonitorCPUModelInfoCopy(const 
qemuMonitorCPUModelInfo *orig)
 }
 
 
+qemuMonitorCPUModelInfoPtr
+qemuMonitorCPUModelInfoCopyDefaultMigratable(const qemuMonitorCPUModelInfo 
*orig)
+{
+qemuMonitorCPUModelInfoPtr ret = NULL;
+qemuMonitorCPUModelInfoPtr tmp = NULL;
+qemuMonitorCPUPropertyPtr prop = NULL;
+size_t i;
+
+if (!(tmp = qemuMonitorCPUModelInfoCopy(orig)))
+goto cleanup;
+
+for (i = 0; i < tmp->nprops; i++) {
+prop = tmp->props + i;
+
+/* Default prop thats in cpu model (true) to migratable (_YES)
+ * unless prop already explicitly set not migratable (_NO)
+ */
+if (prop->type == QEMU_MONITOR_CPU_PROPERTY_BOOLEAN &&
+prop->value.boolean &&
+prop->migratable != VIR_TRISTATE_BOOL_NO)
+prop->migratable = VIR_TRISTATE_BOOL_YES;
+}
+
+tmp->migratability = true; /* prop->migratable = YES/NO for all CPU props 
*/
+
+VIR_STEAL_PTR(ret, tmp);
+
+ cleanup:
+return ret;
+}
+
+
 /* Squash CPU Model Info property list
  * removing props of type boolean matching value */
 void
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 7aaecd97dd..77aa7cfdc6 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1025,7 +1025,7 @@ struct _qemuMonitorCPUModelInfo {
 char *name;
 size_t nprops;
 qemuMonitorCPUPropertyPtr props;
-bool migratability;
+bool migratability; /* true if prop->migratable is YES/NO for all CPU 
props */
 };
 
 typedef enum {
@@ -1048,6 +1048,11 @@ qemuMonitorCPUModelInfoPtr 
qemuMonitorCPUModelInfoNew(const char *name);
 qemuMonitorCPUModelInfoPtr
 qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig);
 
+qemuMonitorCPUModelInfoPtr
+qemuMonitorCPUModelInfoCopyDefaultMigratable(const qemuMonitorCPUModelInfo 
*orig)
+ATTRIBUTE_NONNULL(1);
+
+
 int qemuMonitorCPUModelInfoBoolPropAdd(qemuMonitorCPUModelInfoPtr model,
const char *prop_name,
bool prop_value)
diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml 
b/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml
index 180a688ba2..07f4da579b 100644
--- a/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml
@@ -120,36 +120,36 @@
   306247
   
   s390x
-  
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

[libvirt] [PATCH v5 30/36] qemu_driver: Consolidate code to baseline using libvirt

2018-12-02 Thread Chris Venteicher
Simple cut/paste operations within function
qemuConnectBaselineHypervisorCPU to group together code specific to
computing baseline using only libvirt utility functions.

This is done in anticipation of creating new utility functions for
1) baseline using libvirt utilities (this code)
2) baseline using qemu qmp command (future)

Future patches are easier to follow if the code for using libvirt is
consolidated.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_driver.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7d9e17e72c..007f64d6ad 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13657,7 +13657,6 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 virQEMUCapsPtr qemuCaps = NULL;
 virArch arch;
 virDomainVirtType virttype;
-virDomainCapsCPUModelsPtr cpuModels;
 bool migratable;
 virCPUDefPtr cpu = NULL;
 char *cpustr = NULL;
@@ -13669,8 +13668,6 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 if (virConnectBaselineHypervisorCPUEnsureACL(conn) < 0)
 goto cleanup;
 
-migratable = !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE);
-
 if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_AUTO)))
 goto cleanup;
 
@@ -13683,17 +13680,21 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 if (!qemuCaps)
 goto cleanup;
 
-if (!(cpuModels = virQEMUCapsGetCPUDefinitions(qemuCaps, virttype)) ||
-cpuModels->nmodels == 0) {
-virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
-   _("QEMU '%s' does not support any CPU models for "
- "virttype '%s'"),
-   virQEMUCapsGetBinary(qemuCaps),
-   virDomainVirtTypeToString(virttype));
-goto cleanup;
-}
-
 if (ARCH_IS_X86(arch)) {
+migratable = !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE);
+
+virDomainCapsCPUModelsPtr cpuModels;
+
+if (!(cpuModels = virQEMUCapsGetCPUDefinitions(qemuCaps, virttype)) ||
+cpuModels->nmodels == 0) {
+virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+   _("QEMU '%s' does not support any CPU models for "
+ "virttype '%s'"),
+   virQEMUCapsGetBinary(qemuCaps),
+   virDomainVirtTypeToString(virttype));
+goto cleanup;
+}
+
 int rc = virQEMUCapsGetCPUFeatures(qemuCaps, virttype,
migratable, );
 if (rc < 0)
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 31/36] qemu_driver: Decouple code for baseline using libvirt

2018-12-02 Thread Chris Venteicher
Create utility function encapsulating code to calculate
hypervisor baseline cpu using the local libvirt utility functions.

Similar function encapsulating code to calculating hypervisor baseline
using QEMU QMP messages will be introduced in later commit.

Patch is a cut and paste of existing code into a utility function
wrapper.

s/cpu/*baseline/ (change output variable name ) and
initialize variable "rc" are the only code changes.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_driver.c | 78 --
 1 file changed, 52 insertions(+), 26 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 007f64d6ad..86fc5aa249 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13642,6 +13642,55 @@ qemuConnectBaselineCPU(virConnectPtr conn 
ATTRIBUTE_UNUSED,
 }
 
 
+static int
+qemuConnectBaselineHypervisorCPUViaLibvirt(
+virQEMUCapsPtr qemuCaps,
+bool migratable,
+virDomainVirtType virttype,
+virArch arch,
+virCPUDefPtr *cpus,
+unsigned int ncpus,
+virCPUDefPtr *baseline)
+{
+char **features = NULL;
+int ret = -1;
+int rc = -1;
+virDomainCapsCPUModelsPtr cpuModels;
+
+*baseline = NULL;
+
+if (!(cpuModels = virQEMUCapsGetCPUDefinitions(qemuCaps, virttype)) ||
+cpuModels->nmodels == 0) {
+virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+   _("QEMU '%s' does not support any CPU models for "
+ "virttype '%s'"),
+   virQEMUCapsGetBinary(qemuCaps),
+   virDomainVirtTypeToString(virttype));
+goto cleanup;
+}
+
+rc = virQEMUCapsGetCPUFeatures(qemuCaps, virttype,
+   migratable, );
+if (rc < 0)
+goto cleanup;
+if (features && rc == 0) {
+/* We got only migratable features from QEMU if we asked for them,
+ * no further filtering in virCPUBaseline is desired. */
+migratable = false;
+}
+
+if (!(*baseline = virCPUBaseline(arch, cpus, ncpus, cpuModels,
+ (const char **)features, migratable)))
+goto cleanup;
+
+ret = 0;
+
+ cleanup:
+virStringListFree(features);
+return ret;
+}
+
+
 static char *
 qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
  const char *emulator,
@@ -13660,7 +13709,6 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 bool migratable;
 virCPUDefPtr cpu = NULL;
 char *cpustr = NULL;
-char **features = NULL;
 
 virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES |
   VIR_CONNECT_BASELINE_CPU_MIGRATABLE, NULL);
@@ -13683,30 +13731,9 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 if (ARCH_IS_X86(arch)) {
 migratable = !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE);
 
-virDomainCapsCPUModelsPtr cpuModels;
-
-if (!(cpuModels = virQEMUCapsGetCPUDefinitions(qemuCaps, virttype)) ||
-cpuModels->nmodels == 0) {
-virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
-   _("QEMU '%s' does not support any CPU models for "
- "virttype '%s'"),
-   virQEMUCapsGetBinary(qemuCaps),
-   virDomainVirtTypeToString(virttype));
-goto cleanup;
-}
-
-int rc = virQEMUCapsGetCPUFeatures(qemuCaps, virttype,
-   migratable, );
-if (rc < 0)
-goto cleanup;
-if (features && rc == 0) {
-/* We got only migratable features from QEMU if we asked for them,
- * no further filtering in virCPUBaseline is desired. */
-migratable = false;
-}
-
-if (!(cpu = virCPUBaseline(arch, cpus, ncpus, cpuModels,
-   (const char **)features, migratable)))
+if (qemuConnectBaselineHypervisorCPUViaLibvirt(qemuCaps, migratable,
+   virttype, arch,
+   cpus, ncpus, ) < 0)
 goto cleanup;
 } else {
 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
@@ -13727,7 +13754,6 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
 virCPUDefListFree(cpus);
 virCPUDefFree(cpu);
 virObjectUnref(qemuCaps);
-virStringListFree(features);
 
 return cpustr;
 }
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 27/36] qemu_capabilities: Introduce CPUModelInfo to virCPUDef function

2018-12-02 Thread Chris Venteicher
Move existing code to convert between cpu model info structures
(qemuMonitorCPUModelInfoPtr into virCPUDef)
into a reusable function.

The new function is used in this and future patches.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 84 ++--
 src/qemu/qemu_capabilities.h |  3 ++
 2 files changed, 64 insertions(+), 23 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 8c5ec4cc9a..74f670459f 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2819,7 +2819,8 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
 virCPUDefPtr cpu,
 bool migratable)
 {
-size_t i;
+virCPUDefPtr tmp = NULL;
+int ret = -1;
 
 if (!modelInfo) {
 if (type == VIR_DOMAIN_VIRT_KVM) {
@@ -2832,32 +2833,18 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
 return 2;
 }
 
-if (VIR_STRDUP(cpu->model, modelInfo->name) < 0 ||
-VIR_ALLOC_N(cpu->features, modelInfo->nprops) < 0)
-return -1;
+if (!(tmp = virQEMUCapsCPUModelInfoToCPUDef(migratable, modelInfo)))
+goto cleanup;
 
-cpu->nfeatures_max = modelInfo->nprops;
-cpu->nfeatures = 0;
+/* Free original then copy over model, vendor, vendor_id and features */
+virCPUDefStealModel(cpu, tmp, true);
 
-for (i = 0; i < modelInfo->nprops; i++) {
-virCPUFeatureDefPtr feature = cpu->features + cpu->nfeatures;
-qemuMonitorCPUPropertyPtr prop = modelInfo->props + i;
+ret = 0;
 
-if (prop->type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN)
-continue;
+ cleanup:
+virCPUDefFree(tmp);
 
-if (VIR_STRDUP(feature->name, prop->name) < 0)
-return -1;
-
-if (!prop->value.boolean ||
-(migratable && prop->migratable == VIR_TRISTATE_BOOL_NO))
-feature->policy = VIR_CPU_FEATURE_DISABLE;
-else
-feature->policy = VIR_CPU_FEATURE_REQUIRE;
-cpu->nfeatures++;
-}
-
-return 0;
+return ret;
 }
 
 
@@ -3655,6 +3642,57 @@ virQEMUCapsLoadCache(virArch hostArch,
 }
 
 
+/* qemuMonitorCPUModelInfo name   => virCPUDef model
+ * qemuMonitorCPUModelInfo boolean properties => virCPUDef features
+ *
+ * migratable true: mark non-migratable features as disabled
+ *false: allow all features as required
+ */
+virCPUDefPtr
+virQEMUCapsCPUModelInfoToCPUDef(bool migratable, qemuMonitorCPUModelInfoPtr 
model)
+{
+virCPUDefPtr cpu = NULL;
+virCPUDefPtr ret = NULL;
+size_t i;
+
+if (!model || VIR_ALLOC(cpu) < 0)
+goto cleanup;
+
+VIR_DEBUG("model->name= %s", NULLSTR(model->name));
+
+if (VIR_STRDUP(cpu->model, model->name) < 0 ||
+VIR_ALLOC_N(cpu->features, model->nprops) < 0)
+goto cleanup;
+
+cpu->nfeatures_max = model->nprops;
+cpu->nfeatures = 0;
+
+for (i = 0; i < model->nprops; i++) {
+virCPUFeatureDefPtr feature = cpu->features + cpu->nfeatures;
+qemuMonitorCPUPropertyPtr prop = model->props + i;
+
+if (prop->type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN)
+continue;
+
+if (VIR_STRDUP(feature->name, prop->name) < 0)
+goto cleanup;
+
+if (!prop->value.boolean ||
+(migratable && prop->migratable == VIR_TRISTATE_BOOL_NO))
+feature->policy = VIR_CPU_FEATURE_DISABLE;
+else
+feature->policy = VIR_CPU_FEATURE_REQUIRE;
+
+cpu->nfeatures++;
+}
+
+VIR_STEAL_PTR(ret, cpu);
+
+ cleanup:
+virCPUDefFree(cpu);
+return ret;
+}
+
 static void
 virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsPtr qemuCaps,
   virBufferPtr buf,
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index b1990b6bb8..52e36e76b6 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -579,6 +579,9 @@ int virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps,
 void virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps,
 const char *machineType);
 
+virCPUDefPtr virQEMUCapsCPUModelInfoToCPUDef(bool migratable,
+ qemuMonitorCPUModelInfoPtr model);
+
 virFileCachePtr virQEMUCapsCacheNew(const char *libDir,
 const char *cacheDir,
 uid_t uid,
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 28/36] qemu_capabilities: Introduce virCPUDef to CPUModelInfo function

2018-12-02 Thread Chris Venteicher
Create public function to convert virCPUDef data structure into
qemuMonitorCPUModelInfoPtr data structure.

There was no existing code to reuse to create this function
so this new virQEMUCapsCPUModelInfoFromCPUDef function was based on
reversing the action of the existing virQEMUCapsCPUModelInfoToCPUDef
function.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 46 
 src/qemu/qemu_capabilities.h |  1 +
 2 files changed, 47 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 74f670459f..b36ccda090 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3642,6 +3642,51 @@ virQEMUCapsLoadCache(virArch hostArch,
 }
 
 
+/* virCPUDef model=> qemuMonitorCPUModelInfo name
+ * virCPUDef features => qemuMonitorCPUModelInfo boolean properties */
+qemuMonitorCPUModelInfoPtr
+virQEMUCapsCPUModelInfoFromCPUDef(const virCPUDef *cpuDef)
+{
+size_t i;
+qemuMonitorCPUModelInfoPtr cpuModel = NULL;
+qemuMonitorCPUModelInfoPtr ret = NULL;
+
+if (!cpuDef || (VIR_ALLOC(cpuModel) < 0))
+goto cleanup;
+
+VIR_DEBUG("cpuDef->model = %s", NULLSTR(cpuDef->model));
+
+if (VIR_STRDUP(cpuModel->name, cpuDef->model) < 0 ||
+VIR_ALLOC_N(cpuModel->props, cpuDef->nfeatures) < 0)
+goto cleanup;
+
+cpuModel->nprops = 0;
+
+for (i = 0; i < cpuDef->nfeatures; i++) {
+qemuMonitorCPUPropertyPtr prop = &(cpuModel->props[cpuModel->nprops]);
+virCPUFeatureDefPtr feature = &(cpuDef->features[i]);
+
+if (!(feature->name) ||
+VIR_STRDUP(prop->name, feature->name) < 0)
+goto cleanup;
+
+prop->type = QEMU_MONITOR_CPU_PROPERTY_BOOLEAN;
+
+prop->value.boolean = feature->policy == -1 || /* policy undefined */
+  feature->policy == VIR_CPU_FEATURE_FORCE ||
+  feature->policy == VIR_CPU_FEATURE_REQUIRE;
+
+cpuModel->nprops++;
+}
+
+VIR_STEAL_PTR(ret, cpuModel);
+
+ cleanup:
+qemuMonitorCPUModelInfoFree(cpuModel);
+return ret;
+}
+
+
 /* qemuMonitorCPUModelInfo name   => virCPUDef model
  * qemuMonitorCPUModelInfo boolean properties => virCPUDef features
  *
@@ -3693,6 +3738,7 @@ virQEMUCapsCPUModelInfoToCPUDef(bool migratable, 
qemuMonitorCPUModelInfoPtr mode
 return ret;
 }
 
+
 static void
 virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsPtr qemuCaps,
   virBufferPtr buf,
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 52e36e76b6..9bc6773263 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -579,6 +579,7 @@ int virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps,
 void virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps,
 const char *machineType);
 
+qemuMonitorCPUModelInfoPtr virQEMUCapsCPUModelInfoFromCPUDef(const virCPUDef 
*cpuDef);
 virCPUDefPtr virQEMUCapsCPUModelInfoToCPUDef(bool migratable,
  qemuMonitorCPUModelInfoPtr model);
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 25/36] qemu_capabilities: Introduce virQEMuCapsMigratablePropsDiff

2018-12-02 Thread Chris Venteicher
Create an augmented CPUModelInfo identifying which props are/aren't
migratable based on a diff between migratable and non-migratable
inputs.

This patch pulls existing logic out of virQEMUCapsProbeQMPHostCPU
and wraps the existing logic in a standalone function hopefully
simplifying both functions and making the inputs and outputs clearer.

The patch also sets cpuData->info = NULL to make sure bad data does not
remain in failure cases.

Q) Can the right people quickly determine if they should review this?

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 131 ---
 1 file changed, 92 insertions(+), 39 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index cd685298e6..bd75f82e70 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2378,14 +2378,91 @@ virQEMUCapsProbeQMPCPUDefinitions(virQEMUCapsPtr 
qemuCaps,
 }
 
 
+/* virQEMUCapsMigratablePropsDiff
+ * @migratable: input where all migratable props have value true
+ * and non-migratable and unsupported props have value false
+ *
+ * @nonMigratable: input where all migratable & non-migratable props
+ * have value true and unsupported props have value false
+ *
+ * @augmented: output including all props listed in @migratable but
+ * both migratable & non-migratable props have value true,
+ * unsupported props have value false,
+ * and prop->migratable is set to VIR_TRISTATE_BOOL_{YES/NO}
+ * for each supported prop
+ *
+ * Differences in expanded CPUModelInfo inputs @migratable and @nonMigratable 
are
+ * used to create output @augmented where individual props have 
prop->migratable
+ * set to indicate if prop is or isn't migratable.
+ */
+static int
+virQEMUCapsMigratablePropsDiff(qemuMonitorCPUModelInfoPtr migratable,
+   qemuMonitorCPUModelInfoPtr nonMigratable,
+   qemuMonitorCPUModelInfoPtr *augmented)
+{
+int ret = -1;
+qemuMonitorCPUModelInfoPtr tmp;
+qemuMonitorCPUPropertyPtr prop;
+qemuMonitorCPUPropertyPtr mProp;
+qemuMonitorCPUPropertyPtr nmProp;
+virHashTablePtr hash = NULL;
+size_t i;
+
+*augmented = NULL;
+
+if (!(tmp = qemuMonitorCPUModelInfoCopy(migratable)))
+goto cleanup;
+
+if (!nonMigratable)
+goto done;
+
+if (!(hash = virHashCreate(0, NULL)))
+goto cleanup;
+
+for (i = 0; i < tmp->nprops; i++) {
+prop = tmp->props + i;
+
+if (virHashAddEntry(hash, prop->name, prop) < 0)
+goto cleanup;
+}
+
+for (i = 0; i < nonMigratable->nprops; i++) {
+nmProp = nonMigratable->props + i;
+
+if (!(mProp = virHashLookup(hash, nmProp->name)) ||
+mProp->type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN ||
+mProp->type != nmProp->type)
+continue;  /* In non-migratable list but not in migratable list */
+
+if (mProp->value.boolean) {
+mProp->migratable = VIR_TRISTATE_BOOL_YES;
+} else if (nmProp->value.boolean) {
+mProp->value.boolean = true;
+mProp->migratable = VIR_TRISTATE_BOOL_NO;
+}
+}
+
+tmp->migratability = true;
+
+ done:
+VIR_STEAL_PTR(*augmented, tmp);
+ret = 0;
+
+ cleanup:
+qemuMonitorCPUModelInfoFree(tmp);
+virHashFree(hash);
+return ret;
+}
+
+
 static int
 virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
qemuMonitorPtr mon,
bool tcg)
 {
-qemuMonitorCPUModelInfoPtr modelInfo = NULL;
+qemuMonitorCPUModelInfoPtr migratable = NULL;
 qemuMonitorCPUModelInfoPtr nonMigratable = NULL;
-virHashTablePtr hash = NULL;
+qemuMonitorCPUModelInfoPtr augmented = NULL;
 const char *model;
 qemuMonitorCPUModelExpansionType type;
 virDomainVirtType virtType;
@@ -2404,6 +2481,7 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
 }
 
 cpuData = virQEMUCapsGetHostCPUData(qemuCaps, virtType);
+cpuData->info = NULL;
 
 /* Some x86_64 features defined in cpu_map.xml use spelling which differ
  * from the one preferred by QEMU. Static expansion would give us only the
@@ -2415,54 +2493,29 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
 else
 type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC;
 
-if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, ) < 
0)
+if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, ) < 
0)
 goto cleanup;
 
+if (!migratable) {
+ret = 0;  /* Qemu can't expand the model name, exit without error 
*/
+goto cleanup;
+}
+
 /* Try to check migratability of each feature. */
-if (modelInfo &&
-qemuMonitorGetCPUModelExpansion(mon, type, model, false,
+if (qemuMonitorGetCPUModelExpansion(mon, type, model, false,
 ) &l

[libvirt] [PATCH v5 26/36] qemu_monitor: qemuMonitorGetCPUModelExpansion inputs and outputs CPUModelInfo

2018-12-02 Thread Chris Venteicher
A Full CPUModelInfo structure with props is sent to QEMU for expansion.

virQEMUCapsProbeQMPHostCPU migratability logic partitioned into new function
for clarity.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c |  8 +---
 src/qemu/qemu_monitor.c  | 31 ++-
 src/qemu/qemu_monitor.h  |  5 +++--
 src/qemu/qemu_monitor_json.c | 16 +++-
 src/qemu/qemu_monitor_json.h |  6 +++---
 tests/cputest.c  | 11 ---
 6 files changed, 56 insertions(+), 21 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index bd75f82e70..8c5ec4cc9a 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2460,6 +2460,7 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
qemuMonitorPtr mon,
bool tcg)
 {
+qemuMonitorCPUModelInfoPtr input;
 qemuMonitorCPUModelInfoPtr migratable = NULL;
 qemuMonitorCPUModelInfoPtr nonMigratable = NULL;
 qemuMonitorCPUModelInfoPtr augmented = NULL;
@@ -2493,7 +2494,8 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
 else
 type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC;
 
-if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, ) < 
0)
+if (!(input = qemuMonitorCPUModelInfoNew(model)) ||
+qemuMonitorGetCPUModelExpansion(mon, type, true, input, ) < 
0)
 goto cleanup;
 
 if (!migratable) {
@@ -2502,8 +2504,7 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
 }
 
 /* Try to check migratability of each feature. */
-if (qemuMonitorGetCPUModelExpansion(mon, type, model, false,
-) < 0)
+if (qemuMonitorGetCPUModelExpansion(mon, type, false, input, 
) < 0)
 goto cleanup;
 
 if (virQEMUCapsMigratablePropsDiff(migratable, nonMigratable, ) 
< 0)
@@ -2513,6 +2514,7 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
 ret = 0;
 
  cleanup:
+qemuMonitorCPUModelInfoFree(input);
 qemuMonitorCPUModelInfoFree(migratable);
 qemuMonitorCPUModelInfoFree(nonMigratable);
 qemuMonitorCPUModelInfoFree(augmented);
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index ddf4d96799..bed6a2f90a 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3653,20 +3653,41 @@ qemuMonitorCPUDefInfoFree(qemuMonitorCPUDefInfoPtr cpu)
 }
 
 
+/**
+ * qemuMonitorGetCPUModelExpansion:
+ * @mon:
+ * @type: qemuMonitorCPUModelExpansionType
+ * @migratable: Prompt QEMU to include non-migratable props for X86 models if 
false
+ * @input: Input model
+ * @expansion: Expanded output model (or NULL if QEMU rejects model or request)
+ *
+ * Re-represent @input CPU props using a new CPUModelInfo constructed
+ * by naming a STATIC or DYNAMIC model cooresponding to a set of properties and
+ * a FULL or PARTIAL (only deltas from model) property list.
+ *
+ * if @type == QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC
+ *   construct @expansion using STATIC model name and a PARTIAL (delta) 
property list
+ *
+ * if @type == QEMU_MONITOR_CPU_MODEL_EXPANSION_FULL
+ *   construct @expansion using DYNAMIC model name and a FULL property list
+ *
+ * if @type == QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC_FULL
+ *   construct @expansion using STATIC model name and a FULL property list
+ */
 int
 qemuMonitorGetCPUModelExpansion(qemuMonitorPtr mon,
 qemuMonitorCPUModelExpansionType type,
-const char *model_name,
 bool migratable,
-qemuMonitorCPUModelInfoPtr *model_info)
+qemuMonitorCPUModelInfoPtr input,
+qemuMonitorCPUModelInfoPtr *expansion
+   )
 {
 VIR_DEBUG("type=%d model_name=%s migratable=%d",
-  type, model_name, migratable);
+  type, input->name, migratable);
 
 QEMU_CHECK_MONITOR(mon);
 
-return qemuMonitorJSONGetCPUModelExpansion(mon, type, model_name,
-   migratable, model_info);
+return qemuMonitorJSONGetCPUModelExpansion(mon, type, migratable, input, 
expansion);
 }
 
 
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index d0c54f60a9..78ad8ae428 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1036,9 +1036,10 @@ typedef enum {
 
 int qemuMonitorGetCPUModelExpansion(qemuMonitorPtr mon,
 qemuMonitorCPUModelExpansionType type,
-const char *model_name,
 bool migratable,
-qemuMonitorCPUModelInfoPtr *model_info);
+qemuMonitorCPUModelInfoPtr input,
+qemuMonitorCPUModelInfoPtr *expansion)
+ATTRIBUTE_NO

[libvirt] [PATCH v5 24/36] qemu_monitor: Introduce qemuMonitorCPUModelInfo / JSON conversion

2018-12-02 Thread Chris Venteicher
Conversion functions are used convert CPUModelInfo structs into
QMP JSON and the reverse.

QMP JSON is of form:
{"model": {"name": "IvyBridge", "props": {}}}

qemuMonitorCPUModelInfoBoolPropAdd is used to add boolean properties to
CPUModelInfo struct.

qemuMonitorJSONGetCPUModelExpansion makes full use of conversions and
propAdd in prep to support input of full cpu model in future.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_monitor.c  |  24 ++
 src/qemu/qemu_monitor.h  |   5 ++
 src/qemu/qemu_monitor_json.c | 154 +--
 3 files changed, 138 insertions(+), 45 deletions(-)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 5effc74736..ddf4d96799 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3764,6 +3764,30 @@ qemuMonitorCPUModelInfoCopy(const 
qemuMonitorCPUModelInfo *orig)
 }
 
 
+int
+qemuMonitorCPUModelInfoBoolPropAdd(qemuMonitorCPUModelInfoPtr model,
+   const char *prop_name,
+   bool prop_value)
+{
+int ret = -1;
+qemuMonitorCPUProperty prop;
+prop.type = QEMU_MONITOR_CPU_PROPERTY_BOOLEAN;
+prop.value.boolean = prop_value;
+
+if (VIR_STRDUP(prop.name, prop_name) < 0)
+goto cleanup;
+
+if (VIR_APPEND_ELEMENT(model->props, model->nprops, prop) < 0)
+goto cleanup;
+
+ret = 0;
+
+ cleanup:
+VIR_FREE(prop.name);
+return ret;
+}
+
+
 int
 qemuMonitorGetCommands(qemuMonitorPtr mon,
char ***commands)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index d486af201a..d0c54f60a9 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1047,6 +1047,11 @@ qemuMonitorCPUModelInfoPtr 
qemuMonitorCPUModelInfoNew(const char *name);
 qemuMonitorCPUModelInfoPtr
 qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig);
 
+int qemuMonitorCPUModelInfoBoolPropAdd(qemuMonitorCPUModelInfoPtr model,
+   const char *prop_name,
+   bool prop_value)
+ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
 int qemuMonitorGetCommands(qemuMonitorPtr mon,
char ***commands);
 int qemuMonitorGetEvents(qemuMonitorPtr mon,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 5a806f6c0e..abfa4155ee 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -5505,6 +5505,101 @@ qemuMonitorJSONParseCPUModelProperty(const char *key,
 return 0;
 }
 
+
+/* model_json: {"name": "z13-base", "props": {}}
+ */
+static virJSONValuePtr
+qemuMonitorJSONBuildCPUModelInfoToJSON(qemuMonitorCPUModelInfoPtr model)
+{
+virJSONValuePtr cpu_props = NULL;
+virJSONValuePtr model_json = NULL;
+size_t i;
+
+if (!model)
+goto cleanup;
+
+if (model->nprops > 0 && !(cpu_props = virJSONValueNewObject()))
+goto cleanup;
+
+for (i = 0; i < model->nprops; i++) {
+qemuMonitorCPUPropertyPtr prop = &(model->props[i]);
+
+switch (prop->type) {
+case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN:
+if (virJSONValueObjectAppendBoolean(cpu_props, prop->name,
+prop->value.boolean) < 0)
+goto cleanup;
+break;
+
+case QEMU_MONITOR_CPU_PROPERTY_STRING:
+if (virJSONValueObjectAppendString(cpu_props, prop->name,
+   prop->value.string) < 0)
+goto cleanup;
+break;
+
+case QEMU_MONITOR_CPU_PROPERTY_NUMBER:
+if (virJSONValueObjectAppendNumberLong(cpu_props, prop->name,
+   prop->value.number) < 0)
+goto cleanup;
+break;
+
+case QEMU_MONITOR_CPU_PROPERTY_LAST:
+default:
+virReportEnumRangeError(qemuMonitorCPUPropertyPtr, prop->type);
+goto cleanup;
+}
+}
+
+ignore_value(virJSONValueObjectCreate(_json, "s:name", model->name,
+  "A:props", _props, NULL));
+
+ cleanup:
+virJSONValueFree(cpu_props);
+return model_json;
+}
+
+
+/* model_json: {"name": "IvyBridge", "props": {}}
+ */
+static qemuMonitorCPUModelInfoPtr
+qemuMonitorJSONBuildCPUModelInfoFromJSON(virJSONValuePtr cpu_model)
+{
+virJSONValuePtr cpu_props;
+qemuMonitorCPUModelInfoPtr model = NULL;
+qemuMonitorCPUModelInfoPtr ret = NULL;
+char const *cpu_name;
+
+if (!(cpu_name = virJSONValueObjectGetString(cpu_model, "name"))) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Parsed JSON reply missing 'name'"));
+  

[libvirt] [PATCH v5 29/36] qemu_monitor: Support query-cpu-model-baseline QMP command

2018-12-02 Thread Chris Venteicher
Introduce monitor functions to use QEMU to compute baseline cpu
from an input of two cpu models.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_monitor.c  | 12 
 src/qemu/qemu_monitor.h  |  6 
 src/qemu/qemu_monitor_json.c | 60 
 src/qemu/qemu_monitor_json.h |  6 
 4 files changed, 84 insertions(+)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index bed6a2f90a..c5266b6767 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4514,3 +4514,15 @@ qemuMonitorGetPRManagerInfo(qemuMonitorPtr mon,
 virHashFree(info);
 return ret;
 }
+
+
+int
+qemuMonitorGetCPUModelBaseline(qemuMonitorPtr mon,
+   qemuMonitorCPUModelInfoPtr model_a,
+   qemuMonitorCPUModelInfoPtr model_b,
+   qemuMonitorCPUModelInfoPtr *model_baseline)
+{
+QEMU_CHECK_MONITOR(mon);
+
+return qemuMonitorJSONGetCPUModelBaseline(mon, model_a, model_b, 
model_baseline);
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 78ad8ae428..c87a2d5e47 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1205,4 +1205,10 @@ struct _qemuMonitorPRManagerInfo {
 int qemuMonitorGetPRManagerInfo(qemuMonitorPtr mon,
 virHashTablePtr *retinfo);
 
+int qemuMonitorGetCPUModelBaseline(qemuMonitorPtr mon,
+   qemuMonitorCPUModelInfoPtr model_a,
+   qemuMonitorCPUModelInfoPtr model_b,
+   qemuMonitorCPUModelInfoPtr *model_baseline)
+ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
+
 #endif /* QEMU_MONITOR_H */
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 96e9f0ea3c..bd0e940325 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -8514,3 +8514,63 @@ qemuMonitorJSONGetPRManagerInfo(qemuMonitorPtr mon,
 return ret;
 
 }
+
+
+int
+qemuMonitorJSONGetCPUModelBaseline(qemuMonitorPtr mon,
+   qemuMonitorCPUModelInfoPtr model_a,
+   qemuMonitorCPUModelInfoPtr model_b,
+   qemuMonitorCPUModelInfoPtr *model_baseline)
+{
+int ret = -1;
+virJSONValuePtr cmd = NULL;
+virJSONValuePtr reply = NULL;
+virJSONValuePtr data = NULL;
+virJSONValuePtr modela = NULL;
+virJSONValuePtr modelb = NULL;
+virJSONValuePtr cpu_model = NULL;
+
+*model_baseline = NULL;
+
+if (!(modela = qemuMonitorJSONBuildCPUModelInfoToJSON(model_a)) ||
+!(modelb = qemuMonitorJSONBuildCPUModelInfoToJSON(model_b)))
+goto cleanup;
+
+if (!(cmd = qemuMonitorJSONMakeCommand("query-cpu-model-baseline",
+   "a:modela", ,
+   "a:modelb", ,
+   NULL)))
+goto cleanup;
+
+if (qemuMonitorJSONCommand(mon, cmd, ) < 0)
+goto cleanup;
+
+if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_OBJECT) < 0) {
+virReportError(VIR_ERR_INVALID_ARG,
+   _("QEMU doesn't support baseline or recognize model %s 
or %s"),
+   model_a->name,
+   model_b->name);
+goto cleanup;
+}
+
+data = virJSONValueObjectGetObject(reply, "return");
+
+if (!(cpu_model = virJSONValueObjectGetObject(data, "model"))) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("query-cpu-model-baseline reply data was missing 
'model'"));
+goto cleanup;
+}
+
+if (!(*model_baseline = 
qemuMonitorJSONBuildCPUModelInfoFromJSON(cpu_model)))
+goto cleanup;
+
+ret = 0;
+
+ cleanup:
+virJSONValueFree(cmd);
+virJSONValueFree(reply);
+virJSONValueFree(modela);
+virJSONValueFree(modelb);
+
+return ret;
+}
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 942dd85ee1..7bd161af58 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -581,4 +581,10 @@ int qemuMonitorJSONGetPRManagerInfo(qemuMonitorPtr mon,
 virHashTablePtr info)
 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
+int qemuMonitorJSONGetCPUModelBaseline(qemuMonitorPtr mon,
+   qemuMonitorCPUModelInfoPtr model_a,
+   qemuMonitorCPUModelInfoPtr model_b,
+   qemuMonitorCPUModelInfoPtr 
*model_baseline)
+ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
+
 #endif /* QEMU_MONITOR_JSON_H */
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 16/36] qemu_process: Cleanup qemuProcessQmp alloc function

2018-12-02 Thread Chris Venteicher
qemuProcessQmpNew is one of the 4 public functions used to create and
manage a qemu process for QMP command exchanges outside of domain
operations.

Add descriptive comment block, Debug statement and make source
consistent with the cleanup / VIR_STEAL_PTR format used elsewhere.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 32 ++--
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 31d41688fe..faf86dac5d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8124,6 +8124,18 @@ qemuProcessQmpFree(qemuProcessQmpPtr proc)
 }
 
 
+/**
+ * qemuProcessQmpNew:
+ * @binary: Qemu binary
+ * @libDir: Directory for process and connection artifacts
+ * @runUid: UserId for Qemu Process
+ * @runGid: GroupId for Qemu Process
+ * @forceTCG: Force TCG mode if true
+ *
+ * Allocate and initialize domain structure encapsulating
+ * QEMU Process state and monitor connection to QEMU
+ * for completing QMP Queries.
+ */
 qemuProcessQmpPtr
 qemuProcessQmpNew(const char *binary,
   const char *libDir,
@@ -8131,25 +8143,33 @@ qemuProcessQmpNew(const char *binary,
   gid_t runGid,
   bool forceTCG)
 {
+qemuProcessQmpPtr ret = NULL;
 qemuProcessQmpPtr proc = NULL;
 
+VIR_DEBUG("exec=%s, libDir=%s, runUid=%u, runGid=%u, forceTCG=%d",
+  NULLSTR(binary), NULLSTR(libDir), runUid, runGid, forceTCG);
+
 if (VIR_ALLOC(proc) < 0)
-goto error;
+goto cleanup;
 
 if (VIR_STRDUP(proc->binary, binary) < 0 ||
 VIR_STRDUP(proc->libDir, libDir) < 0)
-goto error;
+goto cleanup;
 
 
 proc->runUid = runUid;
 proc->runGid = runGid;
 proc->forceTCG = forceTCG;
 
-return proc;
+VIR_STEAL_PTR(ret, proc);
 
- error:
-qemuProcessQmpFree(proc);
-return NULL;
+ cleanup:
+if (proc)
+qemuProcessQmpFree(proc);
+
+VIR_DEBUG("ret=%p", ret);
+
+return ret;
 }
 
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 17/36] qemu_process: Cleanup qemuProcessQmpStop function

2018-12-02 Thread Chris Venteicher
qemuProcessQmpStop is one of the 4 public functions used to create and
manage a Qemu process for QMP command exchanges.

Add comment header and debug message.

Other minor code formatting cleanup.

No change in functionality is intended.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index faf86dac5d..e9b50745d3 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8390,10 +8390,20 @@ qemuProcessQmpStart(qemuProcessQmpPtr proc)
 goto cleanup;
 }
 
-
-void
-qemuProcessQmpStop(qemuProcessQmpPtr proc)
+/**
+ * qemuProcessStop:
+ * @proc: Stores Process and Connection State
+ *
+ * Stop Monitor Connection and QEMU Process
+ */
+void qemuProcessQmpStop(qemuProcessQmpPtr proc)
 {
+if (!proc)
+return;
+
+VIR_DEBUG("Shutting down proc=%p emulator=%s mon=%p pid=%lld",
+  proc, proc->binary, proc->mon, (long long)proc->pid);
+
 if (proc->mon) {
 virObjectUnlock(proc->mon);
 qemuMonitorClose(proc->mon);
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 19/36] qemu_monitor: Make monitor callbacks optional

2018-12-02 Thread Chris Venteicher
Qemu process code for capababilities doesn't use monitor callbacks and
defines empty callback functions.

Allow NULL to be passed to qemuMonitorOpen for callbacks and remove the
empty functions from the QMP process code.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_monitor.c |  4 ++--
 src/qemu/qemu_process.c | 14 +-
 2 files changed, 3 insertions(+), 15 deletions(-)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index a65d638ab8..84065c59dc 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -813,12 +813,12 @@ qemuMonitorOpenInternal(virDomainObjPtr vm,
 {
 qemuMonitorPtr mon;
 
-if (!cb->eofNotify) {
+if (cb && !cb->eofNotify) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("EOF notify callback must be supplied"));
 return NULL;
 }
-if (!cb->errorNotify) {
+if (cb && !cb->errorNotify) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Error notify callback must be supplied"));
 return NULL;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 1b6adf1b64..24945b1d17 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8095,18 +8095,6 @@ qemuProcessReconnectAll(virQEMUDriverPtr driver)
 }
 
 
-static void virQEMUCapsMonitorNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- void *opaque ATTRIBUTE_UNUSED)
-{
-}
-
-static qemuMonitorCallbacks callbacks = {
-.eofNotify = virQEMUCapsMonitorNotify,
-.errorNotify = virQEMUCapsMonitorNotify,
-};
-
-
 /**
  * qemuProcessQmpFree:
  * @proc: Stores Process and Connection State
@@ -8302,7 +8290,7 @@ qemuProcessQmpConnectMonitor(qemuProcessQmpPtr proc)
 bool retry = true;
 bool enableJson = true;
 virQEMUDriverPtr driver = NULL;
-qemuMonitorCallbacksPtr monCallbacks = 
+qemuMonitorCallbacksPtr monCallbacks = NULL;
 virDomainXMLOptionPtr xmlopt = NULL;
 virDomainChrSourceDef monConfig;
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 18/36] qemu_process: Catch process free before process stop

2018-12-02 Thread Chris Venteicher
Catch execution paths where qemuProcessQmpFree is called before
qemuProcessQmpStop then report error and force stop before proceeding.

Also added public function header and debug message.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e9b50745d3..1b6adf1b64 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8107,13 +8107,28 @@ static qemuMonitorCallbacks callbacks = {
 };
 
 
+/**
+ * qemuProcessQmpFree:
+ * @proc: Stores Process and Connection State
+ *
+ * Free process data structure.
+ */
 void
 qemuProcessQmpFree(qemuProcessQmpPtr proc)
 {
+VIR_DEBUG("proc=%p, proc->mon=%p", proc, (proc ? proc->mon : NULL));
+
 if (!proc)
 return;
 
-qemuProcessQmpStop(proc);
+/* This should never be non-NULL if we get here, but just in case... */
+if (proc->mon || proc->pid) {
+VIR_ERROR(_("Unexpected QEMU still active during process free"
+" emulator: %s, pid: %lld, mon: %p"),
+  NULLSTR(proc->binary), (long long)proc->pid, proc->mon);
+qemuProcessQmpStop(proc);
+}
+
 VIR_FREE(proc->binary);
 VIR_FREE(proc->libDir);
 VIR_FREE(proc->monpath);
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 20/36] qemu_process: Enter QMP command mode when starting QEMU Process

2018-12-02 Thread Chris Venteicher
qemuProcessQmpStart starts a QEMU process and monitor connection that
can be used by multiple functions possibly for multiple QMP commands.

The QMP exchange to exit capabilities negotiation mode and enter command mode
can only be performed once after the monitor connection is established.

Move responsibility for entering QMP command mode into the qemuProcessQmp
code so multiple functions can issue QMP commands in arbitrary orders.

This also simplifies the functions using the connection provided by
qemuProcessQmpStart to issue QMP commands.

Test code now needs to call qemuMonitorSetCapabilities to send the
message to switch to command mode because the test code does not use the
qemuProcessQmp command that internally calls qemuMonitorSetCapabilities.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 12 
 src/qemu/qemu_process.c  |  8 
 tests/qemucapabilitiestest.c |  7 +++
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index ce60648897..038e3ecf7a 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4035,12 +4035,6 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
 
 /* @mon is supposed to be locked by callee */
 
-if (qemuMonitorSetCapabilities(mon) < 0) {
-VIR_DEBUG("Failed to set monitor capabilities %s",
-  virGetLastErrorMessage());
-goto cleanup;
-}
-
 if (qemuMonitorGetVersion(mon,
   , , ,
   ) < 0) {
@@ -4213,12 +4207,6 @@ virQEMUCapsInitQMPMonitorTCG(virQEMUCapsPtr qemuCaps 
ATTRIBUTE_UNUSED,
 {
 int ret = -1;
 
-if (qemuMonitorSetCapabilities(mon) < 0) {
-VIR_DEBUG("Failed to set monitor capabilities %s",
-  virGetLastErrorMessage());
-goto cleanup;
-}
-
 if (virQEMUCapsProbeQMPCPUDefinitions(qemuCaps, mon, true) < 0)
 goto cleanup;
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 24945b1d17..80b938cc0b 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8332,6 +8332,14 @@ qemuProcessQmpConnectMonitor(qemuProcessQmpPtr proc)
 
 virObjectLock(proc->mon);
 
+/* Exit capabilities negotiation mode and enter QEMU command mode
+ * by issuing qmp_capabilities command to QEMU */
+if (qemuMonitorSetCapabilities(proc->mon) < 0) {
+VIR_DEBUG("Failed to set monitor capabilities %s",
+  virGetLastErrorMessage());
+goto cleanup;
+}
+
 ret = 0;
 
  cleanup:
diff --git a/tests/qemucapabilitiestest.c b/tests/qemucapabilitiestest.c
index a043b0fa64..5fffbc266a 100644
--- a/tests/qemucapabilitiestest.c
+++ b/tests/qemucapabilitiestest.c
@@ -58,6 +58,9 @@ testQemuCaps(const void *opaque)
 if (!(mon = qemuMonitorTestNewFromFileFull(repliesFile, >driver, 
NULL)))
 goto cleanup;
 
+if (qemuMonitorSetCapabilities(qemuMonitorTestGetMonitor(mon)) < 0)
+goto cleanup;
+
 if (!(capsActual = virQEMUCapsNew()) ||
 virQEMUCapsInitQMPMonitor(capsActual,
   qemuMonitorTestGetMonitor(mon)) < 0)
@@ -65,6 +68,10 @@ testQemuCaps(const void *opaque)
 
 if (virQEMUCapsGet(capsActual, QEMU_CAPS_KVM)) {
 qemuMonitorResetCommandID(qemuMonitorTestGetMonitor(mon));
+
+if (qemuMonitorSetCapabilities(qemuMonitorTestGetMonitor(mon)) < 0)
+goto cleanup;
+
 if (virQEMUCapsInitQMPMonitorTCG(capsActual,
  qemuMonitorTestGetMonitor(mon)) < 0)
 goto cleanup;
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 23/36] qemu_monitor: Introduce qemuMonitorCPUModelInfoNew

2018-12-02 Thread Chris Venteicher
Use a helper function to allocate and initializes CPU Model Info structs.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c |  2 +-
 src/qemu/qemu_monitor.c  | 32 +++-
 src/qemu/qemu_monitor.h  |  2 ++
 3 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 038e3ecf7a..cd685298e6 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3047,7 +3047,7 @@ virQEMUCapsLoadHostCPUModelInfo(virQEMUCapsPtr qemuCaps,
 goto cleanup;
 }
 
-if (VIR_ALLOC(hostCPU) < 0)
+if (!(hostCPU = qemuMonitorCPUModelInfoNew(NULL)))
 goto cleanup;
 
 if (!(hostCPU->name = virXMLPropString(hostCPUNode, "model"))) {
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 84065c59dc..5effc74736 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3670,6 +3670,31 @@ qemuMonitorGetCPUModelExpansion(qemuMonitorPtr mon,
 }
 
 
+qemuMonitorCPUModelInfoPtr
+qemuMonitorCPUModelInfoNew(const char *name)
+{
+qemuMonitorCPUModelInfoPtr ret = NULL;
+qemuMonitorCPUModelInfoPtr model;
+
+if (VIR_ALLOC(model) < 0)
+return NULL;
+
+model->name = NULL;
+model->nprops = 0;
+model->props = NULL;
+model->migratability = false;
+
+if (VIR_STRDUP(model->name, name) < 0)
+goto cleanup;
+
+VIR_STEAL_PTR(ret, model);
+
+ cleanup:
+qemuMonitorCPUModelInfoFree(model);
+return ret;
+}
+
+
 void
 qemuMonitorCPUModelInfoFree(qemuMonitorCPUModelInfoPtr model_info)
 {
@@ -3693,18 +3718,15 @@ qemuMonitorCPUModelInfoFree(qemuMonitorCPUModelInfoPtr 
model_info)
 qemuMonitorCPUModelInfoPtr
 qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig)
 {
-qemuMonitorCPUModelInfoPtr copy;
+qemuMonitorCPUModelInfoPtr copy = NULL;
 size_t i;
 
-if (VIR_ALLOC(copy) < 0)
+if (!orig || !(copy = qemuMonitorCPUModelInfoNew(orig->name)))
 goto error;
 
 if (VIR_ALLOC_N(copy->props, orig->nprops) < 0)
 goto error;
 
-if (VIR_STRDUP(copy->name, orig->name) < 0)
-goto error;
-
 copy->migratability = orig->migratability;
 copy->nprops = orig->nprops;
 
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 66bfdb0e5c..d486af201a 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1042,6 +1042,8 @@ int qemuMonitorGetCPUModelExpansion(qemuMonitorPtr mon,
 
 void qemuMonitorCPUModelInfoFree(qemuMonitorCPUModelInfoPtr model_info);
 
+qemuMonitorCPUModelInfoPtr qemuMonitorCPUModelInfoNew(const char *name);
+
 qemuMonitorCPUModelInfoPtr
 qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig);
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 21/36] qemu_process: Use unique directories for QMP processes

2018-12-02 Thread Chris Venteicher
Multiple QEMU processes for QMP commands can operate concurrently.

Use a unique directory under libDir for each QEMU processes
to avoid pidfile and unix socket collision between processes.

The pid file name is changed from "capabilities.pidfile" to "qmp.pid"
because we no longer need to avoid a possible clash with a qemu domain
called "capabilities" now that the processes artifacts are stored in
their own unique temporary directories.

"Capabilities" was changed to "qmp" in the pid file name because these
processes are no longer specific to the capabilities usecase and are
more generic in terms of being used for any general purpose QMP message
exchanges with a QEMU process that is not associated with a domain.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 24 ++--
 src/qemu/qemu_process.h |  1 +
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 80b938cc0b..26ba59143d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8119,6 +8119,7 @@ qemuProcessQmpFree(qemuProcessQmpPtr proc)
 
 VIR_FREE(proc->binary);
 VIR_FREE(proc->libDir);
+VIR_FREE(proc->uniqDir);
 VIR_FREE(proc->monpath);
 VIR_FREE(proc->monarg);
 VIR_FREE(proc->pidfile);
@@ -8181,33 +8182,33 @@ qemuProcessQmpNew(const char *binary,
 static int
 qemuProcessQmpInit(qemuProcessQmpPtr proc)
 {
+char *template = NULL;
 int ret = -1;
 
 VIR_DEBUG("Beginning VM startup process"
   " proc=%p, emulator=%s",
   proc, proc->binary);
 
-/* the ".sock" sufix is important to avoid a possible clash with a qemu
- * domain called "capabilities"
- */
-if (virAsprintf(>monpath, "%s/%s", proc->libDir,
-"capabilities.monitor.sock") < 0)
+if (virAsprintf(, "%s/qemu.XX", proc->libDir) < 0)
+goto cleanup;
+
+proc->uniqDir = mkdtemp(template);
+
+if (virAsprintf(>monpath, "%s/%s", proc->uniqDir,
+"qmp.monitor") < 0)
 goto cleanup;
 
 if (virAsprintf(>monarg, "unix:%s,server,nowait", proc->monpath) < 0)
 goto cleanup;
 
-/* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
- * with a qemu domain called "capabilities"
+/*
  * Normally we'd use runDir for pid files, but because we're using
  * -daemonize we need QEMU to be allowed to create them, rather
  * than libvirtd. So we're using libDir which QEMU can write to
  */
-if (virAsprintf(>pidfile, "%s/%s", proc->libDir, 
"capabilities.pidfile") < 0)
+if (virAsprintf(>pidfile, "%s/%s", proc->uniqDir, "qmp.pid") < 0)
 goto cleanup;
 
-virPidFileForceCleanupPath(proc->pidfile);
-
 ret = 0;
 
  cleanup:
@@ -8446,4 +8447,7 @@ void qemuProcessQmpStop(qemuProcessQmpPtr proc)
 
 if (proc->pidfile)
 unlink(proc->pidfile);
+
+if (proc->uniqDir)
+rmdir(proc->uniqDir);
 }
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 0a79d15290..2ef521d825 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -226,6 +226,7 @@ struct _qemuProcessQmp {
 char *monarg;
 char *monpath;
 char *pidfile;
+char *uniqDir;
 virCommandPtr cmd;
 qemuMonitorPtr mon;
 pid_t pid;
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 22/36] qemu_process: Stop locking QMP process monitor immediately

2018-12-02 Thread Chris Venteicher
Locking the monitor object immediately after call to qemuMonitorOpen
doesn't make sense now that we have expanded the QEMU process code to
cover more than the original capabilities usecase.

Removing the monitor lock makes the qemuProcessQmpConnectMonitor code
consistent with the qemuConnectMonitor code used to establish the
monitor when QEMU process is started for domains.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 26ba59143d..b491f9f91a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8331,8 +8331,6 @@ qemuProcessQmpConnectMonitor(qemuProcessQmpPtr proc)
 
 VIR_STEAL_PTR(proc->mon, mon);
 
-virObjectLock(proc->mon);
-
 /* Exit capabilities negotiation mode and enter QEMU command mode
  * by issuing qmp_capabilities command to QEMU */
 if (qemuMonitorSetCapabilities(proc->mon) < 0) {
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 15/36] qemu_process: Don't open monitor if process failed

2018-12-02 Thread Chris Venteicher
Gracefully handle case when proc activation failed prior to calling.

Consistent with the existing code for qemuConnectMonitor (for domains)
in qemu_process.c...

- Handle qemMonitorOpen failure with INFO message and NULL ptr
- Identify parameters passed to qemuMonitorOpen

Monitor callbacks will be removed in future patch so we prep for passing
NULL for the callback pointer.

Set proc->mon to NULL then use VIR_STEAL_PTR if successful to be
consistent with other functions.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 29 +++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 8906a22e3c..31d41688fe 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8262,25 +8262,50 @@ static int
 qemuProcessQmpConnectMonitor(qemuProcessQmpPtr proc)
 {
 int ret = -1;
+qemuMonitorPtr mon = NULL;
+unsigned long long timeout = 0;
+bool retry = true;
+bool enableJson = true;
+virQEMUDriverPtr driver = NULL;
+qemuMonitorCallbacksPtr monCallbacks = 
 virDomainXMLOptionPtr xmlopt = NULL;
 virDomainChrSourceDef monConfig;
 
 VIR_DEBUG("proc=%p, emulator=%s, proc->pid=%lld",
   proc, NULLSTR(proc->binary), (long long)proc->pid);
 
+if (!proc || !proc->pid) {
+ret = 0;
+goto cleanup;
+}
+
+proc->mon = NULL;
+
 monConfig.type = VIR_DOMAIN_CHR_TYPE_UNIX;
 monConfig.data.nix.path = proc->monpath;
 monConfig.data.nix.listen = false;
 
+/* Create a NULL Domain object for qemuMonitor */
 if (!(xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL, NULL, NULL)) ||
 !(proc->vm = virDomainObjNew(xmlopt)))
 goto cleanup;
 
 proc->vm->pid = proc->pid;
 
-if (!(proc->mon = qemuMonitorOpen(proc->vm, , true, true,
-  0, , NULL)))
+mon = qemuMonitorOpen(proc->vm,
+  ,
+  enableJson,
+  retry,
+  timeout,
+  monCallbacks,
+  driver);
+
+if (!mon) {
+VIR_INFO("Failed to connect monitor to emulator %s", proc->binary);
 goto cleanup;
+}
+
+VIR_STEAL_PTR(proc->mon, mon);
 
 virObjectLock(proc->mon);
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 12/36] qemu_process: Store libDir in qemuProcessQmp struct

2018-12-02 Thread Chris Venteicher
Store libDir path in the qemuProcessQmp struct in anticipation of moving
path construction code into qemuProcessQmpInit function.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 8 +---
 src/qemu/qemu_process.h | 1 +
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index a688be7f2c..d4025ac1bc 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8115,6 +8115,7 @@ qemuProcessQmpFree(qemuProcessQmpPtr proc)
 
 qemuProcessQmpStop(proc);
 VIR_FREE(proc->binary);
+VIR_FREE(proc->libDir);
 VIR_FREE(proc->monpath);
 VIR_FREE(proc->monarg);
 VIR_FREE(proc->pidfile);
@@ -8135,7 +8136,8 @@ qemuProcessQmpNew(const char *binary,
 if (VIR_ALLOC(proc) < 0)
 goto error;
 
-if (VIR_STRDUP(proc->binary, binary) < 0)
+if (VIR_STRDUP(proc->binary, binary) < 0 ||
+VIR_STRDUP(proc->libDir, libDir) < 0)
 goto error;
 
 
@@ -8146,7 +8148,7 @@ qemuProcessQmpNew(const char *binary,
 /* the ".sock" sufix is important to avoid a possible clash with a qemu
  * domain called "capabilities"
  */
-if (virAsprintf(>monpath, "%s/%s", libDir,
+if (virAsprintf(>monpath, "%s/%s", proc->libDir,
 "capabilities.monitor.sock") < 0)
 goto error;
 if (virAsprintf(>monarg, "unix:%s,server,nowait", proc->monpath) < 0)
@@ -8158,7 +8160,7 @@ qemuProcessQmpNew(const char *binary,
  * -daemonize we need QEMU to be allowed to create them, rather
  * than libvirtd. So we're using libDir which QEMU can write to
  */
-if (virAsprintf(>pidfile, "%s/%s", libDir, "capabilities.pidfile") < 
0)
+if (virAsprintf(>pidfile, "%s/%s", proc->libDir, 
"capabilities.pidfile") < 0)
 goto error;
 
 virPidFileForceCleanupPath(proc->pidfile);
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 1b64aeef4e..9967766120 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -218,6 +218,7 @@ typedef struct _qemuProcessQmp qemuProcessQmp;
 typedef qemuProcessQmp *qemuProcessQmpPtr;
 struct _qemuProcessQmp {
 char *binary;
+char *libDir;
 uid_t runUid;
 gid_t runGid;
 int status;
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 11/36] qemu_process: Collect monitor code in single function

2018-12-02 Thread Chris Venteicher
qemuMonitor code lives in qemuProcessQmpConnectMonitor rather than in
qemuProcessQmpNew and qemuProcessQmpLaunch.

This is consistent with existing structure in qemu_process.c where
qemuConnectMonitor function contains monitor code for domain process
activation.

Simple code moves in this patch.  Improvements in later patch.

Only intended functional change in this patch is we don't
move (include) code to initiate process stop on failure to create monitor.

As comments in qemuProcessQmpStart say... Client must always call
qemuProcessStop and qemuProcessQmpFree, even in error cases.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 50 -
 1 file changed, 24 insertions(+), 26 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 938d328235..a688be7f2c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8163,10 +8163,6 @@ qemuProcessQmpNew(const char *binary,
 
 virPidFileForceCleanupPath(proc->pidfile);
 
-proc->config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
-proc->config.data.nix.path = proc->monpath;
-proc->config.data.nix.listen = false;
-
 return proc;
 
  error:
@@ -8198,7 +8194,6 @@ qemuProcessQmpInit(qemuProcessQmpPtr proc)
 static int
 qemuProcessQmpLaunch(qemuProcessQmpPtr proc)
 {
-virDomainXMLOptionPtr xmlopt = NULL;
 const char *machine;
 int ret = -1;
 
@@ -8250,6 +8245,28 @@ qemuProcessQmpLaunch(qemuProcessQmpPtr proc)
 goto cleanup;
 }
 
+ret = 0;
+
+ cleanup:
+return ret;
+}
+
+
+/* Connect Monitor to QEMU Process
+ */
+static int
+qemuProcessQmpConnectMonitor(qemuProcessQmpPtr proc)
+{
+int ret = -1;
+virDomainXMLOptionPtr xmlopt = NULL;
+
+VIR_DEBUG("proc=%p, emulator=%s, proc->pid=%lld",
+  proc, NULLSTR(proc->binary), (long long)proc->pid);
+
+proc->config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
+proc->config.data.nix.path = proc->monpath;
+proc->config.data.nix.listen = false;
+
 if (!(xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL, NULL, NULL)) ||
 !(proc->vm = virDomainObjNew(xmlopt)))
 goto cleanup;
@@ -8257,7 +8274,7 @@ qemuProcessQmpLaunch(qemuProcessQmpPtr proc)
 proc->vm->pid = proc->pid;
 
 if (!(proc->mon = qemuMonitorOpen(proc->vm, >config, true, true,
- 0, , NULL)))
+  0, , NULL)))
 goto cleanup;
 
 virObjectLock(proc->mon);
@@ -8265,27 +8282,8 @@ qemuProcessQmpLaunch(qemuProcessQmpPtr proc)
 ret = 0;
 
  cleanup:
-if (!proc->mon)
-qemuProcessQmpStop(proc);
+VIR_DEBUG("ret=%i", ret);
 virObjectUnref(xmlopt);
-
-return ret;
-}
-
-
-/* Connect Monitor to QEMU Process
- */
-static int
-qemuProcessQmpConnectMonitor(qemuProcessQmpPtr proc)
-{
-int ret = -1;
-
-VIR_DEBUG("proc=%p, emulator=%s, proc->pid=%lld",
-  proc, NULLSTR(proc->binary), (long long)proc->pid);
-
-ret = 0;
-
-VIR_DEBUG("ret=%i", ret);
 return ret;
 }
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 14/36] qemu_process: Stop retaining Monitor config in qemuProcessQmp

2018-12-02 Thread Chris Venteicher
The monitor config data is removed from the qemuProcessQmp struct.

The monitor config data can be initialized immediately before call to
qemuMonitorOpen and does not need to be maintained after the call
because qemuMonitorOpen copies any strings it needs.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 9 +
 src/qemu/qemu_process.h | 1 -
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index fc15cb1a3c..8906a22e3c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8263,13 +8263,14 @@ qemuProcessQmpConnectMonitor(qemuProcessQmpPtr proc)
 {
 int ret = -1;
 virDomainXMLOptionPtr xmlopt = NULL;
+virDomainChrSourceDef monConfig;
 
 VIR_DEBUG("proc=%p, emulator=%s, proc->pid=%lld",
   proc, NULLSTR(proc->binary), (long long)proc->pid);
 
-proc->config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
-proc->config.data.nix.path = proc->monpath;
-proc->config.data.nix.listen = false;
+monConfig.type = VIR_DOMAIN_CHR_TYPE_UNIX;
+monConfig.data.nix.path = proc->monpath;
+monConfig.data.nix.listen = false;
 
 if (!(xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL, NULL, NULL)) ||
 !(proc->vm = virDomainObjNew(xmlopt)))
@@ -8277,7 +8278,7 @@ qemuProcessQmpConnectMonitor(qemuProcessQmpPtr proc)
 
 proc->vm->pid = proc->pid;
 
-if (!(proc->mon = qemuMonitorOpen(proc->vm, >config, true, true,
+if (!(proc->mon = qemuMonitorOpen(proc->vm, , true, true,
   0, , NULL)))
 goto cleanup;
 
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 9967766120..0a79d15290 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -228,7 +228,6 @@ struct _qemuProcessQmp {
 char *pidfile;
 virCommandPtr cmd;
 qemuMonitorPtr mon;
-virDomainChrSourceDef config;
 pid_t pid;
 virDomainObjPtr vm;
 bool forceTCG;
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 06/36] qemu_capabilities: Stop QEMU process before freeing

2018-12-02 Thread Chris Venteicher
virQEMUCapsInitQMP now stops QEMU process in all execution paths,
before freeing the process structure.

The qemuProcessQmpStop function can be called multiple times without
problems... Won't attempt to stop processes and free resources multiple
times.

Follow the convention established in qemu_process of
1) alloc process structure
2) start process
3) use process
4) stop process
5) free process data structure

The process data structure persists after the process activation fails
or the process dies or is killed so stderr strings can be retrieved
until the process data structure is freed.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c |  1 +
 src/qemu/qemu_process.c  | 19 ---
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index d903fbddf8..a79329a134 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4273,6 +4273,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 ret = 0;
 
  cleanup:
+qemuProcessQmpStop(proc);
 qemuProcessQmpFree(proc);
 return ret;
 }
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 8465448a49..fa050a1a27 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8263,14 +8263,17 @@ qemuProcessQmpRun(qemuProcessQmpPtr proc,
 void
 qemuProcessQmpStop(qemuProcessQmpPtr proc)
 {
-if (proc->mon)
+if (proc->mon) {
 virObjectUnlock(proc->mon);
-qemuMonitorClose(proc->mon);
-proc->mon = NULL;
+qemuMonitorClose(proc->mon);
+proc->mon = NULL;
+}
 
-virCommandAbort(proc->cmd);
-virCommandFree(proc->cmd);
-proc->cmd = NULL;
+if (proc->cmd) {
+virCommandAbort(proc->cmd);
+virCommandFree(proc->cmd);
+proc->cmd = NULL;
+}
 
 if (proc->monpath)
 unlink(proc->monpath);
@@ -8287,8 +8290,10 @@ qemuProcessQmpStop(qemuProcessQmpPtr proc)
   virStrerror(errno, ebuf, sizeof(ebuf)));
 
 VIR_FREE(*proc->qmperr);
+
+proc->pid = 0;
 }
+
 if (proc->pidfile)
 unlink(proc->pidfile);
-proc->pid = 0;
 }
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 10/36] qemu_process: Introduce qemuProcessQmpStart

2018-12-02 Thread Chris Venteicher
Move a step closer to the function structure used elsewhere in
qemu_process where qemuProcessStart and qemuProcessStop are the exposed
functions.

qemuProcessQmpStart mirrors qemuProcessStart in calling sub functions to
initialize, launch the process and connect the monitor to the QEMU
process.

static functions qemuProcessQmpInit, qemuProcessQmpLaunch and
qemuProcessQmpConnectMonitor are introduced.

qemuProcessQmpLaunch is just renamed from qemuProcessQmpRun and
encapsulates all of the original code.

qemuProcessQmpInit and qemuProcessQmpMonitor are nearly empty functions
acting as placeholders for later patches where blocks of semi-complicated code
are cut/pasted into these functions without modification
(hopefully making review easier.)

Looking forward, the patch series ultimately moves the code into this
partitioning:

- qemuProcessQmpInit
Becomes the location of ~25 lines of code to create storage
directory, in thread safe way, and initialize paths
for monpath, monarg and pidfile.

- qemuProcessQmpLaunch
Becomes the location of ~48 lines of code used to create and run the
QEMU command.

- qemuProcessQmpConnectMonitor
Becomes the final location of ~58 lines of code used to open and
initialize the monitor connection between libvirt and qemu.

Three smaller, purpose-identifying, functions of ~60 lines or less seem
better than a single large process "start" function of > 130 lines.

Being able to compare and contrast between the domain and non-domain
versions of process code is useful too.  There is some significant
overlap between what the non-domain and domain functions do.  There is
also significant additional functionality in the domain functions that
might be useful in the non-domain functions in the future.
Possibly there could be sharing between non-domain and
domain process code in the future but common code would have
to be carefully extracted from the domain process code (not trivial.)

Mirroring the domain process code has some value, but
partitioning the code into logical chunks of < 60 lines
is the main reason for the static functions.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c |  4 +-
 src/qemu/qemu_process.c  | 94 +++-
 src/qemu/qemu_process.h  |  2 +-
 3 files changed, 95 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 997f8c19d5..ce60648897 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4265,7 +4265,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
runUid, runGid, false)))
 goto cleanup;
 
-if (qemuProcessQmpRun(proc) < 0) {
+if (qemuProcessQmpStart(proc) < 0) {
 if (proc->status != 0)
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to probe QEMU binary with QMP: %s"),
@@ -4288,7 +4288,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 procTCG = qemuProcessQmpNew(qemuCaps->binary, libDir,
 runUid, runGid, true);
 
-if (qemuProcessQmpRun(procTCG) < 0)
+if (qemuProcessQmpStart(procTCG) < 0)
 goto cleanup;
 
 if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, procTCG->mon) < 0)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 8ad685f3ea..938d328235 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8175,8 +8175,28 @@ qemuProcessQmpNew(const char *binary,
 }
 
 
-int
-qemuProcessQmpRun(qemuProcessQmpPtr proc)
+/* Initialize configuration and paths prior to starting QEMU
+ */
+static int
+qemuProcessQmpInit(qemuProcessQmpPtr proc)
+{
+int ret = -1;
+
+VIR_DEBUG("Beginning VM startup process"
+  " proc=%p, emulator=%s",
+  proc, proc->binary);
+
+ret = 0;
+
+VIR_DEBUG("ret=%i", ret);
+return ret;
+}
+
+
+/* Launch QEMU Process
+ */
+static int
+qemuProcessQmpLaunch(qemuProcessQmpPtr proc)
 {
 virDomainXMLOptionPtr xmlopt = NULL;
 const char *machine;
@@ -8253,6 +8273,76 @@ qemuProcessQmpRun(qemuProcessQmpPtr proc)
 }
 
 
+/* Connect Monitor to QEMU Process
+ */
+static int
+qemuProcessQmpConnectMonitor(qemuProcessQmpPtr proc)
+{
+int ret = -1;
+
+VIR_DEBUG("proc=%p, emulator=%s, proc->pid=%lld",
+  proc, NULLSTR(proc->binary), (long long)proc->pid);
+
+ret = 0;
+
+VIR_DEBUG("ret=%i", ret);
+return ret;
+}
+
+
+/**
+ * qemuProcessQmpStart:
+ * @proc: Stores Process and Connection State
+ *
+ * Start and connect to QEMU binary so QMP queries can be made.
+ *
+ * Usage:
+ *   proc = qemuProcessQmpNew(binary, libDir, runUid, runGid, forceTCG);
+ *   qemuProcessQmpStart(proc);
+ *   ** Send QMP Queries to QEMU using monitor (proc->mon) **
+ *   qemuProcessQmpStop(proc);
+ *   qemuProcessQmpFre

[libvirt] [PATCH v5 00/36] BaselineHypervisorCPU using QEMU QMP exchanges

2018-12-02 Thread Chris Venteicher
Some architectures (S390) depend on QEMU to compute baseline CPU model and
expand a models feature set.

Interacting with QEMU requires starting the QEMU process and completing one or
more query-cpu-model-baseline QMP exchanges with QEMU in addition to a
query-cpu-model-expansion QMP exchange to expand all features in the model.

See "s390x CPU models: exposing features" patch set on Qemu-devel for discussion
of QEMU aspects.

This is part of resolution of: 
https://bugzilla.redhat.com/show_bug.cgi?id=1511999

-

This patch set fixes all process code issues identified here:
https://www.redhat.com/archives/libvir-list/2018-November/msg00349.html
in patches 1-22 of the series.

The remaining patches implement the BaselineHypervisorCPU changes using
the non-domain qemu process code.


The process changes (patches 1-22)...

- Make the process code generic (not capabilities specific) for use by
BaselineHypervisorCPU

- Many of the process patches are simple code moves with implementation
changes in other distinct patches

- A thread safe library function creates a unique directory under libDir for 
each QEMU
process (for QMP messaging) to decouple processes in terms of sockets and
file system footprint.


The BaselineHypervisorCPU changes (patches 22-36)...

- Fix all issues raised in patch sets 1-4.

Thanks,
Chris


Chris Venteicher (36):
  qemu_process: Move process code from qemu_capabilities to qemu_process
  qemu_process: Use qemuProcessQmp prefix
  qemu_process: Limit qemuProcessQmpNew to const input strings
  qemu_process: Refer to proc not cmd in process code
  qemu_process: Use consistent name for stop process function
  qemu_capabilities: Stop QEMU process before freeing
  qemu_process: Use qemuProcessQmp struct for a single process
  qemu_process: All ProcessQMP errors are fatal
  qemu_process: Persist stderr in qemuProcessQmp struct
  qemu_process: Introduce qemuProcessQmpStart
  qemu_process: Collect monitor code in single function
  qemu_process: Store libDir in qemuProcessQmp struct
  qemu_process: Setup paths within qemuProcessQmpInit
  qemu_process: Stop retaining Monitor config in qemuProcessQmp
  qemu_process: Don't open monitor if process failed
  qemu_process: Cleanup qemuProcessQmp alloc function
  qemu_process: Cleanup qemuProcessQmpStop function
  qemu_process: Catch process free before process stop
  qemu_monitor: Make monitor callbacks optional
  qemu_process: Enter QMP command mode when starting QEMU Process
  qemu_process: Use unique directories for QMP processes
  qemu_process: Stop locking QMP process monitor immediately
  qemu_monitor: Introduce qemuMonitorCPUModelInfoNew
  qemu_monitor: Introduce qemuMonitorCPUModelInfo / JSON conversion
  qemu_capabilities: Introduce virQEMuCapsMigratablePropsDiff
  qemu_monitor: qemuMonitorGetCPUModelExpansion inputs and outputs
CPUModelInfo
  qemu_capabilities: Introduce CPUModelInfo to virCPUDef function
  qemu_capabilities: Introduce virCPUDef to CPUModelInfo function
  qemu_monitor: Support query-cpu-model-baseline QMP command
  qemu_driver: Consolidate code to baseline using libvirt
  qemu_driver: Decouple code for baseline using libvirt
  qemu_driver: Identify using libvirt as a distinct way to compute
baseline
  qemu_driver: Support baseline calculation using QEMU
  qemu_driver: Support feature expansion via QEMU when baselining cpu
  qemu_driver: Remove unsupported props in expanded hypervisor baseline
output
  qemu_monitor: Default props to migratable when expanding cpu model

 src/qemu/qemu_capabilities.c  | 617 --
 src/qemu/qemu_capabilities.h  |   4 +
 src/qemu/qemu_driver.c| 216 +-
 src/qemu/qemu_monitor.c   | 184 +-
 src/qemu/qemu_monitor.h   |  29 +-
 src/qemu/qemu_monitor_json.c  | 226 +--
 src/qemu/qemu_monitor_json.h  |  12 +-
 src/qemu/qemu_process.c   | 356 ++
 src/qemu/qemu_process.h   |  32 +
 tests/cputest.c   |  11 +-
 .../caps_2.10.0.s390x.xml |  60 +-
 .../caps_2.11.0.s390x.xml |  58 +-
 .../caps_2.12.0.s390x.xml |  56 +-
 .../qemucapabilitiesdata/caps_2.8.0.s390x.xml |  32 +-
 .../qemucapabilitiesdata/caps_2.9.0.s390x.xml |  34 +-
 .../qemucapabilitiesdata/caps_3.0.0.s390x.xml |  64 +-
 tests/qemucapabilitiestest.c  |   7 +
 17 files changed, 1396 insertions(+), 602 deletions(-)

-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 13/36] qemu_process: Setup paths within qemuProcessQmpInit

2018-12-02 Thread Chris Venteicher
Move code for setting paths and prepping file system from
qemuProcessQmpNew to qemuProcessQmpInit.

This keeps qemuProcessQmpNew limited to data structures
and path initialization is done in qemuProcessQmpInit.

The patch is a non-functional, cut / paste change,
however goto is now "cleanup" rather than "error".

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 46 +
 1 file changed, 24 insertions(+), 22 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index d4025ac1bc..fc15cb1a3c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8145,14 +8145,34 @@ qemuProcessQmpNew(const char *binary,
 proc->runGid = runGid;
 proc->forceTCG = forceTCG;
 
+return proc;
+
+ error:
+qemuProcessQmpFree(proc);
+return NULL;
+}
+
+
+/* Initialize configuration and paths prior to starting QEMU
+ */
+static int
+qemuProcessQmpInit(qemuProcessQmpPtr proc)
+{
+int ret = -1;
+
+VIR_DEBUG("Beginning VM startup process"
+  " proc=%p, emulator=%s",
+  proc, proc->binary);
+
 /* the ".sock" sufix is important to avoid a possible clash with a qemu
  * domain called "capabilities"
  */
 if (virAsprintf(>monpath, "%s/%s", proc->libDir,
 "capabilities.monitor.sock") < 0)
-goto error;
+goto cleanup;
+
 if (virAsprintf(>monarg, "unix:%s,server,nowait", proc->monpath) < 0)
-goto error;
+goto cleanup;
 
 /* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
  * with a qemu domain called "capabilities"
@@ -8161,31 +8181,13 @@ qemuProcessQmpNew(const char *binary,
  * than libvirtd. So we're using libDir which QEMU can write to
  */
 if (virAsprintf(>pidfile, "%s/%s", proc->libDir, 
"capabilities.pidfile") < 0)
-goto error;
+goto cleanup;
 
 virPidFileForceCleanupPath(proc->pidfile);
 
-return proc;
-
- error:
-qemuProcessQmpFree(proc);
-return NULL;
-}
-
-
-/* Initialize configuration and paths prior to starting QEMU
- */
-static int
-qemuProcessQmpInit(qemuProcessQmpPtr proc)
-{
-int ret = -1;
-
-VIR_DEBUG("Beginning VM startup process"
-  " proc=%p, emulator=%s",
-  proc, proc->binary);
-
 ret = 0;
 
+ cleanup:
 VIR_DEBUG("ret=%i", ret);
 return ret;
 }
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 08/36] qemu_process: All ProcessQMP errors are fatal

2018-12-02 Thread Chris Venteicher
In the past capabilities could be determined in other ways if QMP
messaging didn't succeed so a non-fatal error case was included in the
capabilities and QMP Process code.

For a while now, QMP capabilities failure has been a fatal case.

This patch makes QMP process failures return as a fatal error in all
cases consistent with 1) all failures actually being fatal in
QMP capabilities code and 2) the QMP process code being made generic.

The process changes impact the capabilities code because non-fatal
return codes are no longer returned.

The rest of the QMP associated capabilities code is updated to make all
errors fatal for consistency.

The process changes also force a change in QMP process stderr reporting
because the previous triggers for stderr reporting are no longer passed
through the function interfaces.

As best I can tell the only case where QMP process stderr should be
explicitly reported is when the QMP process exits with a non-zero
status.

Error reporting is moved to virQEMUCapsInitQMP and the QMP process
stderr is reported only when the QMP process status code is non-zero
(and is only reported for the primary QMP query not the secondary TCG
 specific QMP query.)

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 83 
 src/qemu/qemu_process.c  | 24 ---
 src/qemu/qemu_process.h  |  1 +
 3 files changed, 45 insertions(+), 63 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index bed9ca26a1..1efec85b57 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4038,7 +4038,6 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
 if (qemuMonitorSetCapabilities(mon) < 0) {
 VIR_DEBUG("Failed to set monitor capabilities %s",
   virGetLastErrorMessage());
-ret = 0;
 goto cleanup;
 }
 
@@ -4047,7 +4046,6 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
   ) < 0) {
 VIR_DEBUG("Failed to query monitor version %s",
   virGetLastErrorMessage());
-ret = 0;
 goto cleanup;
 }
 
@@ -4218,7 +4216,6 @@ virQEMUCapsInitQMPMonitorTCG(virQEMUCapsPtr qemuCaps 
ATTRIBUTE_UNUSED,
 if (qemuMonitorSetCapabilities(mon) < 0) {
 VIR_DEBUG("Failed to set monitor capabilities %s",
   virGetLastErrorMessage());
-ret = 0;
 goto cleanup;
 }
 
@@ -4234,25 +4231,47 @@ virQEMUCapsInitQMPMonitorTCG(virQEMUCapsPtr qemuCaps 
ATTRIBUTE_UNUSED,
 }
 
 
+#define MESSAGE_ID_CAPS_PROBE_FAILURE "8ae2f3fb-2dbe-498e-8fbd-012d40afa361"
+
+static void
+virQEMUCapsLogProbeFailure(const char *binary)
+{
+virLogMetadata meta[] = {
+{ .key = "MESSAGE_ID", .s = MESSAGE_ID_CAPS_PROBE_FAILURE, .iv = 0 },
+{ .key = "LIBVIRT_QEMU_BINARY", .s = binary, .iv = 0 },
+{ .key = NULL },
+};
+
+virLogMessage(,
+  VIR_LOG_WARN,
+  __FILE__, __LINE__, __func__,
+  meta,
+  _("Failed to probe capabilities for %s: %s"),
+  binary, virGetLastErrorMessage());
+}
+
+
 static int
 virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
const char *libDir,
uid_t runUid,
-   gid_t runGid,
-   char **qmperr)
+   gid_t runGid)
 {
 qemuProcessQmpPtr proc = NULL;
 qemuProcessQmpPtr procTCG = NULL;
+char *qmperr = NULL;
 int ret = -1;
-int rc;
 
 if (!(proc = qemuProcessQmpNew(qemuCaps->binary, libDir,
-   runUid, runGid, qmperr, false)))
+   runUid, runGid, , false)))
 goto cleanup;
 
-if ((rc = qemuProcessQmpRun(proc)) != 0) {
-if (rc == 1)
-ret = 0;
+if (qemuProcessQmpRun(proc) < 0) {
+if (proc->status != 0)
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Failed to probe QEMU binary with QMP: %s"),
+   qmperr ? qmperr : _("uknown error"));
+
 goto cleanup;
 }
 
@@ -4270,11 +4289,8 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 procTCG = qemuProcessQmpNew(qemuCaps->binary, libDir,
 runUid, runGid, NULL, true);
 
-if ((rc = qemuProcessQmpRun(procTCG)) != 0) {
-if (rc == 1)
-ret = 0;
+if (qemuProcessQmpRun(procTCG) < 0)
 goto cleanup;
-}
 
 if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, procTCG->mon) < 0)
 goto cleanup;
@@ -4283,34 +4299,19 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 ret = 0;
 
  cleanup:
+if (ret < 0)
+virQEMUCapsLogProbeFailure(qemuCaps->binary);
+
 qemuProcessQmpStop(proc);
 qemuProc

[libvirt] [PATCH v5 09/36] qemu_process: Persist stderr in qemuProcessQmp struct

2018-12-02 Thread Chris Venteicher
A qemuProcessQmp struct tracks the entire lifespan of a single QEMU Process
including storing error output when the process terminates or activation
fails.

Error output remains available until qemuProcessQmpFree is called.

The qmperr variable is renamed stderr (captures stderr from process.)

The stderr buffer no longer needs to be maintained outside of the
qemuProcessQmp structure because the structure is used for a single QEMU
process and the structures can be maintained as long as required
to retrieve the process error info.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 8 +++-
 src/qemu/qemu_process.c  | 9 +++--
 src/qemu/qemu_process.h  | 3 +--
 3 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 1efec85b57..997f8c19d5 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4259,18 +4259,17 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 {
 qemuProcessQmpPtr proc = NULL;
 qemuProcessQmpPtr procTCG = NULL;
-char *qmperr = NULL;
 int ret = -1;
 
 if (!(proc = qemuProcessQmpNew(qemuCaps->binary, libDir,
-   runUid, runGid, , false)))
+   runUid, runGid, false)))
 goto cleanup;
 
 if (qemuProcessQmpRun(proc) < 0) {
 if (proc->status != 0)
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to probe QEMU binary with QMP: %s"),
-   qmperr ? qmperr : _("uknown error"));
+   proc->stderr ? proc->stderr : _("uknown error"));
 
 goto cleanup;
 }
@@ -4287,7 +4286,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 qemuProcessQmpStop(proc);
 
 procTCG = qemuProcessQmpNew(qemuCaps->binary, libDir,
-runUid, runGid, NULL, true);
+runUid, runGid, true);
 
 if (qemuProcessQmpRun(procTCG) < 0)
 goto cleanup;
@@ -4306,7 +4305,6 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 qemuProcessQmpStop(procTCG);
 qemuProcessQmpFree(proc);
 qemuProcessQmpFree(procTCG);
-VIR_FREE(qmperr);
 
 return ret;
 }
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 2ec0d5340d..8ad685f3ea 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8118,6 +8118,7 @@ qemuProcessQmpFree(qemuProcessQmpPtr proc)
 VIR_FREE(proc->monpath);
 VIR_FREE(proc->monarg);
 VIR_FREE(proc->pidfile);
+VIR_FREE(proc->stderr);
 VIR_FREE(proc);
 }
 
@@ -8127,7 +8128,6 @@ qemuProcessQmpNew(const char *binary,
   const char *libDir,
   uid_t runUid,
   gid_t runGid,
-  char **qmperr,
   bool forceTCG)
 {
 qemuProcessQmpPtr proc = NULL;
@@ -8141,7 +8141,6 @@ qemuProcessQmpNew(const char *binary,
 
 proc->runUid = runUid;
 proc->runGid = runGid;
-proc->qmperr = qmperr;
 proc->forceTCG = forceTCG;
 
 /* the ".sock" sufix is important to avoid a possible clash with a qemu
@@ -8213,7 +8212,7 @@ qemuProcessQmpRun(qemuProcessQmpPtr proc)
 virCommandSetGID(proc->cmd, proc->runGid);
 virCommandSetUID(proc->cmd, proc->runUid);
 
-virCommandSetErrorBuffer(proc->cmd, proc->qmperr);
+virCommandSetErrorBuffer(proc->cmd, &(proc->stderr));
 
 proc->status = 0;
 
@@ -8222,7 +8221,7 @@ qemuProcessQmpRun(qemuProcessQmpPtr proc)
 
 if (proc->status != 0) {
 VIR_DEBUG("QEMU %s exited with status %d: %s",
-  proc->binary, proc->status, *proc->qmperr);
+  proc->binary, proc->status, proc->stderr);
 goto cleanup;
 }
 
@@ -8283,8 +8282,6 @@ qemuProcessQmpStop(qemuProcessQmpPtr proc)
   (long long)proc->pid,
   virStrerror(errno, ebuf, sizeof(ebuf)));
 
-VIR_FREE(*proc->qmperr);
-
 proc->pid = 0;
 }
 
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index a56e9608cd..3ddfa82918 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -221,7 +221,7 @@ struct _qemuProcessQmp {
 uid_t runUid;
 gid_t runGid;
 int status;
-char **qmperr;
+char *stderr;
 char *monarg;
 char *monpath;
 char *pidfile;
@@ -237,7 +237,6 @@ qemuProcessQmpPtr qemuProcessQmpNew(const char *binary,
 const char *libDir,
 uid_t runUid,
 gid_t runGid,
-char **qmperr,
 bool forceTCG);
 
 void qemuProcessQmpFree(qemuProcessQmpPtr proc);
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 02/36] qemu_process: Use qemuProcessQmp prefix

2018-12-02 Thread Chris Venteicher
s/virQEMUCapsInitQMPCommand/qemuProcessQmp/

No functionality change.

Use file appropriate prefix in moved code.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 14 +++---
 src/qemu/qemu_process.c  | 28 ++--
 src/qemu/qemu_process.h  | 24 
 3 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 14b1ab5bec..2f78fe27fe 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4241,15 +4241,15 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
gid_t runGid,
char **qmperr)
 {
-virQEMUCapsInitQMPCommandPtr cmd = NULL;
+qemuProcessQmpPtr cmd = NULL;
 int ret = -1;
 int rc;
 
-if (!(cmd = virQEMUCapsInitQMPCommandNew(qemuCaps->binary, libDir,
- runUid, runGid, qmperr)))
+if (!(cmd = qemuProcessQmpNew(qemuCaps->binary, libDir,
+  runUid, runGid, qmperr)))
 goto cleanup;
 
-if ((rc = virQEMUCapsInitQMPCommandRun(cmd, false)) != 0) {
+if ((rc = qemuProcessQmpRun(cmd, false)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
@@ -4259,8 +4259,8 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 goto cleanup;
 
 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
-virQEMUCapsInitQMPCommandAbort(cmd);
-if ((rc = virQEMUCapsInitQMPCommandRun(cmd, true)) != 0) {
+qemuProcessQmpAbort(cmd);
+if ((rc = qemuProcessQmpRun(cmd, true)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
@@ -4273,7 +4273,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 ret = 0;
 
  cleanup:
-virQEMUCapsInitQMPCommandFree(cmd);
+qemuProcessQmpFree(cmd);
 return ret;
 }
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 2cc52d3394..35e0c6172a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8108,12 +8108,12 @@ static qemuMonitorCallbacks callbacks = {
 
 
 void
-virQEMUCapsInitQMPCommandFree(virQEMUCapsInitQMPCommandPtr cmd)
+qemuProcessQmpFree(qemuProcessQmpPtr cmd)
 {
 if (!cmd)
 return;
 
-virQEMUCapsInitQMPCommandAbort(cmd);
+qemuProcessQmpAbort(cmd);
 VIR_FREE(cmd->binary);
 VIR_FREE(cmd->monpath);
 VIR_FREE(cmd->monarg);
@@ -8122,14 +8122,14 @@ 
virQEMUCapsInitQMPCommandFree(virQEMUCapsInitQMPCommandPtr cmd)
 }
 
 
-virQEMUCapsInitQMPCommandPtr
-virQEMUCapsInitQMPCommandNew(char *binary,
- const char *libDir,
- uid_t runUid,
- gid_t runGid,
- char **qmperr)
+qemuProcessQmpPtr
+qemuProcessQmpNew(char *binary,
+  const char *libDir,
+  uid_t runUid,
+  gid_t runGid,
+  char **qmperr)
 {
-virQEMUCapsInitQMPCommandPtr cmd = NULL;
+qemuProcessQmpPtr cmd = NULL;
 
 if (VIR_ALLOC(cmd) < 0)
 goto error;
@@ -8168,7 +8168,7 @@ virQEMUCapsInitQMPCommandNew(char *binary,
 return cmd;
 
  error:
-virQEMUCapsInitQMPCommandFree(cmd);
+qemuProcessQmpFree(cmd);
 return NULL;
 }
 
@@ -8178,8 +8178,8 @@ virQEMUCapsInitQMPCommandNew(char *binary,
  *  1 when probing QEMU failed
  */
 int
-virQEMUCapsInitQMPCommandRun(virQEMUCapsInitQMPCommandPtr cmd,
- bool forceTCG)
+qemuProcessQmpRun(qemuProcessQmpPtr cmd,
+  bool forceTCG)
 {
 virDomainXMLOptionPtr xmlopt = NULL;
 const char *machine;
@@ -8249,7 +8249,7 @@ virQEMUCapsInitQMPCommandRun(virQEMUCapsInitQMPCommandPtr 
cmd,
 
  cleanup:
 if (!cmd->mon)
-virQEMUCapsInitQMPCommandAbort(cmd);
+qemuProcessQmpAbort(cmd);
 virObjectUnref(xmlopt);
 
 return ret;
@@ -8261,7 +8261,7 @@ virQEMUCapsInitQMPCommandRun(virQEMUCapsInitQMPCommandPtr 
cmd,
 
 
 void
-virQEMUCapsInitQMPCommandAbort(virQEMUCapsInitQMPCommandPtr cmd)
+qemuProcessQmpAbort(qemuProcessQmpPtr cmd)
 {
 if (cmd->mon)
 virObjectUnlock(cmd->mon);
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 5e6f7c76ac..67ed90ad4d 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -214,9 +214,9 @@ int qemuProcessStartManagedPRDaemon(virDomainObjPtr vm);
 
 void qemuProcessKillManagedPRDaemon(virDomainObjPtr vm);
 
-typedef struct _virQEMUCapsInitQMPCommand virQEMUCapsInitQMPCommand;
-typedef virQEMUCapsInitQMPCommand *virQEMUCapsInitQMPCommandPtr;
-struct _virQEMUCapsInitQMPCommand {
+typedef struct _qemuProcessQmp qemuProcessQmp;
+typedef qemuProcessQmp *qemuProcessQmpPtr;
+struct _qemuProcessQmp {
 char *binary;
 uid_t runUid;
 gid_t runGid;
@@ -231,17 +231,17 @@ struct _virQEMUCapsInitQMPCommand {
 virDomainObjPtr vm;
 };
 
-virQEMUCapsInitQMPCommandPtr virQEMUCapsIni

[libvirt] [PATCH v5 07/36] qemu_process: Use qemuProcessQmp struct for a single process

2018-12-02 Thread Chris Venteicher
In new process code, move from model where qemuProcessQmp struct can be
used to activate a series of Qemu processes to model where one
qemuProcessQmp struct is used for one and only one Qemu process.

By allowing only one process activation per qemuProcessQmp struct, the
struct can safely store process outputs like status and stderr, without
being overwritten, until qemuProcessQmpFree is called.

By doing this, process outputs like status and stderr can remain stored
in the qemuProcessQmp struct without being overwritten by subsequent
process activations.

The forceTCG parameter (use / don't use KVM) will be passed when the
qemuProcessQmp struct is initialized since the qemuProcessQmp struct
won't be reused.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 20 
 src/qemu/qemu_process.c  | 10 ++
 src/qemu/qemu_process.h  |  7 ---
 3 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index a79329a134..bed9ca26a1 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4242,14 +4242,15 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
char **qmperr)
 {
 qemuProcessQmpPtr proc = NULL;
+qemuProcessQmpPtr procTCG = NULL;
 int ret = -1;
 int rc;
 
 if (!(proc = qemuProcessQmpNew(qemuCaps->binary, libDir,
-   runUid, runGid, qmperr)))
+   runUid, runGid, qmperr, false)))
 goto cleanup;
 
-if ((rc = qemuProcessQmpRun(proc, false)) != 0) {
+if ((rc = qemuProcessQmpRun(proc)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
@@ -4259,14 +4260,23 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 goto cleanup;
 
 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
+
+/* The second QEMU process probes for TCG capabilities
+ * in case the first process reported KVM as enabled
+ * (otherwise the first one already reported TCG capabilities). */
+
 qemuProcessQmpStop(proc);
-if ((rc = qemuProcessQmpRun(proc, true)) != 0) {
+
+procTCG = qemuProcessQmpNew(qemuCaps->binary, libDir,
+runUid, runGid, NULL, true);
+
+if ((rc = qemuProcessQmpRun(procTCG)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
 }
 
-if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, proc->mon) < 0)
+if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, procTCG->mon) < 0)
 goto cleanup;
 }
 
@@ -4274,7 +4284,9 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 
  cleanup:
 qemuProcessQmpStop(proc);
+qemuProcessQmpStop(procTCG);
 qemuProcessQmpFree(proc);
+qemuProcessQmpFree(procTCG);
 return ret;
 }
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index fa050a1a27..324151a7c3 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8127,7 +8127,8 @@ qemuProcessQmpNew(const char *binary,
   const char *libDir,
   uid_t runUid,
   gid_t runGid,
-  char **qmperr)
+  char **qmperr,
+  bool forceTCG)
 {
 qemuProcessQmpPtr proc = NULL;
 
@@ -8137,9 +8138,11 @@ qemuProcessQmpNew(const char *binary,
 if (VIR_STRDUP(proc->binary, binary) < 0)
 goto error;
 
+
 proc->runUid = runUid;
 proc->runGid = runGid;
 proc->qmperr = qmperr;
+proc->forceTCG = forceTCG;
 
 /* the ".sock" sufix is important to avoid a possible clash with a qemu
  * domain called "capabilities"
@@ -8178,15 +8181,14 @@ qemuProcessQmpNew(const char *binary,
  *  1 when probing QEMU failed
  */
 int
-qemuProcessQmpRun(qemuProcessQmpPtr proc,
-  bool forceTCG)
+qemuProcessQmpRun(qemuProcessQmpPtr proc)
 {
 virDomainXMLOptionPtr xmlopt = NULL;
 const char *machine;
 int status = 0;
 int ret = -1;
 
-if (forceTCG)
+if (proc->forceTCG)
 machine = "none,accel=tcg";
 else
 machine = "none,accel=kvm:tcg";
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 9a72db9a08..51598b402e 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -229,18 +229,19 @@ struct _qemuProcessQmp {
 virDomainChrSourceDef config;
 pid_t pid;
 virDomainObjPtr vm;
+bool forceTCG;
 };
 
 qemuProcessQmpPtr qemuProcessQmpNew(const char *binary,
 const char *libDir,
 uid_t runUid,
 gid_t runGid,
-char **qmperr);
+char **qmperr,
+bool forceTCG);
 
 void qemuProcessQmpFree(qemuProcessQmpPtr proc);
 
-in

[libvirt] [PATCH v5 04/36] qemu_process: Refer to proc not cmd in process code

2018-12-02 Thread Chris Venteicher
s/cmd/proc/ in process code imported from qemu_capabilities.

No functionality is changed.  Just variable renaming.

Process code imported from qemu_capabilities was oriented around
starting a process to issue a single QMP command.

Future usecases (ex. baseline, compare) expect to use a single process
to issue multiple different QMP commands.

This patch changes the variable naming from cmd to proc to put focus
on the process being maintained to issue commands.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c |  18 ++---
 src/qemu/qemu_process.c  | 138 +--
 src/qemu/qemu_process.h  |   4 +-
 3 files changed, 80 insertions(+), 80 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2f78fe27fe..41a0dfa844 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4241,39 +4241,39 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
gid_t runGid,
char **qmperr)
 {
-qemuProcessQmpPtr cmd = NULL;
+qemuProcessQmpPtr proc = NULL;
 int ret = -1;
 int rc;
 
-if (!(cmd = qemuProcessQmpNew(qemuCaps->binary, libDir,
-  runUid, runGid, qmperr)))
+if (!(proc = qemuProcessQmpNew(qemuCaps->binary, libDir,
+   runUid, runGid, qmperr)))
 goto cleanup;
 
-if ((rc = qemuProcessQmpRun(cmd, false)) != 0) {
+if ((rc = qemuProcessQmpRun(proc, false)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
 }
 
-if (virQEMUCapsInitQMPMonitor(qemuCaps, cmd->mon) < 0)
+if (virQEMUCapsInitQMPMonitor(qemuCaps, proc->mon) < 0)
 goto cleanup;
 
 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
-qemuProcessQmpAbort(cmd);
-if ((rc = qemuProcessQmpRun(cmd, true)) != 0) {
+qemuProcessQmpAbort(proc);
+if ((rc = qemuProcessQmpRun(proc, true)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
 }
 
-if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, cmd->mon) < 0)
+if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, proc->mon) < 0)
 goto cleanup;
 }
 
 ret = 0;
 
  cleanup:
-qemuProcessQmpFree(cmd);
+qemuProcessQmpFree(proc);
 return ret;
 }
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 46aed4fc9c..5f4853e0c4 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8108,17 +8108,17 @@ static qemuMonitorCallbacks callbacks = {
 
 
 void
-qemuProcessQmpFree(qemuProcessQmpPtr cmd)
+qemuProcessQmpFree(qemuProcessQmpPtr proc)
 {
-if (!cmd)
+if (!proc)
 return;
 
-qemuProcessQmpAbort(cmd);
-VIR_FREE(cmd->binary);
-VIR_FREE(cmd->monpath);
-VIR_FREE(cmd->monarg);
-VIR_FREE(cmd->pidfile);
-VIR_FREE(cmd);
+qemuProcessQmpAbort(proc);
+VIR_FREE(proc->binary);
+VIR_FREE(proc->monpath);
+VIR_FREE(proc->monarg);
+VIR_FREE(proc->pidfile);
+VIR_FREE(proc);
 }
 
 
@@ -8129,25 +8129,25 @@ qemuProcessQmpNew(const char *binary,
   gid_t runGid,
   char **qmperr)
 {
-qemuProcessQmpPtr cmd = NULL;
+qemuProcessQmpPtr proc = NULL;
 
-if (VIR_ALLOC(cmd) < 0)
+if (VIR_ALLOC(proc) < 0)
 goto error;
 
-if (VIR_STRDUP(cmd->binary, binary) < 0)
+if (VIR_STRDUP(proc->binary, binary) < 0)
 goto error;
 
-cmd->runUid = runUid;
-cmd->runGid = runGid;
-cmd->qmperr = qmperr;
+proc->runUid = runUid;
+proc->runGid = runGid;
+proc->qmperr = qmperr;
 
 /* the ".sock" sufix is important to avoid a possible clash with a qemu
  * domain called "capabilities"
  */
-if (virAsprintf(>monpath, "%s/%s", libDir,
+if (virAsprintf(>monpath, "%s/%s", libDir,
 "capabilities.monitor.sock") < 0)
 goto error;
-if (virAsprintf(>monarg, "unix:%s,server,nowait", cmd->monpath) < 0)
+if (virAsprintf(>monarg, "unix:%s,server,nowait", proc->monpath) < 0)
 goto error;
 
 /* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
@@ -8156,19 +8156,19 @@ qemuProcessQmpNew(const char *binary,
  * -daemonize we need QEMU to be allowed to create them, rather
  * than libvirtd. So we're using libDir which QEMU can write to
  */
-if (virAsprintf(>pidfile, "%s/%s", libDir, "capabilities.pidfile") < 
0)
+if (virAsprintf(>pidfile, "%s/%s", libDir, "capabilities.pidfile") < 
0)
 goto error;
 
-virPidFileForceCleanupPath(cmd->pidfile);
+virPidFileForceCleanupPath(proc->pidfile);
 
-cmd->config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
-cmd-&

[libvirt] [PATCH v5 01/36] qemu_process: Move process code from qemu_capabilities to qemu_process

2018-12-02 Thread Chris Venteicher
Qemu process code in qemu_capabilities.c is moved to qemu_process.c in
order to make the code usable outside the original capabilities
usecases.

The moved code activates and manages Qemu processes without
establishing a guest domain.

** This patch is a straight cut/paste move between files. **

(Exception: I did change a function prototype in qemu_process.h to be one
 parameter per line.)

Then, subsequent patches modify the process code
to make function prefixes and variable names match qemu_process,
and make the code usable for more than the capabilities usecase.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 218 +--
 src/qemu/qemu_process.c  | 199 
 src/qemu/qemu_process.h  |  30 +
 3 files changed, 230 insertions(+), 217 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 20a1a0c201..14b1ab5bec 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -47,6 +47,7 @@
 #define __QEMU_CAPSPRIV_H_ALLOW__
 #include "qemu_capspriv.h"
 #include "qemu_qapi.h"
+#include "qemu_process.h"
 
 #include 
 #include 
@@ -3939,18 +3940,6 @@ virQEMUCapsIsValid(void *data,
 }
 
 
-static void virQEMUCapsMonitorNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- void *opaque ATTRIBUTE_UNUSED)
-{
-}
-
-static qemuMonitorCallbacks callbacks = {
-.eofNotify = virQEMUCapsMonitorNotify,
-.errorNotify = virQEMUCapsMonitorNotify,
-};
-
-
 /**
  * virQEMUCapsInitQMPArch:
  * @qemuCaps: QEMU capabilities
@@ -4245,211 +4234,6 @@ virQEMUCapsInitQMPMonitorTCG(virQEMUCapsPtr qemuCaps 
ATTRIBUTE_UNUSED,
 }
 
 
-typedef struct _virQEMUCapsInitQMPCommand virQEMUCapsInitQMPCommand;
-typedef virQEMUCapsInitQMPCommand *virQEMUCapsInitQMPCommandPtr;
-struct _virQEMUCapsInitQMPCommand {
-char *binary;
-uid_t runUid;
-gid_t runGid;
-char **qmperr;
-char *monarg;
-char *monpath;
-char *pidfile;
-virCommandPtr cmd;
-qemuMonitorPtr mon;
-virDomainChrSourceDef config;
-pid_t pid;
-virDomainObjPtr vm;
-};
-
-
-static void
-virQEMUCapsInitQMPCommandAbort(virQEMUCapsInitQMPCommandPtr cmd)
-{
-if (cmd->mon)
-virObjectUnlock(cmd->mon);
-qemuMonitorClose(cmd->mon);
-cmd->mon = NULL;
-
-virCommandAbort(cmd->cmd);
-virCommandFree(cmd->cmd);
-cmd->cmd = NULL;
-
-if (cmd->monpath)
-unlink(cmd->monpath);
-
-virDomainObjEndAPI(>vm);
-
-if (cmd->pid != 0) {
-char ebuf[1024];
-
-VIR_DEBUG("Killing QMP caps process %lld", (long long)cmd->pid);
-if (virProcessKill(cmd->pid, SIGKILL) < 0 && errno != ESRCH)
-VIR_ERROR(_("Failed to kill process %lld: %s"),
-  (long long)cmd->pid,
-  virStrerror(errno, ebuf, sizeof(ebuf)));
-
-VIR_FREE(*cmd->qmperr);
-}
-if (cmd->pidfile)
-unlink(cmd->pidfile);
-cmd->pid = 0;
-}
-
-
-static void
-virQEMUCapsInitQMPCommandFree(virQEMUCapsInitQMPCommandPtr cmd)
-{
-if (!cmd)
-return;
-
-virQEMUCapsInitQMPCommandAbort(cmd);
-VIR_FREE(cmd->binary);
-VIR_FREE(cmd->monpath);
-VIR_FREE(cmd->monarg);
-VIR_FREE(cmd->pidfile);
-VIR_FREE(cmd);
-}
-
-
-static virQEMUCapsInitQMPCommandPtr
-virQEMUCapsInitQMPCommandNew(char *binary,
- const char *libDir,
- uid_t runUid,
- gid_t runGid,
- char **qmperr)
-{
-virQEMUCapsInitQMPCommandPtr cmd = NULL;
-
-if (VIR_ALLOC(cmd) < 0)
-goto error;
-
-if (VIR_STRDUP(cmd->binary, binary) < 0)
-goto error;
-
-cmd->runUid = runUid;
-cmd->runGid = runGid;
-cmd->qmperr = qmperr;
-
-/* the ".sock" sufix is important to avoid a possible clash with a qemu
- * domain called "capabilities"
- */
-if (virAsprintf(>monpath, "%s/%s", libDir,
-"capabilities.monitor.sock") < 0)
-goto error;
-if (virAsprintf(>monarg, "unix:%s,server,nowait", cmd->monpath) < 0)
-goto error;
-
-/* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
- * with a qemu domain called "capabilities"
- * Normally we'd use runDir for pid files, but because we're using
- * -daemonize we need QEMU to be allowed to create them, rather
- * than libvirtd. So we're using libDir which QEMU can write to
- */
-if (virAsprintf(>pidfile, "%s/%s", libDir, "capabilities.pidfile") < 
0)
-goto error;
-
-virPidFileForceCleanupPath(

[libvirt] [PATCH v5 05/36] qemu_process: Use consistent name for stop process function

2018-12-02 Thread Chris Venteicher
s/qemuProcessQmpAbort/qemuProcessQmpStop/ applied to change function name
used to stop QEMU processes in process code moved from qemu_capabilities.

No functionality change.

The new name, qemuProcessQmpStop, is consistent with the existing
function qemuProcessStop used to stop Domain processes.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 2 +-
 src/qemu/qemu_process.c  | 6 +++---
 src/qemu/qemu_process.h  | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 41a0dfa844..d903fbddf8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4259,7 +4259,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 goto cleanup;
 
 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
-qemuProcessQmpAbort(proc);
+qemuProcessQmpStop(proc);
 if ((rc = qemuProcessQmpRun(proc, true)) != 0) {
 if (rc == 1)
 ret = 0;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 5f4853e0c4..8465448a49 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8113,7 +8113,7 @@ qemuProcessQmpFree(qemuProcessQmpPtr proc)
 if (!proc)
 return;
 
-qemuProcessQmpAbort(proc);
+qemuProcessQmpStop(proc);
 VIR_FREE(proc->binary);
 VIR_FREE(proc->monpath);
 VIR_FREE(proc->monarg);
@@ -8249,7 +8249,7 @@ qemuProcessQmpRun(qemuProcessQmpPtr proc,
 
  cleanup:
 if (!proc->mon)
-qemuProcessQmpAbort(proc);
+qemuProcessQmpStop(proc);
 virObjectUnref(xmlopt);
 
 return ret;
@@ -8261,7 +8261,7 @@ qemuProcessQmpRun(qemuProcessQmpPtr proc,
 
 
 void
-qemuProcessQmpAbort(qemuProcessQmpPtr proc)
+qemuProcessQmpStop(qemuProcessQmpPtr proc)
 {
 if (proc->mon)
 virObjectUnlock(proc->mon);
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index dea5a84e8c..9a72db9a08 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -242,6 +242,6 @@ void qemuProcessQmpFree(qemuProcessQmpPtr proc);
 int qemuProcessQmpRun(qemuProcessQmpPtr cmd,
   bool forceTCG);
 
-void qemuProcessQmpAbort(qemuProcessQmpPtr proc);
+void qemuProcessQmpStop(qemuProcessQmpPtr proc);
 
 #endif /* __QEMU_PROCESS_H__ */
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v5 03/36] qemu_process: Limit qemuProcessQmpNew to const input strings

2018-12-02 Thread Chris Venteicher
Add the const qualifier on non modified strings
(string only copied inside qemuProcessQmpNew)
so that const strings can be used directly in calls to
qemuProcessQmpNew in future patches.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 2 +-
 src/qemu/qemu_process.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 35e0c6172a..46aed4fc9c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8123,7 +8123,7 @@ qemuProcessQmpFree(qemuProcessQmpPtr cmd)
 
 
 qemuProcessQmpPtr
-qemuProcessQmpNew(char *binary,
+qemuProcessQmpNew(const char *binary,
   const char *libDir,
   uid_t runUid,
   gid_t runGid,
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 67ed90ad4d..6d4fbda5fc 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -231,7 +231,7 @@ struct _qemuProcessQmp {
 virDomainObjPtr vm;
 };
 
-qemuProcessQmpPtr qemuProcessQmpNew(char *binary,
+qemuProcessQmpPtr qemuProcessQmpNew(const char *binary,
 const char *libDir,
 uid_t runUid,
 gid_t runGid,
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH RFC 00/22] Move process code to qemu_process

2018-11-14 Thread Chris Venteicher
Quoting Michal Privoznik (2018-11-14 09:45:06)
> On 11/11/2018 08:59 PM, Chris Venteicher wrote:
> > Make process code usable outside qemu_capabilities by moving code
> > from qemu_capabilities to qemu_process and exposing public functions.
> > 
> > The process code is used to activate a non domain QEMU process for QMP
> > message exchanges.
> > 
> > This patch set modifies capabilities to use the new public functions.
> > 
> > --
> > 
> > The process code is being decoupled from qemu_capabilities now to
> > support hypervisor baseline and comparison using QMP commands.
> > 
> > This patch set was originally submitted as part of the baseline patch set:
> >   [libvirt] [PATCH v4 00/37] BaselineHypervisorCPU using QEMU QMP exchanges
> >   https://www.redhat.com/archives/libvir-list/2018-November/msg00091.html
> 
> Okay, so you want to implement cpu-baseline for s390. But that doesn't
> really explain the code movement. Also, somehow the code movement makes
> the code bigger? I guess what I am saying is that I don't see much
> justification for these patches.
>

Here is the feedback from an earlier hypervisor baseline review that
resulted in this patch set.
https://www.redhat.com/archives/libvir-list/2018-July/msg00881.html

I think Jiri correctly identified capabilities, and now baseline and
comparison, are unrelated services that all independently need to start
a non-domain QEMU process for QMP messaging.

I am not sure, but it seems likely there could be other (S390...)
commands in the future that use QMP messages outside of a domain context
to get info or do work at the QEMU level.

All the baseline code I had in qemu_capabilities didn't make sense there
anymore once I moved the process code from qemu_capabilities to
qemu_process.

Here is the latest baseline patch set:
https://www.redhat.com/archives/libvir-list/2018-November/msg00091.html

In the latest baseline patch set, all the baseline code is in qemu_driver
and uses the process functions exposed now from qemu_process.

So as best I can tell there main choice is...

1) Leave process code in qemu_capabilities and make the 4 core
process functions (new, start, stop, free) and data strut public
so they can also be used by baseline and comparison from qemu_driver.

2) Move the process code from qemu_capabilities to qemu_process.
(this patch set) and expose the functions / data struct from
qemu_process.

In case 1 functions have the virQemuCaps prefix.
In case 2 functions have the qemuProcess prefix.

In either approach there are some changes needed to the process code to
decouple it from the capabilities code to support both capabilities and
baseline.

I did spend a few patches in this patch set breaking out the init,
process launch and monitor connection code into different static
functions in the style used elsewhere in qemu_process.  That could be
reversed if it doesn't add enough value if the decision is to move the
process code to qemu_process.

>
> >
> > The baseline and comparison requirements are described here:
> > https://bugzilla.redhat.com/show_bug.cgi?id=1511999
> > https://bugzilla.redhat.com/show_bug.cgi?id=1511996
> >
> >
> > I am extracting and resubmitting just the process changes as a stand
> > alone series to try to make review easier.
> >
> > The patch set shows capabilities using the public functions.
> > To see baseline using the public functions...
> > Look at the "qemu_driver:" patches at the end of
> > https://www.redhat.com/archives/libvir-list/2018-November/msg00091.html
> >
> > Also,
> > The "qemu_driver: Support feature expansion via QEMU when baselining cpu"
> > patch might be of particular interest because the same QEMU process is
> > used for both baseline and expansion using QMP commands.
> >
> > --
> >
> > Many patches were used to isolate code moves and name changes from other
> > actual implementation changes.
> >
> > The patches reuse the pattern of public qemuProcess{Start,Stop} functions
> > and internal static qemuProcess{Init,Launch,ConnectMonitor} functions
> > but adds a "Qmp" suffix to make them unique.
> >
> > A number of patches are about re-partitioning the code into static
> > functions for initialization, process launch and connection monitor
> > stuff.  This matches the established pattern in qemu_process and seemed
> > to make sense to do.
> >
> > For concurrency...
> > A thread safe library function creates a unique directory under libDir for 
> > each QEMU
> > process (for QMP messaging) to decouple processes in terms of sockets and
> > file system footprint.
> >
> > Every patch should compile independently if 

Re: [libvirt] [PATCH RFC 10/22] qemu_process: Introduce qemuProcessStartQmp

2018-11-14 Thread Chris Venteicher
Quoting Michal Privoznik (2018-11-14 09:45:07)
> On 11/11/2018 08:59 PM, Chris Venteicher wrote:
> > Move a step closer to the function structure used elsewhere in
> > qemu_process where qemuProcessStart and qemuProcessStop are the exposed
> > functions.
> > 
> > qemuProcessStartQmp mirrors qemuProcessStart in calling sub functions to
> > intialize, launch the process and connect the monitor to the QEMU
> > process.
> > 
> > static functions qemuProcessInitQmp, qemuProcessLaunchQmp and
> > qemuConnectMonitorQmp are also introduced.
> > 
> > qemuProcessLaunchQmp is just renamed from qemuProcessRun and
> > encapsulates all of the original code.
> > 
> > qemuProcessInitQmp and qemuProcessMonitorQmp are introduced as empty
> > wrappers into which subsequent patches will partition code from
> > qemuProcessLaunchQmp.
> > 
> > Signed-off-by: Chris Venteicher 
> > ---
> >  src/qemu/qemu_capabilities.c |  4 +-
> >  src/qemu/qemu_process.c  | 96 +++-
> >  src/qemu/qemu_process.h  |  2 +-
> >  3 files changed, 97 insertions(+), 5 deletions(-)
> > 
> > diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> > index fbb4336201..7168c470f6 100644
> > --- a/src/qemu/qemu_capabilities.c
> > +++ b/src/qemu/qemu_capabilities.c
> > @@ -4230,7 +4230,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
> >  goto cleanup;
> >  
> >  
> > -if (qemuProcessRun(proc) < 0)
> > +if (qemuProcessStartQmp(proc) < 0)
> >  goto cleanup;
> >  
> >  if (!(mon = QEMU_PROCESS_MONITOR(proc))) {
> > @@ -4249,7 +4249,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
> >  forceTCG = true;
> >  proc_kvm = qemuProcessNew(qemuCaps->binary, libDir, runUid, 
> > runGid, forceTCG);
> >  
> > -if (qemuProcessRun(proc_kvm) < 0)
> > +if (qemuProcessStartQmp(proc_kvm) < 0)
> >  goto cleanup;
> >  
> >  if (!(mon_kvm = QEMU_PROCESS_MONITOR(proc_kvm))) {
> > diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> > index 2640ec2b32..b6aa3a9af3 100644
> > --- a/src/qemu/qemu_process.c
> > +++ b/src/qemu/qemu_process.c
> > @@ -8148,8 +8148,29 @@ qemuProcessNew(const char *binary,
> >  }
> >  
> >  
> > -int
> > -qemuProcessRun(qemuProcessPtr proc){
> > +/* Initialize configuration and paths prior to starting QEMU
> > + */
> > +static int
> > +qemuProcessInitQmp(qemuProcessPtr proc)
> > +{
> > +int ret = -1;
> > +
> > +VIR_DEBUG("Beginning VM startup process"
> > +  "emulator=%s",
> > +  proc->binary);
> > +
> > +ret = 0;
> > +
> > +VIR_DEBUG("ret=%i", ret);
> > +return ret;
> > +}
> > +
> 
> I am sorry, but I'm failing to see the purpose of this function.
> 
> > +
> > +/* Launch QEMU Process
> > + */
> > +static int
> > +qemuProcessLaunchQmp(qemuProcessPtr proc)
> > +{
> >  virDomainXMLOptionPtr xmlopt = NULL;
> >  const char *machine;
> >  int status = 0;
> > @@ -8226,6 +8247,77 @@ qemuProcessRun(qemuProcessPtr proc){
> >  }
> >  
> >  
> > +/* Connect Monitor to QEMU Process
> > + */
> > +static int
> > +qemuConnectMonitorQmp(qemuProcessPtr proc)
> > +{
> > +int ret = -1;
> > +
> > +VIR_DEBUG("proc=%p, emulator=%s, proc->pid=%lld",
> > +  proc, NULLSTR(proc->binary), (long long) proc->pid);
> > +
> > +ret = 0;
> > +
> > +VIR_DEBUG("ret=%i", ret);
> > +return ret;
> > +}
> 
> Or this function. Looking into next patches I can see that you're
> extending them. Well, I still think it's not worth introducing empty
> functions, just do the rename as you're doing in next patches.

Yep, I was trying to make it easier to review but didn't explain well
enough from the start. Sorry I wasn't clear.

Patch 10 (this patch) and 12 are about making it possible to do simple
cut/paste moves on semi-complicated blocks of original code moved
within patches 11 and 13.

The goal was to make patches 11 and 13 easy to review because
I don't actually change the code.  It's just moved.

If this seems good with the better explanation I can just try to make
that clear in the commit message for patch 10 and 12.

If it's more confusing this way I can start out with qemuProcesStartQmp
only calling qemuProcessLaunchQmp and the add qemuProcessInitQmp and

Re: [libvirt] [PATCH v4 00/37] BaselineHypervisorCPU using QEMU QMP exchanges

2018-11-11 Thread Chris Venteicher
Quoting Collin Walling (2018-11-09 10:44:41)
> Hi Chris,
> 
> On 11/9/18 11:27 AM, Chris Venteicher wrote:
> > Quoting Chris Venteicher (2018-11-02 22:13:01)
> >> Some architectures (S390) depend on QEMU to compute baseline CPU model and
> >> expand a models feature set.
> >>
> >> Interacting with QEMU requires starting the QEMU process and completing 
> >> one or
> >> more query-cpu-model-baseline QMP exchanges with QEMU in addition to a
> >> query-cpu-model-expansion QMP exchange to expand all features in the model.
> >>
> >> See "s390x CPU models: exposing features" patch set on Qemu-devel for 
> >> discussion
> >> of QEMU aspects.
> >>
> >> This is part of resolution of: 
> >> https://bugzilla.redhat.com/show_bug.cgi?id=1511999
> >>
> >> Version 4 attempts to address all issues from V1,2,3 including making the
> >> QEMU process activation for QMP Queries generic (not specific to 
> >> capabilities)
> >> and moving that code from qemu_capabilities to qemu_process.
> >>
> >> Version 4 greatly expands the number of patches to make the set easier
> >> to review.
> >>
> >> The patches to do hypervisor baseline using QEMU are primarily in
> >> qemu_driver.c
> >>
> > Patches 1-2 create the cpumodel to/from Json conversion code.
> > Patches 3-4 modify the cpu expansion interface.
> > Patches 28-36 are the actual baseline changes.
> > 
> >> The patches to make the process code generic (not capabilities specific)
> >> are mostly in qemu_process.c
> > 
> > Patches 5 -> 27 move the process code from qemu_capabilities to
> > qemu_process.
> > 
> > A lot of these are code move or rename patches so the patches with real
> > implementation changes are easy to identify.
> > 
> > I might have ended up with too many patches though.
> > Want to mention... the whole "process" block could be moved to it's own
> > series if that would be easier to review.
> 
> I've been meaning to provide an in-depth review of these patches, but other 
> things
> have been holding me up -- my apologies.
> 
> At a quick glance, a lot of your patches involve a few short patches that 
> don't
> necessarily provide much context on their own. A lot of patches in this 
> series can
> definitely be merged.
> 
> I think moving the "qemu process" code into its own series would be helpful. 
> I would
> include something in the cover that they will benefit the hypervisor CPU 
> baseline and 
> comparison patches. If you feel confident with your qemu process patches, 
> then you 
> could also send your baseline patch series at the same time, and state that 
> your 
> baseline patches rely on your QEMU process patches (make sure to include a 
> mailing 
> list archive link in that header so reviewers can easily reference the other 
> patch 
> series).
> 
> Also, make sure you CC the authors and contributors of the respective files 
> that you
> touch. Most of them are listed at the top of the file. (I think Jiri might be 
> interested
> in this series as well.)
> 
> So let's start there. Repost your qemu_process code as it's own series, and 
> I'd recommend
> tagging it with "RFC" (Request For Comments) instead of giving it a version 
> number. This
> will prompt reviewers that you're mainly looking for areas of improvement and 
> some guidance.
> 
Thanks Collin,

The process stuff has been resubmitted in this patch series:
  [PATCH RFC 00/22] Move process code to qemu_process

The rest of this series can be resubmitted when the process changes are
solid.

> > 
> >> Many of the patches are cut / paste of existing code.  The patches that
> >> change functionality are as modular and minimal as possible to make
> >> reviewing easier.
> >>
> >> I attempted to make the new qemu_process functions
> >> consistent with the existing domain activation qemu_process functions.
> >>
> >> A thread safe library function creates a unique directory under libDir for 
> >> each QEMU
> >> process (for QMP messaging) to decouple processes in terms of sockets and
> >> file system footprint.
> >>
> >> The last patch is based on past discussion of QEMU cpu
> >> expansion only returning migratable features except for one x86 case where
> >> non-migratable features are explicitly requested.  The patch records that 
> >> features
> >> are migratable based on QEMU only returning migratable features.  The main 
> >> 

[libvirt] [PATCH RFC 20/22] qemu_process: Enter QMP command mode when starting QEMU Process

2018-11-11 Thread Chris Venteicher
qemuProcessStartQmp starts a QEMU process and monitor connection that
can be used by multiple functions possibly for multiple QMP commands.

The QMP exchange to exit capabilities negotiation mode and enter command mode
can only be performed once after the monitor connection is established.

Move responsibility for entering QMP command mode into the qemuProcess
code so multiple functions can issue QMP commands in arbitrary orders.

This also simplifies the functions using the connection provided by
qemuProcessStartQmp to issue QMP commands.

Test code now needs to call qemuMonitorSetCapabilities to send the
message to switch to command mode because the test code does not use the
qemuProcess command that internally calls qemuMonitorSetCapabilities.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 14 --
 src/qemu/qemu_process.c  |  8 
 tests/qemucapabilitiestest.c |  7 +++
 3 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 7168c470f6..f06d0a4428 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4013,13 +4013,6 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
 
 /* @mon is supposed to be locked by callee */
 
-if (qemuMonitorSetCapabilities(mon) < 0) {
-VIR_DEBUG("Failed to set monitor capabilities %s",
-  virGetLastErrorMessage());
-ret = 0;
-goto cleanup;
-}
-
 if (qemuMonitorGetVersion(mon,
   , , ,
   ) < 0) {
@@ -4193,13 +4186,6 @@ virQEMUCapsInitQMPMonitorTCG(virQEMUCapsPtr qemuCaps 
ATTRIBUTE_UNUSED,
 {
 int ret = -1;
 
-if (qemuMonitorSetCapabilities(mon) < 0) {
-VIR_DEBUG("Failed to set monitor capabilities %s",
-  virGetLastErrorMessage());
-ret = 0;
-goto cleanup;
-}
-
 if (virQEMUCapsProbeQMPCPUDefinitions(qemuCaps, mon, true) < 0)
 goto cleanup;
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index d20f832053..eba2cd6765 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8298,6 +8298,14 @@ qemuConnectMonitorQmp(qemuProcessPtr proc)
 
 virObjectLock(proc->mon);
 
+/* Exit capabilities negotiation mode and enter QEMU command mode
+ * by issuing qmp_capabilities command to QEMU */
+if (qemuMonitorSetCapabilities(proc->mon) < 0) {
+VIR_DEBUG("Failed to set monitor capabilities %s",
+  virGetLastErrorMessage());
+goto ignore;
+}
+
  ignore:
 ret = 0;
 
diff --git a/tests/qemucapabilitiestest.c b/tests/qemucapabilitiestest.c
index 8fe5a55e1d..ea4671739b 100644
--- a/tests/qemucapabilitiestest.c
+++ b/tests/qemucapabilitiestest.c
@@ -58,6 +58,9 @@ testQemuCaps(const void *opaque)
 if (!(mon = qemuMonitorTestNewFromFileFull(repliesFile, >driver, 
NULL)))
 goto cleanup;
 
+if (qemuMonitorSetCapabilities(qemuMonitorTestGetMonitor(mon)) < 0)
+goto cleanup;
+
 if (!(capsActual = virQEMUCapsNew()) ||
 virQEMUCapsInitQMPMonitor(capsActual,
   qemuMonitorTestGetMonitor(mon)) < 0)
@@ -65,6 +68,10 @@ testQemuCaps(const void *opaque)
 
 if (virQEMUCapsGet(capsActual, QEMU_CAPS_KVM)) {
 qemuMonitorResetCommandID(qemuMonitorTestGetMonitor(mon));
+
+if (qemuMonitorSetCapabilities(qemuMonitorTestGetMonitor(mon)) < 0)
+goto cleanup;
+
 if (virQEMUCapsInitQMPMonitorTCG(capsActual,
  qemuMonitorTestGetMonitor(mon)) < 0)
 goto cleanup;
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 16/22] qemu_process: Cleanup qemuProcess alloc function

2018-11-11 Thread Chris Venteicher
qemuProcessNew is one of the 4 public functions used to create and
manage a qemu process for QMP command exchanges outside of domain
operations.

Add descriptive comment block, Debug statement and make source
consistent with the cleanup / VIR_STEAL_PTR format used elsewhere.

No functional changes are made.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 26 +-
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 55a092ecbb..5ff7d6878c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8097,6 +8097,18 @@ qemuProcessFree(qemuProcessPtr proc)
 }
 
 
+/**
+ * qemuProcessNew:
+ * @binary: Qemu binary
+ * @libDir: Directory for process and connection artifacts
+ * @runUid: UserId for Qemu Process
+ * @runGid: GroupId for Qemu Process
+ * @forceTCG: Force TCG mode if true
+ *
+ * Allocate and initialize domain structure encapsulating
+ * QEMU Process state and monitor connection to QEMU
+ * for completing QMP Queries.
+ */
 qemuProcessPtr
 qemuProcessNew(const char *binary,
const char *libDir,
@@ -8104,25 +8116,29 @@ qemuProcessNew(const char *binary,
gid_t runGid,
bool forceTCG)
 {
+qemuProcessPtr ret = NULL;
 qemuProcessPtr proc = NULL;
 
+VIR_DEBUG("exec=%s, libDir=%s, runUid=%u, runGid=%u, forceTCG=%d",
+  NULLSTR(binary), NULLSTR(libDir), runUid, runGid, forceTCG);
+
 if (VIR_ALLOC(proc) < 0)
-goto error;
+goto cleanup;
 
 if (VIR_STRDUP(proc->binary, binary) < 0 ||
 VIR_STRDUP(proc->libDir, libDir) < 0)
-goto error;
+goto cleanup;
 
 proc->forceTCG = forceTCG;
 
 proc->runUid = runUid;
 proc->runGid = runGid;
 
-return proc;
+VIR_STEAL_PTR(ret, proc);
 
- error:
+ cleanup:
 qemuProcessFree(proc);
-return NULL;
+return ret;
 }
 
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 14/22] qemu_process: Stop retaining Qemu Monitor config in qemuProcess

2018-11-11 Thread Chris Venteicher
The monitor config data is removed from the qemuProcess struct.

The monitor config data can be initialized immediately before call to
qemuMonitorOpen and does not need to be maintained after the call
because qemuMonitorOpen copies any strings it needs.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 9 +
 src/qemu/qemu_process.h | 1 -
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 8e98b97443..d4ed2d6353 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8237,13 +8237,14 @@ qemuConnectMonitorQmp(qemuProcessPtr proc)
 {
 int ret = -1;
 virDomainXMLOptionPtr xmlopt = NULL;
+virDomainChrSourceDef monConfig;
 
 VIR_DEBUG("proc=%p, emulator=%s, proc->pid=%lld",
   proc, NULLSTR(proc->binary), (long long) proc->pid);
 
-proc->config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
-proc->config.data.nix.path = proc->monpath;
-proc->config.data.nix.listen = false;
+monConfig.type = VIR_DOMAIN_CHR_TYPE_UNIX;
+monConfig.data.nix.path = proc->monpath;
+monConfig.data.nix.listen = false;
 
 if (!(xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL, NULL, NULL)) ||
 !(proc->vm = virDomainObjNew(xmlopt)))
@@ -8251,7 +8252,7 @@ qemuConnectMonitorQmp(qemuProcessPtr proc)
 
 proc->vm->pid = proc->pid;
 
-if (!(proc->mon = qemuMonitorOpen(proc->vm, >config, true, true,
+if (!(proc->mon = qemuMonitorOpen(proc->vm, , true, true,
   0, , NULL)))
 goto ignore;
 
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 1b8f743861..d1541d5407 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -227,7 +227,6 @@ struct _qemuProcess {
 char *pidfile;
 virCommandPtr cmd;
 qemuMonitorPtr mon;
-virDomainChrSourceDef config;
 pid_t pid;
 virDomainObjPtr vm;
 bool forceTCG;
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 22/22] qemu_process: Stop locking QMP process monitor immediately

2018-11-11 Thread Chris Venteicher
Locking the monitor object immediately after call to qemuMonitorOpen
doesn't make sense now that we have expanded the QEMU process code to
cover more than the original capabilities usecase.

Removing the monitor lock makes the qemuConnectMonitorQmp code
consistent with the qemuConnectMonitor code used to establish the
monitor when QEMU process is started for domains.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 4dbc7038fd..2f9c1701a3 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8297,8 +8297,6 @@ qemuConnectMonitorQmp(qemuProcessPtr proc)
 
 VIR_STEAL_PTR(proc->mon, mon);
 
-virObjectLock(proc->mon);
-
 /* Exit capabilities negotiation mode and enter QEMU command mode
  * by issuing qmp_capabilities command to QEMU */
 if (qemuMonitorSetCapabilities(proc->mon) < 0) {
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 19/22] qemu_monitor: Make monitor callbacks optional

2018-11-11 Thread Chris Venteicher
Qemu process code for capababilities doesn't use monitor callbacks and
defines empty callback functions.

Allow NULL to be passed to qemuMonitorOpen for callbacks and remove the
empty functions from the QMP process code.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_monitor.c |  4 ++--
 src/qemu/qemu_process.c | 14 +-
 2 files changed, 3 insertions(+), 15 deletions(-)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 7f7013e115..77f4fe7cf7 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -813,12 +813,12 @@ qemuMonitorOpenInternal(virDomainObjPtr vm,
 {
 qemuMonitorPtr mon;
 
-if (!cb->eofNotify) {
+if (cb && !cb->eofNotify) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("EOF notify callback must be supplied"));
 return NULL;
 }
-if (!cb->errorNotify) {
+if (cb && !cb->errorNotify) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Error notify callback must be supplied"));
 return NULL;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index c44e46fc88..d20f832053 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8066,18 +8066,6 @@ qemuProcessReconnectAll(virQEMUDriverPtr driver)
 }
 
 
-static void virQEMUCapsMonitorNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- void *opaque ATTRIBUTE_UNUSED)
-{
-}
-
-static qemuMonitorCallbacks callbacks = {
-.eofNotify = virQEMUCapsMonitorNotify,
-.errorNotify = virQEMUCapsMonitorNotify,
-};
-
-
 /**
  * qemuProcessFree:
  * @proc: Stores Process and Connection State
@@ -8270,7 +8258,7 @@ qemuConnectMonitorQmp(qemuProcessPtr proc)
 bool retry = true;
 bool enableJson = true;
 virQEMUDriverPtr driver = NULL;
-qemuMonitorCallbacksPtr monCallbacks = 
+qemuMonitorCallbacksPtr monCallbacks = NULL;
 virDomainXMLOptionPtr xmlopt = NULL;
 virDomainChrSourceDef monConfig;
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 21/22] qemu_process: Use unique directories for QMP processes

2018-11-11 Thread Chris Venteicher
Multiple QEMU processes for QMP commands can operate concurrently.

Use a unique directory under libDir for each QEMU processes
to avoid pidfile and unix socket collision between processes.

The pid file name is changed from "capabilities.pidfile" to "qmp.pid"
because we no longer need to avoid a possible clash with a qemu domain
called "capabilities" now that the processes artifacts are stored in
their own unique temporary directories.

"Capabilities" was changed to "qmp" in the pid file name because these
processes are no longer specific to the capabilities usecase and are
more generic in terms of being used for any general purpose QMP message
exchanges with a QEMU process that is not associated with a domain.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 26 --
 src/qemu/qemu_process.h |  1 +
 2 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index eba2cd6765..4dbc7038fd 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8090,6 +8090,7 @@ qemuProcessFree(qemuProcessPtr proc)
 
 VIR_FREE(proc->binary);
 VIR_FREE(proc->libDir);
+VIR_FREE(proc->uniqDir);
 VIR_FREE(proc->monpath);
 VIR_FREE(proc->monarg);
 VIR_FREE(proc->pidfile);
@@ -8148,33 +8149,33 @@ qemuProcessNew(const char *binary,
 static int
 qemuProcessInitQmp(qemuProcessPtr proc)
 {
+char *template = NULL;
 int ret = -1;
 
 VIR_DEBUG("Beginning VM startup process"
   "emulator=%s",
   proc->binary);
 
-/* the ".sock" sufix is important to avoid a possible clash with a qemu
- * domain called "capabilities"
- */
-if (virAsprintf(>monpath, "%s/%s", proc->libDir,
-"capabilities.monitor.sock") < 0)
+if (virAsprintf(, "%s/qemu.XX", proc->libDir) < 0)
+goto cleanup;
+
+proc->uniqDir = mkdtemp(template);
+
+if (virAsprintf(>monpath, "%s/%s", proc->uniqDir,
+"qmp.monitor") < 0)
 goto cleanup;
 
 if (virAsprintf(>monarg, "unix:%s,server,nowait", proc->monpath) < 0)
 goto cleanup;
 
-/* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
- * with a qemu domain called "capabilities"
+/*
  * Normally we'd use runDir for pid files, but because we're using
  * -daemonize we need QEMU to be allowed to create them, rather
  * than libvirtd. So we're using libDir which QEMU can write to
  */
-if (virAsprintf(>pidfile, "%s/%s", proc->libDir, 
"capabilities.pidfile") < 0)
+if (virAsprintf(>pidfile, "%s/%s", proc->uniqDir, "qmp.pid") < 0)
 goto cleanup;
 
-virPidFileForceCleanupPath(proc->pidfile);
-
 ret = 0;
 
  cleanup:
@@ -8415,4 +8416,9 @@ void qemuProcessStopQmp(qemuProcessPtr proc)
 unlink(proc->pidfile);
 
 proc->pid = 0;
+
+
+if (proc->uniqDir)
+rmdir(proc->uniqDir);
+
 }
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index d1541d5407..f66fc0c82c 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -225,6 +225,7 @@ struct _qemuProcess {
 char *monarg;
 char *monpath;
 char *pidfile;
+char *uniqDir;
 virCommandPtr cmd;
 qemuMonitorPtr mon;
 pid_t pid;
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 07/22] qemu_process: Use qemuProcess struct for a single process

2018-11-11 Thread Chris Venteicher
In new process code, move from model where qemuProcess struct can be
used to activate a series of Qemu processes to model where one
qemuProcess struct is used for one and only one Qemu process.

The forceTCG parameter (use / don't use KVM) will be passed when the
qemuProcess struct is initialized since the qemuProcess struct won't be
reused.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 16 
 src/qemu/qemu_process.c  | 11 +++
 src/qemu/qemu_process.h  |  6 --
 3 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 082874082b..a957c3bdbd 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4220,14 +4220,16 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
char **qmperr)
 {
 qemuProcessPtr proc = NULL;
+qemuProcessPtr proc_kvm = NULL;
 int ret = -1;
 int rc;
+bool forceTCG = false;
 
 if (!(proc = qemuProcessNew(qemuCaps->binary, libDir,
-runUid, runGid, qmperr)))
+runUid, runGid, qmperr, forceTCG)))
 goto cleanup;
 
-if ((rc = qemuProcessRun(proc, false)) != 0) {
+if ((rc = qemuProcessRun(proc)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
@@ -4238,13 +4240,17 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 
 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
 qemuProcessStopQmp(proc);
-if ((rc = qemuProcessRun(proc, true)) != 0) {
+
+forceTCG = true;
+proc_kvm = qemuProcessNew(qemuCaps->binary, libDir, runUid, runGid, 
NULL, forceTCG);
+
+if ((rc = qemuProcessRun(proc_kvm)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
 }
 
-if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, proc->mon) < 0)
+if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, proc_kvm->mon) < 0)
 goto cleanup;
 }
 
@@ -4252,7 +4258,9 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 
  cleanup:
 qemuProcessStopQmp(proc);
+qemuProcessStopQmp(proc_kvm);
 qemuProcessFree(proc);
+qemuProcessFree(proc_kvm);
 return ret;
 }
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 2571024e8e..dda74d5b7a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8100,7 +8100,8 @@ qemuProcessNew(const char *binary,
const char *libDir,
uid_t runUid,
gid_t runGid,
-   char **qmperr)
+   char **qmperr,
+   bool forceTCG)
 {
 qemuProcessPtr proc = NULL;
 
@@ -8110,10 +8111,13 @@ qemuProcessNew(const char *binary,
 if (VIR_STRDUP(proc->binary, binary) < 0)
 goto error;
 
+proc->forceTCG = forceTCG;
+
 proc->runUid = runUid;
 proc->runGid = runGid;
 proc->qmperr = qmperr;
 
+
 /* the ".sock" sufix is important to avoid a possible clash with a qemu
  * domain called "capabilities"
  */
@@ -8151,15 +8155,14 @@ qemuProcessNew(const char *binary,
  *  1 when probing QEMU failed
  */
 int
-qemuProcessRun(qemuProcessPtr proc,
-   bool forceTCG)
+qemuProcessRun(qemuProcessPtr proc)
 {
 virDomainXMLOptionPtr xmlopt = NULL;
 const char *machine;
 int status = 0;
 int ret = -1;
 
-if (forceTCG)
+if (proc->forceTCG)
 machine = "none,accel=tcg";
 else
 machine = "none,accel=kvm:tcg";
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 25343c4592..ab2640ce7c 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -229,17 +229,19 @@ struct _qemuProcess {
 virDomainChrSourceDef config;
 pid_t pid;
 virDomainObjPtr vm;
+bool forceTCG;
 };
 
 qemuProcessPtr qemuProcessNew(const char *binary,
   const char *libDir,
   uid_t runUid,
   gid_t runGid,
-  char **qmperr);
+  char **qmperr,
+  bool forceTCG);
 
 void qemuProcessFree(qemuProcessPtr proc);
 
-int qemuProcessRun(qemuProcessPtr proc, bool forceTCG);
+int qemuProcessRun(qemuProcessPtr proc);
 
 void qemuProcessStopQmp(qemuProcessPtr proc);
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 13/22] qemu_process: Setup paths within qemuProcessInitQmp

2018-11-11 Thread Chris Venteicher
Move code for setting paths and prepping file system from qemuProcessNew
to qemuProcessInitQmp.

This keeps qemuProcessNew limited to structure initialization and most
closely mirrors pattern established in qemuProcessInit within
qemuProcessInitQmp.

The patch is a non-functional, cut / paste change,
however goto is now "cleanup" rather than "error".

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 42 +
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 0b96debf25..8e98b97443 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8118,26 +8118,6 @@ qemuProcessNew(const char *binary,
 proc->runUid = runUid;
 proc->runGid = runGid;
 
-/* the ".sock" sufix is important to avoid a possible clash with a qemu
- * domain called "capabilities"
- */
-if (virAsprintf(>monpath, "%s/%s", proc->libDir,
-"capabilities.monitor.sock") < 0)
-goto error;
-if (virAsprintf(>monarg, "unix:%s,server,nowait", proc->monpath) < 0)
-goto error;
-
-/* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
- * with a qemu domain called "capabilities"
- * Normally we'd use runDir for pid files, but because we're using
- * -daemonize we need QEMU to be allowed to create them, rather
- * than libvirtd. So we're using libDir which QEMU can write to
- */
-if (virAsprintf(>pidfile, "%s/%s", proc->libDir, 
"capabilities.pidfile") < 0)
-goto error;
-
-virPidFileForceCleanupPath(proc->pidfile);
-
 return proc;
 
  error:
@@ -8157,8 +8137,30 @@ qemuProcessInitQmp(qemuProcessPtr proc)
   "emulator=%s",
   proc->binary);
 
+/* the ".sock" sufix is important to avoid a possible clash with a qemu
+ * domain called "capabilities"
+ */
+if (virAsprintf(>monpath, "%s/%s", proc->libDir,
+"capabilities.monitor.sock") < 0)
+goto cleanup;
+
+if (virAsprintf(>monarg, "unix:%s,server,nowait", proc->monpath) < 0)
+goto cleanup;
+
+/* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
+ * with a qemu domain called "capabilities"
+ * Normally we'd use runDir for pid files, but because we're using
+ * -daemonize we need QEMU to be allowed to create them, rather
+ * than libvirtd. So we're using libDir which QEMU can write to
+ */
+if (virAsprintf(>pidfile, "%s/%s", proc->libDir, 
"capabilities.pidfile") < 0)
+goto cleanup;
+
+virPidFileForceCleanupPath(proc->pidfile);
+
 ret = 0;
 
+ cleanup:
 VIR_DEBUG("ret=%i", ret);
 return ret;
 }
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 12/22] qemu_process: Store libDir in qemuProcess struct

2018-11-11 Thread Chris Venteicher
Store libDir path in the qemuProcess struct in anticipation of moving
path construction code into qemuProcessInitQmp function.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 8 +---
 src/qemu/qemu_process.h | 1 +
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index fe4361ed5d..0b96debf25 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8088,6 +8088,7 @@ qemuProcessFree(qemuProcessPtr proc)
 
 qemuProcessStopQmp(proc);
 VIR_FREE(proc->binary);
+VIR_FREE(proc->libDir);
 VIR_FREE(proc->monpath);
 VIR_FREE(proc->monarg);
 VIR_FREE(proc->pidfile);
@@ -8108,7 +8109,8 @@ qemuProcessNew(const char *binary,
 if (VIR_ALLOC(proc) < 0)
 goto error;
 
-if (VIR_STRDUP(proc->binary, binary) < 0)
+if (VIR_STRDUP(proc->binary, binary) < 0 ||
+VIR_STRDUP(proc->libDir, libDir) < 0)
 goto error;
 
 proc->forceTCG = forceTCG;
@@ -8119,7 +8121,7 @@ qemuProcessNew(const char *binary,
 /* the ".sock" sufix is important to avoid a possible clash with a qemu
  * domain called "capabilities"
  */
-if (virAsprintf(>monpath, "%s/%s", libDir,
+if (virAsprintf(>monpath, "%s/%s", proc->libDir,
 "capabilities.monitor.sock") < 0)
 goto error;
 if (virAsprintf(>monarg, "unix:%s,server,nowait", proc->monpath) < 0)
@@ -8131,7 +8133,7 @@ qemuProcessNew(const char *binary,
  * -daemonize we need QEMU to be allowed to create them, rather
  * than libvirtd. So we're using libDir which QEMU can write to
  */
-if (virAsprintf(>pidfile, "%s/%s", libDir, "capabilities.pidfile") < 
0)
+if (virAsprintf(>pidfile, "%s/%s", proc->libDir, 
"capabilities.pidfile") < 0)
 goto error;
 
 virPidFileForceCleanupPath(proc->pidfile);
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index c34ca52ef5..1b8f743861 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -218,6 +218,7 @@ typedef struct _qemuProcess qemuProcess;
 typedef qemuProcess *qemuProcessPtr;
 struct _qemuProcess {
 char *binary;
+char *libDir;
 uid_t runUid;
 gid_t runGid;
 char *qmperr;  /* qemu process stderr */
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 08/22] qemu_process: Persist stderr in qemuProcess struct

2018-11-11 Thread Chris Venteicher
A qemuProcess struct tracks the entire lifespan of a single QEMU Process
including storing error output when the process terminates or activation
fails.

Error output remains available until qemuProcessFree is called.

The qmperr buffer no longer needs to be maintained outside of the
qemuProcess structure because the structure is used for a single QEMU
process and the structures can be maintained as long as required
to retrieve the process error info.

Capabilities init code is refactored but continues to report QEMU
process error data only when the initial (non KVM) QEMU process activation
fails to result in a usable monitor connection for retrieving
capabilities.

The VIR_ERR_INTERNAL_ERROR "Failed to probe QEMU binary" reporting is
moved into virQEMUCapsInitQMP function and the stderr string is
extracted from the qemuProcess struct using a macro to retrieve the
string.

The same error and log message should be generated, in the same
conditions, after this patch as before.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 27 ---
 src/qemu/qemu_process.c  | 12 
 src/qemu/qemu_process.h  |  6 --
 3 files changed, 20 insertions(+), 25 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index a957c3bdbd..f5e327097e 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4216,8 +4216,7 @@ static int
 virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
const char *libDir,
uid_t runUid,
-   gid_t runGid,
-   char **qmperr)
+   gid_t runGid)
 {
 qemuProcessPtr proc = NULL;
 qemuProcessPtr proc_kvm = NULL;
@@ -4226,7 +4225,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 bool forceTCG = false;
 
 if (!(proc = qemuProcessNew(qemuCaps->binary, libDir,
-runUid, runGid, qmperr, forceTCG)))
+runUid, runGid, forceTCG)))
 goto cleanup;
 
 if ((rc = qemuProcessRun(proc)) != 0) {
@@ -4242,7 +4241,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 qemuProcessStopQmp(proc);
 
 forceTCG = true;
-proc_kvm = qemuProcessNew(qemuCaps->binary, libDir, runUid, runGid, 
NULL, forceTCG);
+proc_kvm = qemuProcessNew(qemuCaps->binary, libDir, runUid, runGid, 
forceTCG);
 
 if ((rc = qemuProcessRun(proc_kvm)) != 0) {
 if (rc == 1)
@@ -4257,6 +4256,13 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 ret = 0;
 
  cleanup:
+if (proc && !proc->mon) {
+char *err = QEMU_PROCESS_ERROR(proc) ? QEMU_PROCESS_ERROR(proc) : 
_("unknown error");
+
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Failed to probe QEMU binary with QMP: %s"), err);
+}
+
 qemuProcessStopQmp(proc);
 qemuProcessStopQmp(proc_kvm);
 qemuProcessFree(proc);
@@ -4296,7 +4302,6 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
 {
 virQEMUCapsPtr qemuCaps;
 struct stat sb;
-char *qmperr = NULL;
 
 if (!(qemuCaps = virQEMUCapsNew()))
 goto error;
@@ -4323,15 +4328,8 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
 goto error;
 }
 
-if (virQEMUCapsInitQMP(qemuCaps, libDir, runUid, runGid, ) < 0) {
-virQEMUCapsLogProbeFailure(binary);
-goto error;
-}
-
-if (!qemuCaps->usedQMP) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("Failed to probe QEMU binary with QMP: %s"),
-   qmperr ? qmperr : _("unknown error"));
+if (virQEMUCapsInitQMP(qemuCaps, libDir, runUid, runGid) < 0 ||
+!qemuCaps->usedQMP) {
 virQEMUCapsLogProbeFailure(binary);
 goto error;
 }
@@ -4350,7 +4348,6 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
 }
 
  cleanup:
-VIR_FREE(qmperr);
 return qemuCaps;
 
  error:
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index dda74d5b7a..a741d1cf91 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8091,6 +8091,7 @@ qemuProcessFree(qemuProcessPtr proc)
 VIR_FREE(proc->monpath);
 VIR_FREE(proc->monarg);
 VIR_FREE(proc->pidfile);
+VIR_FREE(proc->qmperr);
 VIR_FREE(proc);
 }
 
@@ -8100,7 +8101,6 @@ qemuProcessNew(const char *binary,
const char *libDir,
uid_t runUid,
gid_t runGid,
-   char **qmperr,
bool forceTCG)
 {
 qemuProcessPtr proc = NULL;
@@ -8115,8 +8115,6 @@ qemuProcessNew(const char *binary,
 
 proc->runUid = runUid;
 proc->runGid = runGid;
-proc->qmperr = qmperr;
-
 
 /* the ".sock" sufix is important to avoid a possible clash with a qemu
  * domain called "capabilities"
@@ -8155,8 +8153,7 @@ qemuProcessNew(const char *binary,
  

[libvirt] [PATCH RFC 03/22] qemu_process: Limit qemuProcessNew to const input strings

2018-11-11 Thread Chris Venteicher
Prevent compile errors due to trying to use a const string as a
non-const input to qemuProcessNew.

No functionality change.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 2 +-
 src/qemu/qemu_process.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index dff0482856..2f9726d463 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8096,7 +8096,7 @@ qemuProcessFree(qemuProcessPtr cmd)
 
 
 qemuProcessPtr
-qemuProcessNew(char *binary,
+qemuProcessNew(const char *binary,
const char *libDir,
uid_t runUid,
gid_t runGid,
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 5417cb416f..39a2368ce5 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -231,7 +231,7 @@ struct _qemuProcess {
 virDomainObjPtr vm;
 };
 
-qemuProcessPtr qemuProcessNew(char *binary,
+qemuProcessPtr qemuProcessNew(const char *binary,
   const char *libDir,
   uid_t runUid,
   gid_t runGid,
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 04/22] qemu_process: Refer to proc not cmd in process code

2018-11-11 Thread Chris Venteicher
s/cmd/proc/ in process code imported from qemu_capabilities.

No functionality is changed.  Just variable renaming.

Process code imported from qemu_capabilities was oriented around
starting a process to issue a single QMP command.

Future usecases (ex. baseline, compare) expect to use a single process
to issue multiple different QMP commands.

This patch changes the variable naming from cmd to proc to put focus
on the process being maintained to issue commands.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c |  14 ++--
 src/qemu/qemu_process.c  | 140 +--
 src/qemu/qemu_process.h  |   6 +-
 3 files changed, 80 insertions(+), 80 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index f6d97648ce..1ea63000e2 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4219,7 +4219,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
gid_t runGid,
char **qmperr)
 {
-qemuProcessPtr cmd = NULL;
+qemuProcessPtr proc = NULL;
 int ret = -1;
 int rc;
 
@@ -4227,31 +4227,31 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 runUid, runGid, qmperr)))
 goto cleanup;
 
-if ((rc = qemuProcessRun(cmd, false)) != 0) {
+if ((rc = qemuProcessRun(proc, false)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
 }
 
-if (virQEMUCapsInitQMPMonitor(qemuCaps, cmd->mon) < 0)
+if (virQEMUCapsInitQMPMonitor(qemuCaps, proc->mon) < 0)
 goto cleanup;
 
 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
-qemuProcessAbort(cmd);
-if ((rc = qemuProcessRun(cmd, true)) != 0) {
+qemuProcessAbort(proc);
+if ((rc = qemuProcessRun(proc, true)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
 }
 
-if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, cmd->mon) < 0)
+if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, proc->mon) < 0)
 goto cleanup;
 }
 
 ret = 0;
 
  cleanup:
-qemuProcessFree(cmd);
+qemuProcessFree(proc);
 return ret;
 }
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 2f9726d463..e949547124 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8081,17 +8081,17 @@ static qemuMonitorCallbacks callbacks = {
 
 
 void
-qemuProcessFree(qemuProcessPtr cmd)
+qemuProcessFree(qemuProcessPtr proc)
 {
-if (!cmd)
+if (!proc)
 return;
 
-qemuProcessAbort(cmd);
-VIR_FREE(cmd->binary);
-VIR_FREE(cmd->monpath);
-VIR_FREE(cmd->monarg);
-VIR_FREE(cmd->pidfile);
-VIR_FREE(cmd);
+qemuProcessAbort(proc);
+VIR_FREE(proc->binary);
+VIR_FREE(proc->monpath);
+VIR_FREE(proc->monarg);
+VIR_FREE(proc->pidfile);
+VIR_FREE(proc);
 }
 
 
@@ -8102,25 +8102,25 @@ qemuProcessNew(const char *binary,
gid_t runGid,
char **qmperr)
 {
-qemuProcessPtr cmd = NULL;
+qemuProcessPtr proc = NULL;
 
-if (VIR_ALLOC(cmd) < 0)
+if (VIR_ALLOC(proc) < 0)
 goto error;
 
-if (VIR_STRDUP(cmd->binary, binary) < 0)
+if (VIR_STRDUP(proc->binary, binary) < 0)
 goto error;
 
-cmd->runUid = runUid;
-cmd->runGid = runGid;
-cmd->qmperr = qmperr;
+proc->runUid = runUid;
+proc->runGid = runGid;
+proc->qmperr = qmperr;
 
 /* the ".sock" sufix is important to avoid a possible clash with a qemu
  * domain called "capabilities"
  */
-if (virAsprintf(>monpath, "%s/%s", libDir,
+if (virAsprintf(>monpath, "%s/%s", libDir,
 "capabilities.monitor.sock") < 0)
 goto error;
-if (virAsprintf(>monarg, "unix:%s,server,nowait", cmd->monpath) < 0)
+if (virAsprintf(>monarg, "unix:%s,server,nowait", proc->monpath) < 0)
 goto error;
 
 /* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
@@ -8129,19 +8129,19 @@ qemuProcessNew(const char *binary,
  * -daemonize we need QEMU to be allowed to create them, rather
  * than libvirtd. So we're using libDir which QEMU can write to
  */
-if (virAsprintf(>pidfile, "%s/%s", libDir, "capabilities.pidfile") < 
0)
+if (virAsprintf(>pidfile, "%s/%s", libDir, "capabilities.pidfile") < 
0)
 goto error;
 
-virPidFileForceCleanupPath(cmd->pidfile);
+virPidFileForceCleanupPath(proc->pidfile);
 
-cmd->config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
-cmd->config.data.nix.path = cmd->monpath;
-cmd->config.data.nix.listen = false;
+proc->config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
+proc->config.data.nix.path = proc->monp

[libvirt] [PATCH RFC 00/22] Move process code to qemu_process

2018-11-11 Thread Chris Venteicher
Make process code usable outside qemu_capabilities by moving code
from qemu_capabilities to qemu_process and exposing public functions.

The process code is used to activate a non domain QEMU process for QMP
message exchanges.

This patch set modifies capabilities to use the new public functions.

--

The process code is being decoupled from qemu_capabilities now to
support hypervisor baseline and comparison using QMP commands.

This patch set was originally submitted as part of the baseline patch set:
  [libvirt] [PATCH v4 00/37] BaselineHypervisorCPU using QEMU QMP exchanges
  https://www.redhat.com/archives/libvir-list/2018-November/msg00091.html

The baseline and comparison requirements are described here:
https://bugzilla.redhat.com/show_bug.cgi?id=1511999
https://bugzilla.redhat.com/show_bug.cgi?id=1511996


I am extracting and resubmitting just the process changes as a stand
alone series to try to make review easier.

The patch set shows capabilities using the public functions.
To see baseline using the public functions...
Look at the "qemu_driver:" patches at the end of
https://www.redhat.com/archives/libvir-list/2018-November/msg00091.html

Also,
The "qemu_driver: Support feature expansion via QEMU when baselining cpu"
patch might be of particular interest because the same QEMU process is
used for both baseline and expansion using QMP commands.

--

Many patches were used to isolate code moves and name changes from other
actual implementation changes.

The patches reuse the pattern of public qemuProcess{Start,Stop} functions
and internal static qemuProcess{Init,Launch,ConnectMonitor} functions
but adds a "Qmp" suffix to make them unique.

A number of patches are about re-partitioning the code into static
functions for initialization, process launch and connection monitor
stuff.  This matches the established pattern in qemu_process and seemed
to make sense to do.

For concurrency...
A thread safe library function creates a unique directory under libDir for each 
QEMU
process (for QMP messaging) to decouple processes in terms of sockets and
file system footprint.

Every patch should compile independently if applied in sequence.


Chris Venteicher (22):
  qemu_process: Move process code from qemu_capabilities to qemu_process
  qemu_process: Use qemuProcess prefix
  qemu_process: Limit qemuProcessNew to const input strings
  qemu_process: Refer to proc not cmd in process code
  qemu_process: Use consistent name for stop process function
  qemu_capabilities: Stop QEMU process before freeing
  qemu_process: Use qemuProcess struct for a single process
  qemu_process: Persist stderr in qemuProcess struct
  qemu_capabilities: Detect caps probe failure by checking monitor ptr
  qemu_process: Introduce qemuProcessStartQmp
  qemu_process: Collect monitor code in single function
  qemu_process: Store libDir in qemuProcess struct
  qemu_process: Setup paths within qemuProcessInitQmp
  qemu_process: Stop retaining Qemu Monitor config in qemuProcess
  qemu_process: Don't open monitor if process failed
  qemu_process: Cleanup qemuProcess alloc function
  qemu_process: Cleanup qemuProcessStopQmp function
  qemu_process: Catch process free before process stop
  qemu_monitor: Make monitor callbacks optional
  qemu_process: Enter QMP command mode when starting QEMU Process
  qemu_process: Use unique directories for QMP processes
  qemu_process: Stop locking QMP process monitor immediately

 src/qemu/qemu_capabilities.c | 300 +
 src/qemu/qemu_monitor.c  |   4 +-
 src/qemu/qemu_process.c  | 356 +++
 src/qemu/qemu_process.h  |  37 
 tests/qemucapabilitiestest.c |   7 +
 5 files changed, 444 insertions(+), 260 deletions(-)

-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 17/22] qemu_process: Cleanup qemuProcessStopQmp function

2018-11-11 Thread Chris Venteicher
qemuProcessStopQmp is one of the 4 public functions used to create and
manage a Qemu process for QMP command exchanges.

Add comment header and debug message.

Other minor code formatting cleanup.

No change in functionality is intended.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 29 ++---
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 5ff7d6878c..27a959cf9d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8360,14 +8360,27 @@ qemuProcessStartQmp(qemuProcessPtr proc)
 goto cleanup;
 }
 
-
-void
-qemuProcessStopQmp(qemuProcessPtr proc)
+/**
+ * qemuProcessStop:
+ * @proc: Stores Process and Connection State
+ *
+ * Stop Monitor Connection and QEMU Process
+ */
+void qemuProcessStopQmp(qemuProcessPtr proc)
 {
-if (proc->mon)
-virObjectUnlock(proc->mon);
-qemuMonitorClose(proc->mon);
-proc->mon = NULL;
+qemuMonitorPtr mon = NULL;
+
+if (!proc)
+return;
+
+VIR_DEBUG("Shutting down proc=%p emulator=%s mon=%p pid=%lld",
+  proc, proc->binary, proc->mon, (long long)proc->pid);
+
+if ((mon = QEMU_PROCESS_MONITOR(proc))) {
+virObjectUnlock(mon);
+qemuMonitorClose(mon);
+proc->mon = NULL;
+}
 
 virCommandAbort(proc->cmd);
 virCommandFree(proc->cmd);
@@ -8388,7 +8401,9 @@ qemuProcessStopQmp(qemuProcessPtr proc)
   virStrerror(errno, ebuf, sizeof(ebuf)));
 
 }
+
 if (proc->pidfile)
 unlink(proc->pidfile);
+
 proc->pid = 0;
 }
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 18/22] qemu_process: Catch process free before process stop

2018-11-11 Thread Chris Venteicher
Catch execution paths where qemuProcessFree is called before
qemuProcessStopQmp then report error and force stop before proceeding.

Also added public function header and debug message.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 19 ---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 27a959cf9d..c44e46fc88 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8078,15 +8078,28 @@ static qemuMonitorCallbacks callbacks = {
 };
 
 
-
-
+/**
+ * qemuProcessFree:
+ * @proc: Stores Process and Connection State
+ *
+ * Free process data structure.
+ */
 void
 qemuProcessFree(qemuProcessPtr proc)
 {
+VIR_DEBUG("proc=%p, proc->mon=%p", proc, (proc ? proc->mon : NULL));
+
 if (!proc)
 return;
 
-qemuProcessStopQmp(proc);
+/* This should never be non-NULL if we get here, but just in case... */
+if (proc->mon || proc->pid) {
+VIR_ERROR(_("Unexpected QEMU still active during process free"
+" emulator: %s, pid: %lld, mon: %p"),
+NULLSTR(proc->binary), (long long) proc->pid, proc->mon);
+qemuProcessStopQmp(proc);
+}
+
 VIR_FREE(proc->binary);
 VIR_FREE(proc->libDir);
 VIR_FREE(proc->monpath);
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 15/22] qemu_process: Don't open monitor if process failed

2018-11-11 Thread Chris Venteicher
Gracefully handle case when proc activation failed prior to calling.

Consistent with the existing code for qemuConnectMonitor (for domains)
in qemu_process.c...

- Handle qemMonitorOpen failure with INFO message and NULL ptr
- Identify parameters passed to qemuMonitorOpen

Monitor callbacks will be removed in future patch so we prep for passing
NULL for the callback pointer.

Set proc->mon to NULL then use VIR_STEAL_PTR if successful to be
consistent with other functions.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 27 +--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index d4ed2d6353..55a092ecbb 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8236,25 +8236,48 @@ static int
 qemuConnectMonitorQmp(qemuProcessPtr proc)
 {
 int ret = -1;
+qemuMonitorPtr mon = NULL;
+unsigned long long timeout = 0;
+bool retry = true;
+bool enableJson = true;
+virQEMUDriverPtr driver = NULL;
+qemuMonitorCallbacksPtr monCallbacks = 
 virDomainXMLOptionPtr xmlopt = NULL;
 virDomainChrSourceDef monConfig;
 
 VIR_DEBUG("proc=%p, emulator=%s, proc->pid=%lld",
   proc, NULLSTR(proc->binary), (long long) proc->pid);
 
+if (!proc || !proc->pid)
+goto ignore;
+
+proc->mon = NULL;
+
 monConfig.type = VIR_DOMAIN_CHR_TYPE_UNIX;
 monConfig.data.nix.path = proc->monpath;
 monConfig.data.nix.listen = false;
 
+/* Create a NULL Domain object for qemuMonitor */
 if (!(xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL, NULL, NULL)) ||
 !(proc->vm = virDomainObjNew(xmlopt)))
 goto cleanup;
 
 proc->vm->pid = proc->pid;
 
-if (!(proc->mon = qemuMonitorOpen(proc->vm, , true, true,
-  0, , NULL)))
+mon = qemuMonitorOpen(proc->vm,
+  ,
+  enableJson,
+  retry,
+  timeout,
+  monCallbacks,
+  driver);
+
+if (!mon) {
+VIR_INFO("Failed to connect monitor to emulator %s", proc->binary);
 goto ignore;
+}
+
+VIR_STEAL_PTR(proc->mon, mon);
 
 virObjectLock(proc->mon);
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 06/22] qemu_capabilities: Stop QEMU process before freeing

2018-11-11 Thread Chris Venteicher
Follow the convention established in qemu_process of
1) alloc process structure
2) start process
3) use process
4) stop process
5) free process data structure

The process data structure persists after the process activation fails
or the process dies or is killed so stderr strings can be retrieved
until the process data structure is freed.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 73ec8e5c6e..082874082b 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4251,6 +4251,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 ret = 0;
 
  cleanup:
+qemuProcessStopQmp(proc);
 qemuProcessFree(proc);
 return ret;
 }
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 11/22] qemu_process: Collect monitor code in single function

2018-11-11 Thread Chris Venteicher
qemuMonitor code lives in qemuConnectMonitorQmp rather than in
qemuProcessNew and qemuProcessLaunchQmp.

This is consistent with existing structure in qemu_process.c where
qemuConnectMonitor function contains monitor code for domain process
activation.

Simple code moves in this patch.  Improvements in later patch.

Only intended functional change in this patch is we don't
move (include) code to initiate process stop on failure to create monitor.

As comments in qemuProcessStartQmp say... Client must always call
qemuProcessStop and qemuProcessFree, even in error cases.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_process.c | 41 -
 1 file changed, 20 insertions(+), 21 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index b6aa3a9af3..fe4361ed5d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8136,10 +8136,6 @@ qemuProcessNew(const char *binary,
 
 virPidFileForceCleanupPath(proc->pidfile);
 
-proc->config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
-proc->config.data.nix.path = proc->monpath;
-proc->config.data.nix.listen = false;
-
 return proc;
 
  error:
@@ -8171,7 +8167,6 @@ qemuProcessInitQmp(qemuProcessPtr proc)
 static int
 qemuProcessLaunchQmp(qemuProcessPtr proc)
 {
-virDomainXMLOptionPtr xmlopt = NULL;
 const char *machine;
 int status = 0;
 int ret = -1;
@@ -8223,26 +8218,10 @@ qemuProcessLaunchQmp(qemuProcessPtr proc)
 goto ignore;
 }
 
-if (!(xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL, NULL, NULL)) ||
-!(proc->vm = virDomainObjNew(xmlopt)))
-goto cleanup;
-
-proc->vm->pid = proc->pid;
-
-if (!(proc->mon = qemuMonitorOpen(proc->vm, >config, true, true,
- 0, , NULL)))
-goto ignore;
-
-virObjectLock(proc->mon);
-
  ignore:
 ret = 0;
 
  cleanup:
-if (!proc->mon)
-qemuProcessStopQmp(proc);
-virObjectUnref(xmlopt);
-
 return ret;
 }
 
@@ -8253,13 +8232,33 @@ static int
 qemuConnectMonitorQmp(qemuProcessPtr proc)
 {
 int ret = -1;
+virDomainXMLOptionPtr xmlopt = NULL;
 
 VIR_DEBUG("proc=%p, emulator=%s, proc->pid=%lld",
   proc, NULLSTR(proc->binary), (long long) proc->pid);
 
+proc->config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
+proc->config.data.nix.path = proc->monpath;
+proc->config.data.nix.listen = false;
+
+if (!(xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL, NULL, NULL)) ||
+!(proc->vm = virDomainObjNew(xmlopt)))
+goto cleanup;
+
+proc->vm->pid = proc->pid;
+
+if (!(proc->mon = qemuMonitorOpen(proc->vm, >config, true, true,
+  0, , NULL)))
+goto ignore;
+
+virObjectLock(proc->mon);
+
+ ignore:
 ret = 0;
 
+ cleanup:
 VIR_DEBUG("ret=%i", ret);
+virObjectUnref(xmlopt);
 return ret;
 }
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 10/22] qemu_process: Introduce qemuProcessStartQmp

2018-11-11 Thread Chris Venteicher
Move a step closer to the function structure used elsewhere in
qemu_process where qemuProcessStart and qemuProcessStop are the exposed
functions.

qemuProcessStartQmp mirrors qemuProcessStart in calling sub functions to
intialize, launch the process and connect the monitor to the QEMU
process.

static functions qemuProcessInitQmp, qemuProcessLaunchQmp and
qemuConnectMonitorQmp are also introduced.

qemuProcessLaunchQmp is just renamed from qemuProcessRun and
encapsulates all of the original code.

qemuProcessInitQmp and qemuProcessMonitorQmp are introduced as empty
wrappers into which subsequent patches will partition code from
qemuProcessLaunchQmp.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c |  4 +-
 src/qemu/qemu_process.c  | 96 +++-
 src/qemu/qemu_process.h  |  2 +-
 3 files changed, 97 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index fbb4336201..7168c470f6 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4230,7 +4230,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 goto cleanup;
 
 
-if (qemuProcessRun(proc) < 0)
+if (qemuProcessStartQmp(proc) < 0)
 goto cleanup;
 
 if (!(mon = QEMU_PROCESS_MONITOR(proc))) {
@@ -4249,7 +4249,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 forceTCG = true;
 proc_kvm = qemuProcessNew(qemuCaps->binary, libDir, runUid, runGid, 
forceTCG);
 
-if (qemuProcessRun(proc_kvm) < 0)
+if (qemuProcessStartQmp(proc_kvm) < 0)
 goto cleanup;
 
 if (!(mon_kvm = QEMU_PROCESS_MONITOR(proc_kvm))) {
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 2640ec2b32..b6aa3a9af3 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8148,8 +8148,29 @@ qemuProcessNew(const char *binary,
 }
 
 
-int
-qemuProcessRun(qemuProcessPtr proc){
+/* Initialize configuration and paths prior to starting QEMU
+ */
+static int
+qemuProcessInitQmp(qemuProcessPtr proc)
+{
+int ret = -1;
+
+VIR_DEBUG("Beginning VM startup process"
+  "emulator=%s",
+  proc->binary);
+
+ret = 0;
+
+VIR_DEBUG("ret=%i", ret);
+return ret;
+}
+
+
+/* Launch QEMU Process
+ */
+static int
+qemuProcessLaunchQmp(qemuProcessPtr proc)
+{
 virDomainXMLOptionPtr xmlopt = NULL;
 const char *machine;
 int status = 0;
@@ -8226,6 +8247,77 @@ qemuProcessRun(qemuProcessPtr proc){
 }
 
 
+/* Connect Monitor to QEMU Process
+ */
+static int
+qemuConnectMonitorQmp(qemuProcessPtr proc)
+{
+int ret = -1;
+
+VIR_DEBUG("proc=%p, emulator=%s, proc->pid=%lld",
+  proc, NULLSTR(proc->binary), (long long) proc->pid);
+
+ret = 0;
+
+VIR_DEBUG("ret=%i", ret);
+return ret;
+}
+
+
+/**
+ * qemuProcessStartQmp:
+ * @proc: Stores Process and Connection State
+ *
+ * Start and connect to QEMU binary so QMP queries can be made.
+ *
+ * Usage:
+ *   proc = qemuProcessNew(binary, forceTCG, libDir, runUid, runGid);
+ *   qemuProcessStartQmp(proc);
+ *   mon = QEMU_PROCESS_MONITOR(proc);
+ *   ** Send QMP Queries to QEMU using monitor **
+ *   qemuProcessStopQmp(proc);
+ *   qemuProcessFree(proc);
+ *
+ * Check monitor is not NULL before using.
+ *
+ * QEMU probing failure results in monitor being NULL but is not considered
+ * an error case and does not result in a negative return value.
+ *
+ * Both qemuProcessStopQmp and qemuProcessFree must be called to cleanup and
+ * free resources, even in activation failure cases.
+ *
+ * Process error output (proc->qmperr) remains available in qemuProcess struct
+ * until qemuProcessFree is called.
+ */
+int
+qemuProcessStartQmp(qemuProcessPtr proc)
+{
+int ret = -1;
+
+VIR_DEBUG("emulator=%s",
+  proc->binary);
+
+if (qemuProcessInitQmp(proc) < 0)
+goto cleanup;
+
+if (qemuProcessLaunchQmp(proc) < 0)
+goto stop;
+
+if (qemuConnectMonitorQmp(proc) < 0)
+goto stop;
+
+ret = 0;
+
+ cleanup:
+VIR_DEBUG("ret=%i", ret);
+return ret;
+
+ stop:
+qemuProcessStopQmp(proc);
+goto cleanup;
+}
+
+
 void
 qemuProcessStopQmp(qemuProcessPtr proc)
 {
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 37194e2501..c34ca52ef5 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -246,7 +246,7 @@ qemuProcessPtr qemuProcessNew(const char *binary,
 
 void qemuProcessFree(qemuProcessPtr proc);
 
-int qemuProcessRun(qemuProcessPtr proc);
+int qemuProcessStartQmp(qemuProcessPtr proc);
 
 void qemuProcessStopQmp(qemuProcessPtr proc);
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 05/22] qemu_process: Use consistent name for stop process function

2018-11-11 Thread Chris Venteicher
s/qemuProcessAbort/qemuProcessStopQmp/ applied to change function name
used to stop QEMU processes in process code moved from
qemu_capabilities.

No functionality change.

The new name, qemuProcessStopQmp, is consistent with the existing
function qemuProcessStop used to stop Domain processes.

Qmp is added to the end of qemuProcessStop to differentiate between the
Domain and new non-domain version of the functions.  qemuProcessStartQmp
will be used in a future patch to mirror the qemuProcessStart function
with a non-domain equivalent.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 2 +-
 src/qemu/qemu_process.c  | 6 +++---
 src/qemu/qemu_process.h  | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 1ea63000e2..73ec8e5c6e 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4237,7 +4237,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 goto cleanup;
 
 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
-qemuProcessAbort(proc);
+qemuProcessStopQmp(proc);
 if ((rc = qemuProcessRun(proc, true)) != 0) {
 if (rc == 1)
 ret = 0;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e949547124..2571024e8e 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8086,7 +8086,7 @@ qemuProcessFree(qemuProcessPtr proc)
 if (!proc)
 return;
 
-qemuProcessAbort(proc);
+qemuProcessStopQmp(proc);
 VIR_FREE(proc->binary);
 VIR_FREE(proc->monpath);
 VIR_FREE(proc->monarg);
@@ -8222,7 +8222,7 @@ qemuProcessRun(qemuProcessPtr proc,
 
  cleanup:
 if (!proc->mon)
-qemuProcessAbort(proc);
+qemuProcessStopQmp(proc);
 virObjectUnref(xmlopt);
 
 return ret;
@@ -8234,7 +8234,7 @@ qemuProcessRun(qemuProcessPtr proc,
 
 
 void
-qemuProcessAbort(qemuProcessPtr proc)
+qemuProcessStopQmp(qemuProcessPtr proc)
 {
 if (proc->mon)
 virObjectUnlock(proc->mon);
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 161311d007..25343c4592 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -241,6 +241,6 @@ void qemuProcessFree(qemuProcessPtr proc);
 
 int qemuProcessRun(qemuProcessPtr proc, bool forceTCG);
 
-void qemuProcessAbort(qemuProcessPtr proc);
+void qemuProcessStopQmp(qemuProcessPtr proc);
 
 #endif /* __QEMU_PROCESS_H__ */
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 09/22] qemu_capabilities: Detect caps probe failure by checking monitor ptr

2018-11-11 Thread Chris Venteicher
Failure to connect to QEMU to probe capabilities is not considered a error case
and does not result in a negative return value.

Check for a NULL monitor connection pointer before trying to send capabilities
commands to QEMU rather than depending on a special positive return value.

This simplifies logic and is more consistent with the operation of existing
qemu_process functions.

A macro is introduced to easily obtain the monitor pointer from the
qemuProcess structure.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 28 ++--
 src/qemu/qemu_process.c  |  9 +
 src/qemu/qemu_process.h  |  3 +++
 3 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index f5e327097e..fbb4336201 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4220,43 +4220,51 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 {
 qemuProcessPtr proc = NULL;
 qemuProcessPtr proc_kvm = NULL;
+qemuMonitorPtr mon = NULL;
+qemuMonitorPtr mon_kvm = NULL;
 int ret = -1;
-int rc;
 bool forceTCG = false;
 
 if (!(proc = qemuProcessNew(qemuCaps->binary, libDir,
 runUid, runGid, forceTCG)))
 goto cleanup;
 
-if ((rc = qemuProcessRun(proc)) != 0) {
-if (rc == 1)
-ret = 0;
+
+if (qemuProcessRun(proc) < 0)
+goto cleanup;
+
+if (!(mon = QEMU_PROCESS_MONITOR(proc))) {
+ret = 0; /* Failure probing QEMU not considered error case */
 goto cleanup;
 }
 
-if (virQEMUCapsInitQMPMonitor(qemuCaps, proc->mon) < 0)
+/* Pull capabilities from QEMU */
+if (virQEMUCapsInitQMPMonitor(qemuCaps, mon) < 0)
 goto cleanup;
 
+/* Pull capabilities again if KVM supported */
 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
 qemuProcessStopQmp(proc);
 
 forceTCG = true;
 proc_kvm = qemuProcessNew(qemuCaps->binary, libDir, runUid, runGid, 
forceTCG);
 
-if ((rc = qemuProcessRun(proc_kvm)) != 0) {
-if (rc == 1)
-ret = 0;
+if (qemuProcessRun(proc_kvm) < 0)
+goto cleanup;
+
+if (!(mon_kvm = QEMU_PROCESS_MONITOR(proc_kvm))) {
+ret = 0; /* Failure probing QEMU not considered error case */
 goto cleanup;
 }
 
-if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, proc_kvm->mon) < 0)
+if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, mon_kvm) < 0)
 goto cleanup;
 }
 
 ret = 0;
 
  cleanup:
-if (proc && !proc->mon) {
+if (!mon) {
 char *err = QEMU_PROCESS_ERROR(proc) ? QEMU_PROCESS_ERROR(proc) : 
_("unknown error");
 
 virReportError(VIR_ERR_INTERNAL_ERROR,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index a741d1cf91..2640ec2b32 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8148,10 +8148,6 @@ qemuProcessNew(const char *binary,
 }
 
 
-/* Returns -1 on fatal error,
- *  0 on success,
- *  1 when probing QEMU failed
- */
 int
 qemuProcessRun(qemuProcessPtr proc){
 virDomainXMLOptionPtr xmlopt = NULL;
@@ -8218,6 +8214,7 @@ qemuProcessRun(qemuProcessPtr proc){
 
 virObjectLock(proc->mon);
 
+ ignore:
 ret = 0;
 
  cleanup:
@@ -8226,10 +8223,6 @@ qemuProcessRun(qemuProcessPtr proc){
 virObjectUnref(xmlopt);
 
 return ret;
-
- ignore:
-ret = 1;
-goto cleanup;
 }
 
 
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index abd80baf5c..37194e2501 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -235,6 +235,9 @@ struct _qemuProcess {
 #define QEMU_PROCESS_ERROR(proc) \
((char *) (proc ? proc->qmperr: NULL))
 
+#define QEMU_PROCESS_MONITOR(proc) \
+   ((qemuMonitorPtr) (proc ? proc->mon : NULL))
+
 qemuProcessPtr qemuProcessNew(const char *binary,
   const char *libDir,
   uid_t runUid,
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH RFC 02/22] qemu_process: Use qemuProcess prefix

2018-11-11 Thread Chris Venteicher
s/virQEMUCapsInitQMPCommand/qemuProcess/

No functionality change.

Use appropriate prefix in moved code.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 14 +++---
 src/qemu/qemu_process.c  | 28 ++--
 src/qemu/qemu_process.h  | 22 +++---
 3 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 0f70fdf46d..f6d97648ce 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4219,15 +4219,15 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
gid_t runGid,
char **qmperr)
 {
-virQEMUCapsInitQMPCommandPtr cmd = NULL;
+qemuProcessPtr cmd = NULL;
 int ret = -1;
 int rc;
 
-if (!(cmd = virQEMUCapsInitQMPCommandNew(qemuCaps->binary, libDir,
- runUid, runGid, qmperr)))
+if (!(proc = qemuProcessNew(qemuCaps->binary, libDir,
+runUid, runGid, qmperr)))
 goto cleanup;
 
-if ((rc = virQEMUCapsInitQMPCommandRun(cmd, false)) != 0) {
+if ((rc = qemuProcessRun(cmd, false)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
@@ -4237,8 +4237,8 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 goto cleanup;
 
 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
-virQEMUCapsInitQMPCommandAbort(cmd);
-if ((rc = virQEMUCapsInitQMPCommandRun(cmd, true)) != 0) {
+qemuProcessAbort(cmd);
+if ((rc = qemuProcessRun(cmd, true)) != 0) {
 if (rc == 1)
 ret = 0;
 goto cleanup;
@@ -4251,7 +4251,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
 ret = 0;
 
  cleanup:
-virQEMUCapsInitQMPCommandFree(cmd);
+qemuProcessFree(cmd);
 return ret;
 }
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 0b3922fa39..dff0482856 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8081,12 +8081,12 @@ static qemuMonitorCallbacks callbacks = {
 
 
 void
-virQEMUCapsInitQMPCommandFree(virQEMUCapsInitQMPCommandPtr cmd)
+qemuProcessFree(qemuProcessPtr cmd)
 {
 if (!cmd)
 return;
 
-virQEMUCapsInitQMPCommandAbort(cmd);
+qemuProcessAbort(cmd);
 VIR_FREE(cmd->binary);
 VIR_FREE(cmd->monpath);
 VIR_FREE(cmd->monarg);
@@ -8095,14 +8095,14 @@ 
virQEMUCapsInitQMPCommandFree(virQEMUCapsInitQMPCommandPtr cmd)
 }
 
 
-virQEMUCapsInitQMPCommandPtr
-virQEMUCapsInitQMPCommandNew(char *binary,
- const char *libDir,
- uid_t runUid,
- gid_t runGid,
- char **qmperr)
+qemuProcessPtr
+qemuProcessNew(char *binary,
+   const char *libDir,
+   uid_t runUid,
+   gid_t runGid,
+   char **qmperr)
 {
-virQEMUCapsInitQMPCommandPtr cmd = NULL;
+qemuProcessPtr cmd = NULL;
 
 if (VIR_ALLOC(cmd) < 0)
 goto error;
@@ -8141,7 +8141,7 @@ virQEMUCapsInitQMPCommandNew(char *binary,
 return cmd;
 
  error:
-virQEMUCapsInitQMPCommandFree(cmd);
+qemuProcessFree(cmd);
 return NULL;
 }
 
@@ -8151,8 +8151,8 @@ virQEMUCapsInitQMPCommandNew(char *binary,
  *  1 when probing QEMU failed
  */
 int
-virQEMUCapsInitQMPCommandRun(virQEMUCapsInitQMPCommandPtr cmd,
- bool forceTCG)
+qemuProcessRun(qemuProcessPtr cmd,
+   bool forceTCG)
 {
 virDomainXMLOptionPtr xmlopt = NULL;
 const char *machine;
@@ -8222,7 +8222,7 @@ virQEMUCapsInitQMPCommandRun(virQEMUCapsInitQMPCommandPtr 
cmd,
 
  cleanup:
 if (!cmd->mon)
-virQEMUCapsInitQMPCommandAbort(cmd);
+qemuProcessAbort(cmd);
 virObjectUnref(xmlopt);
 
 return ret;
@@ -8234,7 +8234,7 @@ virQEMUCapsInitQMPCommandRun(virQEMUCapsInitQMPCommandPtr 
cmd,
 
 
 void
-virQEMUCapsInitQMPCommandAbort(virQEMUCapsInitQMPCommandPtr cmd)
+qemuProcessAbort(qemuProcessPtr cmd)
 {
 if (cmd->mon)
 virObjectUnlock(cmd->mon);
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 4ba3988e3d..5417cb416f 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -214,9 +214,9 @@ int qemuProcessStartManagedPRDaemon(virDomainObjPtr vm);
 
 void qemuProcessKillManagedPRDaemon(virDomainObjPtr vm);
 
-typedef struct _virQEMUCapsInitQMPCommand virQEMUCapsInitQMPCommand;
-typedef virQEMUCapsInitQMPCommand *virQEMUCapsInitQMPCommandPtr;
-struct _virQEMUCapsInitQMPCommand {
+typedef struct _qemuProcess qemuProcess;
+typedef qemuProcess *qemuProcessPtr;
+struct _qemuProcess {
 char *binary;
 uid_t runUid;
 gid_t runGid;
@@ -231,16 +231,16 @@ struct _virQEMUCapsInitQMPCommand {
 virDomainObjPtr vm;
 };
 
-virQEMUCapsInitQMPCommandPtr virQEMUCapsInitQMPCommandNew(char *binary,
- 

[libvirt] [PATCH RFC 01/22] qemu_process: Move process code from qemu_capabilities to qemu_process

2018-11-11 Thread Chris Venteicher
Qemu process code in qemu_capabilities.c is moved to qemu_process.c in
order to make the code usable outside the original capabilities
usecases.

This process code activates and manages Qemu processes without
establishing a guest domain.

This patch is a straight cut/paste move between files.

Following patches modify the process code
making it more generic and consistent with qemu_process.

Signed-off-by: Chris Venteicher 
---
 src/qemu/qemu_capabilities.c | 218 +--
 src/qemu/qemu_process.c  | 201 
 src/qemu/qemu_process.h  |  29 +
 3 files changed, 231 insertions(+), 217 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2ca5af3297..0f70fdf46d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -47,6 +47,7 @@
 #define __QEMU_CAPSPRIV_H_ALLOW__
 #include "qemu_capspriv.h"
 #include "qemu_qapi.h"
+#include "qemu_process.h"
 
 #include 
 #include 
@@ -3917,18 +3918,6 @@ virQEMUCapsIsValid(void *data,
 }
 
 
-static void virQEMUCapsMonitorNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- void *opaque ATTRIBUTE_UNUSED)
-{
-}
-
-static qemuMonitorCallbacks callbacks = {
-.eofNotify = virQEMUCapsMonitorNotify,
-.errorNotify = virQEMUCapsMonitorNotify,
-};
-
-
 /**
  * virQEMUCapsInitQMPArch:
  * @qemuCaps: QEMU capabilities
@@ -4223,211 +4212,6 @@ virQEMUCapsInitQMPMonitorTCG(virQEMUCapsPtr qemuCaps 
ATTRIBUTE_UNUSED,
 }
 
 
-typedef struct _virQEMUCapsInitQMPCommand virQEMUCapsInitQMPCommand;
-typedef virQEMUCapsInitQMPCommand *virQEMUCapsInitQMPCommandPtr;
-struct _virQEMUCapsInitQMPCommand {
-char *binary;
-uid_t runUid;
-gid_t runGid;
-char **qmperr;
-char *monarg;
-char *monpath;
-char *pidfile;
-virCommandPtr cmd;
-qemuMonitorPtr mon;
-virDomainChrSourceDef config;
-pid_t pid;
-virDomainObjPtr vm;
-};
-
-
-static void
-virQEMUCapsInitQMPCommandAbort(virQEMUCapsInitQMPCommandPtr cmd)
-{
-if (cmd->mon)
-virObjectUnlock(cmd->mon);
-qemuMonitorClose(cmd->mon);
-cmd->mon = NULL;
-
-virCommandAbort(cmd->cmd);
-virCommandFree(cmd->cmd);
-cmd->cmd = NULL;
-
-if (cmd->monpath)
-unlink(cmd->monpath);
-
-virDomainObjEndAPI(>vm);
-
-if (cmd->pid != 0) {
-char ebuf[1024];
-
-VIR_DEBUG("Killing QMP caps process %lld", (long long)cmd->pid);
-if (virProcessKill(cmd->pid, SIGKILL) < 0 && errno != ESRCH)
-VIR_ERROR(_("Failed to kill process %lld: %s"),
-  (long long)cmd->pid,
-  virStrerror(errno, ebuf, sizeof(ebuf)));
-
-VIR_FREE(*cmd->qmperr);
-}
-if (cmd->pidfile)
-unlink(cmd->pidfile);
-cmd->pid = 0;
-}
-
-
-static void
-virQEMUCapsInitQMPCommandFree(virQEMUCapsInitQMPCommandPtr cmd)
-{
-if (!cmd)
-return;
-
-virQEMUCapsInitQMPCommandAbort(cmd);
-VIR_FREE(cmd->binary);
-VIR_FREE(cmd->monpath);
-VIR_FREE(cmd->monarg);
-VIR_FREE(cmd->pidfile);
-VIR_FREE(cmd);
-}
-
-
-static virQEMUCapsInitQMPCommandPtr
-virQEMUCapsInitQMPCommandNew(char *binary,
- const char *libDir,
- uid_t runUid,
- gid_t runGid,
- char **qmperr)
-{
-virQEMUCapsInitQMPCommandPtr cmd = NULL;
-
-if (VIR_ALLOC(cmd) < 0)
-goto error;
-
-if (VIR_STRDUP(cmd->binary, binary) < 0)
-goto error;
-
-cmd->runUid = runUid;
-cmd->runGid = runGid;
-cmd->qmperr = qmperr;
-
-/* the ".sock" sufix is important to avoid a possible clash with a qemu
- * domain called "capabilities"
- */
-if (virAsprintf(>monpath, "%s/%s", libDir,
-"capabilities.monitor.sock") < 0)
-goto error;
-if (virAsprintf(>monarg, "unix:%s,server,nowait", cmd->monpath) < 0)
-goto error;
-
-/* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
- * with a qemu domain called "capabilities"
- * Normally we'd use runDir for pid files, but because we're using
- * -daemonize we need QEMU to be allowed to create them, rather
- * than libvirtd. So we're using libDir which QEMU can write to
- */
-if (virAsprintf(>pidfile, "%s/%s", libDir, "capabilities.pidfile") < 
0)
-goto error;
-
-virPidFileForceCleanupPath(cmd->pidfile);
-
-cmd->config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
-cmd->config.data.nix.path = cmd->monpath;
-cmd->config.data.nix.listen =

Re: [libvirt] [PATCH v4 00/37] BaselineHypervisorCPU using QEMU QMP exchanges

2018-11-09 Thread Chris Venteicher
Quoting Chris Venteicher (2018-11-02 22:13:01)
> Some architectures (S390) depend on QEMU to compute baseline CPU model and
> expand a models feature set.
> 
> Interacting with QEMU requires starting the QEMU process and completing one or
> more query-cpu-model-baseline QMP exchanges with QEMU in addition to a
> query-cpu-model-expansion QMP exchange to expand all features in the model.
> 
> See "s390x CPU models: exposing features" patch set on Qemu-devel for 
> discussion
> of QEMU aspects.
> 
> This is part of resolution of: 
> https://bugzilla.redhat.com/show_bug.cgi?id=1511999
> 
> Version 4 attempts to address all issues from V1,2,3 including making the
> QEMU process activation for QMP Queries generic (not specific to capabilities)
> and moving that code from qemu_capabilities to qemu_process.
> 
> Version 4 greatly expands the number of patches to make the set easier
> to review.
>
> The patches to do hypervisor baseline using QEMU are primarily in
> qemu_driver.c
>
Patches 1-2 create the cpumodel to/from Json conversion code.
Patches 3-4 modify the cpu expansion interface.
Patches 28-36 are the actual baseline changes.

> The patches to make the process code generic (not capabilities specific)
> are mostly in qemu_process.c

Patches 5 -> 27 move the process code from qemu_capabilities to
qemu_process.

A lot of these are code move or rename patches so the patches with real
implementation changes are easy to identify.

I might have ended up with too many patches though.
Want to mention... the whole "process" block could be moved to it's own
series if that would be easier to review.

> Many of the patches are cut / paste of existing code.  The patches that
> change functionality are as modular and minimal as possible to make
> reviewing easier.
> 
> I attempted to make the new qemu_process functions
> consistent with the existing domain activation qemu_process functions.
> 
> A thread safe library function creates a unique directory under libDir for 
> each QEMU
> process (for QMP messaging) to decouple processes in terms of sockets and
> file system footprint.
> 
> The last patch is based on past discussion of QEMU cpu
> expansion only returning migratable features except for one x86 case where
> non-migratable features are explicitly requested.  The patch records that 
> features
> are migratable based on QEMU only returning migratable features.  The main 
> result
> is the CPU xml for S390 CPU's contains the same migratability info the X86 
> currently
> does.  The testcases were updated to reflect the change.
> 
> Every patch should compile independently if applied in sequence.
> 
> Thanks,
> Chris
> 
> 
> Chris Venteicher (37):
>   qemu_monitor: Introduce qemuMonitorCPUModelInfoNew
>   qemu_monitor: Introduce qemuMonitorCPUModelInfo / JSON conversion
>   qemu_capabilities: Introduce virQEMuCapsMigratablePropsDiff
>   qemu_monitor: qemuMonitorGetCPUModelExpansion inputs and outputs
> CPUModelInfo
>   qemu_process: Move process code from qemu_capabilities to qemu_process
>   qemu_process: Use qemuProcess prefix
>   qemu_process: Limit qemuProcessNew to const input strings
>   qemu_process: Refer to proc not cmd in process code
>   qemu_process: Use consistent name for stop process function
>   qemu_capabilities: Stop QEMU process before freeing
>   qemu_process: Use qemuProcess struct for a single process
>   qemu_process: Persist stderr in qemuProcess struct
>   qemu_capabilities: Detect caps probe failure by checking monitor ptr
>   qemu_process: Introduce qemuProcessStartQmp
>   qemu_process: Add debug message in qemuProcessLaunchQmp
>   qemu_process: Collect monitor code in single function
>   qemu_process: Store libDir in qemuProcess struct
>   qemu_process: Setup paths within qemuProcessInitQmp
>   qemu_process: Stop retaining Qemu Monitor config in qemuProcess
>   qemu_process: Don't open monitor if process failed
>   qemu_process: Cleanup qemuProcess alloc function
>   qemu_process: Cleanup qemuProcessStopQmp function
>   qemu_process: Catch process free before process stop
>   qemu_monitor: Make monitor callbacks optional
>   qemu_process: Enter QMP command mode when starting QEMU Process
>   qemu_process: Use unique directories for QMP processes
>   qemu_process: Stop locking QMP process monitor immediately
>   qemu_capabilities: Introduce CPUModelInfo to virCPUDef function
>   qemu_capabilities: Introduce virCPUDef to CPUModelInfo function
>   qemu_monitor: Support query-cpu-model-baseline QMP command
>   qemu_driver: Consolidate code to baseline using libvirt
>   qemu_driver: Decouple code for baseline using libvirt
>   qemu_driver: Identify using libvirt as a distinct way to compute
> ba

  1   2   3   >